feat: 给用户管理添加按钮级权限管理

This commit is contained in:
2025-02-22 03:12:48 +08:00
parent bb38b5016f
commit 3a6cb4897b
18 changed files with 82 additions and 44 deletions

View File

@@ -429,7 +429,7 @@ export const deleteUserAPI = (id: string) => {
* @param data 用户ID列表
* @returns
*/
export const deleteUserListAPI = (data: { userIds: string[] }) => {
export const deleteUserListAPI = (data: { ids: string[] }) => {
return http.request<null>("post", `/api/user/deleteUserList`, { data });
};

View File

@@ -150,7 +150,7 @@ export const useUserStore = defineStore({
return new Promise<ResponseResult<LoginResult>>((resolve, reject) => {
getLogin(data)
.then(data => {
if (data.code === 200) {
if (data.success) {
setToken(data.data);
}
resolve(data);
@@ -189,7 +189,7 @@ export const useUserStore = defineStore({
return new Promise<ResponseResult<LoginResult>>((resolve, reject) => {
refreshTokenApi(data)
.then(data => {
if (data.code === 200) {
if (data.success) {
setToken(data.data);
}
resolve(data);

View File

@@ -109,3 +109,8 @@ export function getTokenInfo(): {
};
}
}
/**判断是否有权限 */
export const hasAuth = (auth: string) => {
return useUserStoreHook().permissions.includes(auth);
};

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import { ref } from "vue";
import { message } from "@/utils/message";
import Avatar from "@/assets/user.png";
import type { FormInstance } from "element-plus";
import ReCropperPreview from "@/components/ReCropperPreview";
import { deviceDetection } from "@pureadmin/utils";
@@ -47,7 +48,7 @@ const handleSubmitImage = async () => {
const res = await postUploadAvatarAPI(userInfo.id, {
file: cropperBlob.value
});
if (res.code === 200) {
if (res.success) {
message("更新头像成功", { type: "success" });
userInfo.avatar = `/file/${res.data.id}`;
const user = storageLocal().getItem<object>(userInfoKey);
@@ -71,7 +72,7 @@ const onSubmit = async (formEl: FormInstance) => {
gender: userInfo.gender
};
const res = await putUpdateBaseUserInfoAPI(updateForm);
if (res.code === 200) {
if (res.success) {
message(res.msg, { type: "success" });
await getUserInfo();
} else {
@@ -94,7 +95,10 @@ const onSubmit = async (formEl: FormInstance) => {
<h3 class="my-8">个人信息</h3>
<el-form ref="userInfoFormRef" label-position="top" :model="userInfo">
<el-form-item label="头像">
<el-avatar :size="80" :src="`/api/${userInfo.avatar}`" />
<el-avatar
:size="80"
:src="userInfo.avatar ? `/api/${userInfo.avatar}` : Avatar"
/>
<el-upload
ref="uploadRef"
accept="image/*"

View File

@@ -2,7 +2,6 @@ import { message } from "@/utils/message";
import { addDialog } from "@/components/ReDialog";
import { reactive, ref, onMounted, watch } from "vue";
import { ElForm, ElFormItem, ElInput, ElProgress } from "element-plus";
import type { UserInfo } from "types/user";
import { getUserInfoAPI } from "@/api/login";
import {
putUpdateEmailAPI,
@@ -12,6 +11,7 @@ import {
import { isAllEmpty, isEmail, isPhone, storageLocal } from "@pureadmin/utils";
import { zxcvbn } from "@zxcvbn-ts/core";
import { setUserInfo, userInfoKey } from "@/utils/auth";
import type { UserInfo } from "types/system";
export const useUserInfo = () => {
/** 密码正则密码格式应为8-18位数字、字母、符号的任意两种组合 */
@@ -52,10 +52,9 @@ export const useUserInfo = () => {
nickname: "",
phone: "",
status: 0,
department_id: "",
create_time: "",
update_time: "",
roles: [],
permissions: []
update_time: ""
});
/**获取个人信息 */
const getUserInfo = async () => {
@@ -200,7 +199,7 @@ export const useUserInfo = () => {
if (valid) {
// 表单规则校验通过
const res = await putUpdatePasswordAPI(passwordForm);
if (res.code === 200) {
if (res.success) {
done();
message(res.msg, {
type: "success"
@@ -262,7 +261,7 @@ export const useUserInfo = () => {
if (valid) {
// 表单规则校验通过
const res = await putUpdatePhoneAPI(phoneForm);
if (res.code === 200) {
if (res.success) {
done();
message(res.msg, {
type: "success"
@@ -323,7 +322,7 @@ export const useUserInfo = () => {
if (valid) {
// 表单规则校验通过
const res = await putUpdateEmailAPI(emailForm);
if (res.code === 200) {
if (res.success) {
done();
message(res.msg, {
type: "success"

View File

@@ -91,7 +91,7 @@ const onUpdate = async (formEl: FormInstance | undefined) => {
code: ruleForm.code,
department_id: ruleForm.department_id
});
if (res.code === 200) {
if (res.success) {
message(transformI18n($t("login:RegisterSuccess")), {
type: "success"
});
@@ -127,7 +127,7 @@ const start = async (
title: "Register",
mail: ruleForm.email
});
if (res.code === 200) {
if (res.success) {
clearInterval(timer.value);
isDisabled.value = true;
text.value = `${time}`;

View File

@@ -84,7 +84,7 @@ const start = async (
title: "Reset",
mail: ruleForm.email
});
if (res.code === 200) {
if (res.success) {
clearInterval(timer.value);
isDisabled.value = true;
text.value = `${time}`;

View File

@@ -202,7 +202,7 @@ export const useConfig = (tableRef: Ref) => {
const res = await deleteConfigListAPI({
ids: getKeyList(curSelected, "id")
});
if (res.code === 200) {
if (res.success) {
message(`已删除项目名称为 ${getKeyList(curSelected, "name")} 的数据`, {
type: "success"
});

View File

@@ -219,7 +219,7 @@ export const useDepartment = () => {
*/
const handleDelete = async (row: DepartmentInfo) => {
const res = await deleteDepartmentAPI(row.id);
if (res.code === 200) {
if (res.success) {
message(`您删除了部门:${row.name}及其附属部门`, { type: "success" });
onSearch();
} else {

View File

@@ -166,7 +166,7 @@ export const useI18n = (tableRef: Ref) => {
locale_id: form.locale_id,
translation: form.translation
});
if (res.code === 200) {
if (res.success) {
dataList.value = res.data.result;
pagination.total = res.data.total;
pagination.currentPage = res.data.page;

View File

@@ -156,7 +156,7 @@ export const useLocale = (tableRef: Ref) => {
name: form.name,
code: form.code
});
if (res.code === 200) {
if (res.success) {
dataList.value = res.data.result;
pagination.total = res.data.total;
pagination.currentPage = res.data.page;

View File

@@ -267,7 +267,7 @@ export const usePermission = () => {
}
}
const res = await postAddPermissionAPI(addForm);
if (res.code === 200) {
if (res.success) {
// 实际开发先调用新增接口,再进行下面操作
chores();
} else {
@@ -305,7 +305,7 @@ export const usePermission = () => {
}
}
const res = await putUpdatePermissionAPI(curData.id, updateForm);
if (res.code === 200) {
if (res.success) {
chores();
} else {
message(`更新失败!`, { type: "error" });
@@ -318,7 +318,7 @@ export const usePermission = () => {
};
const handleDelete = async (row: PermissionInfo) => {
const res = await deletePermissionAPI(row.id);
if (res.code === 200) {
if (res.success) {
message(`您删除了权限名称为${transformI18n(row.title)}的这条数据`, {
type: "success"
});

View File

@@ -52,7 +52,7 @@ function getRef() {
/**获取部门列表 */
const getDepartments = async () => {
const res = await getDepartmentListAPI({ page: 1, pageSize: 9999 });
if (res.code === 200) {
if (res.success) {
departments.value = formatHigherOptions(res.data.result);
} else {
departments.value = [];

View File

@@ -166,7 +166,7 @@ export const useRole = (treeRef: Ref) => {
page: pagination.currentPage,
pageSize: val
});
if (res.code === 200) {
if (res.success) {
const data = res.data;
dataList.value = data.result;
pagination.total = data.total;
@@ -179,7 +179,7 @@ export const useRole = (treeRef: Ref) => {
page: val,
pageSize: pagination.pageSize
});
if (res.code === 200) {
if (res.success) {
const data = res.data;
dataList.value = data.result;
pagination.total = data.total;
@@ -189,7 +189,7 @@ export const useRole = (treeRef: Ref) => {
const handleDelete = async (row: RoleInfo) => {
const res = await deleteRoleAPI(row.id);
if (res.code === 200) {
if (res.success) {
message(`您删除了角色名称为${row.name}的这条数据`, { type: "success" });
onSearch();
} else {
@@ -242,7 +242,7 @@ export const useRole = (treeRef: Ref) => {
if (title === "新增") {
// 实际开发先调用新增接口,再进行下面操作
const res = await postAddRoleAPI(curData);
if (res.code === 200) {
if (res.success) {
chores();
} else {
message(`添加失败!`, {
@@ -253,7 +253,7 @@ export const useRole = (treeRef: Ref) => {
} else {
// 实际开发先调用修改接口,再进行下面操作
const res = await putUpdateRoleAPI(curData, row.id);
if (res.code === 200) {
if (res.success) {
chores();
} else {
message(`修改失败!`, {
@@ -310,7 +310,7 @@ export const useRole = (treeRef: Ref) => {
const res = await putUpdateRolePermissionsAPI(id, {
permission_ids: permissions
});
if (res.code === 200) {
if (res.success) {
message(`角色名称为${name}的权限修改成功~`, {
type: "success"
});
@@ -334,7 +334,7 @@ export const useRole = (treeRef: Ref) => {
/**获取部门列表 */
const getDepartments = async () => {
const res = await getDepartmentListAPI({ page: 1, pageSize: 9999 });
if (res.code === 200) {
if (res.success) {
departments.value = formatHigherOptions(res.data.result);
} else {
departments.value = [];

View File

@@ -16,6 +16,7 @@ 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 { onBeforeRouteUpdate } from "vue-router";
import { hasAuth } from "@/utils/auth";
defineOptions({
name: "SystemUser"
});
@@ -117,6 +118,7 @@ onBeforeRouteUpdate((to, from, next) => {
<PureTableBar title="用户管理" :columns="columns" @refresh="onSearch">
<template #buttons>
<el-button
v-if="hasAuth('user:btn:addUser')"
type="primary"
:icon="useRenderIcon(AddFill)"
@click="openDialog()"
@@ -141,7 +143,11 @@ onBeforeRouteUpdate((to, from, next) => {
{{ t("buttons:Deselect") }}
</el-button>
</div>
<el-popconfirm title="是否确认删除?" @confirm="onbatchDel">
<el-popconfirm
v-if="hasAuth('user:btn:deleteUser')"
title="是否确认删除?"
@confirm="onbatchDel"
>
<template #reference>
<el-button type="danger" text class="mr-1">
{{ t("buttons:DeleteInBatches") }}
@@ -178,6 +184,7 @@ onBeforeRouteUpdate((to, from, next) => {
link
type="primary"
:size="size"
:disabled="!hasAuth('user:btn:updateUser')"
:icon="useRenderIcon(EditPen)"
@click="openDialog('修改', row)"
>
@@ -193,6 +200,7 @@ onBeforeRouteUpdate((to, from, next) => {
link
type="danger"
:size="size"
:disabled="!hasAuth('user:btn:deleteUser')"
:icon="useRenderIcon(Delete)"
>
{{ t("buttons:Delete") }}
@@ -216,6 +224,7 @@ onBeforeRouteUpdate((to, from, next) => {
link
type="primary"
:size="size"
:disabled="!hasAuth('user:btn:uploadAvatar')"
:icon="useRenderIcon(Upload)"
@click="handleUpload(row)"
>
@@ -228,6 +237,7 @@ onBeforeRouteUpdate((to, from, next) => {
link
type="primary"
:size="size"
:disabled="!hasAuth('user:btn:reset_password')"
:icon="useRenderIcon(Password)"
@click="handleReset(row)"
>
@@ -240,6 +250,7 @@ onBeforeRouteUpdate((to, from, next) => {
link
type="primary"
:size="size"
:disabled="!hasAuth('user:btn:updateRole')"
:icon="useRenderIcon(Role)"
@click="handleRole(row)"
>
@@ -252,6 +263,7 @@ onBeforeRouteUpdate((to, from, next) => {
link
type="primary"
:size="size"
:disabled="!hasAuth('user:btn:permissionList')"
:icon="useRenderIcon(Menu)"
@click="openPerDialog(row)"
>

View File

@@ -191,7 +191,7 @@ export const useUser = (tableRef: Ref, treeRef: Ref) => {
*/
const handleDelete = async (row: UserInfo) => {
const res = await deleteUserAPI(row.id);
if (res.code === 200) {
if (res.success) {
message(`您删除了用户账号为${row.username}的这条数据`, {
type: "success"
});
@@ -261,10 +261,10 @@ export const useUser = (tableRef: Ref, treeRef: Ref) => {
// 返回当前选中的行
const curSelected = tableRef.value.getTableRef().getSelectionRows();
const res = await deleteUserListAPI({
userIds: getKeyList(curSelected, "id")
ids: getKeyList(curSelected, "id")
});
if (res.code === 200) {
message(`已删除用户编号为 ${getKeyList(curSelected, "id")} 的数据`, {
if (res.success) {
message(res.msg, {
type: "success"
});
tableRef.value.getTableRef().clearSelection();
@@ -404,7 +404,7 @@ export const useUser = (tableRef: Ref, treeRef: Ref) => {
}
}
const res = await postAddUserAPI(addForm);
if (res.code === 200) {
if (res.success) {
// 实际开发先调用新增接口,再进行下面操作
chores();
} else {
@@ -430,7 +430,7 @@ export const useUser = (tableRef: Ref, treeRef: Ref) => {
}
}
const res = await putUpdateUserAPI(curData.id, updateForm);
if (res.code === 200) {
if (res.success) {
chores();
} else {
message(`更新失败!`, { type: "error" });
@@ -453,14 +453,14 @@ export const useUser = (tableRef: Ref, treeRef: Ref) => {
contentRenderer: () =>
h(croppingUpload, {
ref: cropRef,
imgSrc: row.avatar || Avatar,
imgSrc: `/api/${row.avatar}` || Avatar,
onCropper: info => (avatarInfo.value = info)
}),
beforeSure: async done => {
const res = await postUploadAvatarAPI(row.id, {
file: avatarInfo.value.blob
});
if (res.code === 200) {
if (res.success) {
// 根据实际业务使用avatarInfo.value和row里的某些字段去调用上传头像接口即可
message(`更新成功!`, { type: "success" });
onSearch(); // 刷新表格数据
@@ -541,7 +541,7 @@ export const useUser = (tableRef: Ref, treeRef: Ref) => {
const res = await putUpdateUserPasswordAPI(row.id, {
password: pwdForm.newPwd
});
if (res.code === 200) {
if (res.success) {
console.log(pwdForm.newPwd);
done();
message(`已成功重置 ${row.username} 的密码`, {
@@ -593,7 +593,7 @@ export const useUser = (tableRef: Ref, treeRef: Ref) => {
user_id: row.id,
role_ids: curData.ids as string[]
});
if (res.code === 200) {
if (res.success) {
message(`${row.username}--${row.nickname}的角色信息更新成功!`, {
type: "success",
duration: 5000