diff --git a/.env.example b/.env.example index 996df4a..18651f4 100644 --- a/.env.example +++ b/.env.example @@ -23,6 +23,7 @@ H5_PUBLIC_BASE_URL=http://127.0.0.1:8081 DATABASE_URL=mysql://boot:password@localhost:3306/tkmind # 或分别设置 MYSQL_HOST / MYSQL_PORT / MYSQL_USER / MYSQL_PASSWORD / MYSQL_DATABASE H5_USERS_ROOT=/root/tkmind_go/users +# 新用户赠送余额(人民币分,500 = ¥5.00;勿与美元 cents 混淆) H5_SIGNUP_BALANCE_CENTS=500 H5_ADMIN_USERNAME=admin H5_ADMIN_PASSWORD=change-me-admin @@ -47,12 +48,13 @@ H5_ADMIN_PASSWORD=change-me-admin # H5_LOCAL_LLM_NAME=Local Ollama 7B H5_ACCESS_PASSWORD=change-me -# 计费(Phase 2) -# H5_USE_BACKEND_COST=1 # 优先用后端 accumulatedCost(USD)计费 -# H5_USD_CNY_RATE=7.2 -# H5_BILL_INPUT_CENTS_PER_1K=2 -# H5_BILL_OUTPUT_CENTS_PER_1K=6 +# 计费(Phase 2,金额单位均为人民币分) +# 默认按 Token 单价扣费(人民币结算);勿开启美元成本换算除非明确需要 +# H5_USE_BACKEND_COST=0 +# H5_BILL_INPUT_CENTS_PER_1K=2 # 输入 Token:2 分/1k(¥0.02/1k) +# H5_BILL_OUTPUT_CENTS_PER_1K=6 # 输出 Token:6 分/1k(¥0.06/1k) # H5_MIN_BILL_CENTS=1 +# 仅调试:H5_USE_BACKEND_COST=1 + H5_USD_CNY_RATE=7.2(上游 USD × 汇率 → 人民币分) # 用户自助充值(微信支付) # H5_RECHARGE_TIERS_CENTS=500,1000,3000,5000,10000,20000 diff --git a/billing.mjs b/billing.mjs index a0fe0c7..1a0572f 100644 --- a/billing.mjs +++ b/billing.mjs @@ -1,5 +1,6 @@ export function loadBillingConfig() { - const useBackendCost = process.env.H5_USE_BACKEND_COST !== '0'; + // 默认按人民币分(CNY cents)计费;仅当 H5_USE_BACKEND_COST=1 时才用上游 USD 成本换算。 + const useBackendCost = process.env.H5_USE_BACKEND_COST === '1'; return { useBackendCost, usdCnyRate: Number(process.env.H5_USD_CNY_RATE ?? 7.2), @@ -53,6 +54,8 @@ export function computeDeltaCostCents(previous, current, config = loadBillingCon return Math.max(config.minBillCents, Math.ceil(currCost * config.usdCnyRate * 100)); } + // 默认路径:按 Token 增量 × 人民币单价(分/1k tokens)扣费。 + const prevIn = Number(previous?.lastInputTokens ?? 0); const prevOut = Number(previous?.lastOutputTokens ?? 0); const deltaIn = Math.max(0, current.accumulatedInputTokens - prevIn); diff --git a/billing.test.mjs b/billing.test.mjs index 8cd0da6..5279949 100644 --- a/billing.test.mjs +++ b/billing.test.mjs @@ -39,3 +39,16 @@ test('computeDeltaCostCents returns zero when no usage delta', () => { }); assert.equal(computeDeltaCostCents(previous, current, config), 0); }); + +test('computeDeltaCostCents ignores backend USD cost unless explicitly enabled', () => { + const previous = { lastInputTokens: 0, lastOutputTokens: 0, lastAccumulatedCost: 0.01 }; + const current = normalizeTokenState({ + accumulatedInputTokens: 1000, + accumulatedOutputTokens: 500, + accumulatedCost: 0.02, + }); + const rmbConfig = { ...config, useBackendCost: false }; + assert.equal(computeDeltaCostCents(previous, current, rmbConfig), 5); + const usdConfig = { ...config, useBackendCost: true }; + assert.equal(computeDeltaCostCents(previous, current, usdConfig), 8); +}); diff --git a/mindspace-visual-editor.test.mjs b/mindspace-visual-editor.test.mjs index 67b3877..5fb7ab2 100644 --- a/mindspace-visual-editor.test.mjs +++ b/mindspace-visual-editor.test.mjs @@ -26,3 +26,14 @@ test('buildEditablePreviewDocument provides blank fallback', () => { const result = buildEditablePreviewDocument(''); assert.match(result, /空白页面/); }); + +test('buildEditablePreviewDocument strips CSP meta so editor script can run', () => { + const html = `
+ +- 文字直接改 · 图片/音视频点击换 · 背景点空白区 · 链接双击改地址 + + 文字 + + 图片/媒体 + + 链接 + + 背景 — 预览内左上角有完整图例,虚线框即可直接修改
) : null}