| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493 |
- <template>
- <div class="full-height page-container">
- <SmartLayoutSeparate :show-line="false" first-size="280px" class="full-height">
- <template #first>
- <div class="full-height dept-container">
- <SysDeptTree async show-search @select="handleDeptSelected" />
- </div>
- </template>
- <template #second>
- <SmartTable @register="registerTable" :size="getTableSize">
- <template #table-operation="{ row }">
- <SmartVxeTableAction :actions="getTableActions(row)" />
- </template>
- <template #table-userType="{ row }">
- <span>
- {{ getUserTypeMap[row.userType] }}
- </span>
- </template>
- <template #search-userType="{ model, size }">
- <a-select style="width: 100px" :size="size" v-model:value="model.userType" allowClear>
- <a-select-option
- v-for="item in userTypeListRef"
- :key="'userType_' + item.dictItemCode"
- :value="item.dictItemCode"
- >
- {{ item.dictItemName }}
- </a-select-option>
- </a-select>
- </template>
- <template #table-accountStatus="{ row }">
- <a-tooltip :title="getLockedMessage(row.userAccount?.accountStatus)">
- <span
- :style="{
- color: getAccountData(row.userAccount?.accountStatus).color,
- fontWeight: 'bold',
- }"
- >
- {{ getAccountData(row.userAccount?.accountStatus).label }}
- </span>
- </a-tooltip>
- </template>
- </SmartTable>
- </template>
- </SmartLayoutSeparate>
- <UserAccountUpdateModal @register="registerAccountModal" />
- <UserSetRole @register="registerSetRoleModal" />
- <UserUseYnModal @register="registerUseYnModal" />
- </div>
- </template>
- <script lang="ts" setup>
- import { computed, ref, unref } from 'vue';
- import { useI18n } from '@/hooks/web/useI18n';
- import { storeToRefs } from 'pinia';
- import { useLoadDictItem } from '@/modules/smart-system/hooks/SysDictHooks';
- import { useSizeSetting } from '@/hooks/setting/UseSizeSetting';
- import { hasPermission } from '@/utils/auth';
- import { useModal } from '@/components/Modal';
- import { useUserStore } from '@/store/modules/user';
- import { SmartLayoutSeparate } from '@/components/SmartLayoutSeparate';
- import SysDeptTree from '@/modules/smart-system/components/SysDept/SysDeptTree.vue';
- import { useMessage } from '@/hooks/web/useMessage';
- import {
- SmartTable,
- useSmartTable,
- SmartVxeTableAction,
- ActionItem,
- } from '@/components/SmartTable';
- import UserAccountUpdateModal from './account/UserAccountUpdateModal.vue';
- import UserSetRole from './components/UserSetRole.vue';
- import UserUseYnModal from './components/UserUseYnModal.vue';
- import { getAddEditFormSchemas, getSearchSchemas, getTableColumns } from './UserListView.config';
- import {
- listApi,
- deleteApi,
- saveUpdateWithDataScopeApi,
- getByIdWithDataScopeApi,
- setUseYnApi,
- createAccountApi,
- unlockUserAccountApi,
- resetPassword,
- } from './UserListView.api';
- import {
- SYS_USER_TYPE,
- SystemPermissions,
- } from '@/modules/smart-system/constants/SystemConstants';
- import { copyText } from '@/utils/copyTextToClipboard';
- const { t } = useI18n();
- const { warnMessage, errorMessage, createConfirm, successMessage } = useMessage();
- const { getTableSize } = useSizeSetting();
- const { getIsPlatformTenant } = storeToRefs(useUserStore());
- const [registerUseYnModal, { openModal: openUseYnModal }] = useModal();
- const { dictData: userTypeListRef } = useLoadDictItem(ref('SYSTEM_USER_TYPE'));
- const getUserTypeMap = computed(() => {
- const result: { [index: string]: string } = {};
- result[SYS_USER_TYPE] = '系统用户';
- for (let userType of unref(userTypeListRef)) {
- result[userType.dictItemCode] = userType.dictItemName;
- }
- return result;
- });
- const accountLockedMessage = {
- LOGIN_FAIL_LOCKED: '多次登录失败锁定',
- LONG_TIME_LOCKED: '超出指定时间未登录锁定',
- LONG_TIME_PASSWORD_MODIFY_LOCKED: '超出指定时间未修改密码锁定',
- };
- const [registerSetRoleModal, { openModal: openSetRoleModal }] = useModal();
- const getLockedMessage = (status: string | null | undefined) => {
- if (!status || status === 'NORMAL') {
- return '正常';
- }
- return accountLockedMessage[status];
- };
- /**
- * 账户状态
- */
- const accountStatusMap = {
- empty: {
- label: '未创建',
- color: '#A9A9A9',
- },
- NORMAL: {
- label: '正常',
- color: '#228B22',
- },
- LOCKED: {
- label: '锁定',
- color: 'red',
- },
- };
- const getAccountData = (status: string | null | undefined) => {
- if (status === undefined || status === null) {
- return accountStatusMap.empty;
- }
- if (status === 'NORMAL') {
- return accountStatusMap.NORMAL;
- }
- return accountStatusMap.LOCKED;
- };
- /**
- * 权限处理
- */
- const permissions = SystemPermissions.user;
- const hasPermissionUpdateSystemUser = hasPermission('sys:systemUser:update');
- const hasSystemUserUpdate = (type: string) => {
- return hasPermissionUpdateSystemUser || type !== SYS_USER_TYPE;
- };
- /**
- * 选中组织架构操作
- * @param selectedKeys
- */
- const currentDeptId = ref<number | null>(null);
- const handleDeptSelected = (selectedKeys: Array<number>) => {
- if (selectedKeys.length > 0) {
- currentDeptId.value = selectedKeys[0];
- } else {
- currentDeptId.value = null;
- }
- // 重新加载数据
- query();
- };
- /**
- * 账户弹窗
- */
- const [registerAccountModal, { openModal }] = useModal();
- /**
- * table行按钮
- */
- const getTableActions = (row): ActionItem[] => {
- return [
- {
- label: t('common.button.edit'),
- onClick: () => editByRowModal(row),
- disabled: !hasPermission(permissions.update) || !hasSystemUserUpdate(row.userType),
- },
- {
- label: t('system.views.user.button.showAccount'),
- disabled: !hasPermission('sys:account:query') || !hasSystemUserUpdate(row.userType),
- onClick: () => openModal(true, row),
- },
- {
- label: t('system.views.user.button.unlockUserAccount'),
- auth: permissions.unlockUserAccount,
- disabled:
- !hasPermission(permissions.unlockUserAccount) ||
- (row.userAccount && row.userAccount.accountStatus === 'NORMAL'),
- onClick: () => handleUnlockUserAccount(row.userId),
- },
- ];
- };
- const handleUnlockUserAccount = (id: number) => {
- createConfirm({
- iconType: 'warning',
- content: t('system.views.user.message.confirmUnlockUserAccount'),
- onOk: async () => {
- await unlockUserAccountApi(id);
- successMessage(t('system.views.user.message.unlockUserAccountSuccess'));
- await query();
- },
- });
- };
- /**
- * 用户操作验证
- * @param userList
- */
- const validateOperateUser = (userList: Array<any>) => {
- if (userList.length === 0) {
- warnMessage({
- message: t('system.views.user.validate.selectUser'),
- });
- return false;
- }
- if (!hasPermissionUpdateSystemUser) {
- // 如果没有修改系统用户的权限,判断用户中是否有系统用户
- const hasSysUser = userList.some(({ userType }: any) => userType === SYS_USER_TYPE);
- if (hasSysUser) {
- errorMessage(t('system.views.user.validate.noSysUserUpdatePermission'));
- return false;
- }
- }
- return true;
- };
- /**
- * 创建账户
- */
- const handleCreateAccount = () => {
- const userList = getCheckboxRecords(false);
- if (userList.length === 0) {
- warnMessage({
- message: t('system.views.user.validate.selectUser'),
- });
- return false;
- }
- if (!hasPermissionUpdateSystemUser) {
- // 如果没有修改系统用户的权限,判断用户中是否有系统用户
- const hasSysUser = userList.some(({ userType }: any) => userType === SYS_USER_TYPE);
- if (hasSysUser) {
- errorMessage(t('system.views.user.validate.noSysUserUpdatePermission'));
- return false;
- }
- }
- // 判断是否有停用用户
- const hasNoUse = userList.some((item) => item.useYn === false);
- if (hasNoUse) {
- warnMessage(t('system.views.user.message.noUseUserNotCreateAccount'));
- return false;
- }
- createConfirm({
- iconType: 'warning',
- title: t('system.views.user.validate.createAccountConfirm'),
- onOk: () => createAccountApi(userList),
- });
- };
- const validateSelectRows = () => {
- const rows = getCheckboxRecords();
- if (!rows.length) {
- warnMessage(t('common.notice.select'));
- return false;
- }
- return rows;
- };
- const [
- registerTable,
- { editByRowModal, getCheckboxRecords, query, deleteByCheckbox, showAddModal, useYnByCheckbox },
- ] = useSmartTable({
- columns: getTableColumns(),
- stripe: true,
- height: 'auto',
- border: true,
- align: 'left',
- rowConfig: {
- isHover: true,
- },
- pagerConfig: true,
- useSearchForm: true,
- sortConfig: {
- remote: true,
- defaultSort: {
- field: 'seq',
- order: 'asc',
- },
- },
- searchFormConfig: {
- layout: 'inline',
- schemas: getSearchSchemas(t),
- colon: true,
- searchWithSymbol: true,
- actionColOptions: {
- span: undefined,
- },
- compact: true,
- },
- addEditConfig: {
- modalConfig: {
- width: '700px',
- },
- formConfig: {
- colon: true,
- schemas: getAddEditFormSchemas(t, userTypeListRef),
- labelCol: {
- span: 4,
- },
- wrapperCol: {
- span: 19,
- },
- baseColProps: {
- span: 24,
- },
- },
- },
- proxyConfig: {
- ajax: {
- query: ({ ajaxParameter }) => {
- const parameter = {
- ...ajaxParameter,
- };
- const deptId = unref(currentDeptId);
- if (deptId) {
- parameter.deptIdList = [deptId];
- }
- return listApi(parameter);
- },
- delete: deleteApi,
- save: saveUpdateWithDataScopeApi,
- getById: getByIdWithDataScopeApi,
- useYn: setUseYnApi,
- },
- },
- toolbarConfig: {
- refresh: true,
- resizable: true,
- buttons: [
- {
- code: 'ModalAdd',
- auth: permissions.add,
- props: {
- onClick: () => {
- showAddModal({ deptId: unref(currentDeptId) });
- },
- },
- },
- {
- name: t('system.views.user.button.createAccount'),
- customRender: 'ant',
- auth: permissions.createAccount,
- props: {
- onClick: () => handleCreateAccount(),
- type: 'primary',
- },
- },
- {
- code: 'delete',
- props: {
- onClick: () => {
- const userList = getCheckboxRecords(false);
- // 验证用户
- const result = validateOperateUser(userList);
- if (!result) {
- return false;
- }
- // 验证是否包含系统用户
- const sysUserValidate = userList.some((item: any) => item.userType === SYS_USER_TYPE);
- if (sysUserValidate) {
- errorMessage(t('system.views.user.validate.sysUserNoDelete'));
- return false;
- }
- // 执行删除操作
- deleteByCheckbox();
- },
- },
- },
- {
- code: 'useYnTrue',
- props: {
- onClick() {
- if (!unref(getIsPlatformTenant)) {
- useYnByCheckbox(true);
- } else {
- const rows = validateSelectRows();
- if (!rows) {
- return false;
- }
- openUseYnModal(true, { rows, useYn: true });
- }
- },
- },
- },
- {
- code: 'useYnFalse',
- props: {
- onClick() {
- if (!unref(getIsPlatformTenant)) {
- useYnByCheckbox(true);
- } else {
- const rows = validateSelectRows();
- if (!rows) {
- return false;
- }
- openUseYnModal(true, { rows, useYn: false });
- }
- },
- },
- },
- {
- name: t('system.views.user.button.resetPassword'),
- auth: permissions.unlockPassword,
- customRender: 'ant',
- props: {
- type: 'primary',
- preIcon: 'ant-design:unlock-outlined',
- onClick: () => {
- const selectRows = getCheckboxRecords(false);
- if (selectRows.length !== 1) {
- warnMessage('请选择一条数据');
- return;
- }
- createConfirm({
- iconType: 'warning',
- title: t('system.views.user.button.resetPassword'),
- content: t('system.views.user.validate.resetPassword'),
- onOk: async () => {
- const newPassword = await resetPassword(selectRows[0].userId);
- createConfirm({
- iconType: 'warning',
- okText: t('system.views.user.button.copyPassword'),
- onOk: () => {
- copyText(newPassword);
- },
- title: t('system.views.user.message.resetSavePassword'),
- content: newPassword,
- });
- },
- });
- },
- },
- },
- {
- name: t('system.views.user.button.setRole'),
- auth: permissions.setRole,
- customRender: 'ant',
- props: {
- type: 'primary',
- preIcon: 'ant-design:team-outlined',
- onClick: () => {
- const selectRows = getCheckboxRecords(false);
- if (selectRows.length !== 1) {
- warnMessage('请选择一条数据');
- return;
- }
- openSetRoleModal(true, { userId: selectRows[0].userId });
- },
- },
- },
- ],
- },
- });
- </script>
- <style scoped lang="less">
- .page-container {
- :deep(.smart-search-container) {
- .ant-col {
- //padding: 0 5px;
- }
- }
- }
- .dept-container {
- margin-right: 5px;
- padding: 10px;
- background: white;
- }
- </style>
|