功能:按资源配置平台列表搜索
This commit is contained in:
@@ -32,6 +32,11 @@ const embeddedResources = new Set([
|
||||
'payment_refund',
|
||||
'wallet_apply_cash',
|
||||
]);
|
||||
const fieldLabelKeys = new Set(
|
||||
[...source.matchAll(/^\s{2}([a-z0-9_]+):\s*'/gm)].map(
|
||||
(match) => match[1],
|
||||
),
|
||||
);
|
||||
|
||||
for (const name of frontendNames) {
|
||||
const item = backend.get(name);
|
||||
@@ -50,8 +55,31 @@ for (const item of contract.resources) {
|
||||
);
|
||||
if (!embeddedResources.has(item.name) && !routes.includes(`'/${item.name}'`))
|
||||
throw new Error(`缺少后端资源路由:${item.name}`);
|
||||
const searchKeys = new Set();
|
||||
for (const field of item.searchFields ?? []) {
|
||||
if (searchKeys.has(field.key))
|
||||
throw new Error(`搜索字段重复:${item.name}.${field.key}`);
|
||||
searchKeys.add(field.key);
|
||||
if (!fieldLabelKeys.has(field.key))
|
||||
throw new Error(`搜索字段缺少中文列名:${item.name}.${field.key}`);
|
||||
if (!['text', 'enum'].includes(field.kind))
|
||||
throw new Error(`搜索字段类型无效:${item.name}.${field.key}`);
|
||||
if (field.kind === 'enum') {
|
||||
if (!field.values?.length)
|
||||
throw new Error(`搜索枚举缺少值:${item.name}.${field.key}`);
|
||||
for (const value of field.values) {
|
||||
if (!value.value || !value.label || value.value === value.label)
|
||||
throw new Error(`搜索枚举中英文映射无效:${item.name}.${field.key}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item.pageKind === 'tree' && searchKeys.size)
|
||||
throw new Error(`树形资源不应声明标准列表搜索:${item.name}`);
|
||||
}
|
||||
|
||||
if (backend.get('user_address')?.searchFields?.length)
|
||||
throw new Error('用户地址包含动态用户关系,本轮必须隐藏搜索框');
|
||||
|
||||
const forbidden = [
|
||||
'/platform/platform_',
|
||||
'/gas/gas_',
|
||||
|
||||
40
frontend/platform_admin/scripts/check-resource-search.mjs
Normal file
40
frontend/platform_admin/scripts/check-resource-search.mjs
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 功能:校验标准资源列表仅在具备真实搜索能力时显示动态中文提示。
|
||||
* 版本:v1.0.0
|
||||
*/
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const listPage = readFileSync(
|
||||
resolve(root, 'src/views/shared/CrudListPage.vue'),
|
||||
'utf8',
|
||||
);
|
||||
const searchState = readFileSync(
|
||||
resolve(root, 'src/views/shared/use-resource-list-search.ts'),
|
||||
'utf8',
|
||||
);
|
||||
const resources = readFileSync(resolve(root, 'src/api/resources.ts'), 'utf8');
|
||||
|
||||
const expectations = [
|
||||
[listPage, 'v-if="searchEnabled"', '不支持搜索时隐藏表单'],
|
||||
[listPage, ':placeholder="searchPlaceholder"', '动态显示可搜索字段'],
|
||||
[listPage, 'const keyword = requestKeyword();', '只发送受支持的关键字'],
|
||||
[searchState, 'definition.value.searchFields', '读取后端搜索契约'],
|
||||
[searchState, 'resourceListDisplayFields', '搜索字段与实际列表列求交集'],
|
||||
[searchState, 'if (searchEnabled.value || !route.query.keyword) return;', '清理不支持页面的陈旧关键字'],
|
||||
[searchState, '`可搜索:${searchableFields.value', '明确列出可搜索中文字段'],
|
||||
[resources, 'searchFields: resourceSearchFields(name)', '资源定义消费后端搜索契约'],
|
||||
[resources, "resourceSearchEnumOptions('staff_account', 'role_code')", '工作人员中文角色与搜索契约同源'],
|
||||
[resources, "resourceSearchEnumOptions('gasorder_basic', 'creator_type')", '订单创建方中文枚举与搜索契约同源'],
|
||||
];
|
||||
|
||||
for (const [content, fragment, description] of expectations) {
|
||||
if (!content.includes(fragment)) throw new Error(`资源搜索检查失败:${description}`);
|
||||
}
|
||||
if (listPage.includes('关键字段模糊搜索')) {
|
||||
throw new Error('仍存在未说明具体字段的旧搜索提示');
|
||||
}
|
||||
|
||||
console.log('资源搜索检查通过:动态提示、隐藏逻辑、URL 清理和中文枚举均已覆盖');
|
||||
Reference in New Issue
Block a user