Showing
4 changed files
with
137 additions
and
59 deletions
| @@ -9,7 +9,7 @@ export const getTenantList = (params: AccountParams) => { | @@ -9,7 +9,7 @@ export const getTenantList = (params: AccountParams) => { | ||
| 9 | const url = Api.GET_TENANT_List; | 9 | const url = Api.GET_TENANT_List; |
| 10 | return defHttp.get({ url: url, params }); | 10 | return defHttp.get({ url: url, params }); |
| 11 | }; | 11 | }; |
| 12 | -export const addTenantList = (params: AccountParams) => { | 12 | +export const addTenantList = (params: any) => { |
| 13 | const url = Api.ADD_TANANT_LIST; | 13 | const url = Api.ADD_TANANT_LIST; |
| 14 | return defHttp.post({ url: url, params }); | 14 | return defHttp.post({ url: url, params }); |
| 15 | }; | 15 | }; |
| @@ -71,6 +71,9 @@ | @@ -71,6 +71,9 @@ | ||
| 71 | import { useDrawer } from '/@/components/Drawer'; | 71 | import { useDrawer } from '/@/components/Drawer'; |
| 72 | import RoleDrawer from '../../role/RoleDrawer.vue'; | 72 | import RoleDrawer from '../../role/RoleDrawer.vue'; |
| 73 | import OrganizationDrawer from '/@/views/system/organization/OrganizationDrawer.vue'; | 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 | export default defineComponent({ | 78 | export default defineComponent({ |
| 76 | name: 'TenantModal', | 79 | name: 'TenantModal', |
| @@ -90,9 +93,10 @@ | @@ -90,9 +93,10 @@ | ||
| 90 | setup(_, { emit }) { | 93 | setup(_, { emit }) { |
| 91 | const [registerRoleDrawer, { openDrawer }] = useDrawer(); | 94 | const [registerRoleDrawer, { openDrawer }] = useDrawer(); |
| 92 | const { createMessage } = useMessage(); | 95 | const { createMessage } = useMessage(); |
| 96 | + const userInfo = useUserStore(); | ||
| 93 | 97 | ||
| 94 | const roleOptions = ref<TOption[]>([]); | 98 | const roleOptions = ref<TOption[]>([]); |
| 95 | - const isUpdate = ref(true); | 99 | + const isAdd = ref(true); |
| 96 | const rowId = ref(''); | 100 | const rowId = ref(''); |
| 97 | const organizationTreeData = ref<TreeItem[]>([]); | 101 | const organizationTreeData = ref<TreeItem[]>([]); |
| 98 | const basicTreeRef = ref(); | 102 | const basicTreeRef = ref(); |
| @@ -118,7 +122,7 @@ | @@ -118,7 +122,7 @@ | ||
| 118 | }); | 122 | }); |
| 119 | const handleOpenRole = () => { | 123 | const handleOpenRole = () => { |
| 120 | openDrawer(true, { | 124 | openDrawer(true, { |
| 121 | - isUpdate: false, | 125 | + isAdd: false, |
| 122 | }); | 126 | }); |
| 123 | }; | 127 | }; |
| 124 | const clearValidateByField = (field: string) => { | 128 | const clearValidateByField = (field: string) => { |
| @@ -164,7 +168,7 @@ | @@ -164,7 +168,7 @@ | ||
| 164 | const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { | 168 | const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { |
| 165 | await resetFields(); | 169 | await resetFields(); |
| 166 | setModalProps({ confirmLoading: false }); | 170 | setModalProps({ confirmLoading: false }); |
| 167 | - isUpdate.value = !!data?.isUpdate; | 171 | + isAdd.value = !!data?.isAdd; |
| 168 | const groupListModel = await findCurrentUserGroups(); | 172 | const groupListModel = await findCurrentUserGroups(); |
| 169 | if (!unref(organizationTreeData).length) { | 173 | if (!unref(organizationTreeData).length) { |
| 170 | copyTransTreeFun(groupListModel); | 174 | copyTransTreeFun(groupListModel); |
| @@ -173,39 +177,93 @@ | @@ -173,39 +177,93 @@ | ||
| 173 | //设置要展开的id | 177 | //设置要展开的id |
| 174 | treeExpandData.value = getAllIds; | 178 | treeExpandData.value = getAllIds; |
| 175 | } | 179 | } |
| 176 | - if (unref(isUpdate)) { | 180 | + |
| 181 | + if (!unref(isAdd)) { | ||
| 177 | rowId.value = data.record.id; | 182 | rowId.value = data.record.id; |
| 178 | const roleParams = new RoleOrOrganizationParam(rowId.value, true, false); | 183 | const roleParams = new RoleOrOrganizationParam(rowId.value, true, false); |
| 179 | olderPhoneNumber.value = data.record.phoneNumber; | 184 | olderPhoneNumber.value = data.record.phoneNumber; |
| 180 | singleEditPostPhoneNumber.phoneNumber = data.record.phoneNumber; | 185 | singleEditPostPhoneNumber.phoneNumber = data.record.phoneNumber; |
| 181 | findCurrentUserRelation(roleParams).then((result) => { | 186 | findCurrentUserRelation(roleParams).then((result) => { |
| 182 | Reflect.set(data.record, 'roleIds', result); | 187 | Reflect.set(data.record, 'roleIds', result); |
| 183 | - Reflect.set(data.record, 'password', '******'); | ||
| 184 | setFieldsValue(data.record); | 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 | const organizationParams = new RoleOrOrganizationParam(rowId.value, false, true); | 213 | const organizationParams = new RoleOrOrganizationParam(rowId.value, false, true); |
| 187 | checkGroup.value = await findCurrentUserRelation(organizationParams); | 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 | await updateSchema([ | 251 | await updateSchema([ |
| 190 | { | 252 | { |
| 191 | field: 'username', | 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 | async function handleSubmit() { | 260 | async function handleSubmit() { |
| 203 | setModalProps({ confirmLoading: true }); | 261 | setModalProps({ confirmLoading: true }); |
| 204 | try { | 262 | try { |
| 205 | await validate(); | 263 | await validate(); |
| 206 | const values = getFieldsValue(); | 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 | closeModal(); | 267 | closeModal(); |
| 210 | emit('success'); | 268 | emit('success'); |
| 211 | } finally { | 269 | } finally { |
| @@ -242,7 +300,7 @@ | @@ -242,7 +300,7 @@ | ||
| 242 | const [registerDrawer, { openDrawer: addOpenDrawer }] = useDrawer(); | 300 | const [registerDrawer, { openDrawer: addOpenDrawer }] = useDrawer(); |
| 243 | 301 | ||
| 244 | const handleOpenCreate = () => { | 302 | const handleOpenCreate = () => { |
| 245 | - addOpenDrawer(true, { isUpdate: false }); | 303 | + addOpenDrawer(true, { isAdd: false }); |
| 246 | }; | 304 | }; |
| 247 | const handleReload = async () => { | 305 | const handleReload = async () => { |
| 248 | const groupListModel = await findCurrentUserGroups(); | 306 | const groupListModel = await findCurrentUserGroups(); |
| @@ -26,11 +26,6 @@ export const columns: BasicColumn[] = [ | @@ -26,11 +26,6 @@ export const columns: BasicColumn[] = [ | ||
| 26 | width: 120, | 26 | width: 120, |
| 27 | }, | 27 | }, |
| 28 | { | 28 | { |
| 29 | - title: '创建时间', | ||
| 30 | - dataIndex: 'createTime', | ||
| 31 | - width: 180, | ||
| 32 | - }, | ||
| 33 | - { | ||
| 34 | title: '状态', | 29 | title: '状态', |
| 35 | dataIndex: 'userStatusEnum', | 30 | dataIndex: 'userStatusEnum', |
| 36 | width: 120, | 31 | width: 120, |
| @@ -10,17 +10,17 @@ | @@ -10,17 +10,17 @@ | ||
| 10 | class="w-3/4 xl:w-4/5" | 10 | class="w-3/4 xl:w-4/5" |
| 11 | > | 11 | > |
| 12 | <template #toolbar> | 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 | </Authority> | 15 | </Authority> |
| 16 | - <Authority value="api:yt:user:delete"> | 16 | + <Authority value="api:yt:admin:user:deleteTenantAdmin:delete"> |
| 17 | <Popconfirm | 17 | <Popconfirm |
| 18 | title="您确定要批量删除数据" | 18 | title="您确定要批量删除数据" |
| 19 | ok-text="确定" | 19 | ok-text="确定" |
| 20 | cancel-text="取消" | 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 | </Popconfirm> | 24 | </Popconfirm> |
| 25 | </Authority> | 25 | </Authority> |
| 26 | </template> | 26 | </template> |
| @@ -46,33 +46,23 @@ | @@ -46,33 +46,23 @@ | ||
| 46 | <template #action="{ record }"> | 46 | <template #action="{ record }"> |
| 47 | <TableAction | 47 | <TableAction |
| 48 | :actions="[ | 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 | label: '编辑', | 56 | label: '编辑', |
| 65 | - auth: 'api:yt:user:update', | 57 | + auth: 'api:yt:user:saveCommonTenant:post', |
| 66 | icon: 'clarity:note-edit-line', | 58 | icon: 'clarity:note-edit-line', |
| 67 | tooltip: '编辑', | 59 | tooltip: '编辑', |
| 68 | onClick: handleEdit.bind(null, record), | 60 | onClick: handleEdit.bind(null, record), |
| 69 | ifShow: record.level != 0, | 61 | ifShow: record.level != 0, |
| 70 | }, | 62 | }, |
| 71 | - ]" | ||
| 72 | - :drop-down-actions="[ | ||
| 73 | { | 63 | { |
| 74 | label: '删除', | 64 | label: '删除', |
| 75 | - auth: 'api:yt:user:delete', | 65 | + auth: 'api:yt:admin:user:deleteTenantAdmin:delete', |
| 76 | icon: 'ant-design:delete-outlined', | 66 | icon: 'ant-design:delete-outlined', |
| 77 | color: 'error', | 67 | color: 'error', |
| 78 | tooltip: '删除', | 68 | tooltip: '删除', |
| @@ -82,17 +72,6 @@ | @@ -82,17 +72,6 @@ | ||
| 82 | confirm: handleDeleteOrBatchDelete.bind(null, record), | 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 | </template> | 77 | </template> |
| @@ -107,20 +86,35 @@ | @@ -107,20 +86,35 @@ | ||
| 107 | import { getTenantList } from '/@/api/system/account'; | 86 | import { getTenantList } from '/@/api/system/account'; |
| 108 | import { columns, searchFormSchema } from './config'; | 87 | import { columns, searchFormSchema } from './config'; |
| 109 | import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree'; | 88 | import { useResetOrganizationTree, OrganizationIdTree } from '/@/views/common/organizationIdTree'; |
| 110 | - import { reactive } from 'vue'; | 89 | + import { reactive, nextTick } from 'vue'; |
| 111 | import { Authority } from '/@/components/Authority'; | 90 | import { Authority } from '/@/components/Authority'; |
| 112 | import { useUserStore } from '/@/store/modules/user'; | 91 | import { useUserStore } from '/@/store/modules/user'; |
| 113 | import { PageWrapper } from '/@/components/Page'; | 92 | import { PageWrapper } from '/@/components/Page'; |
| 93 | + import { useGo } from '/@/hooks/web/usePage'; | ||
| 114 | import { Tag, Popconfirm } from 'ant-design-vue'; | 94 | import { Tag, Popconfirm } from 'ant-design-vue'; |
| 115 | import TenantModal from './TenantModal.vue'; | 95 | import TenantModal from './TenantModal.vue'; |
| 116 | import { useModal } from '/@/components/Modal'; | 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 | const searchInfo = reactive<Recordable>({}); | 107 | const searchInfo = reactive<Recordable>({}); |
| 108 | + const go = useGo(); | ||
| 119 | 109 | ||
| 120 | const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo); | 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 | const userInfo = useUserStore(); | 116 | const userInfo = useUserStore(); |
| 123 | - const [registerTable, { reload }] = useTable({ | 117 | + const [registerTable, { reload, setProps }] = useTable({ |
| 124 | title: '租户账号列表', | 118 | title: '租户账号列表', |
| 125 | columns, | 119 | columns, |
| 126 | api: getTenantList, | 120 | api: getTenantList, |
| @@ -150,6 +144,14 @@ | @@ -150,6 +144,14 @@ | ||
| 150 | fixed: 'right', | 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 | const [registerModal, { openModal }] = useModal(); | 156 | const [registerModal, { openModal }] = useModal(); |
| 155 | 157 | ||
| @@ -163,9 +165,32 @@ | @@ -163,9 +165,32 @@ | ||
| 163 | isAdd: true, | 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 | </script> | 196 | </script> |