npm install @tntd/assign-modal用于管理机构、应用(渠道)、用户授权的复杂业务组件,支持树形机构选择、多选应用和用户,以及全局授权等功能。
- 🌲 树形机构选择:支持多级机构树形结构,带有智能联动逻辑
- 🔄 智能联动:选中子机构自动勾选上级,取消上级自动取消下级
- 🌐 全局授权:支持一键授权所有机构/应用/用户
- 👁 双模式:编辑模式和查看模式自动切换
- 🔍 搜索过滤:支持对机构、应用、用户进行实时搜索
- 🌍 国际化:内置中英文支持,可自定义语言包
- 🎨 自定义禁用:支持自定义机构和应用的禁用规则
``bash`
npm install @tddc/assign-modal --save或
yarn add @tddc/assign-modal
`jsx
import React, { useState } from 'react';
import { Button, message } from 'tntd';
import AssignModal from '@tddc/assign-modal';
const Example = () => {
const [visible, setVisible] = useState(false);
// 机构列表(树形结构)
const orgList = [
{
uuid: 'org-1',
code: 'ROOT',
name: '总公司',
level: 1,
children: [
{
uuid: 'org-2',
code: 'BRANCH_A',
name: '分公司A',
level: 2,
children: [],
},
],
},
];
// 应用列表
const appList = [
{ uuid: 'app-1', name: 'APP1', value: 'APP1', label: '应用系统1' },
{ uuid: 'app-2', name: 'APP2', value: 'APP2', label: '应用系统2' },
];
// 用户列表(可选)
const userList = [
{ uuid: 'user-1', account: 'user1', userName: '用户A', orgCode: 'ROOT' },
{ uuid: 'user-2', account: 'user2', userName: '用户B', orgCode: 'BRANCH_A' },
];
// 授权数据
const dataItem = {
orgCode: 'ROOT',
appCode: 'APP1',
account: 'user1',
orgCodes: ['ROOT'],
appCodes: ['APP1'],
accounts: ['user1'],
};
const handleSubmit = (data) => {
console.log('授权数据:', data);
message.success('授权成功');
setVisible(false);
};
return (
<>
title="权限配置"
orgList={orgList}
appList={appList}
userList={userList}
dataItem={dataItem}
showUser={true}
onSubmit={handleSubmit}
close={() => setVisible(false)}
/>
>
);
};
export default Example;
`
- 选中子机构:点击授权某下级机构时,该机构的所有上级机构会自动一起授权
- 取消上级机构:点击取消某上级机构授权时,该机构的所有下级机构会自动一起取消授权
- 所属机构保护:组件所属机构及其上级机构默认授权勾选且置灰,不得修改
- 全局授权:勾选全局时,系统内所有机构都被授权,返回数据中 checkedKeys = ['all']
- 多选模式:支持选择多个渠道
- 所属渠道保护:组件所属渠道默认授权勾选且置灰,不得修改
- 全局授权:勾选全局时,系统内所有渠道都被授权,返回数据中 appKeys = ['all']
- 多选模式:支持选择多个用户
- 所属用户保护:组件所属用户默认授权勾选且置灰,不得修改
- 全局授权:勾选全局时,系统内所有用户都被授权,返回数据中 userKeys = ['all']
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| visible | 弹窗是否可见 | boolean | false | - |boolean
| disabled | 是否禁用编辑(开启后为查看模式) | | false | - |string
| title | 弹窗标题 | | - | - |string
| okText | 确定按钮文字 | | '确定' | - |string
| cancelText | 取消按钮文字 | | '取消' | - |Array
| orgList | 机构列表,见下方 orgList 数据结构 | | [] | - |Array
| appList | 应用列表,见下方 appList 数据结构 | | [] | - |Array
| userList | 用户列表,见下方 userList 数据结构 | | [] | - |DataItem
| dataItem | 授权数据项,见下方 dataItem 数据结构 | | - | - |boolean
| showUser | 是否展示用户授权面板 | | false | - |(data: SubmitData) => void
| onSubmit | 确定操作回调 | | - | - |() => void
| close | 关闭操作回调 | | - | - |cn
| lang | 语言设置,支持 、en | string | 'cn' | - |object
| locale | 自定义语言包(会覆盖内置语言包) | | - | - |string
| orgTitle | 机构列表面板标题 | | '可用机构' | - |string
| appTitle | 应用列表面板标题 | | '可用渠道' | - |string
| userTitle | 用户列表面板标题 | | '可用用户' | - |string
| orgCheckboxTitle | 机构全局授权复选框标题 | | '全部机构可用' | - |string
| appCheckboxTitle | 应用全局授权复选框标题 | | '全部渠道可用' | - |string
| userCheckboxTitle | 用户全局授权复选框标题 | | '全部用户可用' | - |(org: OrgNode) => boolean
| customOrgDisabled | 自定义机构禁用规则 | | - | - |(app: AppNode) => boolean
| customAppDisabled | 自定义应用禁用规则 | | - | - |
机构列表为树形结构数组,每个节点包含以下字段:
`javascript`
[
{
uuid: 'org-1',
code: 'ROOT',
level: 1,
name: '总公司',
children: [
{
uuid: 'org-2',
code: 'BRANCH_A',
level: 2,
parentUuid: 'org-1',
name: '分公司A',
children: [
{
uuid: 'org-3',
code: 'DEPT_A1',
level: 3,
parentUuid: 'org-2',
name: '部门A1',
children: [],
},
],
},
{
uuid: 'org-4',
code: 'BRANCH_B',
level: 2,
parentUuid: 'org-1',
name: '分公司B',
children: [],
},
],
},
];
字段说明:
- uuid:机构唯一标识code
- :机构编码(必需)name
- :机构名称(必需)level
- :机构层级children
- :子机构数组(必需,即使为空也要提供空数组)orgAttribute
- :机构属性(1 为职能部门,会显示特殊标签)
应用列表为扁平数组,每个应用包含以下字段:
`javascript`
[
{
uuid: 'app-1',
name: 'APP1',
displayName: '应用系统1',
label: '应用系统1',
value: 'APP1',
},
{
uuid: 'app-2',
name: 'APP2',
displayName: '应用系统2',
label: '应用系统2',
value: 'APP2',
},
{
uuid: 'app-3',
name: 'APP3',
displayName: '应用系统3',
label: '应用系统3',
value: 'APP3',
},
];
字段说明:
- uuid:应用唯一标识name
- :应用编码value
- :应用值(必需)label
- / displayName:应用显示名称(必需)
用户列表为扁平数组,每个用户包含以下字段:
`javascript`
[
{
uuid: 'user-1',
account: 'user1',
userName: '用户A',
orgCode: 'ROOT',
status: 0,
},
{
uuid: 'user-2',
account: 'user2',
userName: '用户B',
orgCode: 'BRANCH_A',
status: 0,
},
];
字段说明:
- uuid:用户唯一标识account
- :用户账号(必需)userName
- :用户名称(必需)orgCode
- :所属机构编码status
- :用户状态
授权数据项,用于初始化组件的授权状态:
`javascript
{
// 所属信息(会被自动选中且禁用)
orgCode: 'ROOT', // 所属机构编码
appCode: 'APP1', // 所属应用编码
account: 'user1', // 所属用户账号
// 已授权列表
orgCodes: ['ROOT', 'BRANCH_A'], // 已授权的机构编码列表,['all'] 表示全局授权
appCodes: ['APP1', 'APP2'], // 已授权的应用编码列表,['all'] 表示全局授权
accounts: ['user1', 'user2'] // 已授权的用户账号列表,['all'] 表示全局授权
}
`
点击确定按钮时,会触发 onSubmit 回调,返回的数据格式如下:
`javascript
{
// 授权的编码列表
checkedKeys: ['ROOT', 'BRANCH_A'] | ['all'], // 机构编码列表
appKeys: ['APP1', 'APP2'] | ['all'], // 应用编码列表
userKeys: ['user1', 'user2'] | ['all'], // 用户账号列表
// 是否全局授权标识
orgCheckAll: false, // 机构是否全局授权
appCheckAll: false, // 应用是否全局授权
userCheckAll: false, // 用户是否全局授权
// 实际数据(包含全部的具体编码,不使用 'all')
checkData: {
orgs: ['ROOT', 'BRANCH_A', ...], // 所有被授权的机构编码
apps: ['APP1', 'APP2', ...], // 所有被授权的应用编码
accounts: ['user1', 'user2', ...] // 所有被授权的用户账号
}
}
`
数据说明:
- 当选择全局授权时,checkedKeys/appKeys/userKeys 的值为 ['all']checkData
- 中始终包含具体的编码列表,即使选择了全局授权orgCheckAll
- 使用 /appCheckAll/userCheckAll 可以判断是否为全局授权
将 disabled 设置为 true 即可切换为查看模式,此时不显示操作按钮,所有选项为只读状态:
`jsx`
disabled={true} // 查看模式
orgList={orgList}
appList={appList}
dataItem={dataItem}
close={() => setVisible(false)}
/>
可以通过 customOrgDisabled 和 customAppDisabled 自定义禁用规则:
`jsx`
orgList={orgList}
appList={appList}
dataItem={dataItem}
// 自定义机构禁用规则:禁用 3 级以下机构
customOrgDisabled={(org) => org.level > 3}
// 自定义应用禁用规则:禁用非激活状态的应用
customAppDisabled={(app) => app.status !== 'active'}
onSubmit={(data) => console.log(data)}
close={() => setVisible(false)}
/>
#### 使用内置语言
组件内置中英文支持,通过 lang 属性切换:
`jsx`
lang="en" // 'cn' | 'en'
orgList={orgList}
appList={appList}
dataItem={dataItem}
onSubmit={(data) => console.log(data)}
close={() => setVisible(false)}
/>
#### 自定义语言包
可以通过 locale 属性传入自定义语言包,会覆盖内置语言包:
`jsx
const customLocale = {
authorizesOrgList: '自定义机构列表',
allOrgAvailable: '自定义全部机构',
search: '自定义搜索提示',
// ... 更多文案
};
locale={customLocale}
orgList={orgList}
appList={appList}
dataItem={dataItem}
onSubmit={(data) => console.log(data)}
close={() => setVisible(false)}
/>;
`
可以自定义各个面板的标题:
`jsx`
title="权限配置"
orgTitle="授权机构"
appTitle="授权渠道"
userTitle="授权账号"
orgCheckboxTitle="授权全部机构"
appCheckboxTitle="授权全部渠道"
userCheckboxTitle="授权全部账号"
orgList={orgList}
appList={appList}
userList={userList}
dataItem={dataItem}
showUser={true}
onSubmit={(data) => console.log(data)}
close={() => setVisible(false)}
/>
如果不需要用户授权功能,不传 showUser 或设置为 false 即可:
`jsx`
orgList={orgList}
appList={appList}
dataItem={dataItem}
showUser={false} // 或不传此属性
onSubmit={(data) => console.log(data)}
close={() => setVisible(false)}
/>
确保每个机构节点包含必需字段:code(机构编码)、name(机构名称)、children(子机构数组)
这是保护机制,dataItem 中的 orgCode、appCode、account 会被自动选中且禁用,确保组件至少有基本的授权。
通过 orgCheckAll/appCheckAll/userCheckAll 字段或判断 checkedKeys/appKeys/userKeys 是否为 ['all']
通过 dataItem 传入已有的授权数据:
`javascript`
const dataItem = {
orgCode: 'ROOT', // 所属机构(必填)
appCode: 'APP1', // 所属应用(必填)
orgCodes: ['ROOT', 'BRANCH_A'], // 已授权的机构列表
appCodes: ['APP1', 'APP2'], // 已授权的应用列表
};
- react: >= 16.8.0tntd
- :组件库universal-cookie
- :Cookie 管理lodash
- :工具函数库
1. 数据格式:务必确保 orgList、appList、userList 的数据格式正确,特别是必需字段checkedKeys
2. 联动逻辑:选中子机构会自动选中父机构,取消父机构会自动取消子机构
3. 全局授权:使用全局授权时,返回的 /appKeys/userKeys 为 ['all'],但 checkData 中包含实际的完整列表
4. 性能优化:对于大量机构数据,组件内部使用了虚拟滚动优化
组件支持通过 locale 属性自定义文案:
`jsx``
authorizesOrgList: '组织架构',
allOrgAvailable: '授权全部组织',
search: '搜索组织...',
// 更多字段...
}}
// 其他属性...
/>