fix(admin): 让后台「销量浮动」设置真正生效
资源 metabox 和快捷编辑都能设置「销量浮动」(pay_count),但设了完全 不起作用——所有读取方用的是另一个键 virtual_sales(§3.8 电商的虚拟 销量加成),pay_count 只被写、从未被读。 新增统一读取口径 aksrt_get_content_sales_count($post, $pay_meta): 真实订单销量 + pay_count,并把四处各自拼装销量的地方全部接到这个 口径上: - aksrt_get_download_box_meta() 的 sales_count(内容帖) - aksrt_get_resource_meta() 的 sales_count(资源帖) - 付费墙 aksrt_get_paywall_html() 的已售徽标 - 付费盒 aksrt_get_paid_box_html() 的已售徽标 - 后台「所有文章」销售数据列的销量 此前资源帖的 sales_count 走的是「虚拟销量 + 下载量」这条与内容帖 不一致的口径,现统一。 快捷编辑的 pay_count 运算本是整数加减 + max(0,...) 归零,与读取口径 一致,无需改动。 _aksrt_sales_volume 保持不变,它仍是订单流水累加的副本;列表列取 订单表统计与 meta 副本的较大值再加浮动量,避免两条链路数字打架。 新增 sales-volume-float-contract.test.cjs 4 项,锁住「pay_count 必须 被销量读取方消费」这一契约,防止以后又被改成摆设。 验证:node --test tests/widget-system/*.test.cjs 449 项全部通过 (原有 445 项 + 新增 4 项);php -l 三个 PHP 文件无语法错误。
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
const test = require('node:test')
|
||||
const assert = require('node:assert/strict')
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
|
||||
const root = path.resolve(__dirname, '../..')
|
||||
const read = file => fs.readFileSync(path.join(root, file), 'utf8')
|
||||
|
||||
const pay = read('inc/helpers/aksrt-pay.php')
|
||||
const resource = read('inc/helpers/aksrt-resource.php')
|
||||
const list = read('src/Admin/Native/PostListEnhance.php')
|
||||
const domain = read('src/Core/DomainModel.php')
|
||||
|
||||
test('sales count has a single read path that adds the 销量浮动', () => {
|
||||
// 展示销量只有一个口径:真实订单 + 后台「销量浮动」(pay_count)。
|
||||
// 此前各调用点各自拼 virtual_sales / sales_volume,pay_count 写进去却没人读。
|
||||
assert.match(pay, /function aksrt_get_content_sales_count\(/)
|
||||
assert.match(pay, /RESOURCE_SALES_VOLUME_KEY/)
|
||||
assert.match(pay, /\$pay_meta\['pay_count'\]/)
|
||||
// 两部分都必须下限为 0,避免负的浮动把销量拉成负数。
|
||||
assert.match(pay, /max\(0, \$real \+ \$float\)/)
|
||||
})
|
||||
|
||||
test('every sales_count producer goes through that read path', () => {
|
||||
// 内容帖、资源帖、付费墙、付费盒四处不得再各自拼装销量。
|
||||
assert.match(pay, /'sales_count'\s*=>\s*\$show_sales \? aksrt_get_content_sales_count\(\$p, \$pay_meta\) : 0/)
|
||||
assert.match(resource, /'sales_count'\s*=>\s*\$show_sales \? aksrt_get_content_sales_count\(\$p, \$pay_meta\) : 0/)
|
||||
assert.match(pay, /\$sales = aksrt_get_content_sales_count\(\$post, \$meta\)/)
|
||||
|
||||
// 不得再出现按 virtual_sales 现拼销量的旧写法。
|
||||
assert.doesNotMatch(pay, /\$sales\s*=\s*max\(0, \(int\) \(\$meta\['virtual_sales'\] \?\? 0\)\);/)
|
||||
assert.doesNotMatch(pay, /\$virtual_sales \+ max\(0, \$sales_volume, \$download_count\)/)
|
||||
assert.doesNotMatch(resource, /\$virtual_sales \+ max\(0, max\(\$download_count, \$legacy_download_count\)\)/)
|
||||
})
|
||||
|
||||
test('pay_count is declared, sanitized and consumed end to end', () => {
|
||||
// 删掉任何一段,这个字段就又变成「设了不生效」的摆设。
|
||||
assert.match(domain, /'pay_count'\s*=>\s*0/, 'default value exists')
|
||||
assert.match(domain, /\$meta\['pay_count'\]\s*=\s*\(int\)/, 'sanitize exists')
|
||||
|
||||
// 后台两个入口都写这个键:资源 metabox 与文章列表快捷/批量编辑。
|
||||
assert.match(read('src/Core/ResourceMetaBox.php'), /'pay_count'/)
|
||||
assert.match(list, /case 'pay_count':/)
|
||||
|
||||
// 快捷编辑按整数运算,与读取口径的 max(0,(int)) 一致。
|
||||
const branch = list.slice(list.indexOf("case 'pay_count':"), list.indexOf('case \'price\':'))
|
||||
assert.match(branch, /apply_operation/)
|
||||
assert.match(branch, /max\(0, \(int\) \$new\)/)
|
||||
})
|
||||
|
||||
test('the admin sales column shows 真实 + 浮动, not the raw meta', () => {
|
||||
// 列表列与前台同一口径:真实订单 + pay_count,否则后台与前台数字不一致。
|
||||
assert.match(list, /\$sales_volume = max\(\$real_sales, \$meta_sales\) \+ max\(0, \(int\) \(\$pay_meta\['pay_count'\] \?\? 0\)\)/)
|
||||
// 真实销量取订单表统计,不能只有 meta 副本。
|
||||
assert.match(list, /\$real_sales = \$this->real_sales_count\(\$post_id\)/)
|
||||
})
|
||||
Reference in New Issue
Block a user