初始化提交:go比特版本精简

This commit is contained in:
2026-09-20 17:02:11 +08:00
commit f41a979462
213 changed files with 58288 additions and 0 deletions
+324
View File
@@ -0,0 +1,324 @@
'use strict';
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const vm = require('vm');
(async () => {
const root = path.join(__dirname, '..');
const appSource = fs.readFileSync(path.join(root, 'public', 'app.js'), 'utf8');
const html = fs.readFileSync(path.join(root, 'public', 'index.html'), 'utf8');
const styles = fs.readFileSync(path.join(root, 'public', 'style.css'), 'utf8');
const operations = fs.readFileSync(path.join(root, 'src', 'routes', 'operations.js'), 'utf8');
const accountsRoute = fs.readFileSync(path.join(root, 'src', 'routes', 'accounts.js'), 'utf8');
const runner = fs.readFileSync(path.join(root, 'src', 'workers', 'task_runner.js'), 'utf8');
const rechargeService = fs.readFileSync(path.join(root, 'src', 'services', 'recharge_task_service.js'), 'utf8');
assert.match(
html,
/runOpenAIGetAuth\(\)[\s\S]{0,200}runOpenAIQueryPlan\(\)[\s\S]{0,200}openRechargeModal\(\)/,
'查询套餐按钮应位于提取授权JSON右侧',
);
assert.match(html, /<th>ChatGPT<\/th>\s*<th>是否已充值<\/th>\s*<th>授权JSON<\/th>\s*<th>AC凭证<\/th>\s*<th>Cli_AC凭证<\/th>\s*<th>账号套餐<\/th>/);
assert.match(html, /x-model="rechargeCredentialForm\.keyId"/);
assert.match(html, /type="password"[^>]*x-model="rechargeCredentialForm\.secret"/);
assert.match(styles, /input\[type="text"\],\s*input\[type="password"\],\s*input\[type="number"\]/,
'API Secret 密码框应与 Key ID 使用同一套输入框样式');
assert.match(html, /x-model="rechargeCardKeys"/);
assert.match(html, /完整 ChatGPT Session(结构化 JSON)/);
assert.match(operations, /taskType === 'card_pay_recharge' && !isLocalRequest\(req\)/);
assert.match(operations, /hasOwnProperty\.call\(params, 'confirmDuplicate'\)[\s\S]{0,100}params\.confirmDuplicate !== false/);
assert.match(runner, /latest\.chatgpt_session/);
assert.match(runner, /sessionText:\s*latest\.chatgpt_session/);
assert.match(runner, /confirmDuplicate:\s*false/);
assert.match(runner, /parseInt\(params && params\.threadCount, 10\) \|\| 2/,
'未指定充值并发时服务端应默认使用 2');
assert.match(runner, /Math\.min\(requestedRechargeConcurrency, 5\)/,
'卡付充值应限制为最多 5 路并发');
assert.match(runner, /const rechargeStartSpacingMs\s*=\s*1000/,
'卡付充值请求应相隔 1 秒发起');
assert.match(runner, /const rechargeQueryConcurrency\s*=\s*2/,
'卡付任务查询应与提交并发分离并限制为 2 路');
assert.match(html, /id="recharge-concurrency"[\s\S]{0,180}min="1" max="5"/,
'充值弹窗应提供 1 到 5 的独立并发设置');
assert.match(runner, /type:\s*'progress',\s*current:\s*0,\s*total:\s*accounts\.length/,
'充值开始时应立即推送 0/总数进度');
assert.match(runner, /onPrepared:[\s\S]{0,800}onConfirmed:[\s\S]{0,800}onPoll:/,
'充值应逐阶段推送预创建、确认和轮询进度');
assert.match(runner, /stagePrefix[\s\S]{0,300}开始处理/,
'每个账号应实时打印开始处理信息');
assert.match(runner, /maxRechargeAttempts\s*=\s*3/,
'单个账号充值最多应尝试三次');
assert.match(runner, /const rechargeOperationId\s*=\s*operationMap\.get\(emailKey\)[\s\S]{0,100}createRechargeOperationId\(email, cardKey, false\)/,
'每个账号应复用认领阶段生成的稳定充值操作号');
assert.match(runner, /operationId:\s*attemptOffset\s*>\s*0[\s\S]{0,180}rechargeOperationId/,
'只有远端任务明确失败后才应使用新的尝试幂等号');
assert.match(runner, /使用同一卡密重试/,
'重试进度应明确提示使用同一卡密');
assert.match(rechargeService, /error\s*&&\s*error\.retryable\s*===\s*true/,
'修改型充值请求的瞬时HTTP错误必须保留为待确认');
assert.match(runner, /rechargeNeedsManualConfirmation\(error, remoteTaskId\)/,
'最终失败状态必须结合远端任务号判断是否等待人工确认');
assert.match(operations, /message:\s*account\s*\?\s*\(account\.message/,
'充值结论应通过 SSE 同步到通用处理结论');
assert.match(runner, /publishRecharge\([\s\S]{0,180}'等待已确认'/,
'结果待确认时应转为等待人工确认状态');
assert.match(operations, /const nextStatus\s*=\s*remoteTaskId\s*\?\s*'充值中'\s*:\s*'充值失败'/,
'任务中断时已提交任务应保持充值中,未提交账号才标记失败');
assert.match(accountsRoute, /router\.put\('\/:email\/recharge-status'/,
'应提供本机人工修改充值状态接口');
assert.match(html, /<option value="账号本身已有会员">账号本身已有会员<\/option>/,
'充值状态原地下拉框应包含账号本身已有会员');
assert.match(appSource, /rechargeStatusOptions:[^\n]*'账号本身已有会员'/,
'组合筛选的充值状态应包含账号本身已有会员');
assert.match(accountsRoute, /allowedStatuses[^\n]*'账号本身已有会员'/,
'服务端应允许人工保存账号本身已有会员');
assert.match(styles, /\.status-账号本身已有会员\s*\{/,
'账号本身已有会员应有独立状态样式');
assert.match(accountsRoute, /router\.get\('\/:email\/recharge-card'/,
'应提供本机按需查看最近充值卡密的接口');
assert.match(accountsRoute, /recharge_card_key,[\s\S]{0,180}has_recharge_card/,
'账号列表只能返回是否有卡密,不能返回卡密明文');
assert.match(html, /openRechargeCard\(account\)[\s\S]{0,80}查看卡密/,
'充值状态旁应提供查看卡密按钮');
assert.match(html, /showRechargeCardModal/,
'应提供本次充值卡密查看弹窗');
assert.match(html, /充值完成时间:[\s\S]{0,180}rechargeCardCompletedAt/,
'查看卡密弹窗应显示本次充值完成时间');
assert.match(appSource, /CURRENT_TIMESTAMP 保存 UTC[\s\S]{0,500}timeZone:\s*'Asia\/Shanghai'/,
'数据库时间应按UTC解析并强制显示为北京时间');
assert.match(accountsRoute, /rechargeStatus:[\s\S]{0,120}rechargedAt:/,
'卡密接口应同时返回充值状态和完成时间');
assert.match(html, /@dblclick\.stop="startInlineEditRechargeStatus\(account\.email\)"/);
assert.match(html, /inlineEditRechargeStatusEmail === account\.email[\s\S]{0,700}<select class="status-select"/,
'充值状态应使用与状态列一致的原地下拉框');
for (const status of ['未充值', '充值中', '等待已确认', '充值成功', '充值失败']) {
assert.match(html, new RegExp(`<option value="${status}">${status}<\\/option>`));
}
assert.match(html, /quickSetRechargeStatus\(account\.email, \$event\.target\.value\)/);
assert.doesNotMatch(appSource, /请输入充值状态/,
'充值状态不应继续使用手工输入提示框');
assert.match(appSource, /startsWith\('等待已确认'\)/);
assert.match(styles, /\.status-等待已确认\s*\{/);
assert.doesNotMatch(runner, /openai_auth_json[^\n]*card_pay_recharge/);
let fetchImpl = async () => ({
ok: true,
json: async () => ({ success: true, data: { configured: true, keyIdMasked: 'unit••••mask' } }),
});
let latestEventSource = null;
let promptValue = '等待已确认';
class TestEventSource {
constructor(url) {
this.url = url;
latestEventSource = this;
}
close() { this.closed = true; }
}
const context = vm.createContext({
console, Set, Map, Date, JSON, Math, String, Number, Object, Array, RegExp, Promise,
setTimeout, clearTimeout,
fetch: (...args) => fetchImpl(...args),
confirm: () => true,
prompt: () => promptValue,
EventSource: TestEventSource,
});
vm.runInContext(`${appSource}\nthis.__geminiApp = geminiApp;`, context, { filename: 'public/app.js' });
const app = context.__geminiApp();
assert.match(app.formatDate('2026-08-22 05:51:48'), /13:51:48/,
'SQLite UTC时间 05:51:48 应显示为北京时间 13:51:48');
assert.match(app.formatDate('2026-08-22T05:51:48Z'), /13:51:48/,
'标准UTC时间也应显示为北京时间');
assert.strictEqual(app.formatDate('invalid-time'), 'invalid-time');
const logs = [];
app.addLog = (message, type) => logs.push({ message, type });
app.accounts = [
{ email: 'first@example.com' },
{ email: 'second@example.com' },
];
app._accountByEmail = new Map(app.accounts.map(account => [account.email, account]));
app.selectedEmails = new Set(app.accounts.map(account => account.email));
app.rechargeCredentialMeta = { configured: true, keyIdMasked: 'unit••••mask', updatedAt: null };
app.loadRechargeCredentialMeta = async () => {};
await app.openRechargeModal();
assert.strictEqual(app.showRechargeModal, true);
assert.strictEqual(app.rechargeConcurrency, 2, '充值并发默认值应为 2');
app.rechargeConcurrency = 99;
assert.strictEqual(app.normalizedRechargeConcurrency, 5, '充值并发不得超过 5');
app.rechargeConcurrency = 0;
assert.strictEqual(app.normalizedRechargeConcurrency, 1, '充值并发不得小于 1');
app.rechargeConcurrency = 'invalid';
assert.strictEqual(app.normalizedRechargeConcurrency, 2, '无效充值并发应恢复默认值 2');
app.rechargeConcurrency = 2;
assert.deepStrictEqual(
Array.from(app.rechargeAccounts, row => row.email),
['first@example.com', 'second@example.com'],
);
app.rechargeCardKeys = 'CARD-ONE\n\nCARD-TWO';
assert.strictEqual(app.rechargeInputError, '卡密中间不能有空行');
app.rechargeCardKeys = 'CARD-ONE\nCARD-ONE';
assert.strictEqual(app.rechargeInputError, '卡密不能重复');
app.rechargeCardKeys = 'CARD-ONE\nCARD-TWO\n';
assert.strictEqual(app.rechargeInputError, '');
let submitted = null;
app.runTask = async (taskType, params, accounts) => {
submitted = { taskType, params, accounts };
return true;
};
await app.confirmRecharge();
assert.strictEqual(submitted.taskType, 'card_pay_recharge');
assert.strictEqual(submitted.params.threadCount, 2);
assert.deepStrictEqual(
JSON.parse(JSON.stringify(submitted.params.assignments)),
[
{ email: 'first@example.com', cardKey: 'CARD-ONE' },
{ email: 'second@example.com', cardKey: 'CARD-TWO' },
],
);
assert.strictEqual(Object.prototype.hasOwnProperty.call(submitted.params, 'accessToken'), false);
assert.strictEqual(Object.prototype.hasOwnProperty.call(submitted.params, 'session'), false);
assert.deepStrictEqual(
JSON.parse(JSON.stringify(submitted.accounts)),
[{ email: 'first@example.com' }, { email: 'second@example.com' }],
'充值任务只应把邮箱传给 Worker,不发送完整账号记录',
);
assert.strictEqual(app.showRechargeModal, false);
assert.strictEqual(app.rechargeCardKeys, '');
let request = null;
fetchImpl = async (url, options) => {
request = { url, options };
return {
ok: true,
json: async () => ({
success: true,
data: { configured: true, keyIdMasked: 'abcd••••wxyz', updatedAt: '2026-08-21T00:00:00Z' },
}),
};
};
app.rechargeCredentialForm = { keyId: ' api-key-id ', secret: 'unit-secret' };
await app.saveRechargeCredentials();
assert.strictEqual(request.url, '/api/recharge-credentials');
assert.strictEqual(request.options.method, 'PUT');
assert.deepStrictEqual(JSON.parse(request.options.body), { keyId: 'api-key-id', secret: 'unit-secret' });
assert.deepStrictEqual(
JSON.parse(JSON.stringify(app.rechargeCredentialForm)),
{ keyId: '', secret: '' },
'保存后必须立即清空前端凭据表单',
);
assert.strictEqual(Object.values(app.settings).includes('unit-secret'), false);
const account = app.accounts[0];
account.has_recharge_card = true;
fetchImpl = async (url, options) => {
request = { url, options };
return {
ok: true,
status: 200,
json: async () => ({
success: true,
data: {
cardKey: 'CARD-USED-THIS-TIME',
rechargeStatus: '充值成功',
rechargedAt: '2026-08-21T00:00:00Z',
},
}),
};
};
await app.openRechargeCard(account);
assert.strictEqual(request.url, '/api/accounts/first%40example.com/recharge-card');
assert.strictEqual(request.options.cache, 'no-store');
assert.strictEqual(app.showRechargeCardModal, true);
assert.strictEqual(app.rechargeCardText, 'CARD-USED-THIS-TIME');
assert.strictEqual(app.rechargeCardCompletedAt, '2026-08-21T00:00:00Z');
app.closeRechargeCard();
assert.strictEqual(app.rechargeCardText, '');
assert.strictEqual(app.rechargeCardCompletedAt, '');
fetchImpl = async (url, options) => {
request = { url, options };
return {
ok: true,
json: async () => ({
success: true,
data: { ...account, recharge_status: '等待已确认', recharge_message: '人工修改为等待已确认' },
}),
};
};
app._rebuildDashboardStats = () => {};
app.editRechargeStatus(account);
assert.strictEqual(app.inlineEditRechargeStatusEmail, account.email);
await app.quickSetRechargeStatus(account.email, '等待已确认');
assert.strictEqual(request.url, '/api/accounts/first%40example.com/recharge-status');
assert.strictEqual(request.options.method, 'PUT');
assert.deepStrictEqual(JSON.parse(request.options.body), { status: '等待已确认' });
assert.strictEqual(account.recharge_status, '等待已确认');
app._pendingAccountUpdates = new Map([[account.email, {
message: '充值成功',
recharge_status: '充值成功',
recharge_task_id: '123',
recharge_message: '充值成功',
recharged_at: '2026-08-21T00:00:00Z',
has_recharge_card: true,
}]]);
app._flushAccountUpdates();
assert.strictEqual(account.recharge_status, '充值成功');
assert.strictEqual(account.recharge_task_id, '123');
assert.strictEqual(account.message, '充值成功');
assert.strictEqual(account.has_recharge_card, true);
app.isRunning = false;
account.recharge_status = '充值失败';
account.recharge_message = '开放接口未查到卡密记录,请确认卡密及所属线路';
account.message = account.recharge_message;
account.failure_label = '功能失败';
app.accountLogs = {};
assert.strictEqual(
app.getLiveMessage(account),
'开放接口未查到卡密记录,请确认卡密及所属线路',
'充值完成后处理结论应显示完整充值原因,不能压缩为通用失败标签',
);
app.loadBrowsers = async () => {};
app.loadAccounts = async () => {};
app.isRunning = true;
app.currentTaskId = 'task-error';
app._activeTaskType = 'card_pay_recharge';
app._setActiveTaskEmails([account.email]);
app.startSSEListener('task-error');
latestEventSource.onmessage({
data: JSON.stringify({
type: 'done',
result: { taskType: 'card_pay_recharge', success: false, error: '手动停止' },
}),
});
assert.strictEqual(logs[logs.length - 1].message, '⚠️ 任务已停止或异常结束');
assert.strictEqual(logs[logs.length - 1].type, 'warn');
let stopRequest = null;
fetchImpl = async (url, options) => {
stopRequest = { url, options };
return { ok: true, json: async () => ({ success: true }) };
};
app.isRunning = true;
app.currentTaskId = 'task-soft-stop';
app._activeTaskType = 'card_pay_recharge';
app.startSSEListener('task-soft-stop');
const softStopEventSource = latestEventSource;
await app.stopTask();
assert.strictEqual(stopRequest.url, '/api/operations/stop/task-soft-stop');
assert.strictEqual(app.isRunning, true, '充值软停止时应等待 Worker 的 done 事件');
assert.strictEqual(app.currentTaskId, 'task-soft-stop');
assert.strictEqual(softStopEventSource.closed, undefined, '充值软停止时不得提前关闭 SSE');
assert.strictEqual(logs[logs.length - 1].message, '⏳ 正在安全停止充值任务,请等待当前请求完成...');
console.log('recharge_ui.test.js: PASS');
})().catch(error => {
console.error(error);
process.exitCode = 1;
});