From 40905cbd04c2e332cd4bc2b9e0c5b3e1da9cccfa Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期一, 30 三月 2026 08:17:32 +0800
Subject: [PATCH] feat: complete rsf-design phase 1 integration
---
rsf-design/tests/system-role-scope-contract.test.mjs | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 204 insertions(+), 14 deletions(-)
diff --git a/rsf-design/tests/system-role-scope-contract.test.mjs b/rsf-design/tests/system-role-scope-contract.test.mjs
index 30c293e..dd8b2af 100644
--- a/rsf-design/tests/system-role-scope-contract.test.mjs
+++ b/rsf-design/tests/system-role-scope-contract.test.mjs
@@ -1,21 +1,211 @@
import assert from 'node:assert/strict'
+import fs from 'node:fs'
import test from 'node:test'
-import {
- buildScopeTreeNodes,
- buildScopeSavePayload,
- SCOPE_TYPES
-} from '../src/views/system/role/roleScope.config.js'
-test('menu scope nodes preserve backend ids for save', () => {
- const tree = buildScopeTreeNodes(SCOPE_TYPES.menu, [{ id: 1, label: '绯荤粺绠$悊' }])
- assert.equal(tree[0].id, 1)
+import {
+ buildRoleDialogModel,
+ buildRolePageQueryParams,
+ buildRoleSavePayload,
+ buildRoleScopeSubmitPayload,
+ buildRoleSearchParams,
+ getRoleScopeConfig,
+ normalizeRoleScopeTreeData,
+ normalizeRoleListRow,
+ createRoleSearchState
+} from '../src/views/system/role/rolePage.helpers.js'
+import { resolveBackendMenuTitle } from '../src/utils/backend-menu-title.js'
+
+const rolePermissionDialogSource = fs.readFileSync(
+ new URL('../src/views/system/role/modules/role-permission-dialog.vue', import.meta.url),
+ 'utf8'
+)
+const roleEditDialogSource = fs.readFileSync(
+ new URL('../src/views/system/role/modules/role-edit-dialog.vue', import.meta.url),
+ 'utf8'
+)
+const roleIndexSource = fs.readFileSync(
+ new URL('../src/views/system/role/index.vue', import.meta.url),
+ 'utf8'
+)
+
+test('buildRoleSearchParams keeps real role search fields', () => {
+ assert.deepEqual(
+ buildRoleSearchParams({
+ name: '绠$悊鍛�',
+ code: 'R_ADMIN',
+ memo: '鏍稿績瑙掕壊',
+ status: 1,
+ condition: 'admin'
+ }),
+ {
+ name: '绠$悊鍛�',
+ code: 'R_ADMIN',
+ memo: '鏍稿績瑙掕壊',
+ status: 1,
+ condition: 'admin'
+ }
+ )
})
-test('scope save payload is delegated per scope type', () => {
- const payload = buildScopeSavePayload(SCOPE_TYPES.menu, {
- roleId: 9,
- selectedIds: [1, 2],
- authType: 0
+test('buildRolePageQueryParams merges paging and search fields', () => {
+ assert.deepEqual(
+ buildRolePageQueryParams({
+ current: 3,
+ size: 20,
+ name: '绠$悊鍛�'
+ }),
+ {
+ current: 3,
+ pageSize: 20,
+ name: '绠$悊鍛�'
+ }
+ )
+})
+
+test('buildRoleDialogModel normalizes backend role data into the form model', () => {
+ assert.deepEqual(
+ buildRoleDialogModel({
+ id: 7,
+ name: '绠$悊鍛�',
+ code: 'R_ADMIN',
+ memo: '鏍稿績瑙掕壊',
+ status: 0
+ }),
+ {
+ id: 7,
+ name: '绠$悊鍛�',
+ code: 'R_ADMIN',
+ memo: '鏍稿績瑙掕壊',
+ status: 0
+ }
+ )
+})
+
+test('buildRoleSavePayload submits backend role fields', () => {
+ assert.deepEqual(
+ buildRoleSavePayload({
+ id: 7,
+ name: '绠$悊鍛�',
+ code: 'R_ADMIN',
+ memo: '鏍稿績瑙掕壊',
+ status: 1
+ }),
+ {
+ id: 7,
+ name: '绠$悊鍛�',
+ code: 'R_ADMIN',
+ memo: '鏍稿績瑙掕壊',
+ status: 1
+ }
+ )
+})
+
+test('normalizeRoleListRow exposes table friendly fields', () => {
+ const normalized = normalizeRoleListRow({
+ id: 7,
+ name: '绠$悊鍛�',
+ code: 'R_ADMIN',
+ memo: '鏍稿績瑙掕壊',
+ status: 1,
+ createTime: '2025-03-28 10:00:00',
+ updateTime: '2025-03-28 11:00:00'
})
- assert.equal(payload.id, 9)
+
+ assert.equal(normalized.name, '绠$悊鍛�')
+ assert.equal(normalized.statusBool, true)
+ assert.equal(normalized.statusText, '姝e父')
+ assert.equal(normalized.statusType, 'success')
+ assert.equal(normalized.createTimeText, '2025-03-28 10:00:00')
+ assert.equal(normalized.updateTimeText, '2025-03-28 11:00:00')
+})
+
+test('buildRoleScopeSubmitPayload normalizes checked keys for backend scope update', () => {
+ assert.deepEqual(
+ buildRoleScopeSubmitPayload(7, ['1', 2], ['3']),
+ {
+ id: 7,
+ menuIds: {
+ checked: [1, 2],
+ halfChecked: [3]
+ }
+ }
+ )
+})
+
+test('getRoleScopeConfig resolves the four backend scope contracts', () => {
+ assert.deepEqual(getRoleScopeConfig('menu'), {
+ scopeType: 'menu',
+ title: '缃戦〉鏉冮檺',
+ listUrl: '/role/scope/list',
+ treeUrl: '/menu/tree'
+ })
+ assert.deepEqual(getRoleScopeConfig('warehouse'), {
+ scopeType: 'warehouse',
+ title: '浠撳簱鏉冮檺',
+ listUrl: '/roleWarehouse/scope/list',
+ treeUrl: '/menuWarehouse/tree'
+ })
+ assert.throws(() => getRoleScopeConfig('invalid'), /Unsupported scope type/i)
+})
+
+test('normalizeRoleScopeTreeData folds menu auth buttons into child nodes', () => {
+ const tree = normalizeRoleScopeTreeData('menu', [
+ {
+ id: 1,
+ name: 'menu.role',
+ type: 0,
+ children: [
+ {
+ id: 2,
+ name: 'Query Role',
+ type: 1,
+ authority: 'system:role:list'
+ }
+ ]
+ }
+ ])
+
+ assert.equal(tree[0].label, 'menus.role')
+ assert.equal(tree[0].children[0].isAuthButton, true)
+ assert.equal(tree[0].children[0].authMark, 'system:role:list')
+})
+
+test('resolveBackendMenuTitle translates legacy backend menu keys into readable labels', () => {
+ assert.equal(resolveBackendMenuTitle('menu.role'), '瑙掕壊绠$悊')
+ assert.equal(resolveBackendMenuTitle('menus.aiParam'), 'AI 鍙傛暟')
+ assert.equal(resolveBackendMenuTitle('AI绠$悊涓績'), 'AI绠$悊涓績')
+})
+
+test('role permission dialog only loads the active scope instead of all scopes together', () => {
+ assert.match(rolePermissionDialogSource, /ensureScopeLoaded\(activeScopeType\.value, \{ force: true \}\)/)
+ assert.doesNotMatch(rolePermissionDialogSource, /loadAllScopeData/)
+})
+
+test('role permission dialog keeps scope tree search and readable labels', () => {
+ assert.match(rolePermissionDialogSource, /placeholder="鎼滅储鏉冮檺鏍�"/)
+ assert.match(rolePermissionDialogSource, /reloadSelection: false/)
+ assert.match(rolePermissionDialogSource, /resolveBackendMenuTitle/)
+})
+
+test('role edit dialog keeps code optional to match the backend contract', () => {
+ assert.match(roleEditDialogSource, /name: \[\{ required: true, message: '璇疯緭鍏ヨ鑹插悕绉�'/)
+ assert.doesNotMatch(roleEditDialogSource, /code: \[\{ required: true, message: '璇疯緭鍏ヨ鑹茬紪鐮�'/)
+})
+
+test('role page uses semantic auth aliases so backend permissions render actions', () => {
+ assert.match(roleIndexSource, /v-auth=\"'add'\"/)
+ assert.match(roleIndexSource, /v-auth=\"'delete'\"/)
+ assert.match(roleIndexSource, /v-auth=\"'query'\"/)
+ assert.match(roleIndexSource, /auth: 'edit'/)
+ assert.match(roleIndexSource, /auth: 'delete'/)
+})
+
+test('createRoleSearchState exposes the role search form model', () => {
+ assert.deepEqual(createRoleSearchState(), {
+ name: '',
+ code: '',
+ memo: '',
+ status: void 0,
+ condition: ''
+ })
})
--
Gitblit v1.9.1