fix(后台本地预览): 会员档位保存按请求体回显

- 假后台读取 POST 请求体,把提交字段覆盖到对应档位行再回显,保存非 starter 档不再把表单与列表重置成 starter。
- 抽出 UNLIMITED_CONCURRENCY_THRESHOLD 常量,列表与回显共用同一哨兵。
This commit is contained in:
2026-10-03 17:47:22 +08:00
parent 44bbc846ae
commit dec44ec4ea
+48 -12
View File
@@ -4,6 +4,9 @@ import http from 'node:http';
const port = Number(process.argv[2] ?? 8099);
/** 与后端 `MEMBERSHIP_UNLIMITED_CONCURRENCY` 一致的假数据哨兵。 */
const UNLIMITED_CONCURRENCY_THRESHOLD = 128;
const admin = {
subject: 'admin:local',
username: 'owner',
@@ -473,7 +476,15 @@ const userDetail = {
tags: ['vip', '内测'],
};
function route(pathname, method, url) {
function parseJsonBody(requestBody) {
try {
return JSON.parse(requestBody);
} catch {
return null;
}
}
function route(pathname, method, url, requestBody = '') {
if (pathname === '/admin/api/login' && method === 'POST') {
return { token: 'local-fake-token', admin };
}
@@ -756,7 +767,8 @@ function route(pathname, method, url) {
periodPoints,
modelAccess,
concurrentJobLimit,
unlimitedConcurrency: concurrentJobLimit >= 128,
unlimitedConcurrency:
concurrentJobLimit >= UNLIMITED_CONCURRENCY_THRESHOLD,
enabled,
});
const plans = [
@@ -766,10 +778,22 @@ function route(pathname, method, url) {
plan('pro', '专业会员', 3, 29_900, 299_000, 3_650, 'full', 5, true),
plan('max', '旗舰会员', 4, 69_900, 699_000, 8_650, 'full', 128, true),
];
// 本地预览不解析请求体:POST 统一回显 starter,仅用于页面回填。
return method === 'POST'
? plans[1]
: { entries: plans, unlimitedConcurrencyThreshold: 128 };
// 本地预览按请求体回显被保存的档位:把提交字段覆盖到对应档位行,避免保存非 starter 档后表单被回填成 starter。
if (method === 'POST') {
const submitted = parseJsonBody(requestBody);
const target =
plans.find((entry) => entry.plan === submitted?.plan) ?? plans[1];
const merged = { ...target, ...(submitted ?? {}) };
return {
...merged,
unlimitedConcurrency:
Number(merged.concurrentJobLimit) >= UNLIMITED_CONCURRENCY_THRESHOLD,
};
}
return {
entries: plans,
unlimitedConcurrencyThreshold: UNLIMITED_CONCURRENCY_THRESHOLD,
};
}
if (pathname === '/admin/api/profile/recharge-products') {
const product = (
@@ -1152,13 +1176,25 @@ function route(pathname, method, url) {
const server = http.createServer((request, response) => {
const url = new URL(request.url ?? '/', `http://127.0.0.1:${port}`);
const payload = route(url.pathname, request.method ?? 'GET', url);
const body = JSON.stringify({ data: payload });
response.writeHead(200, {
'Content-Type': 'application/json; charset=utf-8',
'x-genarrative-response-envelope': 'v1',
const chunks = [];
request.on('data', (chunk) => {
chunks.push(chunk);
});
request.on('end', () => {
const requestBody = Buffer.concat(chunks).toString('utf8');
const payload = route(
url.pathname,
request.method ?? 'GET',
url,
requestBody,
);
const body = JSON.stringify({ data: payload });
response.writeHead(200, {
'Content-Type': 'application/json; charset=utf-8',
'x-genarrative-response-envelope': 'v1',
});
response.end(body);
});
response.end(body);
});
server.listen(port, '127.0.0.1', () => {