feat(accounts): display business status with distinct colors

This commit is contained in:
2026-10-06 10:21:37 +08:00
parent 221cc30e31
commit 58e9a73cc4
2 changed files with 83 additions and 0 deletions
@@ -32,6 +32,7 @@ interface Row {
douyin_number?: string;
tags?: string[];
runtime_status?: string;
business_status: 'normal' | 'muted' | 'banned' | 'deleted';
environment?: EnvironmentView;
work_count?: number;
latest_published_at?: string | null;
@@ -220,6 +221,20 @@ export default function AccountManagementList() {
</Tag>
);
} },
{
title: '业务状态',
dataIndex: 'business_status',
render: (status: Row['business_status']) => {
const statuses = {
normal: { label: '正常', color: 'success' },
muted: { label: '禁言', color: 'warning' },
banned: { label: '封禁', color: 'error' },
deleted: { label: '注销', color: 'default' },
};
const { label, color } = statuses[status];
return <Tag color={color}>{label}</Tag>;
},
},
{
title: '操作',
key: 'actions',
@@ -0,0 +1,68 @@
const assert = require('node:assert/strict');
const { readFileSync } = require('node:fs');
const { createRequire } = require('node:module');
const { test } = require('node:test');
const vm = require('node:vm');
const ts = require('typescript');
const source = ts.createSourceFile(
'AccountManagementList.tsx',
readFileSync(`${__dirname}/../src/components/accounts/AccountManagementList.tsx`, 'utf8'),
ts.ScriptTarget.Latest,
true,
ts.ScriptKind.TSX,
);
const requireWeb = createRequire(`${__dirname}/../package.json`);
const { Tag } = requireWeb('antd');
let columns;
function visit(node) {
if (ts.isVariableDeclaration(node) && node.name.getText(source) === 'columns') {
columns = node.initializer.elements;
}
ts.forEachChild(node, visit);
}
visit(source);
function property(column, key) {
return column.properties.find(
(prop) => ts.isPropertyAssignment(prop) && prop.name.getText(source) === key,
)?.initializer;
}
function businessColumn() {
const column = columns.find((item) => property(item, 'title')?.text === '业务状态');
assert.ok(column, '我的账号列表必须有业务状态列');
const { outputText } = ts.transpileModule(`exports.column = (${column.getText(source)});`, {
compilerOptions: { jsx: ts.JsxEmit.ReactJSX, module: ts.ModuleKind.CommonJS },
});
const context = { exports: {}, require: requireWeb, Tag };
vm.runInNewContext(outputText, context);
return context.exports.column;
}
for (const [status, label, color] of [
['normal', '正常', 'success'],
['muted', '禁言', 'warning'],
['banned', '封禁', 'error'],
['deleted', '注销', 'default'],
]) {
test(`业务状态 ${status} 显示“${label}”及对应颜色`, () => {
const column = businessColumn();
assert.equal(column.dataIndex, 'business_status');
const result = column.render(status, { business_status: status, runtime_status: 'paused' });
assert.equal(result.type, Tag);
assert.equal(result.props.children, label);
assert.equal(result.props.color, color);
assert.equal(result.props.style, undefined, '使用默认 Tag 样式');
});
}
test('业务状态列紧邻现有状态列,运行状态判定保持不变', () => {
const titles = columns.map((column) => property(column, 'title')?.text);
const index = titles.indexOf('业务状态');
assert.ok(index > 0, '必须有独立的业务状态列');
assert.equal(titles[index - 1], '状态');
assert.equal(titles[index + 1], '操作');
const readiness = property(columns[index - 1], 'render').getText(source);
assert.match(readiness, /accountReadiness\(account, account\.environment \?\? null\)/);
});