Commit 623681bf22faf5be09a6c6146bf3422744c5c72d

Authored by loveumiko
1 parent dbe4f6d5

feat/新增菜单客户租户

1 import { AccountParams } from './model/systemModel'; 1 import { AccountParams } from './model/systemModel';
2 import { defHttp } from '/@/utils/http/axios'; 2 import { defHttp } from '/@/utils/http/axios';
3 enum Api { 3 enum Api {
4 - TENANT_List = '/user/tenantt/page', 4 + GET_TENANT_List = '/user/tenant/page',
  5 + ADD_TANANT_LIST = '/user/save_common_tenant',
5 } 6 }
6 7
7 export const getTenantList = (params: AccountParams) => { 8 export const getTenantList = (params: AccountParams) => {
8 - const url = Api.TENANT_List; 9 + const url = Api.GET_TENANT_List;
9 return defHttp.get({ url: url, params }); 10 return defHttp.get({ url: url, params });
10 }; 11 };
  12 +export const addTenantList = (params: AccountParams) => {
  13 + const url = Api.ADD_TANANT_LIST;
  14 + return defHttp.post({ url: url, params });
  15 +};
@@ -94,12 +94,17 @@ export const getAllRoleList = async (params?: RoleParams) => { @@ -94,12 +94,17 @@ export const getAllRoleList = async (params?: RoleParams) => {
94 }; 94 };
95 95
96 // 过滤角色列表----根据登录的账号所属的角色-过滤掉其他平台类型的角色 96 // 过滤角色列表----根据登录的账号所属的角色-过滤掉其他平台类型的角色
97 -export const filterRoleList = async () => {  
98 - const res = await defHttp.post<RoleListGetResultModel>({ url: Api.GetAllRoleList }); 97 +export const filterRoleList = async (params?: { roleType: string }) => {
  98 + const res = await defHttp.post<RoleListGetResultModel>({
  99 + url: Api.GetAllRoleList,
  100 + params: params,
  101 + });
99 const userInfo: any = getAuthCache(USER_INFO_KEY); 102 const userInfo: any = getAuthCache(USER_INFO_KEY);
100 const role = userInfo.roles[0]; 103 const role = userInfo.roles[0];
101 const options = res.filter((item) => { 104 const options = res.filter((item) => {
102 - if (role === 'SYS_ADMIN' || role === 'PLATFORM_ADMIN') { 105 + if (params?.roleType && params.roleType === 'TENANT_ADMIN') {
  106 + return item;
  107 + } else if (role === 'SYS_ADMIN' || role === 'PLATFORM_ADMIN') {
103 return item.roleType === 'PLATFORM_ADMIN'; 108 return item.roleType === 'PLATFORM_ADMIN';
104 } else { 109 } else {
105 return item.roleType === 'CUSTOMER_USER'; 110 return item.roleType === 'CUSTOMER_USER';
  1 +<template>
  2 + <BasicModal
  3 + width="650px"
  4 + v-bind="$attrs"
  5 + @register="registerModal"
  6 + :title="getTitle"
  7 + @ok="handleSubmit"
  8 + >
  9 + <div style="height: 40vh">
  10 + <BasicForm @register="registerForm">
  11 + <template #organizationId="{ model, field }">
  12 + <Button type="link" @click="handleOpenCreate" style="padding: 0; z-index: 9999"
  13 + >新增组织
  14 + </Button>
  15 + <BasicTree
  16 + v-if="organizationTreeData.length"
  17 + v-model:value="model[field]"
  18 + :treeData="organizationTreeData"
  19 + :checked-keys="checkGroup"
  20 + :expandedKeys="treeExpandData"
  21 + ref="basicTreeRef"
  22 + @check="handleCheckClick"
  23 + @unSelectAll="handleUnSelectAll"
  24 + @strictlyStatus="handleStrictlyStatus"
  25 + checkable
  26 + toolbar
  27 + @change="handleTreeSelect"
  28 + />
  29 + </template>
  30 + <template #roleSlot="{ model, field }">
  31 + <a-select
  32 + mode="multiple"
  33 + allowClear
  34 + placeholder="请选择角色"
  35 + v-model:value="model[field]"
  36 + @change="handleRoleSelect"
  37 + :options="roleOptions.map((item) => ({ value: item.value, label: item.label }))"
  38 + >
  39 + <template #dropdownRender="{ menuNode: menu }">
  40 + <v-nodes :vnodes="menu" />
  41 + <a-divider style="margin: 4px 0" />
  42 + <div @click="handleOpenRole" style="padding: 4px 0; cursor: pointer">
  43 + <plus-outlined />
  44 + 新增角色
  45 + </div>
  46 + </template>
  47 + </a-select>
  48 + </template>
  49 + </BasicForm>
  50 +
  51 + <OrganizationDrawer @register="registerDrawer" @success="handleReload" />
  52 + </div>
  53 + </BasicModal>
  54 + <RoleDrawer @register="registerRoleDrawer" @success="handleSuccess" />
  55 +</template>
  56 +<script lang="ts">
  57 + import { defineComponent, ref, computed, unref, reactive, onMounted } from 'vue';
  58 + import { BasicModal, useModalInner } from '/@/components/Modal';
  59 + import { BasicForm, useForm } from '/@/components/Form/index';
  60 + import { accountFormSchema } from './config';
  61 + import { Button } from 'ant-design-vue';
  62 + import { findCurrentUserRelation, filterRoleList } from '/@/api/system/system';
  63 + import { addTenantList } from '/@/api/system/account';
  64 + import { BasicTree, TreeItem, CheckKeys, CheckEvent } from '/@/components/Tree';
  65 + import { findCurrentUserGroups } from '/@/api/system/group';
  66 + import { RoleOrOrganizationParam } from '/@/api/system/model/systemModel';
  67 + import { useMessage } from '/@/hooks/web/useMessage';
  68 + import { copyTransTreeFun } from '/@/utils/fnUtils';
  69 + import { TOption } from '/@/views/rule/linkedge/config/config.data';
  70 + import { PlusOutlined } from '@ant-design/icons-vue';
  71 + import { useDrawer } from '/@/components/Drawer';
  72 + import RoleDrawer from '../../role/RoleDrawer.vue';
  73 + import OrganizationDrawer from '/@/views/system/organization/OrganizationDrawer.vue';
  74 +
  75 + export default defineComponent({
  76 + name: 'TenantModal',
  77 + components: {
  78 + BasicModal,
  79 + BasicForm,
  80 + Button,
  81 + BasicTree,
  82 + OrganizationDrawer,
  83 + PlusOutlined,
  84 + RoleDrawer,
  85 + VNodes: (_, { attrs }) => {
  86 + return attrs.vnodes;
  87 + },
  88 + },
  89 + emits: ['success', 'register'],
  90 + setup(_, { emit }) {
  91 + const [registerRoleDrawer, { openDrawer }] = useDrawer();
  92 + const { createMessage } = useMessage();
  93 +
  94 + const roleOptions = ref<TOption[]>([]);
  95 + const isUpdate = ref(true);
  96 + const rowId = ref('');
  97 + const organizationTreeData = ref<TreeItem[]>([]);
  98 + const basicTreeRef = ref();
  99 + const checkGroup = ref<string[]>([]);
  100 + const treeExpandData = ref([]);
  101 + const olderPhoneNumber = ref();
  102 + const singleEditPostPhoneNumber = reactive({
  103 + phoneNumber: '',
  104 + });
  105 + const checkedKeysWithHalfChecked = ref<(string | number)[]>([]);
  106 + const getRoleList = async () => {
  107 + const res = await filterRoleList({ roleType: 'TENANT_ADMIN' });
  108 + roleOptions.value = res.map((m) => {
  109 + return {
  110 + label: m.name,
  111 + value: m.id,
  112 + };
  113 + });
  114 + };
  115 +
  116 + onMounted(async () => {
  117 + await getRoleList();
  118 + });
  119 + const handleOpenRole = () => {
  120 + openDrawer(true, {
  121 + isUpdate: false,
  122 + });
  123 + };
  124 + const clearValidateByField = (field: string) => {
  125 + clearValidate(field);
  126 + };
  127 + const handleRoleSelect = (e) => {
  128 + if (e?.length > 0) clearValidateByField('roleIds');
  129 + else validateFields(['roleIds']);
  130 + };
  131 + const handleTreeSelect = (e) => {
  132 + if (e) clearValidateByField('organizationIds');
  133 + };
  134 + const handleSuccess = async () => {
  135 + await getRoleList();
  136 + };
  137 + const [
  138 + registerForm,
  139 + {
  140 + setFieldsValue,
  141 + updateSchema,
  142 + resetFields,
  143 + validate,
  144 + getFieldsValue,
  145 + clearValidate,
  146 + validateFields,
  147 + },
  148 + ] = useForm({
  149 + labelWidth: 100,
  150 + schemas: accountFormSchema,
  151 + showActionButtonGroup: false,
  152 + actionColOptions: {
  153 + span: 18,
  154 + },
  155 + });
  156 + //获取所有父级id
  157 + function findForAllId(data = [], arr = []) {
  158 + for (const item of data) {
  159 + arr.push(item.id);
  160 + }
  161 + return arr;
  162 + }
  163 +
  164 + const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
  165 + await resetFields();
  166 + setModalProps({ confirmLoading: false });
  167 + isUpdate.value = !!data?.isUpdate;
  168 + const groupListModel = await findCurrentUserGroups();
  169 + if (!unref(organizationTreeData).length) {
  170 + copyTransTreeFun(groupListModel);
  171 + organizationTreeData.value = groupListModel;
  172 + const getAllIds = findForAllId(organizationTreeData.value as any, []);
  173 + //设置要展开的id
  174 + treeExpandData.value = getAllIds;
  175 + }
  176 + if (unref(isUpdate)) {
  177 + rowId.value = data.record.id;
  178 + const roleParams = new RoleOrOrganizationParam(rowId.value, true, false);
  179 + olderPhoneNumber.value = data.record.phoneNumber;
  180 + singleEditPostPhoneNumber.phoneNumber = data.record.phoneNumber;
  181 + findCurrentUserRelation(roleParams).then((result) => {
  182 + Reflect.set(data.record, 'roleIds', result);
  183 + Reflect.set(data.record, 'password', '******');
  184 + setFieldsValue(data.record);
  185 + });
  186 + const organizationParams = new RoleOrOrganizationParam(rowId.value, false, true);
  187 + checkGroup.value = await findCurrentUserRelation(organizationParams);
  188 + }
  189 + await updateSchema([
  190 + {
  191 + field: 'username',
  192 + dynamicDisabled: unref(isUpdate),
  193 + },
  194 + {
  195 + field: 'password',
  196 + ifShow: !unref(isUpdate),
  197 + },
  198 + ]);
  199 + });
  200 + const getTitle = computed(() => (!unref(isUpdate) ? '新增账号' : '编辑账号'));
  201 +
  202 + async function handleSubmit() {
  203 + setModalProps({ confirmLoading: true });
  204 + try {
  205 + await validate();
  206 + const values = getFieldsValue();
  207 + await addTenantList({ ...values, level: 4 });
  208 + createMessage.success('操作成功');
  209 + closeModal();
  210 + emit('success');
  211 + } finally {
  212 + setModalProps({ confirmLoading: false });
  213 + }
  214 + }
  215 + // 取消全部的时候清除回显时获取的
  216 + const handleUnSelectAll = () => {
  217 + checkedKeysWithHalfChecked.value = [];
  218 + };
  219 +
  220 + const strictlyStatus = ref(false); //层级关联或独立的状态 false为层级关联 true为层级独立
  221 +
  222 + const handleStrictlyStatus = (status) => (strictlyStatus.value = status);
  223 +
  224 + const handleCheckClick = (selectedKeys: CheckKeys, event: CheckEvent) => {
  225 + //fix 取消层级独立后selectedKeys不是数组,是{checked:[],halfChecked:[]}对象 迭代报错
  226 + // 层级独立
  227 + if (strictlyStatus.value) {
  228 + if (!Array.isArray(selectedKeys)) {
  229 + selectedKeys = selectedKeys?.checked;
  230 + event.halfCheckedKeys = [];
  231 + }
  232 + } else {
  233 + // 层级关联
  234 + event.halfCheckedKeys = [];
  235 + }
  236 + checkedKeysWithHalfChecked.value = [
  237 + ...selectedKeys,
  238 + ...(event.halfCheckedKeys as string[]),
  239 + ];
  240 + };
  241 +
  242 + const [registerDrawer, { openDrawer: addOpenDrawer }] = useDrawer();
  243 +
  244 + const handleOpenCreate = () => {
  245 + addOpenDrawer(true, { isUpdate: false });
  246 + };
  247 + const handleReload = async () => {
  248 + const groupListModel = await findCurrentUserGroups();
  249 + copyTransTreeFun(groupListModel);
  250 + organizationTreeData.value = groupListModel;
  251 + };
  252 +
  253 + return {
  254 + registerModal,
  255 + registerForm,
  256 + handleSubmit,
  257 + getTitle,
  258 + organizationTreeData,
  259 + checkGroup,
  260 + basicTreeRef,
  261 + treeExpandData,
  262 + roleOptions,
  263 + registerRoleDrawer,
  264 + handleOpenRole,
  265 + handleSuccess,
  266 + handleRoleSelect,
  267 + handleTreeSelect,
  268 + handleCheckClick,
  269 + handleUnSelectAll,
  270 + handleStrictlyStatus,
  271 + handleOpenCreate,
  272 + registerDrawer,
  273 + handleReload,
  274 + };
  275 + },
  276 + });
  277 +</script>
  278 +<style scoped lang="less">
  279 + :deep(.vben-basic-tree) {
  280 + width: 100% !important;
  281 + margin-top: -28px !important;
  282 + padding: 0;
  283 + }
  284 +
  285 + :deep(.is-unflod) {
  286 + display: none !important;
  287 + }
  288 +
  289 + :deep(.is-flod) {
  290 + display: none !important;
  291 + }
  292 +</style>
  1 +import { IsPhoneExist, isAccountExist } from '/@/api/system/system';
1 import { BasicColumn, FormSchema } from '/@/components/Table'; 2 import { BasicColumn, FormSchema } from '/@/components/Table';
  3 +import { ChineseRegexp, EmailRegexp, emailRule, phoneRegexp } from '/@/utils/rules';
  4 +
  5 +let olderPhoneNumber;
2 6
3 export const columns: BasicColumn[] = [ 7 export const columns: BasicColumn[] = [
4 { 8 {
@@ -56,3 +60,180 @@ export const searchFormSchema: FormSchema[] = [ @@ -56,3 +60,180 @@ export const searchFormSchema: FormSchema[] = [
56 }, 60 },
57 }, 61 },
58 ]; 62 ];
  63 +
  64 +export const accountFormSchema: FormSchema[] = [
  65 + {
  66 + field: 'id',
  67 + label: 'id',
  68 + component: 'Input',
  69 + show: false,
  70 + componentProps: {
  71 + maxLength: 36,
  72 + },
  73 + },
  74 + {
  75 + field: 'username',
  76 + label: '用户名',
  77 + component: 'Input',
  78 + colProps: { span: 12 },
  79 + dynamicDisabled: false,
  80 + componentProps: {
  81 + maxLength: 36,
  82 + placeholder: '请输入用户名',
  83 + },
  84 + dynamicRules: ({ values }) => {
  85 + return [
  86 + {
  87 + required: true,
  88 + validator(_, value) {
  89 + return new Promise((resolve, reject) => {
  90 + if (value == '') {
  91 + reject('请输入用户名');
  92 + } else if (ChineseRegexp.test(value)) {
  93 + reject('用户名不能含有中文');
  94 + } else if (EmailRegexp.test(value)) {
  95 + reject('用户名不能为电子邮箱格式');
  96 + } else {
  97 + if (values.username != undefined && values.id == undefined) {
  98 + isAccountExist(value).then(({ data }) => {
  99 + if (data != null) {
  100 + reject('用户名已存在');
  101 + } else {
  102 + resolve();
  103 + }
  104 + });
  105 + } else {
  106 + resolve();
  107 + }
  108 + }
  109 + });
  110 + },
  111 + },
  112 + ];
  113 + },
  114 + },
  115 + // {
  116 + // field: 'password',
  117 + // label: '密码',
  118 + // component: 'InputPassword',
  119 + // required: true,
  120 + // colProps: { span: 12 },
  121 + // },
  122 + {
  123 + field: 'realName',
  124 + label: '真实姓名',
  125 + component: 'Input',
  126 + colProps: { span: 12 },
  127 + required: true,
  128 + componentProps: {
  129 + maxLength: 10,
  130 + },
  131 + },
  132 +
  133 + {
  134 + label: '手机号',
  135 + field: 'phoneNumber',
  136 + component: 'Input',
  137 + colProps: { span: 12 },
  138 + dynamicRules: ({ values }) => {
  139 + return [
  140 + {
  141 + required: true,
  142 + validator(_, value) {
  143 + return new Promise((resolve, reject) => {
  144 + if (value == '') {
  145 + reject('请输入手机号');
  146 + } else if (!phoneRegexp.test(value)) {
  147 + reject('请输入正确的手机号');
  148 + } else {
  149 + if (values.phoneNumber != undefined) {
  150 + // 此处可以用防抖函数优化性能
  151 + IsPhoneExist(value).then(({ data }) => {
  152 + if (data != null) {
  153 + reject('手机号已存在');
  154 + } else {
  155 + resolve();
  156 + }
  157 + });
  158 + } else {
  159 + resolve();
  160 + }
  161 + }
  162 + });
  163 + },
  164 + },
  165 + ];
  166 + },
  167 + componentProps({ formActionType }) {
  168 + const { clearValidate } = formActionType;
  169 + return {
  170 + onChange(value) {
  171 + if (value == olderPhoneNumber) {
  172 + clearValidate('phoneNumber');
  173 + }
  174 + },
  175 + };
  176 + },
  177 + },
  178 + {
  179 + label: '角色',
  180 + field: 'roleIds',
  181 + component: 'Select',
  182 + colProps: { span: 12 },
  183 + slot: 'roleSlot',
  184 + rules: [
  185 + {
  186 + required: true,
  187 + message: '请选择角色',
  188 + type: 'array',
  189 + },
  190 + ],
  191 + },
  192 + {
  193 + label: '邮箱',
  194 + field: 'email',
  195 + component: 'Input',
  196 + colProps: { span: 12 },
  197 + rules: emailRule,
  198 + },
  199 + // {
  200 + // field: 'accountExpireTime',
  201 + // label: '有效期',
  202 + // component: 'DatePicker',
  203 + // colProps: { span: 12 },
  204 + // componentProps: {
  205 + // showTime: true,
  206 + // format: 'YYYY-MM-DD HH:mm:ss',
  207 + // },
  208 + // },
  209 + {
  210 + field: 'enabled',
  211 + label: '状态',
  212 + component: 'RadioButtonGroup',
  213 + colProps: { span: 12 },
  214 + defaultValue: true,
  215 + componentProps: {
  216 + options: [
  217 + { label: '启用', value: true },
  218 + { label: '禁用', value: false },
  219 + ],
  220 + },
  221 + },
  222 + // {
  223 + // field: 'remark',
  224 + // label: '备注',
  225 + // component: 'InputTextArea',
  226 + // colProps: { span: 24 },
  227 + // componentProps: {
  228 + // maxLength: 255,
  229 + // placeholder: '请输入备注',
  230 + // },
  231 + // },
  232 + {
  233 + field: 'organizationIds',
  234 + label: '所属组织',
  235 + component: 'Input',
  236 + slot: 'organizationId',
  237 + required: true,
  238 + },
  239 +];
1 <template> 1 <template>
2 <div> 2 <div>
3 - <BasicTable style="flex: auto" :clickToRowSelect="false" @register="registerTable">  
4 - <template #toolbar>  
5 - <Authority value="api:yt:user:post">  
6 - <a-button type="primary" @click="handleCreate">新增账号</a-button>  
7 - </Authority>  
8 - <Authority value="api:yt:user:delete">  
9 - <Popconfirm  
10 - title="您确定要批量删除数据"  
11 - ok-text="确定"  
12 - cancel-text="取消"  
13 - @confirm="() => {}" 3 + <PageWrapper dense contentFullHeight contentClass="flex">
  4 + <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" />
  5 +
  6 + <BasicTable
  7 + style="flex: auto"
  8 + :clickToRowSelect="false"
  9 + @register="registerTable"
  10 + class="w-3/4 xl:w-4/5"
  11 + >
  12 + <template #toolbar>
  13 + <Authority value="api:yt:user:post">
  14 + <a-button type="primary" @click="handleCreate">新增租户</a-button>
  15 + </Authority>
  16 + <Authority value="api:yt:user:delete">
  17 + <Popconfirm
  18 + title="您确定要批量删除数据"
  19 + ok-text="确定"
  20 + cancel-text="取消"
  21 + @confirm="() => {}"
  22 + >
  23 + <a-button color="error"> 批量删除 </a-button>
  24 + </Popconfirm>
  25 + </Authority>
  26 + </template>
  27 + <template #status="{ record }">
  28 + <Tag
  29 + :color="
  30 + record.userStatusEnum === 'NORMAL'
  31 + ? 'green'
  32 + : record.userStatusEnum === 'DISABLED'
  33 + ? 'red'
  34 + : 'orange'
  35 + "
14 > 36 >
15 - <a-button color="error"> 批量删除 </a-button>  
16 - </Popconfirm>  
17 - </Authority>  
18 - </template>  
19 - <template #status="{ record }">  
20 - <Tag  
21 - :color="  
22 - record.userStatusEnum === 'NORMAL'  
23 - ? 'green'  
24 - : record.userStatusEnum === 'DISABLED'  
25 - ? 'red'  
26 - : 'orange'  
27 - "  
28 - >  
29 - {{  
30 - record.userStatusEnum === 'NORMAL'  
31 - ? '正常'  
32 - : record.userStatusEnum === 'DISABLED'  
33 - ? '已禁用'  
34 - : '已过期'  
35 - }}  
36 - </Tag>  
37 - </template>  
38 - <template #action="{ record }">  
39 - <TableAction  
40 - :actions="[  
41 - // {  
42 - // label: '进入',  
43 - // icon: 'ant-design:login-outlined',  
44 - // tooltip: `以${!isAdmin(role) ? '客户' : '平台'}用户身份登录`,  
45 - // onClick: handleLoginCustomAdmin.bind(null, record),  
46 - // },  
47 - {  
48 - label: '用户详情',  
49 - auth: 'api:yt:user:get',  
50 - icon: 'clarity:info-standard-line',  
51 - tooltip: '用户详情',  
52 - onClick: handledetail.bind(null, record),  
53 - ifShow: record.level != 0,  
54 - },  
55 - {  
56 - label: '编辑',  
57 - auth: 'api:yt:user:update',  
58 - icon: 'clarity:note-edit-line',  
59 - tooltip: '编辑',  
60 - onClick: handleEdit.bind(null, record),  
61 - ifShow: record.level != 0,  
62 - },  
63 - ]"  
64 - :drop-down-actions="[  
65 - {  
66 - label: '删除',  
67 - auth: 'api:yt:user:delete',  
68 - icon: 'ant-design:delete-outlined',  
69 - color: 'error',  
70 - tooltip: '删除',  
71 - ifShow: record.level != 0,  
72 - popConfirm: {  
73 - title: '是否确认删除',  
74 - confirm: handleDeleteOrBatchDelete.bind(null, record), 37 + {{
  38 + record.userStatusEnum === 'NORMAL'
  39 + ? '正常'
  40 + : record.userStatusEnum === 'DISABLED'
  41 + ? '已禁用'
  42 + : '已过期'
  43 + }}
  44 + </Tag>
  45 + </template>
  46 + <template #action="{ record }">
  47 + <TableAction
  48 + :actions="[
  49 + // {
  50 + // label: '进入',
  51 + // icon: 'ant-design:login-outlined',
  52 + // tooltip: `以${!isAdmin(role) ? '客户' : '平台'}用户身份登录`,
  53 + // onClick: handleLoginCustomAdmin.bind(null, record),
  54 + // },
  55 + {
  56 + label: '用户详情',
  57 + auth: 'api:yt:user:get',
  58 + icon: 'clarity:info-standard-line',
  59 + tooltip: '用户详情',
  60 + onClick: handledetail.bind(null, record),
  61 + ifShow: record.level != 0,
  62 + },
  63 + {
  64 + label: '编辑',
  65 + auth: 'api:yt:user:update',
  66 + icon: 'clarity:note-edit-line',
  67 + tooltip: '编辑',
  68 + onClick: handleEdit.bind(null, record),
  69 + ifShow: record.level != 0,
75 }, 70 },
76 - },  
77 - {  
78 - label: '清除密码',  
79 - auth: 'api:yt:user:resetPassword',  
80 - icon: 'ant-design:delete-outlined',  
81 - color: 'error',  
82 - tooltip: '清除密码',  
83 - popConfirm: {  
84 - title: '是否确认清除密码',  
85 - confirm: handleClearPassword.bind(null, record), 71 + ]"
  72 + :drop-down-actions="[
  73 + {
  74 + label: '删除',
  75 + auth: 'api:yt:user:delete',
  76 + icon: 'ant-design:delete-outlined',
  77 + color: 'error',
  78 + tooltip: '删除',
  79 + ifShow: record.level != 0,
  80 + popConfirm: {
  81 + title: '是否确认删除',
  82 + confirm: handleDeleteOrBatchDelete.bind(null, record),
  83 + },
86 }, 84 },
87 - },  
88 - ]"  
89 - />  
90 - </template>  
91 - </BasicTable> 85 + {
  86 + label: '清除密码',
  87 + auth: 'api:yt:user:resetPassword',
  88 + icon: 'ant-design:delete-outlined',
  89 + color: 'error',
  90 + tooltip: '清除密码',
  91 + popConfirm: {
  92 + title: '是否确认清除密码',
  93 + confirm: handleClearPassword.bind(null, record),
  94 + },
  95 + },
  96 + ]"
  97 + />
  98 + </template>
  99 + </BasicTable>
  100 + <TenantModal @register="registerModal" @success="handleSuccess" />
  101 + </PageWrapper>
92 </div> 102 </div>
93 </template> 103 </template>
94 104
@@ -96,22 +106,35 @@ @@ -96,22 +106,35 @@
96 import { BasicTable, useTable, TableAction } from '/@/components/Table'; 106 import { BasicTable, useTable, TableAction } from '/@/components/Table';
97 import { getTenantList } from '/@/api/system/account'; 107 import { getTenantList } from '/@/api/system/account';
98 import { columns, searchFormSchema } from './config'; 108 import { columns, searchFormSchema } from './config';
99 - // import { useResetOrganizationTree } from '/@/views/common/organizationIdTree'; 109 + import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree';
100 import { reactive } from 'vue'; 110 import { reactive } from 'vue';
101 import { Authority } from '/@/components/Authority'; 111 import { Authority } from '/@/components/Authority';
  112 + import { useUserStore } from '/@/store/modules/user';
  113 + import { PageWrapper } from '/@/components/Page';
  114 + import { Tag, Popconfirm } from 'ant-design-vue';
  115 + import TenantModal from './TenantModal.vue';
  116 + import { useModal } from '/@/components/Modal';
102 117
103 const searchInfo = reactive<Recordable>({}); 118 const searchInfo = reactive<Recordable>({});
104 119
105 - // const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo); 120 + const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
106 121
107 - const [registerTable, {}] = useTable({ 122 + const userInfo = useUserStore();
  123 + const [registerTable, { reload }] = useTable({
108 title: '租户账号列表', 124 title: '租户账号列表',
109 columns, 125 columns,
110 api: getTenantList, 126 api: getTenantList,
111 formConfig: { 127 formConfig: {
112 labelWidth: 100, 128 labelWidth: 100,
113 schemas: searchFormSchema, 129 schemas: searchFormSchema,
114 - // resetFunc: resetFn, 130 + resetFunc: resetFn,
  131 + },
  132 +
  133 + beforeFetch: (params) => {
  134 + return {
  135 + ...params,
  136 + tenantId: userInfo.getUserInfo.tenantId!,
  137 + };
115 }, 138 },
116 useSearchForm: true, 139 useSearchForm: true,
117 showTableSetting: true, 140 showTableSetting: true,
@@ -128,9 +151,21 @@ @@ -128,9 +151,21 @@
128 }, 151 },
129 }); 152 });
130 153
131 - const handleCreate = () => {}; 154 + const [registerModal, { openModal }] = useModal();
  155 +
  156 + function handleSelect(organization) {
  157 + searchInfo.organizationId = organization;
  158 + reload();
  159 + }
  160 +
  161 + const handleCreate = () => {
  162 + openModal(true, {
  163 + isAdd: true,
  164 + });
  165 + };
132 const handledetail = (_data?: any[]) => {}; 166 const handledetail = (_data?: any[]) => {};
133 const handleEdit = (_data?: any[]) => {}; 167 const handleEdit = (_data?: any[]) => {};
134 const handleDeleteOrBatchDelete = (_data?: any[]) => {}; 168 const handleDeleteOrBatchDelete = (_data?: any[]) => {};
135 const handleClearPassword = (_data?: any[]) => {}; 169 const handleClearPassword = (_data?: any[]) => {};
  170 + const handleSuccess = () => {};
136 </script> 171 </script>