@tddc/assign-modal
v3.1.6
Published
assign-modal
Keywords
Readme
AssignModal 授权弹窗组件
用于管理机构、应用(渠道)、用户授权的复杂业务组件,支持树形机构选择、多选应用和用户,以及全局授权等功能。
特性
- 🌲 树形机构选择:支持多级机构树形结构,带有智能联动逻辑
- 🔄 智能联动:选中子机构自动勾选上级,取消上级自动取消下级
- 🌐 全局授权:支持一键授权所有机构/应用/用户
- 👁 双模式:编辑模式和查看模式自动切换
- 🔍 搜索过滤:支持对机构、应用、用户进行实时搜索
- 🌍 国际化:内置中英文支持,可自定义语言包
- 🎨 自定义禁用:支持自定义机构和应用的禁用规则
安装
npm install @tddc/assign-modal --save
# 或
yarn add @tddc/assign-modal基础用法
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 (
<>
<Button onClick={() => setVisible(true)}>配置权限</Button>
<AssignModal
visible={visible}
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']
API
Props
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| visible | 弹窗是否可见 | boolean | false | - |
| disabled | 是否禁用编辑(开启后为查看模式) | boolean | false | - |
| title | 弹窗标题 | string | - | - |
| okText | 确定按钮文字 | string | '确定' | - |
| cancelText | 取消按钮文字 | string | '取消' | - |
| orgList | 机构列表,见下方 orgList 数据结构 | Array<OrgNode> | [] | - |
| appList | 应用列表,见下方 appList 数据结构 | Array<AppNode> | [] | - |
| userList | 用户列表,见下方 userList 数据结构 | Array<UserNode> | [] | - |
| dataItem | 授权数据项,见下方 dataItem 数据结构 | DataItem | - | - |
| showUser | 是否展示用户授权面板 | boolean | false | - |
| onSubmit | 确定操作回调 | (data: SubmitData) => void | - | - |
| close | 关闭操作回调 | () => void | - | - |
| lang | 语言设置,支持 cn、en | string | 'cn' | - |
| locale | 自定义语言包(会覆盖内置语言包) | object | - | - |
| orgTitle | 机构列表面板标题 | string | '可用机构' | - |
| appTitle | 应用列表面板标题 | string | '可用渠道' | - |
| userTitle | 用户列表面板标题 | string | '可用用户' | - |
| orgCheckboxTitle | 机构全局授权复选框标题 | string | '全部机构可用' | - |
| appCheckboxTitle | 应用全局授权复选框标题 | string | '全部渠道可用' | - |
| userCheckboxTitle | 用户全局授权复选框标题 | string | '全部用户可用' | - |
| customOrgDisabled | 自定义机构禁用规则 | (org: OrgNode) => boolean | - | - |
| customAppDisabled | 自定义应用禁用规则 | (app: AppNode) => boolean | - | - |
orgList 数据结构
机构列表为树形结构数组,每个节点包含以下字段:
[
{
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为职能部门,会显示特殊标签)
appList 数据结构
应用列表为扁平数组,每个应用包含以下字段:
[
{
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:应用显示名称(必需)
userList 数据结构
用户列表为扁平数组,每个用户包含以下字段:
[
{
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:用户状态
dataItem 数据结构
授权数据项,用于初始化组件的授权状态:
{
// 所属信息(会被自动选中且禁用)
orgCode: 'ROOT', // 所属机构编码
appCode: 'APP1', // 所属应用编码
account: 'user1', // 所属用户账号
// 已授权列表
orgCodes: ['ROOT', 'BRANCH_A'], // 已授权的机构编码列表,['all'] 表示全局授权
appCodes: ['APP1', 'APP2'], // 已授权的应用编码列表,['all'] 表示全局授权
accounts: ['user1', 'user2'] // 已授权的用户账号列表,['all'] 表示全局授权
}onSubmit 回调数据格式
点击确定按钮时,会触发 onSubmit 回调,返回的数据格式如下:
{
// 授权的编码列表
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 即可切换为查看模式,此时不显示操作按钮,所有选项为只读状态:
<AssignModal
visible={true}
disabled={true} // 查看模式
orgList={orgList}
appList={appList}
dataItem={dataItem}
close={() => setVisible(false)}
/>自定义禁用规则
可以通过 customOrgDisabled 和 customAppDisabled 自定义禁用规则:
<AssignModal
visible={true}
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 属性切换:
<AssignModal
visible={true}
lang="en" // 'cn' | 'en'
orgList={orgList}
appList={appList}
dataItem={dataItem}
onSubmit={(data) => console.log(data)}
close={() => setVisible(false)}
/>自定义语言包
可以通过 locale 属性传入自定义语言包,会覆盖内置语言包:
const customLocale = {
authorizesOrgList: '自定义机构列表',
allOrgAvailable: '自定义全部机构',
search: '自定义搜索提示',
// ... 更多文案
};
<AssignModal
visible={true}
locale={customLocale}
orgList={orgList}
appList={appList}
dataItem={dataItem}
onSubmit={(data) => console.log(data)}
close={() => setVisible(false)}
/>;自定义标题
可以自定义各个面板的标题:
<AssignModal
visible={true}
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 即可:
<AssignModal
visible={true}
orgList={orgList}
appList={appList}
dataItem={dataItem}
showUser={false} // 或不传此属性
onSubmit={(data) => console.log(data)}
close={() => setVisible(false)}
/>常见问题
1. 机构树不显示?
确保每个机构节点包含必需字段:code(机构编码)、name(机构名称)、children(子机构数组)
2. 所属机构/应用无法取消?
这是保护机制,dataItem 中的 orgCode、appCode、account 会被自动选中且禁用,确保组件至少有基本的授权。
3. 如何判断全局授权?
通过 orgCheckAll/appCheckAll/userCheckAll 字段或判断 checkedKeys/appKeys/userKeys 是否为 ['all']
4. 如何预填充授权数据?
通过 dataItem 传入已有的授权数据:
const dataItem = {
orgCode: 'ROOT', // 所属机构(必填)
appCode: 'APP1', // 所属应用(必填)
orgCodes: ['ROOT', 'BRANCH_A'], // 已授权的机构列表
appCodes: ['APP1', 'APP2'], // 已授权的应用列表
};依赖
react: >= 16.8.0tntd:组件库universal-cookie:Cookie 管理lodash:工具函数库
注意事项
- 数据格式:务必确保
orgList、appList、userList的数据格式正确,特别是必需字段 - 联动逻辑:选中子机构会自动选中父机构,取消父机构会自动取消子机构
- 全局授权:使用全局授权时,返回的
checkedKeys/appKeys/userKeys为['all'],但checkData中包含实际的完整列表 - 性能优化:对于大量机构数据,组件内部使用了虚拟滚动优化
语言包配置
组件支持通过 locale 属性自定义文案:
<AssignModal
locale={{
authorizesOrgList: '组织架构',
allOrgAvailable: '授权全部组织',
search: '搜索组织...',
// 更多字段...
}}
// 其他属性...
/>