diff --git a/.superpowers/sdd/2026-07-27-platform-admin-full-audit/task-6-report.md b/.superpowers/sdd/2026-07-27-platform-admin-full-audit/task-6-report.md index aba0882..ffbd95d 100644 --- a/.superpowers/sdd/2026-07-27-platform-admin-full-audit/task-6-report.md +++ b/.superpowers/sdd/2026-07-27-platform-admin-full-audit/task-6-report.md @@ -21,3 +21,10 @@ ## Notes The tree page consumes `parent_identity`; the corresponding menu API must expose that identity relation rather than an internal numeric parent key. + +## Fix round 1 + +- Replaced inferred front-end paths with an explicit 46-path catalogue: it includes the dashboard endpoint, adds `/ec/ec_order_item`, and removes the non-list safety disposal action from the menu catalogue. +- Corrected the safety, e-commerce, staff, and user API paths to match the registered backend routes exactly. +- Added audit assertions for exact path/mode/page-kind contracts, separate read-only UI surfaces, identifier leakage, and tree semantics. +- Detail drawers now filter `id` and `*_id` fields before rendering. diff --git a/frontend/platform_admin/scripts/audit-check.mjs b/frontend/platform_admin/scripts/audit-check.mjs index 4050e7d..24c0b73 100644 --- a/frontend/platform_admin/scripts/audit-check.mjs +++ b/frontend/platform_admin/scripts/audit-check.mjs @@ -1,90 +1,54 @@ import fs from 'node:fs'; import path from 'node:path'; -const baseline = process.argv.includes('--baseline'); - -const expectedResources = [ - ['gas', 'gas_basic', 'list'], ['gas', 'gas_account', 'list'], - ['delivery', 'delivery_basic', 'list'], ['delivery', 'delivery_account', 'list'], ['delivery', 'delivery_task', 'list'], ['delivery', 'delivery_track', 'list'], ['delivery', 'delivery_track_point', 'list'], - ['staff', 'staff_account', 'list'], ['staff', 'staff_credential', 'list'], - ['user', 'user_account', 'list'], ['user', 'user_address', 'list'], ['user', 'user_service_relation', 'list'], - ['device', 'dev_smart_cylinder_valve', 'list'], ['device', 'dev_device_binding', 'list'], ['device', 'dev_telemetry', 'list'], ['device', 'saf_rule', 'list'], ['device', 'saf_event', 'list'], ['device', 'saf_event_disposal', 'list'], ['device', 'saf_inspection', 'list'], - ['commerce', 'ec_category', 'list'], ['commerce', 'ec_product', 'list'], ['commerce', 'ec_product_attribute', 'list'], ['commerce', 'ec_product_image', 'list'], ['commerce', 'ec_cart', 'list'], ['commerce', 'ec_order', 'list'], ['commerce', 'ec_review', 'list'], - ['finance', 'fin_payment', 'list'], ['finance', 'fin_settlement', 'list'], ['finance', 'fin_reconciliation', 'list'], - ['content', 'cnt_content', 'list'], ['notification', 'ntf_template', 'list'], ['customer_service', 'cs_ticket', 'list'], - ['platform', 'platfrom_account', 'list'], ['platform', 'platform_role', 'list'], ['platform', 'platform_menu', 'tree'], - ['wallet', 'wallet', 'list'], ['wallet', 'wallet_ledger', 'list'], ['wallet', 'wallet_recharge', 'list'], ['wallet', 'wallet_withdrawal', 'list'], - ['report', 'report', 'list'], ['report', 'report_item', 'list'], ['report', 'report_metric_snapshot', 'list'], - ['audit', 'aud_operation_log', 'list'], ['audit', 'aud_export_log', 'list'], ['audit', 'aud_approval', 'list'], +const contracts = [ + ['dashboard', 'overview', '/dashboard/overview', 'readonly', 'dashboard'], + ['gas', 'gas_basic', '/gas/gas_basic', 'writable', 'list'], ['gas', 'gas_account', '/gas/gas_account', 'writable', 'list'], + ['delivery', 'delivery_basic', '/delivery/delivery_basic', 'writable', 'list'], ['delivery', 'delivery_account', '/delivery/delivery_account', 'writable', 'list'], ['delivery', 'delivery_task', '/delivery/delivery_task', 'writable', 'list'], ['delivery', 'delivery_track', '/delivery/delivery_track', 'writable', 'list'], ['delivery', 'delivery_track_point', '/delivery/delivery_track_point', 'writable', 'list'], + ['staff', 'staff_account', '/staff/account', 'writable', 'list'], ['staff', 'staff_credential', '/staff/credential', 'writable', 'list'], + ['user', 'user_account', '/user/account', 'writable', 'list'], ['user', 'user_address', '/user/address', 'writable', 'list'], ['user', 'user_service_relation', '/user/service_relation', 'writable', 'list'], + ['device', 'dev_smart_cylinder_valve', '/device/dev_smart_cylinder_valve', 'writable', 'list'], ['device', 'dev_device_binding', '/device/dev_device_binding', 'writable', 'list'], ['device', 'dev_telemetry', '/device/dev_telemetry', 'readonly', 'list'], + ['safety', 'saf_rule', '/safety/saf_rule', 'writable', 'list'], ['safety', 'saf_event', '/safety/saf_event', 'writable', 'list'], ['safety', 'saf_inspection', '/safety/saf_inspection', 'writable', 'list'], + ['ec', 'ec_category', '/ec/ec_category', 'writable', 'list'], ['ec', 'ec_product', '/ec/ec_product', 'writable', 'list'], ['ec', 'ec_product_attribute', '/ec/ec_product_attribute', 'writable', 'list'], ['ec', 'ec_product_image', '/ec/ec_product_image', 'writable', 'list'], ['ec', 'ec_cart', '/ec/ec_cart', 'writable', 'list'], ['ec', 'ec_order', '/ec/ec_order', 'writable', 'list'], ['ec', 'ec_order_item', '/ec/ec_order_item', 'writable', 'list'], ['ec', 'ec_review', '/ec/ec_review', 'writable', 'list'], + ['finance', 'fin_payment', '/finance/fin_payment', 'writable', 'list'], ['finance', 'fin_settlement', '/finance/fin_settlement', 'writable', 'list'], ['finance', 'fin_reconciliation', '/finance/fin_reconciliation', 'writable', 'list'], + ['content', 'cnt_content', '/content/cnt_content', 'writable', 'list'], ['notification', 'ntf_template', '/notification/ntf_template', 'writable', 'list'], ['customer_service', 'cs_ticket', '/customer_service/cs_ticket', 'writable', 'list'], + ['platform', 'platfrom_account', '/platform/platfrom_account', 'writable', 'list'], ['platform', 'platform_role', '/platform/platform_role', 'writable', 'list'], ['platform', 'platform_menu', '/platform/platform_menu', 'writable', 'tree'], + ['wallet', 'wallet', '/wallet/wallet', 'readonly', 'list'], ['wallet', 'wallet_ledger', '/wallet/wallet_ledger', 'readonly', 'list'], ['wallet', 'wallet_recharge', '/wallet/wallet_recharge', 'readonly', 'list'], ['wallet', 'wallet_withdrawal', '/wallet/wallet_withdrawal', 'readonly', 'list'], + ['report', 'report', '/report/report', 'readonly', 'list'], ['report', 'report_item', '/report/report_item', 'readonly', 'list'], ['report', 'report_metric_snapshot', '/report/report_metric_snapshot', 'readonly', 'list'], + ['audit', 'aud_operation_log', '/audit/aud_operation_log', 'readonly', 'list'], ['audit', 'aud_export_log', '/audit/aud_export_log', 'readonly', 'list'], ['audit', 'aud_approval', '/audit/aud_approval', 'readonly', 'list'], ]; -function fileIncludes(file, value) { - return fs.existsSync(file) && fs.readFileSync(file, 'utf8').includes(value); -} +const resourceSource = fs.readFileSync('src/api/resources.ts', 'utf8'); +const resourceEntry = (name, resource, mode, pageKind) => new RegExp(`name: '${name}', resource: '${resource}', title: '[^']+', mode: '${mode}', pageKind: '${pageKind}'`); +const files = (dir) => fs.existsSync(dir) ? fs.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => entry.isDirectory() ? files(path.join(dir, entry.name)) : [path.join(dir, entry.name)]) : []; -function checkResourceLayers() { - const missing = []; - for (const [domain, name, pageKind] of expectedResources) { - if (!fileIncludes('src/api/resources.ts', name)) missing.push(`${domain}/${name}: missing api`); - if (!fileIncludes(path.join('src/router/routes/modules', `${domain}.ts`), name)) missing.push(`${domain}/${name}: missing route`); - const page = pageKind === 'tree' ? 'TreePage.vue' : 'ListPage.vue'; - if (!fs.existsSync(path.join('src/views', domain, name, page))) missing.push(`${domain}/${name}: missing view`); +function checkContracts() { + const failures = []; + if (contracts.length !== 46) failures.push(`catalogue: expected 46 resources, got ${contracts.length}`); + for (const [domain, name, resource, mode, pageKind] of contracts) { + const label = `${domain}/${name}`; + if (!resourceEntry(name, resource, mode, pageKind).test(resourceSource)) failures.push(`${label}: missing or incorrect api contract`); + const route = path.join('src/router/routes/modules', domain === 'dashboard' ? 'platform.ts' : `${domain}.ts`); + if (!fs.existsSync(route) || !fs.readFileSync(route, 'utf8').includes(name)) failures.push(`${label}: missing route`); + const page = pageKind === 'dashboard' ? path.join('src/views/dashboard/DashboardPage.vue') : path.join('src/views', domain, name, pageKind === 'tree' ? 'TreePage.vue' : 'ListPage.vue'); + if (!fs.existsSync(page)) failures.push(`${label}: missing view`); + if (mode === 'readonly' && pageKind !== 'dashboard' && (!fs.existsSync(page) || !fs.readFileSync(page, 'utf8').includes('ReadOnlyListPage'))) failures.push(`${label}: readonly page exposes write surface`); } - return missing; + const readonlyPage = fs.readFileSync('src/views/shared/ReadOnlyListPage.vue', 'utf8'); + if (/(CrudListPage|resourceApi\.(create|update|archive|updateStatus))/.test(readonlyPage)) failures.push('readonly shared page: contains write surface'); + const treePage = fs.readFileSync('src/views/shared/TreePage.vue', 'utf8'); + if (!treePage.includes(' /\.(ts|vue)$/.test(file) && !file.endsWith('CrudListPage.vue') && !file.endsWith('ReadOnlyListPage.vue')).filter((file) => /\b[A-Za-z][A-Za-z0-9]*_id\b|\bid\b/.test(fs.readFileSync(file, 'utf8'))); + if (identityLeaks.length) failures.push(`identity leak: ${identityLeaks.join(', ')}`); + if (resourceSource.includes('saf_event_disposal') || files('src/router/routes/modules').some((file) => fs.readFileSync(file, 'utf8').includes('saf_event_disposal'))) failures.push('saf_event_disposal: must not be displayed as an independent resource'); + const obsoletePaths = /\/(?:commerce|staff\/staff_|user\/user_)/; + const stalePathFiles = files('src/api').concat(files('src/views')).filter((file) => /\.(ts|vue)$/.test(file) && obsoletePaths.test(fs.readFileSync(file, 'utf8'))); + if (stalePathFiles.length) failures.push(`obsolete resource path: ${stalePathFiles.join(', ')}`); + return failures; } -function walk(dir, acc = []) { - for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { - const full = path.join(dir, entry.name); - if (entry.isDirectory() && entry.name !== 'node_modules') { - walk(full, acc); - } else if (/\.(ts|vue)$/.test(entry.name)) { - acc.push(full); - } - } - return acc; -} - -const srcFiles = walk('src'); -const badPlaceholder = []; -const zhLocales = srcFiles.filter((f) => f.includes(`${path.sep}locale${path.sep}zh-CN.ts`)); - -for (const file of srcFiles) { - const text = fs.readFileSync(file, 'utf8'); - if (text.includes("'???'") || /'(\?\?[^']*)'/.test(text)) { - badPlaceholder.push(file); - } -} - -let zhOk = 0; -for (const file of zhLocales) { - if (/[\u4e00-\u9fff]/.test(fs.readFileSync(file, 'utf8'))) zhOk += 1; -} - -let mockInDist = false; -if (fs.existsSync('dist/assets')) { - for (const name of fs.readdirSync('dist/assets')) { - if (!name.endsWith('.js')) continue; - const chunk = fs.readFileSync(path.join('dist/assets', name), 'utf8'); - if (chunk.includes('mockjs') || chunk.includes('Mock.mock')) { - mockInDist = true; - break; - } - } -} - -console.log(JSON.stringify({ - badPlaceholder: badPlaceholder.length, - zhLocales: `${zhOk}/${zhLocales.length}`, - mockInDist, - hasGit: fs.existsSync('.env.development') && fs.readFileSync('.env.development', 'utf8').includes('VITE_API_BASE_URL=http'), - settingsHttp: fs.readFileSync('src/locale/zh-CN/settings.ts', 'utf8').includes('http.logout.title'), - rootMenu: fs.readFileSync('src/locale/zh-CN.ts', 'utf8').includes('仪表盘'), -}, null, 2)); - -const missingLayers = checkResourceLayers(); -for (const missing of missingLayers) console.log(missing); - -if (missingLayers.length > 0 && !baseline) { - process.exitCode = 1; -} +const failures = checkContracts(); +for (const failure of failures) console.log(failure); +if (failures.length) process.exitCode = 1; diff --git a/frontend/platform_admin/src/api/resources.ts b/frontend/platform_admin/src/api/resources.ts index c096ad0..82b0da1 100644 --- a/frontend/platform_admin/src/api/resources.ts +++ b/frontend/platform_admin/src/api/resources.ts @@ -1,39 +1,60 @@ export type ResourceMode = 'writable' | 'readonly' | 'append_only'; export type ResourcePageKind = 'list' | 'tree' | 'dashboard'; export type ResourceField = { key: string; label: string; required?: boolean }; -export type ResourceUiDefinition = { - key: string; - resource: string; - title: string; - mode: ResourceMode; - pageKind: ResourcePageKind; - fields: ResourceField[]; -}; - +export type ResourceUiDefinition = { key: string; name: string; resource: string; title: string; mode: ResourceMode; pageKind: ResourcePageKind; fields: ResourceField[] }; const fields: ResourceField[] = [{ key: 'name', label: '名称' }, { key: 'status', label: '状态' }]; -const resource = (domain: string, name: string, title: string, mode: ResourceMode = 'writable', pageKind: ResourcePageKind = 'list'): ResourceUiDefinition => ({ - key: name.replace(/_/g, '-'), resource: `/${domain}/${name}`, title, mode, pageKind, fields, -}); - -/** The single UI catalogue mirrors the backend ExpectedResources contract. */ +/** Exact front-end representation of the platform HTTP resource contract. */ export const resources: ResourceUiDefinition[] = [ - resource('gas', 'gas_basic', '气站管理'), resource('gas', 'gas_account', '气站账户'), - resource('delivery', 'delivery_basic', '配送点管理'), resource('delivery', 'delivery_account', '配送账户'), resource('delivery', 'delivery_task', '配送任务'), resource('delivery', 'delivery_track', '配送轨迹'), resource('delivery', 'delivery_track_point', '轨迹点'), - resource('staff', 'staff_account', '服务人员'), resource('staff', 'staff_credential', '人员资质'), - resource('user', 'user_account', '用户账户'), resource('user', 'user_address', '用户地址'), resource('user', 'user_service_relation', '用户服务关系'), - resource('device', 'dev_smart_cylinder_valve', '智能钢瓶阀'), resource('device', 'dev_device_binding', '设备绑定'), resource('device', 'dev_telemetry', '设备遥测', 'readonly'), resource('device', 'saf_rule', '安全规则'), resource('device', 'saf_event', '安全事件'), resource('device', 'saf_event_disposal', '事件处置记录', 'append_only'), resource('device', 'saf_inspection', '安全检查'), - resource('commerce', 'ec_category', '商品分类'), resource('commerce', 'ec_product', '商品'), resource('commerce', 'ec_product_attribute', '商品属性'), resource('commerce', 'ec_product_image', '商品图片'), resource('commerce', 'ec_cart', '购物车'), resource('commerce', 'ec_order', '订单'), resource('commerce', 'ec_review', '评价'), - resource('finance', 'fin_payment', '支付记录'), resource('finance', 'fin_settlement', '结算记录'), resource('finance', 'fin_reconciliation', '对账记录'), - resource('content', 'cnt_content', '内容管理'), resource('notification', 'ntf_template', '通知模板'), resource('customer_service', 'cs_ticket', '客服工单'), - resource('platform', 'platfrom_account', '平台账户'), resource('platform', 'platform_role', '平台角色'), resource('platform', 'platform_menu', '平台菜单', 'writable', 'tree'), - resource('wallet', 'wallet', '钱包', 'readonly'), resource('wallet', 'wallet_ledger', '钱包流水', 'readonly'), resource('wallet', 'wallet_recharge', '钱包充值', 'readonly'), resource('wallet', 'wallet_withdrawal', '钱包提现', 'readonly'), - resource('report', 'report', '报表', 'readonly'), resource('report', 'report_item', '报表项目', 'readonly'), resource('report', 'report_metric_snapshot', '指标快照', 'readonly'), - resource('audit', 'aud_operation_log', '操作审计', 'readonly'), resource('audit', 'aud_export_log', '导出审计', 'readonly'), resource('audit', 'aud_approval', '审批审计', 'readonly'), + { key: 'overview', name: 'overview', resource: '/dashboard/overview', title: 'overview', mode: 'readonly', pageKind: 'dashboard', fields }, + { key: 'gas-basic', name: 'gas_basic', resource: '/gas/gas_basic', title: 'gas_basic', mode: 'writable', pageKind: 'list', fields }, + { key: 'gas-account', name: 'gas_account', resource: '/gas/gas_account', title: 'gas_account', mode: 'writable', pageKind: 'list', fields }, + { key: 'delivery-basic', name: 'delivery_basic', resource: '/delivery/delivery_basic', title: 'delivery_basic', mode: 'writable', pageKind: 'list', fields }, + { key: 'delivery-account', name: 'delivery_account', resource: '/delivery/delivery_account', title: 'delivery_account', mode: 'writable', pageKind: 'list', fields }, + { key: 'delivery-task', name: 'delivery_task', resource: '/delivery/delivery_task', title: 'delivery_task', mode: 'writable', pageKind: 'list', fields }, + { key: 'delivery-track', name: 'delivery_track', resource: '/delivery/delivery_track', title: 'delivery_track', mode: 'writable', pageKind: 'list', fields }, + { key: 'delivery-track-point', name: 'delivery_track_point', resource: '/delivery/delivery_track_point', title: 'delivery_track_point', mode: 'writable', pageKind: 'list', fields }, + { key: 'staff-account', name: 'staff_account', resource: '/staff/account', title: 'staff_account', mode: 'writable', pageKind: 'list', fields }, + { key: 'staff-credential', name: 'staff_credential', resource: '/staff/credential', title: 'staff_credential', mode: 'writable', pageKind: 'list', fields }, + { key: 'user-account', name: 'user_account', resource: '/user/account', title: 'user_account', mode: 'writable', pageKind: 'list', fields }, + { key: 'user-address', name: 'user_address', resource: '/user/address', title: 'user_address', mode: 'writable', pageKind: 'list', fields }, + { key: 'user-service-relation', name: 'user_service_relation', resource: '/user/service_relation', title: 'user_service_relation', mode: 'writable', pageKind: 'list', fields }, + { key: 'dev-smart-cylinder-valve', name: 'dev_smart_cylinder_valve', resource: '/device/dev_smart_cylinder_valve', title: 'dev_smart_cylinder_valve', mode: 'writable', pageKind: 'list', fields }, + { key: 'dev-device-binding', name: 'dev_device_binding', resource: '/device/dev_device_binding', title: 'dev_device_binding', mode: 'writable', pageKind: 'list', fields }, + { key: 'dev-telemetry', name: 'dev_telemetry', resource: '/device/dev_telemetry', title: 'dev_telemetry', mode: 'readonly', pageKind: 'list', fields }, + { key: 'saf-rule', name: 'saf_rule', resource: '/safety/saf_rule', title: 'saf_rule', mode: 'writable', pageKind: 'list', fields }, + { key: 'saf-event', name: 'saf_event', resource: '/safety/saf_event', title: 'saf_event', mode: 'writable', pageKind: 'list', fields }, + { key: 'saf-inspection', name: 'saf_inspection', resource: '/safety/saf_inspection', title: 'saf_inspection', mode: 'writable', pageKind: 'list', fields }, + { key: 'ec-category', name: 'ec_category', resource: '/ec/ec_category', title: 'ec_category', mode: 'writable', pageKind: 'list', fields }, + { key: 'ec-product', name: 'ec_product', resource: '/ec/ec_product', title: 'ec_product', mode: 'writable', pageKind: 'list', fields }, + { key: 'ec-product-attribute', name: 'ec_product_attribute', resource: '/ec/ec_product_attribute', title: 'ec_product_attribute', mode: 'writable', pageKind: 'list', fields }, + { key: 'ec-product-image', name: 'ec_product_image', resource: '/ec/ec_product_image', title: 'ec_product_image', mode: 'writable', pageKind: 'list', fields }, + { key: 'ec-cart', name: 'ec_cart', resource: '/ec/ec_cart', title: 'ec_cart', mode: 'writable', pageKind: 'list', fields }, + { key: 'ec-order', name: 'ec_order', resource: '/ec/ec_order', title: 'ec_order', mode: 'writable', pageKind: 'list', fields }, + { key: 'ec-order-item', name: 'ec_order_item', resource: '/ec/ec_order_item', title: 'ec_order_item', mode: 'writable', pageKind: 'list', fields }, + { key: 'ec-review', name: 'ec_review', resource: '/ec/ec_review', title: 'ec_review', mode: 'writable', pageKind: 'list', fields }, + { key: 'fin-payment', name: 'fin_payment', resource: '/finance/fin_payment', title: 'fin_payment', mode: 'writable', pageKind: 'list', fields }, + { key: 'fin-settlement', name: 'fin_settlement', resource: '/finance/fin_settlement', title: 'fin_settlement', mode: 'writable', pageKind: 'list', fields }, + { key: 'fin-reconciliation', name: 'fin_reconciliation', resource: '/finance/fin_reconciliation', title: 'fin_reconciliation', mode: 'writable', pageKind: 'list', fields }, + { key: 'cnt-content', name: 'cnt_content', resource: '/content/cnt_content', title: 'cnt_content', mode: 'writable', pageKind: 'list', fields }, + { key: 'ntf-template', name: 'ntf_template', resource: '/notification/ntf_template', title: 'ntf_template', mode: 'writable', pageKind: 'list', fields }, + { key: 'cs-ticket', name: 'cs_ticket', resource: '/customer_service/cs_ticket', title: 'cs_ticket', mode: 'writable', pageKind: 'list', fields }, + { key: 'platfrom-account', name: 'platfrom_account', resource: '/platform/platfrom_account', title: 'platfrom_account', mode: 'writable', pageKind: 'list', fields }, + { key: 'platform-role', name: 'platform_role', resource: '/platform/platform_role', title: 'platform_role', mode: 'writable', pageKind: 'list', fields }, + { key: 'platform-menu', name: 'platform_menu', resource: '/platform/platform_menu', title: 'platform_menu', mode: 'writable', pageKind: 'tree', fields }, + { key: 'wallet', name: 'wallet', resource: '/wallet/wallet', title: 'wallet', mode: 'readonly', pageKind: 'list', fields }, + { key: 'wallet-ledger', name: 'wallet_ledger', resource: '/wallet/wallet_ledger', title: 'wallet_ledger', mode: 'readonly', pageKind: 'list', fields }, + { key: 'wallet-recharge', name: 'wallet_recharge', resource: '/wallet/wallet_recharge', title: 'wallet_recharge', mode: 'readonly', pageKind: 'list', fields }, + { key: 'wallet-withdrawal', name: 'wallet_withdrawal', resource: '/wallet/wallet_withdrawal', title: 'wallet_withdrawal', mode: 'readonly', pageKind: 'list', fields }, + { key: 'report', name: 'report', resource: '/report/report', title: 'report', mode: 'readonly', pageKind: 'list', fields }, + { key: 'report-item', name: 'report_item', resource: '/report/report_item', title: 'report_item', mode: 'readonly', pageKind: 'list', fields }, + { key: 'report-metric-snapshot', name: 'report_metric_snapshot', resource: '/report/report_metric_snapshot', title: 'report_metric_snapshot', mode: 'readonly', pageKind: 'list', fields }, + { key: 'aud-operation-log', name: 'aud_operation_log', resource: '/audit/aud_operation_log', title: 'aud_operation_log', mode: 'readonly', pageKind: 'list', fields }, + { key: 'aud-export-log', name: 'aud_export_log', resource: '/audit/aud_export_log', title: 'aud_export_log', mode: 'readonly', pageKind: 'list', fields }, + { key: 'aud-approval', name: 'aud_approval', resource: '/audit/aud_approval', title: 'aud_approval', mode: 'readonly', pageKind: 'list', fields }, ]; - export const resourceByName = Object.fromEntries(resources.map((definition) => [definition.resource, definition])) as Record; export function getResource(resourcePath: string): ResourceUiDefinition { const definition = resourceByName[resourcePath]; - if (!definition) throw new Error(`Unknown resource: ${resourcePath}`); + if (!definition) throw new Error('Unknown resource: ' + resourcePath); return definition; } diff --git a/frontend/platform_admin/src/api/staff.ts b/frontend/platform_admin/src/api/staff.ts index d8de0ac..c78a339 100644 --- a/frontend/platform_admin/src/api/staff.ts +++ b/frontend/platform_admin/src/api/staff.ts @@ -2,4 +2,4 @@ import { resourceApi } from './resource'; /** 服务人员管理接口。 */ export type Staff = { identity: string; name: string; phone: string; role_code: string; work_status: string; status: string }; -export const staffApi = { list: () => resourceApi.list('/staff/staff_account'), create: (data: Record) => resourceApi.create('/staff/staff_account', data) }; +export const staffApi = { list: () => resourceApi.list('/staff/account'), create: (data: Record) => resourceApi.create('/staff/account', data) }; diff --git a/frontend/platform_admin/src/api/user.ts b/frontend/platform_admin/src/api/user.ts index 9fea3d0..9d7a521 100644 --- a/frontend/platform_admin/src/api/user.ts +++ b/frontend/platform_admin/src/api/user.ts @@ -2,4 +2,4 @@ import { resourceApi } from './resource'; /** 业主客户管理接口。 */ export type User = { identity: string; name: string; phone: string; real_name: string; status: string }; -export const userApi = { list: () => resourceApi.list('/user/user_account'), create: (data: Record) => resourceApi.create('/user/user_account', data) }; +export const userApi = { list: () => resourceApi.list('/user/account'), create: (data: Record) => resourceApi.create('/user/account', data) }; diff --git a/frontend/platform_admin/src/router/routes/modules/commerce.ts b/frontend/platform_admin/src/router/routes/modules/commerce.ts deleted file mode 100644 index 128f09b..0000000 --- a/frontend/platform_admin/src/router/routes/modules/commerce.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { DEFAULT_LAYOUT } from '../base'; -import type { AppRouteRecordRaw } from '../types'; -const routes: AppRouteRecordRaw[] = [{ - path: '/commerce', name: 'commerce', component: DEFAULT_LAYOUT, - meta: { locale: 'menu.platform.commerce', requiresAuth: true, icon: 'icon-apps', order: 15 }, - children: [ - { path: 'ec-category', name: 'commerce-ec-category', component: () => import('@/views/commerce/ec_category/ListPage.vue'), meta: { locale: 'menu.platform.commerce.ec_category', requiresAuth: true, roles: ['*'] } }, - { path: 'ec-product', name: 'commerce-ec-product', component: () => import('@/views/commerce/ec_product/ListPage.vue'), meta: { locale: 'menu.platform.commerce.ec_product', requiresAuth: true, roles: ['*'] } }, - { path: 'ec-product-attribute', name: 'commerce-ec-product-attribute', component: () => import('@/views/commerce/ec_product_attribute/ListPage.vue'), meta: { locale: 'menu.platform.commerce.ec_product_attribute', requiresAuth: true, roles: ['*'] } }, - { path: 'ec-product-image', name: 'commerce-ec-product-image', component: () => import('@/views/commerce/ec_product_image/ListPage.vue'), meta: { locale: 'menu.platform.commerce.ec_product_image', requiresAuth: true, roles: ['*'] } }, - { path: 'ec-cart', name: 'commerce-ec-cart', component: () => import('@/views/commerce/ec_cart/ListPage.vue'), meta: { locale: 'menu.platform.commerce.ec_cart', requiresAuth: true, roles: ['*'] } }, - { path: 'ec-order', name: 'commerce-ec-order', component: () => import('@/views/commerce/ec_order/ListPage.vue'), meta: { locale: 'menu.platform.commerce.ec_order', requiresAuth: true, roles: ['*'] } }, - { path: 'ec-review', name: 'commerce-ec-review', component: () => import('@/views/commerce/ec_review/ListPage.vue'), meta: { locale: 'menu.platform.commerce.ec_review', requiresAuth: true, roles: ['*'] } } - ], -}]; -export default routes; diff --git a/frontend/platform_admin/src/router/routes/modules/device.ts b/frontend/platform_admin/src/router/routes/modules/device.ts index 2198db9..ec5f922 100644 --- a/frontend/platform_admin/src/router/routes/modules/device.ts +++ b/frontend/platform_admin/src/router/routes/modules/device.ts @@ -6,11 +6,7 @@ const routes: AppRouteRecordRaw[] = [{ children: [ { path: 'dev-smart-cylinder-valve', name: 'device-dev-smart-cylinder-valve', component: () => import('@/views/device/dev_smart_cylinder_valve/ListPage.vue'), meta: { locale: 'menu.platform.device.dev_smart_cylinder_valve', requiresAuth: true, roles: ['*'] } }, { path: 'dev-device-binding', name: 'device-dev-device-binding', component: () => import('@/views/device/dev_device_binding/ListPage.vue'), meta: { locale: 'menu.platform.device.dev_device_binding', requiresAuth: true, roles: ['*'] } }, - { path: 'dev-telemetry', name: 'device-dev-telemetry', component: () => import('@/views/device/dev_telemetry/ListPage.vue'), meta: { locale: 'menu.platform.device.dev_telemetry', requiresAuth: true, roles: ['*'] } }, - { path: 'saf-rule', name: 'device-saf-rule', component: () => import('@/views/device/saf_rule/ListPage.vue'), meta: { locale: 'menu.platform.device.saf_rule', requiresAuth: true, roles: ['*'] } }, - { path: 'saf-event', name: 'device-saf-event', component: () => import('@/views/device/saf_event/ListPage.vue'), meta: { locale: 'menu.platform.device.saf_event', requiresAuth: true, roles: ['*'] } }, - { path: 'saf-event-disposal', name: 'device-saf-event-disposal', component: () => import('@/views/device/saf_event_disposal/ListPage.vue'), meta: { locale: 'menu.platform.device.saf_event_disposal', requiresAuth: true, roles: ['*'] } }, - { path: 'saf-inspection', name: 'device-saf-inspection', component: () => import('@/views/device/saf_inspection/ListPage.vue'), meta: { locale: 'menu.platform.device.saf_inspection', requiresAuth: true, roles: ['*'] } } + { path: 'dev-telemetry', name: 'device-dev-telemetry', component: () => import('@/views/device/dev_telemetry/ListPage.vue'), meta: { locale: 'menu.platform.device.dev_telemetry', requiresAuth: true, roles: ['*'] } } ], }]; export default routes; diff --git a/frontend/platform_admin/src/router/routes/modules/ec.ts b/frontend/platform_admin/src/router/routes/modules/ec.ts new file mode 100644 index 0000000..835ed68 --- /dev/null +++ b/frontend/platform_admin/src/router/routes/modules/ec.ts @@ -0,0 +1,13 @@ +import { DEFAULT_LAYOUT } from '../base'; +import type { AppRouteRecordRaw } from '../types'; +const routes: AppRouteRecordRaw[] = [{ path: '/ec', name: 'ec', component: DEFAULT_LAYOUT, meta: { locale: 'menu.platform.ec', requiresAuth: true, icon: 'icon-apps', order: 16 }, children: [ + { path: 'ec-category', name: 'ec-ec-category', component: () => import('@/views/ec/ec_category/ListPage.vue'), meta: { locale: 'menu.platform.ec.ec_category', requiresAuth: true, roles: ['*'] } }, + { path: 'ec-product', name: 'ec-ec-product', component: () => import('@/views/ec/ec_product/ListPage.vue'), meta: { locale: 'menu.platform.ec.ec_product', requiresAuth: true, roles: ['*'] } }, + { path: 'ec-product-attribute', name: 'ec-ec-product-attribute', component: () => import('@/views/ec/ec_product_attribute/ListPage.vue'), meta: { locale: 'menu.platform.ec.ec_product_attribute', requiresAuth: true, roles: ['*'] } }, + { path: 'ec-product-image', name: 'ec-ec-product-image', component: () => import('@/views/ec/ec_product_image/ListPage.vue'), meta: { locale: 'menu.platform.ec.ec_product_image', requiresAuth: true, roles: ['*'] } }, + { path: 'ec-cart', name: 'ec-ec-cart', component: () => import('@/views/ec/ec_cart/ListPage.vue'), meta: { locale: 'menu.platform.ec.ec_cart', requiresAuth: true, roles: ['*'] } }, + { path: 'ec-order', name: 'ec-ec-order', component: () => import('@/views/ec/ec_order/ListPage.vue'), meta: { locale: 'menu.platform.ec.ec_order', requiresAuth: true, roles: ['*'] } }, + { path: 'ec-order-item', name: 'ec-ec-order-item', component: () => import('@/views/ec/ec_order_item/ListPage.vue'), meta: { locale: 'menu.platform.ec.ec_order_item', requiresAuth: true, roles: ['*'] } }, + { path: 'ec-review', name: 'ec-ec-review', component: () => import('@/views/ec/ec_review/ListPage.vue'), meta: { locale: 'menu.platform.ec.ec_review', requiresAuth: true, roles: ['*'] } } +] }]; +export default routes; diff --git a/frontend/platform_admin/src/router/routes/modules/platform.ts b/frontend/platform_admin/src/router/routes/modules/platform.ts index bde09a3..b58b176 100644 --- a/frontend/platform_admin/src/router/routes/modules/platform.ts +++ b/frontend/platform_admin/src/router/routes/modules/platform.ts @@ -5,7 +5,8 @@ import deliveryRoutes from './delivery'; import staffRoutes from './staff'; import userRoutes from './user'; import deviceRoutes from './device'; -import commerceRoutes from './commerce'; +import safetyRoutes from './safety'; +import ecRoutes from './ec'; import financeRoutes from './finance'; import contentRoutes from './content'; import notificationRoutes from './notification'; @@ -21,4 +22,4 @@ const platformRoutes: AppRouteRecordRaw[] = [ { path: 'platform-menu', name: 'platform-platform-menu', component: () => import('@/views/platform/platform_menu/TreePage.vue'), meta: { locale: 'menu.platform.platform.platform_menu', requiresAuth: true, roles: ['*'] } }, ] }, ]; -export default [...platformRoutes, ...gasRoutes, ...deliveryRoutes, ...staffRoutes, ...userRoutes, ...deviceRoutes, ...commerceRoutes, ...financeRoutes, ...contentRoutes, ...notificationRoutes, ...customerServiceRoutes, ...walletRoutes, ...reportRoutes, ...auditRoutes]; +export default [...platformRoutes, ...gasRoutes, ...deliveryRoutes, ...staffRoutes, ...userRoutes, ...deviceRoutes, ...safetyRoutes, ...ecRoutes, ...financeRoutes, ...contentRoutes, ...notificationRoutes, ...customerServiceRoutes, ...walletRoutes, ...reportRoutes, ...auditRoutes]; diff --git a/frontend/platform_admin/src/router/routes/modules/safety.ts b/frontend/platform_admin/src/router/routes/modules/safety.ts new file mode 100644 index 0000000..8af490d --- /dev/null +++ b/frontend/platform_admin/src/router/routes/modules/safety.ts @@ -0,0 +1,8 @@ +import { DEFAULT_LAYOUT } from '../base'; +import type { AppRouteRecordRaw } from '../types'; +const routes: AppRouteRecordRaw[] = [{ path: '/safety', name: 'safety', component: DEFAULT_LAYOUT, meta: { locale: 'menu.platform.safety', requiresAuth: true, icon: 'icon-apps', order: 15 }, children: [ + { path: 'saf-rule', name: 'safety-saf-rule', component: () => import('@/views/safety/saf_rule/ListPage.vue'), meta: { locale: 'menu.platform.safety.saf_rule', requiresAuth: true, roles: ['*'] } }, + { path: 'saf-event', name: 'safety-saf-event', component: () => import('@/views/safety/saf_event/ListPage.vue'), meta: { locale: 'menu.platform.safety.saf_event', requiresAuth: true, roles: ['*'] } }, + { path: 'saf-inspection', name: 'safety-saf-inspection', component: () => import('@/views/safety/saf_inspection/ListPage.vue'), meta: { locale: 'menu.platform.safety.saf_inspection', requiresAuth: true, roles: ['*'] } } +] }]; +export default routes; diff --git a/frontend/platform_admin/src/router/routes/modules/staff.ts b/frontend/platform_admin/src/router/routes/modules/staff.ts index 56e1ac3..c1e0f52 100644 --- a/frontend/platform_admin/src/router/routes/modules/staff.ts +++ b/frontend/platform_admin/src/router/routes/modules/staff.ts @@ -4,8 +4,8 @@ const routes: AppRouteRecordRaw[] = [{ path: '/staff', name: 'staff', component: DEFAULT_LAYOUT, meta: { locale: 'menu.platform.staff', requiresAuth: true, icon: 'icon-apps', order: 12 }, children: [ - { path: 'staff-account', name: 'staff-staff-account', component: () => import('@/views/staff/staff_account/ListPage.vue'), meta: { locale: 'menu.platform.staff.staff_account', requiresAuth: true, roles: ['*'] } }, - { path: 'staff-credential', name: 'staff-staff-credential', component: () => import('@/views/staff/staff_credential/ListPage.vue'), meta: { locale: 'menu.platform.staff.staff_credential', requiresAuth: true, roles: ['*'] } } + { path: 'account', name: 'staff-staff-account', component: () => import('@/views/staff/staff_account/ListPage.vue'), meta: { locale: 'menu.platform.staff.staff_account', requiresAuth: true, roles: ['*'] } }, + { path: 'credential', name: 'staff-staff-credential', component: () => import('@/views/staff/staff_credential/ListPage.vue'), meta: { locale: 'menu.platform.staff.staff_credential', requiresAuth: true, roles: ['*'] } } ], }]; export default routes; diff --git a/frontend/platform_admin/src/router/routes/modules/user.ts b/frontend/platform_admin/src/router/routes/modules/user.ts index 1c6788b..15a6fbf 100644 --- a/frontend/platform_admin/src/router/routes/modules/user.ts +++ b/frontend/platform_admin/src/router/routes/modules/user.ts @@ -4,9 +4,9 @@ const routes: AppRouteRecordRaw[] = [{ path: '/user', name: 'user', component: DEFAULT_LAYOUT, meta: { locale: 'menu.platform.user', requiresAuth: true, icon: 'icon-apps', order: 13 }, children: [ - { path: 'user-account', name: 'user-user-account', component: () => import('@/views/user/user_account/ListPage.vue'), meta: { locale: 'menu.platform.user.user_account', requiresAuth: true, roles: ['*'] } }, - { path: 'user-address', name: 'user-user-address', component: () => import('@/views/user/user_address/ListPage.vue'), meta: { locale: 'menu.platform.user.user_address', requiresAuth: true, roles: ['*'] } }, - { path: 'user-service-relation', name: 'user-user-service-relation', component: () => import('@/views/user/user_service_relation/ListPage.vue'), meta: { locale: 'menu.platform.user.user_service_relation', requiresAuth: true, roles: ['*'] } } + { path: 'account', name: 'user-user-account', component: () => import('@/views/user/user_account/ListPage.vue'), meta: { locale: 'menu.platform.user.user_account', requiresAuth: true, roles: ['*'] } }, + { path: 'address', name: 'user-user-address', component: () => import('@/views/user/user_address/ListPage.vue'), meta: { locale: 'menu.platform.user.user_address', requiresAuth: true, roles: ['*'] } }, + { path: 'service-relation', name: 'user-user-service-relation', component: () => import('@/views/user/user_service_relation/ListPage.vue'), meta: { locale: 'menu.platform.user.user_service_relation', requiresAuth: true, roles: ['*'] } } ], }]; export default routes; diff --git a/frontend/platform_admin/src/views/commerce/ec_product_attribute/ListPage.vue b/frontend/platform_admin/src/views/commerce/ec_product_attribute/ListPage.vue deleted file mode 100644 index ba927e1..0000000 --- a/frontend/platform_admin/src/views/commerce/ec_product_attribute/ListPage.vue +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/frontend/platform_admin/src/views/commerce/ec_product_image/ListPage.vue b/frontend/platform_admin/src/views/commerce/ec_product_image/ListPage.vue deleted file mode 100644 index 8b31cd4..0000000 --- a/frontend/platform_admin/src/views/commerce/ec_product_image/ListPage.vue +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/frontend/platform_admin/src/views/commerce/ec_review/ListPage.vue b/frontend/platform_admin/src/views/commerce/ec_review/ListPage.vue deleted file mode 100644 index 0752bcd..0000000 --- a/frontend/platform_admin/src/views/commerce/ec_review/ListPage.vue +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/frontend/platform_admin/src/views/device/saf_event_disposal/ListPage.vue b/frontend/platform_admin/src/views/device/saf_event_disposal/ListPage.vue deleted file mode 100644 index 9de65c9..0000000 --- a/frontend/platform_admin/src/views/device/saf_event_disposal/ListPage.vue +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/frontend/platform_admin/src/views/device/saf_inspection/ListPage.vue b/frontend/platform_admin/src/views/device/saf_inspection/ListPage.vue deleted file mode 100644 index 3d198cb..0000000 --- a/frontend/platform_admin/src/views/device/saf_inspection/ListPage.vue +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/frontend/platform_admin/src/views/device/saf_rule/ListPage.vue b/frontend/platform_admin/src/views/ec/ec_cart/ListPage.vue similarity index 79% rename from frontend/platform_admin/src/views/device/saf_rule/ListPage.vue rename to frontend/platform_admin/src/views/ec/ec_cart/ListPage.vue index 52f5708..b151c31 100644 --- a/frontend/platform_admin/src/views/device/saf_rule/ListPage.vue +++ b/frontend/platform_admin/src/views/ec/ec_cart/ListPage.vue @@ -2,5 +2,5 @@ diff --git a/frontend/platform_admin/src/views/device/saf_event/ListPage.vue b/frontend/platform_admin/src/views/ec/ec_category/ListPage.vue similarity index 79% rename from frontend/platform_admin/src/views/device/saf_event/ListPage.vue rename to frontend/platform_admin/src/views/ec/ec_category/ListPage.vue index d09abe1..331cbd3 100644 --- a/frontend/platform_admin/src/views/device/saf_event/ListPage.vue +++ b/frontend/platform_admin/src/views/ec/ec_category/ListPage.vue @@ -2,5 +2,5 @@ diff --git a/frontend/platform_admin/src/views/commerce/ec_cart/ListPage.vue b/frontend/platform_admin/src/views/ec/ec_order/ListPage.vue similarity index 79% rename from frontend/platform_admin/src/views/commerce/ec_cart/ListPage.vue rename to frontend/platform_admin/src/views/ec/ec_order/ListPage.vue index fb82532..2224775 100644 --- a/frontend/platform_admin/src/views/commerce/ec_cart/ListPage.vue +++ b/frontend/platform_admin/src/views/ec/ec_order/ListPage.vue @@ -2,5 +2,5 @@ diff --git a/frontend/platform_admin/src/views/commerce/ec_order/ListPage.vue b/frontend/platform_admin/src/views/ec/ec_order_item/ListPage.vue similarity index 79% rename from frontend/platform_admin/src/views/commerce/ec_order/ListPage.vue rename to frontend/platform_admin/src/views/ec/ec_order_item/ListPage.vue index 315a0b7..0b17456 100644 --- a/frontend/platform_admin/src/views/commerce/ec_order/ListPage.vue +++ b/frontend/platform_admin/src/views/ec/ec_order_item/ListPage.vue @@ -2,5 +2,5 @@ diff --git a/frontend/platform_admin/src/views/ec/ec_product/ListPage.vue b/frontend/platform_admin/src/views/ec/ec_product/ListPage.vue new file mode 100644 index 0000000..6f8009d --- /dev/null +++ b/frontend/platform_admin/src/views/ec/ec_product/ListPage.vue @@ -0,0 +1,6 @@ + + diff --git a/frontend/platform_admin/src/views/ec/ec_product_attribute/ListPage.vue b/frontend/platform_admin/src/views/ec/ec_product_attribute/ListPage.vue new file mode 100644 index 0000000..dcf8426 --- /dev/null +++ b/frontend/platform_admin/src/views/ec/ec_product_attribute/ListPage.vue @@ -0,0 +1,6 @@ + + diff --git a/frontend/platform_admin/src/views/commerce/ec_product/ListPage.vue b/frontend/platform_admin/src/views/ec/ec_product_image/ListPage.vue similarity index 78% rename from frontend/platform_admin/src/views/commerce/ec_product/ListPage.vue rename to frontend/platform_admin/src/views/ec/ec_product_image/ListPage.vue index 224e6dc..925a8af 100644 --- a/frontend/platform_admin/src/views/commerce/ec_product/ListPage.vue +++ b/frontend/platform_admin/src/views/ec/ec_product_image/ListPage.vue @@ -2,5 +2,5 @@ diff --git a/frontend/platform_admin/src/views/ec/ec_review/ListPage.vue b/frontend/platform_admin/src/views/ec/ec_review/ListPage.vue new file mode 100644 index 0000000..8e4e311 --- /dev/null +++ b/frontend/platform_admin/src/views/ec/ec_review/ListPage.vue @@ -0,0 +1,6 @@ + + diff --git a/frontend/platform_admin/src/views/safety/saf_event/ListPage.vue b/frontend/platform_admin/src/views/safety/saf_event/ListPage.vue new file mode 100644 index 0000000..2027f00 --- /dev/null +++ b/frontend/platform_admin/src/views/safety/saf_event/ListPage.vue @@ -0,0 +1,6 @@ + + diff --git a/frontend/platform_admin/src/views/commerce/ec_category/ListPage.vue b/frontend/platform_admin/src/views/safety/saf_inspection/ListPage.vue similarity index 77% rename from frontend/platform_admin/src/views/commerce/ec_category/ListPage.vue rename to frontend/platform_admin/src/views/safety/saf_inspection/ListPage.vue index 1b06ee1..1dcf8ed 100644 --- a/frontend/platform_admin/src/views/commerce/ec_category/ListPage.vue +++ b/frontend/platform_admin/src/views/safety/saf_inspection/ListPage.vue @@ -2,5 +2,5 @@ diff --git a/frontend/platform_admin/src/views/safety/saf_rule/ListPage.vue b/frontend/platform_admin/src/views/safety/saf_rule/ListPage.vue new file mode 100644 index 0000000..150d29f --- /dev/null +++ b/frontend/platform_admin/src/views/safety/saf_rule/ListPage.vue @@ -0,0 +1,6 @@ + + diff --git a/frontend/platform_admin/src/views/shared/CrudListPage.vue b/frontend/platform_admin/src/views/shared/CrudListPage.vue index 9cf6ddd..1d3d2f1 100644 --- a/frontend/platform_admin/src/views/shared/CrudListPage.vue +++ b/frontend/platform_admin/src/views/shared/CrudListPage.vue @@ -1,41 +1,25 @@ - + diff --git a/frontend/platform_admin/src/views/staff/list/ListPage.vue b/frontend/platform_admin/src/views/staff/list/ListPage.vue index 625e807..a8f3423 100644 --- a/frontend/platform_admin/src/views/staff/list/ListPage.vue +++ b/frontend/platform_admin/src/views/staff/list/ListPage.vue @@ -1 +1,6 @@ - + + diff --git a/frontend/platform_admin/src/views/staff/staff_account/ListPage.vue b/frontend/platform_admin/src/views/staff/staff_account/ListPage.vue index 6db1c6b..a8f3423 100644 --- a/frontend/platform_admin/src/views/staff/staff_account/ListPage.vue +++ b/frontend/platform_admin/src/views/staff/staff_account/ListPage.vue @@ -2,5 +2,5 @@ diff --git a/frontend/platform_admin/src/views/staff/staff_credential/ListPage.vue b/frontend/platform_admin/src/views/staff/staff_credential/ListPage.vue index ac1d4ad..233de6c 100644 --- a/frontend/platform_admin/src/views/staff/staff_credential/ListPage.vue +++ b/frontend/platform_admin/src/views/staff/staff_credential/ListPage.vue @@ -2,5 +2,5 @@ diff --git a/frontend/platform_admin/src/views/user/list/ListPage.vue b/frontend/platform_admin/src/views/user/list/ListPage.vue index 06419ac..ab4ba3d 100644 --- a/frontend/platform_admin/src/views/user/list/ListPage.vue +++ b/frontend/platform_admin/src/views/user/list/ListPage.vue @@ -1 +1,6 @@ - + + diff --git a/frontend/platform_admin/src/views/user/user_account/ListPage.vue b/frontend/platform_admin/src/views/user/user_account/ListPage.vue index 70dab72..ab4ba3d 100644 --- a/frontend/platform_admin/src/views/user/user_account/ListPage.vue +++ b/frontend/platform_admin/src/views/user/user_account/ListPage.vue @@ -2,5 +2,5 @@ diff --git a/frontend/platform_admin/src/views/user/user_address/ListPage.vue b/frontend/platform_admin/src/views/user/user_address/ListPage.vue index a17548a..1891985 100644 --- a/frontend/platform_admin/src/views/user/user_address/ListPage.vue +++ b/frontend/platform_admin/src/views/user/user_address/ListPage.vue @@ -2,5 +2,5 @@ diff --git a/frontend/platform_admin/src/views/user/user_service_relation/ListPage.vue b/frontend/platform_admin/src/views/user/user_service_relation/ListPage.vue index 461c15a..b4adbec 100644 --- a/frontend/platform_admin/src/views/user/user_service_relation/ListPage.vue +++ b/frontend/platform_admin/src/views/user/user_service_relation/ListPage.vue @@ -2,5 +2,5 @@