Commit c61720dbcbb8d114c7dc710313488a3aec9c7603

Authored by dev001
1 parent 623681bf

feat: 新增权限页面

... ... @@ -9,7 +9,7 @@ export const getTenantList = (params: AccountParams) => {
9 9 const url = Api.GET_TENANT_List;
10 10 return defHttp.get({ url: url, params });
11 11 };
12   -export const addTenantList = (params: AccountParams) => {
  12 +export const addTenantList = (params: any) => {
13 13 const url = Api.ADD_TANANT_LIST;
14 14 return defHttp.post({ url: url, params });
15 15 };
... ...
... ... @@ -71,6 +71,9 @@
71 71 import { useDrawer } from '/@/components/Drawer';
72 72 import RoleDrawer from '../../role/RoleDrawer.vue';
73 73 import OrganizationDrawer from '/@/views/system/organization/OrganizationDrawer.vue';
  74 + import { useUserStore } from '/@/store/modules/user';
  75 + import { IsPhoneExist } from '/@/api/system/system';
  76 + import { phoneRegexp } from '/@/utils/rules';
74 77
75 78 export default defineComponent({
76 79 name: 'TenantModal',
... ... @@ -90,9 +93,10 @@
90 93 setup(_, { emit }) {
91 94 const [registerRoleDrawer, { openDrawer }] = useDrawer();
92 95 const { createMessage } = useMessage();
  96 + const userInfo = useUserStore();
93 97
94 98 const roleOptions = ref<TOption[]>([]);
95   - const isUpdate = ref(true);
  99 + const isAdd = ref(true);
96 100 const rowId = ref('');
97 101 const organizationTreeData = ref<TreeItem[]>([]);
98 102 const basicTreeRef = ref();
... ... @@ -118,7 +122,7 @@
118 122 });
119 123 const handleOpenRole = () => {
120 124 openDrawer(true, {
121   - isUpdate: false,
  125 + isAdd: false,
122 126 });
123 127 };
124 128 const clearValidateByField = (field: string) => {
... ... @@ -164,7 +168,7 @@
164 168 const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
165 169 await resetFields();
166 170 setModalProps({ confirmLoading: false });
167   - isUpdate.value = !!data?.isUpdate;
  171 + isAdd.value = !!data?.isAdd;
168 172 const groupListModel = await findCurrentUserGroups();
169 173 if (!unref(organizationTreeData).length) {
170 174 copyTransTreeFun(groupListModel);
... ... @@ -173,39 +177,93 @@
173 177 //设置要展开的id
174 178 treeExpandData.value = getAllIds;
175 179 }
176   - if (unref(isUpdate)) {
  180 +
  181 + if (!unref(isAdd)) {
177 182 rowId.value = data.record.id;
178 183 const roleParams = new RoleOrOrganizationParam(rowId.value, true, false);
179 184 olderPhoneNumber.value = data.record.phoneNumber;
180 185 singleEditPostPhoneNumber.phoneNumber = data.record.phoneNumber;
181 186 findCurrentUserRelation(roleParams).then((result) => {
182 187 Reflect.set(data.record, 'roleIds', result);
183   - Reflect.set(data.record, 'password', '******');
184 188 setFieldsValue(data.record);
185 189 });
  190 + updateSchema([
  191 + {
  192 + field: 'phoneNumber',
  193 + dynamicRules: () => {
  194 + return [
  195 + {
  196 + required: true,
  197 + validator(_, value) {
  198 + return new Promise((resolve, reject) => {
  199 + if (value == '') {
  200 + reject('请输入手机号');
  201 + } else if (!phoneRegexp.test(value)) {
  202 + reject('请输入正确的手机号');
  203 + } else {
  204 + resolve();
  205 + }
  206 + });
  207 + },
  208 + },
  209 + ];
  210 + },
  211 + },
  212 + ]);
186 213 const organizationParams = new RoleOrOrganizationParam(rowId.value, false, true);
187 214 checkGroup.value = await findCurrentUserRelation(organizationParams);
  215 + } else {
  216 + updateSchema([
  217 + {
  218 + field: 'phoneNumber',
  219 + dynamicRules: ({ values }) => {
  220 + return [
  221 + {
  222 + required: true,
  223 + validator(_, value) {
  224 + return new Promise((resolve, reject) => {
  225 + if (value == '') {
  226 + reject('请输入手机号');
  227 + } else if (!phoneRegexp.test(value)) {
  228 + reject('请输入正确的手机号');
  229 + } else {
  230 + if (values.phoneNumber != undefined) {
  231 + // 此处可以用防抖函数优化性能
  232 + IsPhoneExist(value).then(({ data }) => {
  233 + if (data != null) {
  234 + reject('手机号已存在');
  235 + } else {
  236 + resolve();
  237 + }
  238 + });
  239 + } else {
  240 + resolve();
  241 + }
  242 + }
  243 + });
  244 + },
  245 + },
  246 + ];
  247 + },
  248 + },
  249 + ]);
188 250 }
189 251 await updateSchema([
190 252 {
191 253 field: 'username',
192   - dynamicDisabled: unref(isUpdate),
193   - },
194   - {
195   - field: 'password',
196   - ifShow: !unref(isUpdate),
  254 + dynamicDisabled: !unref(isAdd),
197 255 },
198 256 ]);
199 257 });
200   - const getTitle = computed(() => (!unref(isUpdate) ? '新增账号' : '编辑账号'));
  258 + const getTitle = computed(() => (unref(isAdd) ? '新增租户账号' : '编辑租户账号'));
201 259
202 260 async function handleSubmit() {
203 261 setModalProps({ confirmLoading: true });
204 262 try {
205 263 await validate();
206 264 const values = getFieldsValue();
207   - await addTenantList({ ...values, level: 4 });
208   - createMessage.success('操作成功');
  265 + await addTenantList({ ...values, level: 4, tenantId: userInfo.getUserInfo.tenantId! });
  266 + createMessage.success(unref(isAdd) ? '新增成功' : '编辑成功');
209 267 closeModal();
210 268 emit('success');
211 269 } finally {
... ... @@ -242,7 +300,7 @@
242 300 const [registerDrawer, { openDrawer: addOpenDrawer }] = useDrawer();
243 301
244 302 const handleOpenCreate = () => {
245   - addOpenDrawer(true, { isUpdate: false });
  303 + addOpenDrawer(true, { isAdd: false });
246 304 };
247 305 const handleReload = async () => {
248 306 const groupListModel = await findCurrentUserGroups();
... ...
... ... @@ -26,11 +26,6 @@ export const columns: BasicColumn[] = [
26 26 width: 120,
27 27 },
28 28 {
29   - title: '创建时间',
30   - dataIndex: 'createTime',
31   - width: 180,
32   - },
33   - {
34 29 title: '状态',
35 30 dataIndex: 'userStatusEnum',
36 31 width: 120,
... ...
... ... @@ -10,17 +10,17 @@
10 10 class="w-3/4 xl:w-4/5"
11 11 >
12 12 <template #toolbar>
13   - <Authority value="api:yt:user:post">
14   - <a-button type="primary" @click="handleCreate">新增租户</a-button>
  13 + <Authority value="api:yt:user:saveCommonTenant:post">
  14 + <a-button type="primary" @click="handleCreate">新增普通租户</a-button>
15 15 </Authority>
16   - <Authority value="api:yt:user:delete">
  16 + <Authority value="api:yt:admin:user:deleteTenantAdmin:delete">
17 17 <Popconfirm
18 18 title="您确定要批量删除数据"
19 19 ok-text="确定"
20 20 cancel-text="取消"
21   - @confirm="() => {}"
  21 + @confirm="handleDeleteOrBatchDelete(null)"
22 22 >
23   - <a-button color="error"> 批量删除 </a-button>
  23 + <a-button color="error" :disabled="hasBatchDelete"> 批量删除 </a-button>
24 24 </Popconfirm>
25 25 </Authority>
26 26 </template>
... ... @@ -46,33 +46,23 @@
46 46 <template #action="{ record }">
47 47 <TableAction
48 48 :actions="[
49   - // {
50   - // label: '进入',
51   - // icon: 'ant-design:login-outlined',
52   - // tooltip: `以${!isAdmin(role) ? '客户' : '平台'}用户身份登录`,
53   - // onClick: handleLoginCustomAdmin.bind(null, record),
54   - // },
55 49 {
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,
  50 + label: '进入',
  51 + icon: 'ant-design:login-outlined',
  52 + tooltip: `以${!isAdmin(role) ? '租户' : '平台'}用户身份登录`,
  53 + onClick: handleLoginCustomAdmin.bind(null, record),
62 54 },
63 55 {
64 56 label: '编辑',
65   - auth: 'api:yt:user:update',
  57 + auth: 'api:yt:user:saveCommonTenant:post',
66 58 icon: 'clarity:note-edit-line',
67 59 tooltip: '编辑',
68 60 onClick: handleEdit.bind(null, record),
69 61 ifShow: record.level != 0,
70 62 },
71   - ]"
72   - :drop-down-actions="[
73 63 {
74 64 label: '删除',
75   - auth: 'api:yt:user:delete',
  65 + auth: 'api:yt:admin:user:deleteTenantAdmin:delete',
76 66 icon: 'ant-design:delete-outlined',
77 67 color: 'error',
78 68 tooltip: '删除',
... ... @@ -82,17 +72,6 @@
82 72 confirm: handleDeleteOrBatchDelete.bind(null, record),
83 73 },
84 74 },
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 75 ]"
97 76 />
98 77 </template>
... ... @@ -107,20 +86,35 @@
107 86 import { getTenantList } from '/@/api/system/account';
108 87 import { columns, searchFormSchema } from './config';
109 88 import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree';
110   - import { reactive } from 'vue';
  89 + import { reactive, nextTick } from 'vue';
111 90 import { Authority } from '/@/components/Authority';
112 91 import { useUserStore } from '/@/store/modules/user';
113 92 import { PageWrapper } from '/@/components/Page';
  93 + import { useGo } from '/@/hooks/web/usePage';
114 94 import { Tag, Popconfirm } from 'ant-design-vue';
115 95 import TenantModal from './TenantModal.vue';
116 96 import { useModal } from '/@/components/Modal';
  97 + import { useFastEnter } from '/@/hooks/business/useFastEnter';
  98 + import { TenantListItemRecord } from '/@/api/tenant/tenantInfo';
  99 + import { isAdmin } from '/@/enums/roleEnum';
  100 + import { getAuthCache } from '/@/utils/auth';
  101 + import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
  102 + import { deleteTenantAdmin } from '/@/api/tenant/tenantApi';
  103 + // import { useMessage } from '/@/hooks/web/useMessage';
  104 +
  105 + import { USER_INFO_KEY } from '/@/enums/cacheEnum';
117 106
118 107 const searchInfo = reactive<Recordable>({});
  108 + const go = useGo();
119 109
120 110 const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
121 111
  112 + const userRole: any = getAuthCache(USER_INFO_KEY);
  113 + const role: string = userRole?.roles[0];
  114 + // const { createMessage } = useMessage();
  115 +
122 116 const userInfo = useUserStore();
123   - const [registerTable, { reload }] = useTable({
  117 + const [registerTable, { reload, setProps }] = useTable({
124 118 title: '租户账号列表',
125 119 columns,
126 120 api: getTenantList,
... ... @@ -150,6 +144,14 @@
150 144 fixed: 'right',
151 145 },
152 146 });
  147 + const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions } = useBatchDelete(
  148 + deleteTenantAdmin,
  149 + handleSuccess,
  150 + setProps
  151 + );
  152 + nextTick(() => {
  153 + setProps(selectionOptions);
  154 + });
153 155
154 156 const [registerModal, { openModal }] = useModal();
155 157
... ... @@ -163,9 +165,32 @@
163 165 isAdd: true,
164 166 });
165 167 };
166   - const handledetail = (_data?: any[]) => {};
167   - const handleEdit = (_data?: any[]) => {};
168   - const handleDeleteOrBatchDelete = (_data?: any[]) => {};
169   - const handleClearPassword = (_data?: any[]) => {};
170   - const handleSuccess = () => {};
  168 + const handleLoginCustomAdmin = async (record: TenantListItemRecord) => {
  169 + try {
  170 + useFastEnter(record, go);
  171 + } catch (errpr) {
  172 + } finally {
  173 + }
  174 + };
  175 + const handleEdit = (record: Recordable) => {
  176 + openModal(true, {
  177 + isAdd: false,
  178 + record,
  179 + });
  180 + };
  181 + // const handleDeleteOrBatchDelete = (record: Recordable) => {
  182 + // deleteTenantAdmin([record.id]).then(() => {
  183 + // createMessage.success('删除成功');
  184 + // handleSuccess();
  185 + // });
  186 + // };
  187 + // const handleClearPassword = async (record: Recordable) => {
  188 + // const { id } = record;
  189 + // if (!id) return;
  190 + // const { message } = await clearUserPassword(id);
  191 + // createMessage.success(message);
  192 + // };
  193 + function handleSuccess() {
  194 + reload();
  195 + }
171 196 </script>
... ...