feat: 同步管理端、用户端与后端业务,并接通线上 Web 接口

补齐平台订阅、外部登录、CRM 同步与用户端页面;Nginx 转发用户端接口,登录页使用 Google 与 Apple 标志。

Co-authored-by: Cursor <cursoragent@cursor.com>
这个提交包含在:
wikiboss
2026-09-23 18:01:47 +08:00
父节点 8ea9c25386
当前提交 62e0ae4435
共有 227 个文件被更改,包括 21855 次插入 和 5264 次删除

查看文件

@@ -3,7 +3,6 @@ import assert from 'node:assert/strict';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import defaultI18n from '../src/locale/index.ts';
const adminRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const billingPagePath = path.join(
@@ -14,6 +13,7 @@ const billingLocalePath = path.join(
adminRoot,
'src/pages/settings/billing/locale/index.ts'
);
const mainLocalePath = path.join(adminRoot, 'src/locale/index.ts');
function readPage(): string {
assert.ok(fs.existsSync(billingPagePath), '订阅账单页面必须存在');
@@ -25,6 +25,31 @@ function readLocale(): string {
return fs.readFileSync(billingLocalePath, 'utf-8');
}
function assertNoFabricatedCheckoutUrl(content: string, label: string) {
assert.ok(!content.includes('cs_test_'), `${label}禁止前端自造 cs_test_`);
assert.ok(
!content.includes('https://checkout.stripe.com'),
`${label}禁止前端自造完整 checkout URL`
);
assert.ok(!content.includes('sk_live'), `${label}禁止出现 sk_live`);
}
function assertNoFakePayPalCheckout(content: string, label: string) {
assert.ok(
!/paypal\.com/i.test(content),
`${label}禁止出现 paypal.com 假结账地址`
);
assert.ok(
!/www\.paypal\.com/i.test(content),
`${label}禁止出现 www.paypal.com`
);
assert.ok(
!content.includes('paypal-checkout') &&
!content.includes('billing/paypal'),
`${label}禁止伪造 PayPal 结账接口`
);
}
test('1. settings/billing 必须请求 billing/currentPlan', () => {
const content = readPage();
@@ -58,10 +83,8 @@ test('1. settings/billing 必须请求 billing/currentPlan', () => {
'禁止用 Mock.js 假数据冒充成功'
);
assert.ok(!/\bany\b/.test(content), '禁止使用 any');
assert.ok(
!content.includes('stripe.com') && !content.includes('sk_live'),
'源码不含 stripe.com 或 sk_live'
);
assertNoFabricatedCheckoutUrl(content, '页面');
assertNoFakePayPalCheckout(content, '页面');
});
test('2. settings/billing 必须使用 Card / Progress / Tag', () => {
@@ -94,10 +117,8 @@ test('2. settings/billing 必须使用 Card / Progress / Tag', () => {
'禁止用 Mock.js'
);
assert.ok(!/\bany\b/.test(content), '禁止使用 any');
assert.ok(
!content.includes('stripe.com') && !content.includes('sk_live'),
'源码不含 stripe.com 或 sk_live'
);
assertNoFabricatedCheckoutUrl(content, '页面');
assertNoFakePayPalCheckout(content, '页面');
});
test('3. settings/billing locale 必须包含 menu.settings.billing', () => {
@@ -109,6 +130,7 @@ test('3. settings/billing locale 必须包含 menu.settings.billing', () => {
);
assert.ok(content.includes("'en-US'"), '必须包含英文案');
assert.ok(content.includes("'zh-CN'"), '必须包含中文案');
assert.ok(content.includes("'ar-SA'"), '必须包含阿语文案');
assert.ok(
content.includes('settingsBilling.request.fail'),
'必须包含失败提示文案'
@@ -121,16 +143,146 @@ test('3. settings/billing locale 必须包含 menu.settings.billing', () => {
content.includes('settingsBilling.alert'),
'必须包含国际卡与发票后续接入提示'
);
assert.ok(
content.includes('settingsBilling.checkout.stripeMissing'),
'必须包含未配置 Stripe 无法打开支付的 i18n'
);
assert.ok(
content.includes('settingsBilling.action.upgrade'),
'必须包含升级/结账文案'
);
assert.ok(
content.includes('settingsBilling.checkout.paypalUnavailable'),
'必须包含 PayPal 暂不可用文案 key'
);
assert.ok(
content.includes('settingsBilling.action.paypal'),
'必须包含 PayPal 按钮文案 key'
);
assert.ok(!/\bany\b/.test(content), 'locale 禁止使用 any');
assert.ok(
!/[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/u.test(content),
'locale 禁止使用 emoji'
);
assert.ok(
!content.includes('stripe.com') && !content.includes('sk_live'),
'源码不含 stripe.com 或 sk_live'
);
assertNoFabricatedCheckoutUrl(content, 'locale');
assertNoFakePayPalCheckout(content, 'locale');
assert.equal(defaultI18n['en-US']['menu.settings.billing'], 'Billing');
assert.equal(defaultI18n['zh-CN']['menu.settings.billing'], '订阅账单');
const mainLocale = fs.readFileSync(mainLocalePath, 'utf-8');
assert.ok(
/'en-US'[\s\S]*'menu\.settings\.billing':\s*'Billing'/.test(mainLocale),
'主词典 en-US menu.settings.billing 应为 Billing'
);
assert.ok(
/'zh-CN'[\s\S]*'menu\.settings\.billing':\s*'订阅账单'/.test(mainLocale),
'主词典 zh-CN menu.settings.billing 应为 订阅账单'
);
});
test('4. settings/billing 升级结账仅信任 Stripe 结账域', () => {
const content = readPage();
const locale = readLocale();
assert.ok(
content.includes('stripe-checkout') ||
content.includes('billing/stripe-checkout'),
'必须请求 POST /api/admin/team/billing/stripe-checkout'
);
assert.ok(content.includes('window.open'), '成功时必须 window.open 打开结账页');
assert.ok(content.includes('Message.error'), '失败必须 Message.error');
assert.ok(
content.includes('checkout.stripe.com'),
'必须校验返回 url 主机为 checkout.stripe.com'
);
assert.ok(
content.includes("protocol === 'https:'") ||
content.includes('protocol === "https:"') ||
content.includes("protocol==='https:'"),
'必须校验返回 url 协议为 https'
);
assert.ok(
content.includes('settingsBilling.checkout.stripeMissing'),
'缺服务端文案时必须回退到 Stripe 未配置 i18n'
);
assert.ok(
locale.includes("'settingsBilling.checkout.stripeMissing'"),
'locale 必须声明 Stripe 未配置文案 key'
);
assert.ok(
/'zh-CN'[\s\S]*settingsBilling\.checkout\.stripeMissing'[\s\S]*未配置 Stripe/.test(
locale
),
'中文案必须含「未配置 Stripe」'
);
assert.ok(
/'en-US'[\s\S]*settingsBilling\.checkout\.stripeMissing'/.test(locale),
'英文案必须含 Stripe missing 提示'
);
assert.ok(
/'ar-SA'[\s\S]*settingsBilling\.checkout\.stripeMissing'/.test(locale),
'阿语文案必须含 Stripe missing 提示'
);
assertNoFabricatedCheckoutUrl(content, '结账逻辑');
assertNoFakePayPalCheckout(content, '结账逻辑');
assert.ok(!/\bany\b/.test(content), '结账逻辑禁止 any');
});
test('5. settings/billing PayPal 按钮必须禁用且不可假结账', () => {
const content = readPage();
const locale = readLocale();
assert.ok(
content.includes('settingsBilling.action.paypal'),
'页面必须渲染 PayPal 按钮文案'
);
assert.ok(
content.includes('settingsBilling.checkout.paypalUnavailable'),
'页面必须展示 PayPal 暂不可用说明'
);
assert.ok(
/disabled(\s*=\s*\{?\s*true\s*\}?)?/.test(content) ||
content.includes('disabled={true}') ||
content.includes('disabled'),
'PayPal 按钮必须 disabled'
);
assert.ok(
!content.includes('Message.success'),
'PayPal 点击不得 Message.success'
);
assert.ok(
!content.includes('window.open') ||
content.includes('isTrustedStripeCheckoutUrl'),
'window.open 仅允许用于受信 Stripe URL'
);
assert.ok(
!content.includes('paypal-checkout') &&
!content.includes('billing/paypal'),
'禁止请求不存在的 PayPal 结账接口'
);
assert.ok(
locale.includes("'settingsBilling.action.paypal'"),
'locale 必须声明 PayPal 按钮文案'
);
assert.ok(
locale.includes("'settingsBilling.checkout.paypalUnavailable'"),
'locale 必须声明 PayPal 暂不可用文案'
);
assert.ok(
/'zh-CN'[\s\S]*settingsBilling\.checkout\.paypalUnavailable'[\s\S]*暂不可用/.test(
locale
),
'中文案必须说明 PayPal 暂不可用'
);
assert.ok(
/'en-US'[\s\S]*settingsBilling\.checkout\.paypalUnavailable'[\s\S]*(unavailable|not available|temporarily)/i.test(
locale
),
'英文案必须说明 PayPal 暂不可用'
);
assert.ok(
/'ar-SA'[\s\S]*settingsBilling\.checkout\.paypalUnavailable'/.test(locale),
'阿语文案必须含 PayPal 暂不可用提示'
);
assertNoFakePayPalCheckout(content, 'PayPal 按钮');
assertNoFakePayPalCheckout(locale, 'PayPal locale');
assert.ok(!/\bany\b/.test(content), 'PayPal 逻辑禁止 any');
});