completepage: 🍻 用户管理页面完成,添加部门,查询部门完成

This commit is contained in:
bunny 2024-10-09 15:02:47 +08:00
parent 3a115c82d1
commit d303cbce44
15 changed files with 334 additions and 232 deletions

View File

@ -1,6 +1,62 @@
import { http } from '@/api/service/request';
import type { BaseResult, ResultTable } from '@/api/service/types';
export interface UserResult {
/** 头像 */
avatar: string;
/** 用户名 */
username: string;
/** 昵称 */
nickname: string;
/** 当前登录用户的角色 */
roles: Array<string>;
/** 按钮级别权限 */
permissions: Array<string>;
/** `token` */
accessToken: string;
/** 用于调用刷新`accessToken`的接口时所需的`token` */
refreshToken: string;
/** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx' */
expires: Date;
}
export interface RefreshTokenResult {
/** `token` */
accessToken: string;
/** 用于调用刷新`accessToken`的接口时所需的`token` */
refreshToken: string;
/** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx' */
expires: Date;
}
/**
*
*/
export const fetchLogin = (data?: object) => {
return http.request<BaseResult<UserResult>>('post', '/login', { data });
};
/**
* *
* @param data
*/
export const fetchPostEmailCode = (data: any) => {
return http.request<BaseResult<any>>('post', '/user/noAuth/sendLoginEmail', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};
/** 刷新`token` */
export const refreshTokenApi = (data?: object) => {
return http.request<BaseResult<RefreshTokenResult>>('post', 'user/noAuth/refreshToken', { data });
};
/**
* * 退
* @param data
*/
export const fetchLogout = (data?: object) => {
return http.request<BaseResult<any>>('post', 'user/logout', { data });
};
/**
* ---
*/
@ -36,3 +92,47 @@ export const fetchUpdateAdminUser = (data: any) => {
export const fetchDeleteAdminUser = (data: any) => {
return http.request<BaseResult<object>>('delete', 'user/deleteAdminUser', { data });
};
/**
*
*/
export const fetchGetUserinfoById = (data?: object) => {
return http.request<BaseResult<UserResult>>('get', 'user/getUserinfoById', { params: data });
};
/** 修改用户状态 */
export const fetchUpdateUserStatusByAdmin = (data?: object) => {
return http.request<BaseResult<UserResult>>('put', 'user/updateUserStatusByAdmin', { data });
};
/**
*
* @param data
*/
export const fetchUpdateUserPasswordByAdmin = (data: any) => {
return http.request<BaseResult<UserResult>>('put', 'user/updateUserPasswordByAdmin', { data });
};
/**
*
* @param data
*/
export const fetchUploadAvatarByAdmin = (data: any) => {
return http.request<BaseResult<UserResult>>('put', 'user/uploadAvatarByAdmin', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};
/**
* 线
* @param data
*/
export const fetchForcedOffline = (data: any) => {
return http.request<BaseResult<UserResult>>('put', 'user/forcedOffline', { data });
};
/**
*
* @param data
*/
export const fetchAssignRolesToUsers = (data: object) => {
return http.request<BaseResult<any>>('post', 'userRole/assignRolesToUsers', { data });
};

View File

@ -8,5 +8,5 @@ export const getRouterAsync = () => {
/** 上传文件 */
export const fetchUploadFile = (data: any) => {
return http.post<BaseResult<any>>('/files/upload', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
return http.request<BaseResult<any>>('post', '/files/upload', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};

View File

@ -1,97 +0,0 @@
import { http } from '@/api/service/request';
import type { BaseResult } from '@/api/service/types';
export interface UserResult {
/** 头像 */
avatar: string;
/** 用户名 */
username: string;
/** 昵称 */
nickname: string;
/** 当前登录用户的角色 */
roles: Array<string>;
/** 按钮级别权限 */
permissions: Array<string>;
/** `token` */
accessToken: string;
/** 用于调用刷新`accessToken`的接口时所需的`token` */
refreshToken: string;
/** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx' */
expires: Date;
}
export interface RefreshTokenResult {
/** `token` */
accessToken: string;
/** 用于调用刷新`accessToken`的接口时所需的`token` */
refreshToken: string;
/** `accessToken`的过期时间(格式'xxxx/xx/xx xx:xx:xx' */
expires: Date;
}
/**
*
*/
export const fetchLogin = (data?: object) => {
return http.request<BaseResult<UserResult>>('post', '/login', { data });
};
/**
* *
* @param data
*/
export const fetchPostEmailCode = (data: any) => {
return http.request<BaseResult<any>>('post', '/user/noAuth/sendLoginEmail', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};
/** 刷新`token` */
export const refreshTokenApi = (data?: object) => {
return http.request<BaseResult<RefreshTokenResult>>('post', 'user/noAuth/refreshToken', { data });
};
/**
* * 退
* @param data
*/
export const fetchLogout = (data?: object) => {
return http.request<BaseResult<any>>('post', 'user/logout', { data });
};
/**
*
*/
export const fetchGetUserinfoById = (data?: object) => {
return http.request<BaseResult<UserResult>>('get', 'user/getUserinfoById', { params: data });
};
/**
*
* @param data
*/
export const fetchUpdateUserPasswordByAdmin = (data: any) => {
return http.request<BaseResult<UserResult>>('put', 'user/updateUserPasswordByAdmin', { data });
};
/**
*
* @param data
*/
export const fetchUploadAvatarByAdmin = (data: any) => {
return http.request<BaseResult<UserResult>>('put', 'user/uploadAvatarByAdmin', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
};
/**
* 线
* @param data
*/
export const fetchForcedOffline = (data: any) => {
return http.request<BaseResult<UserResult>>('put', 'user/forcedOffline', { data });
};
/**
*
* @param data
*/
export const fetchAssignRolesToUsers = (data: object) => {
return http.request<BaseResult<any>>('post', 'userRole/assignRolesToUsers', { data });
};

View File

@ -3,7 +3,7 @@ import userAvatarIcon from '@/assets/svg/user_avatar.svg?component';
import { columns } from './columns';
import TablePlus from '@/components/TableBar/src/TablePlus.vue';
import { onMounted, ref } from 'vue';
import { fetchGetUserinfoById } from '@/api/v1/user';
import { fetchGetUserinfoById } from '@/api/v1/adminUser';
import { $t } from '@/plugins/i18n';
const props = defineProps({

View File

@ -1,9 +1,8 @@
import { defineStore } from 'pinia';
import { fetchAddAdminUser, fetchDeleteAdminUser, fetchGetAdminUserList, fetchQueryUser, fetchUpdateAdminUser } from '@/api/v1/adminUser';
import { pageSizes } from '@/enums/baseConstant';
import { storeMessage } from '@/utils/message';
import { storePagination } from '@/store/useStorePagination';
import { fetchUpdateUserPasswordByAdmin } from '@/api/v1/user';
import { fetchAddAdminUser, fetchDeleteAdminUser, fetchGetAdminUserList, fetchQueryUser, fetchUpdateAdminUser, fetchUpdateUserPasswordByAdmin, fetchUpdateUserStatusByAdmin } from '@/api/v1/adminUser';
/**
* Store
@ -29,6 +28,8 @@ export const useAdminUserStore = defineStore('adminUserStore', {
summary: undefined,
// 状态
status: undefined,
// 部门Id查询
deptIds: undefined,
},
// 分页查询结果
pagination: {
@ -46,7 +47,7 @@ export const useAdminUserStore = defineStore('adminUserStore', {
/**
* *
*/
async getAdminUserList() {
getAdminUserList: async function () {
// 整理请求参数
const data = { ...this.pagination, ...this.form };
delete data.pageSizes;
@ -99,5 +100,14 @@ export const useAdminUserStore = defineStore('adminUserStore', {
const result: any = await fetchUpdateUserPasswordByAdmin(data);
return storeMessage(result);
},
/**
* *
* @param data
*/
async updateUserStatusByAdmin(data: any) {
const result = await fetchUpdateUserStatusByAdmin(data);
return storeMessage(result);
},
},
});

View File

@ -1,6 +1,6 @@
import { defineStore } from 'pinia';
import { resetRouter, router, routerArrays, storageLocal, store, type userType } from '../utils';
import { fetchAssignRolesToUsers, fetchLogin, fetchLogout, fetchPostEmailCode, refreshTokenApi } from '@/api/v1/user';
import { fetchAssignRolesToUsers, fetchLogin, fetchLogout, fetchPostEmailCode, refreshTokenApi } from '@/api/v1/adminUser';
import { useMultiTagsStoreHook } from '../multiTags';
import { type DataInfo, removeToken, setToken, userKey } from '@/utils/auth';
import { message, storeMessage } from '@/utils/message';

View File

@ -1,39 +1,39 @@
// 抽离可公用的工具函数等用于系统管理页面逻辑
import { computed } from "vue";
import { useDark } from "@pureadmin/utils";
import { computed } from 'vue';
import { useDark } from '@pureadmin/utils';
export function usePublicHooks() {
const { isDark } = useDark();
const { isDark } = useDark();
const switchStyle = computed(() => {
return {
"--el-switch-on-color": "#6abe39",
"--el-switch-off-color": "#e84749"
};
});
const switchStyle = computed(() => {
return {
'--el-switch-on-color': '#6abe39',
'--el-switch-off-color': '#e84749',
};
});
const tagStyle = computed(() => {
return (status: number) => {
return status === 1
? {
"--el-tag-text-color": isDark.value ? "#6abe39" : "#389e0d",
"--el-tag-bg-color": isDark.value ? "#172412" : "#f6ffed",
"--el-tag-border-color": isDark.value ? "#274a17" : "#b7eb8f"
}
: {
"--el-tag-text-color": isDark.value ? "#e84749" : "#cf1322",
"--el-tag-bg-color": isDark.value ? "#2b1316" : "#fff1f0",
"--el-tag-border-color": isDark.value ? "#58191c" : "#ffa39e"
};
};
});
const tagStyle = computed(() => {
return (status: number) => {
return status === 1
? {
'--el-tag-text-color': isDark.value ? '#6abe39' : '#389e0d',
'--el-tag-bg-color': isDark.value ? '#172412' : '#f6ffed',
'--el-tag-border-color': isDark.value ? '#274a17' : '#b7eb8f',
}
: {
'--el-tag-text-color': isDark.value ? '#e84749' : '#cf1322',
'--el-tag-bg-color': isDark.value ? '#2b1316' : '#fff1f0',
'--el-tag-border-color': isDark.value ? '#58191c' : '#ffa39e',
};
};
});
return {
/** 当前网页是否为`dark`模式 */
isDark,
/** 表现更鲜明的`el-switch`组件 */
switchStyle,
/** 表现更鲜明的`el-tag`组件 */
tagStyle
};
return {
/** 当前网页是否为`dark`模式 */
isDark,
/** 表现更鲜明的`el-switch`组件 */
switchStyle,
/** 表现更鲜明的`el-tag`组件 */
tagStyle,
};
}

View File

@ -6,6 +6,9 @@ import { FormProps } from '@/views/system/adminUser/utils/types';
import { $t } from '@/plugins/i18n';
import ReCol from '@/components/MyCol';
import { sexConstant } from '@/enums/baseConstant';
import { deptSelector } from '@/views/system/dept/utils/columns';
import { deptList } from '@/views/system/adminUser/utils/hooks';
import { usePublicHooks } from '@/views/hooks';
const props = withDefaults(defineProps<FormProps>(), {
formInline: () => ({
@ -27,20 +30,15 @@ const props = withDefaults(defineProps<FormProps>(), {
summary: undefined,
//
status: undefined,
//
deptIds: undefined,
}),
});
const formRef = ref<FormInstance>();
const form = ref(props.formInline);
/**
* * 上传头像回调
* @param data
*/
const onUploadCallback = ({ data }) => {
console.log('value=>', data);
form.value.avatar = data.filepath;
};
//
const { switchStyle } = usePublicHooks();
defineExpose({ formRef });
</script>
@ -92,17 +90,28 @@ defineExpose({ formRef });
</el-form-item>
</re-col>
<!-- 用户简介 -->
<re-col :sm="24" :value="24" :xs="24">
<el-form-item :label="$t('adminUser_summary')" prop="summary">
<el-input v-model="form.summary" :placeholder="$t('adminUser_summary')" autocomplete="off" maxlength="200" show-word-limit type="textarea" />
<re-col :sm="24" :value="12" :xs="24">
<el-form-item :label="$t('adminUser_dept')" prop="deptId">
<el-cascader v-model="form.deptId" :options="deptList" :props="deptSelector" class="w-full" clearable filterable placeholder="请选择归属部门">
<template #default="{ node, data }">
<span>{{ data.deptName }}</span>
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
</template>
</el-cascader>
</el-form-item>
</re-col>
<!-- 用户状态 -->
<re-col :sm="24" :value="12" :xs="24">
<el-form-item :label="$t('adminUser_status')" prop="status">
<el-switch v-model="form.status" active-text="禁用" class="ml-2" inactive-text="正常" inline-prompt style="--el-switch-on-color: #ff4949; --el-switch-off-color: #13ce66" />
<el-switch v-model="form.status" :active-value="false" :inactive-value="true" :style="switchStyle" active-text="已启用" inactive-text="已停用" inline-prompt />
</el-form-item>
</re-col>
<!-- 用户简介 -->
<re-col :sm="24" :value="24" :xs="24">
<el-form-item :label="$t('adminUser_summary')" prop="summary">
<el-input v-model="form.summary" :placeholder="$t('adminUser_summary')" autocomplete="off" maxlength="200" show-word-limit type="textarea" />
</el-form-item>
</re-col>
</el-row>

View File

@ -1,11 +1,12 @@
<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue';
import { onMounted, ref } from 'vue';
import { columns } from '@/views/system/adminUser/utils/columns';
import PureTableBar from '@/components/TableBar/src/bar';
import AddFill from '@iconify-icons/ri/add-circle-line';
import PureTable from '@pureadmin/table';
import {
deleteIds,
deptList,
onAdd,
onAssignRolesToUser,
onDelete,
@ -13,8 +14,10 @@ import {
onForcedOffline,
onResetPassword,
onSearch,
onTreeSelect,
onUpdate,
onUploadAvatar,
switchLoadMap,
updateUserStatus,
} from '@/views/system/adminUser/utils/hooks';
import Delete from '@iconify-icons/ep/delete';
@ -30,17 +33,19 @@ import Password from '@iconify-icons/ri/lock-password-line';
import More from '@iconify-icons/ep/more-filled';
import { useAdminUserStore } from '@/store/system/adminUser';
import { sexConstant, tableSelectButtonClass, userStatus } from '@/enums/baseConstant';
import { deviceDetection, handleTree } from '@pureadmin/utils';
import { deviceDetection } from '@pureadmin/utils';
import Tree from '@/views/system/adminUser/tree.vue';
import Airplane from '@/assets/svg/airplane.svg';
import { useDeptStore } from '@/store/system/dept';
import { FormInstance } from 'element-plus';
import { usePublicHooks } from '@/views/hooks';
const tableRef = ref();
const formRef = ref();
const adminUserStore = useAdminUserStore();
const deptStore = useDeptStore();
const deptList = computed(() => handleTree(deptStore.allDeptList));
//
const { switchStyle } = usePublicHooks();
const tableRef = ref();
const formRef = ref();
/**
* * 加载部门列表
@ -75,6 +80,7 @@ const onPageSizeChange = async (value: number) => {
const resetForm = async (formEl: FormInstance) => {
if (!formEl) return;
formEl.resetFields();
adminUserStore.form.deptIds = undefined;
await onSearch();
};
@ -86,15 +92,6 @@ const onSelectionChange = (rows: Array<any>) => {
deleteIds.value = rows.map((row: any) => row.id);
};
/**
* * 当树形结构选择时
* 搜索当前用户属于哪个部门
* @param dept
*/
const onTreeSelect = (dept: any) => {
console.log(dept);
};
onMounted(() => {
onSearch();
onSearchDept();
@ -188,15 +185,17 @@ onMounted(() => {
</template>
<!-- 显示用户状态 -->
<template #status="{ row }">
<template #status="{ row, index }">
<el-switch
v-model="row.status"
active-text="禁用"
class="ml-2"
inactive-text="正常"
:active-value="false"
:inactive-value="true"
:loading="switchLoadMap[index]?.loading"
:style="switchStyle"
active-text="已启用"
inactive-text="已停用"
inline-prompt
style="--el-switch-on-color: #ff4949; --el-switch-off-color: #13ce66"
@click="updateUserStatus(row)"
@click="updateUserStatus(row, index)"
/>
</template>

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { computed, getCurrentInstance, ref, watch } from 'vue';
import { getCurrentInstance, ref, watch } from 'vue';
import Dept from '@iconify-icons/ri/git-branch-line';
import More2Fill from '@iconify-icons/ri/more-2-fill';
import OfficeBuilding from '@iconify-icons/ep/office-building';
@ -9,6 +9,9 @@ import UnExpandIcon from '@/assets/svg/unexpand.svg?component';
import { useRenderIcon } from '@/components/CommonIcon/src/hooks';
import Reset from '@iconify-icons/ri/restart-line';
import { Tree } from '@/views/system/adminUser/utils/types';
import { buttonClass, defaultProps } from '@/views/system/adminUser/utils/columns';
import { useAdminUserStore } from '@/store/system/adminUser';
import { onSearch } from '@/views/system/adminUser/utils/hooks';
defineProps({
treeLoading: Boolean,
@ -17,17 +20,12 @@ defineProps({
const emit = defineEmits(['tree-select']);
const adminUserStore = useAdminUserStore();
const treeRef = ref();
const isExpand = ref(true);
const searchValue = ref('');
const highlightMap = ref({});
const { proxy } = getCurrentInstance();
const defaultProps = {
children: 'children',
value: 'id',
label: 'deptName',
};
const buttonClass = computed(() => ['!h-[20px]', '!text-sm', 'reset-margin', '!text-[var(--el-text-color-regular)]', 'dark:!text-white', 'dark:hover:!text-primary']);
const filterNode = (value: string, data: Tree) => {
if (!value) return true;
@ -71,7 +69,9 @@ function toggleRowExpansionAll(status) {
function onTreeReset() {
highlightMap.value = {};
searchValue.value = '';
adminUserStore.form.deptIds = undefined;
toggleRowExpansionAll(true);
onSearch();
}
watch(searchValue, val => {

View File

@ -1,4 +1,4 @@
import { reactive, ref } from 'vue';
import { computed, reactive, ref } from 'vue';
import { $t } from '@/plugins/i18n';
// 是否是更新用户信息
@ -34,24 +34,22 @@ export const columns: TableColumnList = [
];
// 添加规则
export const rules = reactive({
export const rules: any = reactive({
// 用户名
username: [{ required: true, message: `${$t('input')}${$t('adminUser_username')}`, trigger: 'blur' }],
// 密码
password: [
{
required: isAddUserinfo,
message: `${$t('input')}${$t('adminUser_password')}`,
trigger: 'blur',
},
],
password: [{ required: isAddUserinfo, message: `${$t('input')}${$t('adminUser_password')}`, trigger: 'blur' }],
// 邮箱
email: [
{ required: true, message: `${$t('input')}${$t('adminUser_email')}`, trigger: 'blur' },
{ type: 'email', message: `${$t('input')}${$t('adminUser_email')}${$t('format_error')}` },
],
// 个人描述
summary: [{ required: true, message: `${$t('input')}${$t('adminUser_summary')}`, trigger: 'blur' }],
// 状态
status: [{ required: true, message: `${$t('input')}${$t('adminUser_status')}`, trigger: 'blur' }],
// 部门
deptId: [{ required: true, message: `${$t('input')}${$t('adminUser_dept')}`, trigger: 'blur' }],
});
export const defaultProps = { children: 'children', value: 'id', label: 'deptName' };
export const buttonClass = computed(() => ['!h-[20px]', '!text-sm', 'reset-margin', '!text-[var(--el-text-color-regular)]', 'dark:!text-white', 'dark:hover:!text-primary']);

View File

@ -1,21 +1,23 @@
import { addDialog } from '@/components/BaseDialog/index';
import AdminUserDialog from '@/views/system/adminUser/admin-user-dialog.vue';
import { useAdminUserStore } from '@/store/system/adminUser';
import { h, reactive, ref } from 'vue';
import { computed, h, reactive, ref } from 'vue';
import { message, messageBox } from '@/utils/message';
import type { FormItemProps } from '@/views/system/adminUser/utils/types';
import { $t } from '@/plugins/i18n';
import { isAddUserinfo } from '@/views/system/adminUser/utils/columns';
import ResetPasswordDialog from '@/views/system/adminUser/reset-passwords.vue';
import { deviceDetection } from '@pureadmin/utils';
import { deviceDetection, handleTree } from '@pureadmin/utils';
import CropperPreview from '@/components/CropperPreview';
import AssignUserToRole from '@/views/system/adminUser/assign-roles-to-user.vue';
import userAvatar from '@/assets/user.jpg';
import { fetchForcedOffline, fetchUploadAvatarByAdmin } from '@/api/v1/user';
import { fetchForcedOffline, fetchUploadAvatarByAdmin } from '@/api/v1/adminUser';
import { useUserStore } from '@/store/system/user';
import { useDeptStore } from '@/store/system/dept';
const adminUserStore = useAdminUserStore();
const userStore = useUserStore();
const deptStore = useDeptStore();
// 表单Ref
const formRef = ref();
// 剪裁头像的Ref
@ -33,6 +35,10 @@ const restPasswordForm = reactive({
});
// 批量删除id列表
export const deleteIds = ref([]);
// 用户是否停用加载集合
export const switchLoadMap = ref({});
// 部门数据树形结构
export const deptList = computed(() => handleTree(deptStore.allDeptList));
/**
* *
@ -62,6 +68,7 @@ export function onAdd() {
sex: undefined,
summary: undefined,
status: false,
deptId: undefined,
},
},
draggable: true,
@ -102,6 +109,7 @@ export function onUpdate(row: any) {
sex: row.sex,
summary: row.summary,
status: row.status,
deptId: row.deptId,
},
},
draggable: true,
@ -159,25 +167,49 @@ export const onDeleteBatch = async () => {
await adminUserStore.deleteAdminUser(deleteIds.value);
await onSearch();
};
/**
* *
* @param row
* @param index
*/
export const updateUserStatus = async (row: any) => {
export const updateUserStatus = async (row: any, index: number) => {
// 点击时开始loading加载
switchLoadMap.value[index] = Object.assign({}, switchLoadMap.value[index], {
loading: true,
});
// 是否确认修改弹窗内容
const confirm = await messageBox({
title: $t('confirm_update_status'),
showMessage: false,
confirmMessage: undefined,
cancelMessage: $t('cancel'),
});
// 如果不修改将值恢复到之前状态
if (!confirm) {
row.status = !row.status;
switchLoadMap.value[index] = Object.assign({}, switchLoadMap.value[index], {
loading: false,
});
return;
}
// 修改用户状态
const data = { userId: row.id, status: row.status };
const result = await adminUserStore.updateUserStatusByAdmin(data);
if (!result) {
row.status = !row.status;
switchLoadMap.value[index] = Object.assign({}, switchLoadMap.value[index], {
loading: false,
});
return;
}
const data = { id: row.id, username: row.username, nickName: row.nickName, email: row.email, status: row.status };
const result = await adminUserStore.updateAdminUser(data);
if (!result) return;
await onSearch();
switchLoadMap.value[index] = Object.assign({}, switchLoadMap.value[index], {
loading: false,
});
};
/**
@ -281,3 +313,31 @@ export const onForcedOffline = async (row: any) => {
if (result.code !== 200) return;
message(result.message, { type: 'success' });
};
/**
* *
*
* @param dept
*/
export const onTreeSelect = async (dept: any) => {
/** 递归查找子级Id*/
function findChildIds(node: any, ids: string[]) {
ids.push(node.id);
if (!node.children) return ids;
// 递归查找子节点的 ID
for (const child of node.children) {
ids.push(child.id);
findChildIds(child, ids);
}
return ids;
}
// 查询属于这个部门下的用户
const list = findChildIds(dept, []);
const deptIds = new Set(list);
adminUserStore.form.deptIds = Array.from(deptIds);
await onSearch();
};

View File

@ -18,6 +18,8 @@ export interface FormItemProps {
summary: string;
// 状态
status: boolean;
// 部门
deptId: string;
}
// 添加或修改表单Props

View File

@ -6,7 +6,7 @@ import Delete from '@iconify-icons/ep/delete';
import EditPen from '@iconify-icons/ep/edit-pen';
import Refresh from '@iconify-icons/ep/refresh';
import AddFill from '@iconify-icons/ri/add-circle-line';
import { assignRolesToRouter, handleDelete, onAdd, onSearch, onUpdate } from '@/views/system/menu/utils/hooks';
import { assignRolesToRouter, handleDelete, onAdd, onchangeVisible, onSearch, onUpdate, switchLoadMap } from '@/views/system/menu/utils/hooks';
import PureTable from '@pureadmin/table';
import { columns } from '@/views/system/menu/utils/columns';
import { userMenuStore } from '@/store/system/menu';
@ -15,41 +15,14 @@ import { selectUserinfo } from '@/components/Table/Userinfo/columns';
import More from '@iconify-icons/ep/more-filled';
import { tableSelectButtonClass } from '@/enums/baseConstant';
import Upload from '@iconify-icons/ri/upload-line';
import { messageBox } from '@/utils/message';
import { FormInstance } from 'element-plus';
import { usePublicHooks } from '@/views/hooks';
const formRef = ref();
const tableRef = ref();
const routerStore = userMenuStore();
/**
* * 修改菜单是否显示
* @param row
*/
const onchangeVisible = async (row: any) => {
//
const confirm = await messageBox({
title: $t('confirm_update_status'),
showMessage: false,
confirmMessage: undefined,
cancelMessage: $t('cancel'),
});
if (!confirm) {
row.visible = !row.visible;
return;
}
const data = {
id: row.id,
visible: row.visible,
menuType: row.menuType,
title: row.title,
name: row.name,
path: row.path,
};
await routerStore.updateMenu(data);
await onSearch();
};
//
const { switchStyle } = usePublicHooks();
/**
* 表单重置
@ -98,18 +71,17 @@ onMounted(() => {
showOverflowTooltip
table-layout="auto"
>
<template #visible="{ row }">
<template #visible="{ row, index }">
<el-switch
v-model="row.visible"
:active-value="true"
:inactive-value="false"
:loading="switchLoadMap[index]?.loading"
:style="switchStyle"
active-text="显示"
class="ml-2"
inactive-text="隐藏"
inline-prompt
style="
--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
width="60"
@update:modelValue="onchangeVisible(row)"
@click="onchangeVisible(row, index)"
/>
</template>

View File

@ -6,8 +6,12 @@ import type { FormItemProps } from './types';
import { cloneDeep, deviceDetection } from '@pureadmin/utils';
import { userMenuStore } from '@/store/system/menu';
import AssignRouterToRole from '@/views/system/menu/assign-router-to-role.vue';
import { messageBox } from '@/utils/message';
// 用户是否停用加载集合
export const switchLoadMap = ref({});
const menuStore = userMenuStore();
const routerStore = userMenuStore();
const assignRouterToRolesRef = ref();
const formRef = ref();
@ -147,6 +151,51 @@ export const handleDelete = async row => {
await onSearch();
};
/**
* *
* @param row
* @param index
*/
export const onchangeVisible = async (row: any, index: number) => {
// 点击时开始loading加载
switchLoadMap.value[index] = Object.assign({}, switchLoadMap.value[index], {
loading: true,
});
// 是否确认修改显示状态
const confirm = await messageBox({
title: $t('confirm_update_status'),
showMessage: false,
confirmMessage: undefined,
cancelMessage: $t('cancel'),
});
// 取消修改
if (!confirm) {
row.visible = !row.visible;
switchLoadMap.value[index] = Object.assign({}, switchLoadMap.value[index], {
loading: false,
});
return;
}
// 确认修改
const data = {
id: row.id,
visible: row.visible,
menuType: row.menuType,
title: row.title,
name: row.name,
path: row.path,
};
await routerStore.updateMenu(data);
await onSearch();
switchLoadMap.value[index] = Object.assign({}, switchLoadMap.value[index], {
loading: false,
});
};
/**
*
* @param row