completepage: 🍻 用户管理页面完成,添加部门,查询部门完成
This commit is contained in:
parent
3a115c82d1
commit
d303cbce44
|
@ -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 });
|
||||
};
|
||||
|
|
|
@ -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' } });
|
||||
};
|
||||
|
|
|
@ -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 });
|
||||
};
|
|
@ -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({
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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']);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -18,6 +18,8 @@ export interface FormItemProps {
|
|||
summary: string;
|
||||
// 状态
|
||||
status: boolean;
|
||||
// 部门
|
||||
deptId: string;
|
||||
}
|
||||
|
||||
// 添加或修改表单Props
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue