feat: ✨ 角色权限的分配
This commit is contained in:
parent
5b5f0638b3
commit
47d72c9f21
@ -9,4 +9,4 @@ VITE_APP_PORT = 8090
|
||||
VITE_APP_BASE_API = '/api'
|
||||
|
||||
# proxy代理配置
|
||||
VITE_APP_API_URL = ' http://192.168.1.7:12500/'
|
||||
VITE_APP_API_URL = 'http://192.168.1.7:12500/'
|
||||
|
||||
@ -6,4 +6,4 @@ VITE_APP_PORT = 3000
|
||||
VITE_APP_BASE_API = '/zsqy'
|
||||
|
||||
# proxy代理配置
|
||||
VITE_APP_API_URL = ""
|
||||
VITE_APP_API_URL = "http://175.27.240.186:12500"
|
||||
|
||||
@ -23,10 +23,7 @@ axiosInstance.interceptors.request.use(
|
||||
// 响应拦截器
|
||||
axiosInstance.interceptors.response.use(
|
||||
(res: AxiosResponse) => {
|
||||
const { message, success } = res.data as {
|
||||
success: boolean;
|
||||
message: string;
|
||||
};
|
||||
const { message, success } = res.data as IResponse;
|
||||
|
||||
// 如果是文件流,直接过
|
||||
if (res.config.responseType === "blob") return Promise.resolve(res.data);
|
||||
|
||||
@ -1 +0,0 @@
|
||||
export * from "./menu";
|
||||
25
src/api/system/role.ts
Normal file
25
src/api/system/role.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { get, post } from "@/api/http";
|
||||
|
||||
const fix = "/role";
|
||||
|
||||
const url = {
|
||||
insert: `${fix}/insert`,
|
||||
page: `${fix}/page`,
|
||||
update: `${fix}/update`,
|
||||
delete: `${fix}/delete`,
|
||||
};
|
||||
|
||||
export const insertRule = (params: Object) => {
|
||||
return post(url.insert, params);
|
||||
};
|
||||
|
||||
export const getRuleList = (params: Object) => {
|
||||
return get(url.page, params);
|
||||
};
|
||||
|
||||
export const updateRule = (params: Object) => {
|
||||
return post(url.update, params);
|
||||
};
|
||||
export const deleteRule = (params: Object) => {
|
||||
return post(url.delete, params);
|
||||
};
|
||||
15
src/api/system/roleMenu.ts
Normal file
15
src/api/system/roleMenu.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { get, post } from "@/api/http";
|
||||
|
||||
const fix = "/roleMenu";
|
||||
|
||||
const url = {
|
||||
queryMenuByRole: `${fix}/queryMenuByRole`, // 根据角色查询菜单
|
||||
save: `${fix}/save`, // 保存角色菜单
|
||||
};
|
||||
|
||||
export const queryMenuByRole = (params: Object) => {
|
||||
return get(url.queryMenuByRole, params);
|
||||
};
|
||||
export const saveRoleMenu = (params: Object) => {
|
||||
return post(url.save, params);
|
||||
};
|
||||
26
src/api/system/user.ts
Normal file
26
src/api/system/user.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { get, post } from "@/api/http";
|
||||
|
||||
const fix = "/user";
|
||||
|
||||
const url = {
|
||||
insert: `${fix}/insert`,
|
||||
page: `${fix}/page`,
|
||||
update: `${fix}/update`,
|
||||
delete: `${fix}/delete`,
|
||||
};
|
||||
|
||||
export const insertUser = (params: Object) => {
|
||||
return post(url.insert, params);
|
||||
};
|
||||
|
||||
export const getUserList = (params: Object) => {
|
||||
return get(url.page, params);
|
||||
};
|
||||
|
||||
export const updateUser = (params: Object) => {
|
||||
return post(url.update, params);
|
||||
};
|
||||
|
||||
export const deleteUser = (params: Object) => {
|
||||
return post(url.delete, params);
|
||||
};
|
||||
13
src/api/system/userrole.ts
Normal file
13
src/api/system/userrole.ts
Normal file
@ -0,0 +1,13 @@
|
||||
// 用户角色关系
|
||||
import { get, post } from "@/api/http";
|
||||
const fix = "/userRole";
|
||||
const url = {
|
||||
save: `${fix}/save`,
|
||||
queryMenuTree: `${fix}/queryMenuTree `,
|
||||
};
|
||||
export const saveUserRole = (params: Object) => {
|
||||
return post(url.save, params);
|
||||
};
|
||||
export const queryUserRole = (params: Object) => {
|
||||
return get(url.queryMenuTree, params);
|
||||
};
|
||||
@ -47,12 +47,15 @@ export function useDataSource(
|
||||
setLoading(true);
|
||||
const { request, pagination, beforeRequest, afterRequest }: any =
|
||||
unref(propsRef);
|
||||
|
||||
if (!request) return;
|
||||
//组装分页信息
|
||||
const pageField = APISETTING.pageField;
|
||||
const sizeField = APISETTING.sizeField;
|
||||
const totalField = APISETTING.totalField;
|
||||
const listField = APISETTING.listField;
|
||||
console.log(listField);
|
||||
|
||||
const itemCount = APISETTING.countField;
|
||||
let pageParams = {};
|
||||
const { page = 1, pageSize = 10 } = unref(
|
||||
@ -71,7 +74,7 @@ export function useDataSource(
|
||||
|
||||
let params = {
|
||||
...pageParams,
|
||||
// ...opt,
|
||||
...opt,
|
||||
};
|
||||
// console.log(opt);
|
||||
|
||||
@ -80,6 +83,7 @@ export function useDataSource(
|
||||
params = (await beforeRequest(params)) || params;
|
||||
}
|
||||
const res = await request(params);
|
||||
|
||||
const resultTotal = res[totalField];
|
||||
const currentPage = res[pageField];
|
||||
const total = res[itemCount];
|
||||
|
||||
@ -6,6 +6,8 @@ import { OptionsSharp } from "@vicons/ionicons5";
|
||||
|
||||
// 引入路径
|
||||
const importPath = {
|
||||
USER: () => import("@/views/system/user/user.vue"),
|
||||
ROLE: () => import("@/views/system/role/role.vue"),
|
||||
MENU: () => import("@/views/system/menu/menu.vue"),
|
||||
};
|
||||
|
||||
@ -20,22 +22,30 @@ const systemRoutes: RouteRecordRaw = {
|
||||
sort: 1,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "menu",
|
||||
name: "system_menu",
|
||||
meta: {
|
||||
title: "菜单权限管理",
|
||||
},
|
||||
component: importPath["MENU"],
|
||||
},
|
||||
{
|
||||
path: "role",
|
||||
name: "system_role",
|
||||
meta: {
|
||||
title: "角色权限管理",
|
||||
title: "角色管理",
|
||||
},
|
||||
component: () => import("@/views/system/role/role.vue"),
|
||||
},
|
||||
{
|
||||
path: "user",
|
||||
name: "system_user",
|
||||
meta: {
|
||||
title: "用户管理",
|
||||
},
|
||||
component: () => import("@/views/system/user/user.vue"),
|
||||
},
|
||||
{
|
||||
path: "menu",
|
||||
name: "system_menu",
|
||||
meta: {
|
||||
title: "菜单管理",
|
||||
},
|
||||
component: importPath["MENU"],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@ -97,7 +97,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { insertMenu } from "@/api/system";
|
||||
import { insertMenu } from "@/api/system/menu";
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
|
||||
@ -340,7 +340,7 @@ const selectedTree = (keys) => {
|
||||
|
||||
const handleDel = async () => {
|
||||
const res = await deleteMenu({ id: formParams.id });
|
||||
if (res.status) window["$message"].success("删除成功!");
|
||||
if (res.status === 200) window["$message"].success("删除成功!");
|
||||
getMenuTreeApi();
|
||||
};
|
||||
|
||||
@ -353,7 +353,7 @@ const formSubmit = () => {
|
||||
formRef.value.validate(async (errors: boolean) => {
|
||||
if (!errors) {
|
||||
const res = await updateMenu(formParams);
|
||||
if (res.status) window["$message"].success("修改成功");
|
||||
if (res.status === 200) window["$message"].success("修改成功");
|
||||
getMenuTreeApi();
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,36 +1,32 @@
|
||||
import { h } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { h } from "vue";
|
||||
import { NTag } from "naive-ui";
|
||||
|
||||
export const columns = [
|
||||
{
|
||||
title: 'id',
|
||||
key: 'id',
|
||||
title: "ID",
|
||||
key: "id",
|
||||
},
|
||||
{
|
||||
title: '角色名称',
|
||||
key: 'name',
|
||||
title: "角色名称",
|
||||
key: "roleName",
|
||||
},
|
||||
{
|
||||
title: '说明',
|
||||
key: 'explain',
|
||||
title: "说明",
|
||||
key: "description",
|
||||
},
|
||||
{
|
||||
title: '是否默认角色',
|
||||
key: 'isDefault',
|
||||
title: "状态",
|
||||
key: "status",
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
type: row.isDefault ? 'success' : 'error',
|
||||
type: row.status ? "success" : "error",
|
||||
},
|
||||
{
|
||||
default: () => (row.isDefault ? '是' : '否'),
|
||||
default: () => (row.status ? "正常" : "冻结"),
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'create_date',
|
||||
},
|
||||
];
|
||||
|
||||
0
src/views/system/role/components/MenuModal.vue
Normal file
0
src/views/system/role/components/MenuModal.vue
Normal file
108
src/views/system/role/components/RoleModal.vue
Normal file
108
src/views/system/role/components/RoleModal.vue
Normal file
@ -0,0 +1,108 @@
|
||||
<script setup lang="ts">
|
||||
import { insertRule } from "@/api/system/role";
|
||||
const props = defineProps({
|
||||
formRoleValue: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const formRef = ref();
|
||||
const { formRoleValue } = toRefs(props);
|
||||
const roleTitle = ref("新增角色");
|
||||
const formBtnLoading = ref(false);
|
||||
const showRoleModal = ref(false);
|
||||
const rules = {
|
||||
roleName: {
|
||||
required: true,
|
||||
message: "请输入角色名称",
|
||||
trigger: "blur",
|
||||
},
|
||||
};
|
||||
// 提交表单
|
||||
const confirmForm = () => {
|
||||
formRef.value.validate(async (errors: any) => {
|
||||
if (!errors) {
|
||||
formRoleValue.value.id ? updateRuleApi() : insertRuleApi();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 修改
|
||||
const updateRuleApi = () => {};
|
||||
|
||||
// 新增
|
||||
const insertRuleApi = async () => {
|
||||
const { roleName, description, status } = formRoleValue.value;
|
||||
const params = {
|
||||
roleName,
|
||||
description,
|
||||
status,
|
||||
};
|
||||
const res = await insertRule(params);
|
||||
if (res.status === 200) window["$message"].success("新增成功!");
|
||||
};
|
||||
|
||||
const init = (str: string) => {
|
||||
if (str === "add") {
|
||||
roleTitle.value = "新增角色";
|
||||
} else {
|
||||
roleTitle.value = "编辑角色";
|
||||
}
|
||||
showRoleModal.value = true;
|
||||
};
|
||||
const close = () => {
|
||||
showRoleModal.value = false;
|
||||
};
|
||||
defineExpose({
|
||||
init,
|
||||
close,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 新增角色 -->
|
||||
<n-modal
|
||||
v-model:show="showRoleModal"
|
||||
:show-icon="false"
|
||||
preset="dialog"
|
||||
:title="roleTitle"
|
||||
>
|
||||
<n-form
|
||||
ref="formRef"
|
||||
:rules="rules"
|
||||
label-placement="left"
|
||||
label-width="auto"
|
||||
:model="formRoleValue"
|
||||
require-mark-placement="right-hanging"
|
||||
>
|
||||
<n-form-item label="角色名称" path="roleName">
|
||||
<n-input
|
||||
v-model:value="formRoleValue.roleName"
|
||||
placeholder="输入角色名称"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="状态">
|
||||
<n-radio-group v-model:value="formRoleValue.status" name="radiogroup1">
|
||||
<n-space>
|
||||
<n-radio :value="0"> 冻结 </n-radio>
|
||||
<n-radio :value="1"> 启用 </n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<n-form-item label="描述">
|
||||
<n-input
|
||||
v-model:value="formRoleValue.description"
|
||||
type="textarea"
|
||||
placeholder="请输入描述"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
<template #action>
|
||||
<n-space>
|
||||
<n-button type="primary" :loading="formBtnLoading" @click="confirmForm"
|
||||
>提交</n-button
|
||||
>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-modal>
|
||||
</template>
|
||||
@ -1,6 +1,247 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<div>345</div>
|
||||
<div>
|
||||
<n-card :bordered="false" class="mt-4 proCard">
|
||||
<BasicTable
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
ref="actionRef"
|
||||
:actionColumn="actionColumn"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<n-button type="primary" @click="addRole">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<PlusOutlined />
|
||||
</n-icon>
|
||||
</template>
|
||||
添加角色
|
||||
</n-button>
|
||||
</template>
|
||||
|
||||
<template #action>
|
||||
<TableAction />
|
||||
</template>
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
|
||||
<!-- 添加角色 -->
|
||||
<RoleModal ref="formRole" :formRoleValue="formRoleValue" />
|
||||
|
||||
<!-- 菜单权限 -->
|
||||
<n-modal
|
||||
v-model:show="showModal"
|
||||
:show-icon="false"
|
||||
preset="dialog"
|
||||
:title="editRoleTitle"
|
||||
>
|
||||
<div class="py-3 menu-list">
|
||||
<n-tree
|
||||
block-line
|
||||
cascade
|
||||
checkable
|
||||
:virtual-scroll="true"
|
||||
:data="treeData"
|
||||
:expanded-keys="expandedKeys"
|
||||
:checked-keys="checkedKeys"
|
||||
style="max-height: 950px; overflow: hidden"
|
||||
@update:checked-keys="checkedTree"
|
||||
@update:expanded-keys="onExpandedKeys"
|
||||
/>
|
||||
</div>
|
||||
<template #action>
|
||||
<n-space>
|
||||
<n-button type="info" ghost icon-placement="left" @click="packHandle">
|
||||
全部{{ expandedKeys.length ? "收起" : "展开" }}
|
||||
</n-button>
|
||||
|
||||
<n-button
|
||||
type="info"
|
||||
ghost
|
||||
icon-placement="left"
|
||||
@click="checkedAllHandle"
|
||||
>
|
||||
全部{{ checkedAll ? "取消" : "选择" }}
|
||||
</n-button>
|
||||
<n-button
|
||||
type="primary"
|
||||
:loading="formBtnLoading"
|
||||
@click="confirmForm"
|
||||
>提交</n-button
|
||||
>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-modal>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { BasicTable, TableAction } from "@/components/Table";
|
||||
|
||||
import { columns } from "./columns";
|
||||
import { PlusOutlined } from "@vicons/antd";
|
||||
import { getTreeAll } from "@/utils";
|
||||
import { getRuleList } from "@/api/system/role";
|
||||
import { getMenuTree } from "@/api/system/menu";
|
||||
import { queryMenuByRole, saveRoleMenu } from "@/api/system/roleMenu";
|
||||
|
||||
const actionRef = ref();
|
||||
const formRole = ref();
|
||||
const formRoleValue = reactive({
|
||||
id: null,
|
||||
roleName: "",
|
||||
roleCode: null,
|
||||
status: 1,
|
||||
description: "",
|
||||
});
|
||||
const lastMenuIds = ref([]);
|
||||
const showModal = ref(false);
|
||||
const formBtnLoading = ref(false);
|
||||
const checkedAll = ref(false);
|
||||
const editRoleTitle = ref("");
|
||||
const treeData = ref([]);
|
||||
const expandedKeys = ref([]);
|
||||
const checkedKeys: Ref<any[]> = ref([]);
|
||||
const roleId = ref(null);
|
||||
const params = reactive({
|
||||
roleName: "",
|
||||
});
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 250,
|
||||
title: "操作",
|
||||
key: "action",
|
||||
fixed: "right",
|
||||
render(record) {
|
||||
return h(TableAction, {
|
||||
style: "button",
|
||||
actions: [
|
||||
{
|
||||
label: "菜单权限",
|
||||
onClick: handleMenuAuth.bind(null, record),
|
||||
// 根据业务控制是否显示 isShow 和 auth 是并且关系
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "编辑",
|
||||
onClick: handleEdit.bind(null, record),
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "删除",
|
||||
onClick: handleDelete.bind(null, record),
|
||||
// 根据业务控制是否显示 isShow 和 auth 是并且关系
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const mapTreeData = (data) => {
|
||||
return data.map((ele) => ({
|
||||
...ele,
|
||||
key: ele.id,
|
||||
label: ele.meta.title,
|
||||
children: ele.children ? mapTreeData(ele.children) : undefined,
|
||||
}));
|
||||
};
|
||||
|
||||
// 新增按钮
|
||||
const addRole = () => {
|
||||
formRole.value.init("add");
|
||||
};
|
||||
|
||||
const loadDataTable = async (res: any) => {
|
||||
let _params = {
|
||||
...unref(params),
|
||||
...res,
|
||||
};
|
||||
const { data } = await getRuleList(_params);
|
||||
return data;
|
||||
};
|
||||
|
||||
function onCheckedRow(rowKeys: any[]) {
|
||||
console.log(rowKeys);
|
||||
}
|
||||
|
||||
function reloadTable() {
|
||||
actionRef.value.reload();
|
||||
}
|
||||
|
||||
async function confirmForm(e: any) {
|
||||
e.preventDefault();
|
||||
formBtnLoading.value = true;
|
||||
const res = await saveRoleMenu({
|
||||
roleId: roleId.value,
|
||||
menuIds: checkedKeys.value,
|
||||
lastMenuIds: lastMenuIds.value,
|
||||
});
|
||||
if (res.status === 200) {
|
||||
showModal.value = false;
|
||||
reloadTable();
|
||||
window["$message"].success("保存成功");
|
||||
formBtnLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleEdit(record: Recordable) {
|
||||
console.log("点击了编辑", record);
|
||||
}
|
||||
|
||||
function handleDelete(record: Recordable) {
|
||||
console.log("点击了删除", record);
|
||||
}
|
||||
|
||||
async function handleMenuAuth(record: Recordable) {
|
||||
editRoleTitle.value = `分配 ${record.roleName} 的菜单权限`;
|
||||
roleId.value = record.id;
|
||||
const res = await queryMenuByRole({ roleId: record.id });
|
||||
lastMenuIds.value = res.data;
|
||||
|
||||
checkedKeys.value = res.data; // 根据roleid查询权限菜单
|
||||
showModal.value = true;
|
||||
}
|
||||
|
||||
function checkedTree(keys) {
|
||||
checkedKeys.value = keys;
|
||||
}
|
||||
|
||||
function onExpandedKeys(keys) {
|
||||
expandedKeys.value = keys;
|
||||
}
|
||||
|
||||
function packHandle() {
|
||||
if (expandedKeys.value.length) {
|
||||
expandedKeys.value = [];
|
||||
} else {
|
||||
expandedKeys.value = treeData.value.map((item: any) => item.key) as [];
|
||||
}
|
||||
}
|
||||
|
||||
function checkedAllHandle() {
|
||||
if (!checkedAll.value) {
|
||||
checkedKeys.value = getTreeAll(treeData.value);
|
||||
checkedAll.value = true;
|
||||
} else {
|
||||
checkedKeys.value = [];
|
||||
checkedAll.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const treeMenuList = await getMenuTree();
|
||||
const res = mapTreeData(treeMenuList.data);
|
||||
expandedKeys.value = treeMenuList.data.map((item) => item.key);
|
||||
treeData.value = res;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
51
src/views/system/user/columns.ts
Normal file
51
src/views/system/user/columns.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { h } from "vue";
|
||||
import { NTag } from "naive-ui";
|
||||
|
||||
export const columns = [
|
||||
{
|
||||
title: "用户名",
|
||||
key: "username",
|
||||
},
|
||||
{
|
||||
title: "真实姓名",
|
||||
key: "realname",
|
||||
},
|
||||
{
|
||||
title: "手机号",
|
||||
key: "phone",
|
||||
},
|
||||
{
|
||||
title: "电子邮箱",
|
||||
key: "email",
|
||||
},
|
||||
{
|
||||
title: "用户类型",
|
||||
key: "userType",
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
type: row.userType === 1 ? "success" : "info",
|
||||
},
|
||||
{
|
||||
default: () => (row.userType === 1 ? "员工" : "用户"),
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "性别",
|
||||
key: "sex",
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
type: row.sex === 1 ? "success" : "info",
|
||||
},
|
||||
{
|
||||
default: () => (row.sex === 1 ? "男" : "女"),
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
0
src/views/system/user/components/MenuModal.vue
Normal file
0
src/views/system/user/components/MenuModal.vue
Normal file
135
src/views/system/user/components/UserModal.vue
Normal file
135
src/views/system/user/components/UserModal.vue
Normal file
@ -0,0 +1,135 @@
|
||||
<script setup lang="ts">
|
||||
import { insertUser } from "@/api/system/user";
|
||||
const props = defineProps({
|
||||
formRoleValue: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const formRef = ref();
|
||||
const { formRoleValue } = toRefs(props);
|
||||
const roleTitle = ref("新增角色");
|
||||
const formBtnLoading = ref(false);
|
||||
const showRoleModal = ref(false);
|
||||
const rules = {
|
||||
roleName: {
|
||||
required: true,
|
||||
message: "请输入角色名称",
|
||||
trigger: "blur",
|
||||
},
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const confirmForm = () => {
|
||||
formRef.value.validate(async (errors: any) => {
|
||||
if (!errors) {
|
||||
formRoleValue.value.id ? updateUserApi() : insertUserApi();
|
||||
} else {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 修改
|
||||
const updateUserApi = () => {};
|
||||
|
||||
// 新增
|
||||
const insertUserApi = async () => {
|
||||
const res = await insertUser(formRoleValue.value);
|
||||
if (res.status === 200) window["$message"].success("新增成功!");
|
||||
};
|
||||
|
||||
const init = (str: string) => {
|
||||
if (str === "add") {
|
||||
roleTitle.value = "新增用户";
|
||||
} else {
|
||||
roleTitle.value = "编辑用户";
|
||||
}
|
||||
showRoleModal.value = true;
|
||||
};
|
||||
const close = () => {
|
||||
showRoleModal.value = false;
|
||||
};
|
||||
defineExpose({
|
||||
init,
|
||||
close,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 新增角色 -->
|
||||
<n-modal
|
||||
v-model:show="showRoleModal"
|
||||
:show-icon="false"
|
||||
preset="dialog"
|
||||
:title="roleTitle"
|
||||
>
|
||||
<n-form
|
||||
ref="formRef"
|
||||
:rules="rules"
|
||||
label-placement="left"
|
||||
label-width="auto"
|
||||
:model="formRoleValue"
|
||||
require-mark-placement="right-hanging"
|
||||
>
|
||||
<n-form-item label="用户名" path="username">
|
||||
<n-input
|
||||
v-model:value="formRoleValue.username"
|
||||
placeholder="请输入用户名"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="真实姓名">
|
||||
<n-input
|
||||
v-model:value="formRoleValue.realname"
|
||||
placeholder="请输入真实姓名"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="电子邮箱">
|
||||
<n-input
|
||||
v-model:value="formRoleValue.email"
|
||||
placeholder="请输入电子邮箱"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="手机号">
|
||||
<n-input
|
||||
v-model:value="formRoleValue.phone"
|
||||
placeholder="请输入手机号"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="密码">
|
||||
<n-input
|
||||
type="password"
|
||||
v-model:value="formRoleValue.password"
|
||||
placeholder="请输入密码"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="性别">
|
||||
<n-radio-group v-model:value="formRoleValue.sex" name="radiogroup1">
|
||||
<n-space>
|
||||
<n-radio :value="0"> 女 </n-radio>
|
||||
<n-radio :value="1"> 男 </n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<n-form-item label="用户类型">
|
||||
<n-radio-group
|
||||
v-model:value="formRoleValue.userType"
|
||||
name="radiogroup1"
|
||||
>
|
||||
<n-space>
|
||||
<n-radio :value="2"> 用户 </n-radio>
|
||||
<n-radio :value="1"> 员工 </n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
<template #action>
|
||||
<n-space>
|
||||
<n-button type="primary" :loading="formBtnLoading" @click="confirmForm"
|
||||
>提交</n-button
|
||||
>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-modal>
|
||||
</template>
|
||||
228
src/views/system/user/user.vue
Normal file
228
src/views/system/user/user.vue
Normal file
@ -0,0 +1,228 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-card :bordered="false" class="mt-4 proCard">
|
||||
<BasicTable
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
ref="actionRef"
|
||||
:actionColumn="actionColumn"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<n-button type="primary" @click="addRole">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<PlusOutlined />
|
||||
</n-icon>
|
||||
</template>
|
||||
添加用户
|
||||
</n-button>
|
||||
</template>
|
||||
|
||||
<template #action>
|
||||
<TableAction />
|
||||
</template>
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
|
||||
<!-- 添加角色 -->
|
||||
<UserModal ref="formRole" :formRoleValue="formRoleValue" />
|
||||
|
||||
<!-- 分配角色 -->
|
||||
<n-modal
|
||||
v-model:show="showModal"
|
||||
:show-icon="false"
|
||||
preset="dialog"
|
||||
:title="editRoleTitle"
|
||||
>
|
||||
<n-form
|
||||
ref="formRef"
|
||||
:rules="rules"
|
||||
label-placement="left"
|
||||
label-width="auto"
|
||||
:model="formRoleValue"
|
||||
require-mark-placement="right-hanging"
|
||||
>
|
||||
<n-form-item label="用户名">
|
||||
<n-input
|
||||
disabled
|
||||
v-model:value="formRoleValue.username"
|
||||
placeholder="请输入用户名"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="真实姓名">
|
||||
<n-input
|
||||
disabled
|
||||
v-model:value="formRoleValue.realname"
|
||||
placeholder="请输入真实姓名"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="角色" path="roleIds">
|
||||
<n-select
|
||||
label-field="roleName"
|
||||
value-field="id"
|
||||
multiple
|
||||
clearable
|
||||
v-model:value="formRoleValue.roleIds"
|
||||
:options="roleOptions"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
<template #action>
|
||||
<n-space>
|
||||
<n-button
|
||||
type="primary"
|
||||
:loading="formBtnLoading"
|
||||
@click="confirmForm"
|
||||
>提交</n-button
|
||||
>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { BasicTable, TableAction } from "@/components/Table";
|
||||
|
||||
import { columns } from "./columns";
|
||||
import { PlusOutlined } from "@vicons/antd";
|
||||
import { getUserList, updateUser } from "@/api/system/user";
|
||||
import { getRuleList } from "@/api/system/role";
|
||||
import { saveUserRole } from "@/api/system/userrole";
|
||||
const actionRef = ref();
|
||||
const formRef = ref();
|
||||
const formRole = ref();
|
||||
const rules = {
|
||||
// roleIds: {
|
||||
// type: "array",
|
||||
// required: true,
|
||||
// message: "请选择角色",
|
||||
// trigger: ["blur", "change"],
|
||||
// },
|
||||
};
|
||||
const roleIds = ref([]);
|
||||
const formRoleValue = reactive({
|
||||
id: null,
|
||||
username: "",
|
||||
realname: null,
|
||||
password: "123456",
|
||||
userType: 2,
|
||||
sex: 1,
|
||||
email: "",
|
||||
phone: "",
|
||||
status: 1,
|
||||
skinColor: "white",
|
||||
roleIds: [],
|
||||
});
|
||||
|
||||
const roleOptions = ref([]);
|
||||
|
||||
const showModal = ref(false);
|
||||
const formBtnLoading = ref(false);
|
||||
const editRoleTitle = ref("");
|
||||
const params = reactive({
|
||||
username: "",
|
||||
});
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 250,
|
||||
title: "操作",
|
||||
key: "action",
|
||||
fixed: "right",
|
||||
render(record) {
|
||||
return h(TableAction, {
|
||||
style: "button",
|
||||
actions: [
|
||||
{
|
||||
label: "配置角色",
|
||||
onClick: handleMenuAuth.bind(null, record),
|
||||
// 根据业务控制是否显示 isShow 和 auth 是并且关系
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "编辑",
|
||||
onClick: handleEdit.bind(null, record),
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "删除",
|
||||
onClick: handleDelete.bind(null, record),
|
||||
// 根据业务控制是否显示 isShow 和 auth 是并且关系
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// 新增按钮
|
||||
const addRole = () => {
|
||||
formRole.value.init("add");
|
||||
};
|
||||
|
||||
const loadDataTable = async (res: any) => {
|
||||
let _params = {
|
||||
...unref(params),
|
||||
...res,
|
||||
};
|
||||
const { data } = await getUserList(_params);
|
||||
return data;
|
||||
};
|
||||
|
||||
function onCheckedRow(rowKeys: any[]) {
|
||||
console.log(rowKeys);
|
||||
}
|
||||
|
||||
function reloadTable() {
|
||||
actionRef.value.reload();
|
||||
}
|
||||
|
||||
async function confirmForm() {
|
||||
formRef.value.validate(async (errors: any) => {
|
||||
if (!errors) {
|
||||
formBtnLoading.value = true;
|
||||
|
||||
const res = await saveUserRole({
|
||||
userId: formRoleValue.id,
|
||||
roleIds: formRoleValue.roleIds,
|
||||
});
|
||||
if (res.status === 200) {
|
||||
showModal.value = false;
|
||||
window["$message"].success("保存成功");
|
||||
reloadTable();
|
||||
formBtnLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleEdit(record: Recordable) {
|
||||
Object.assign(formRoleValue, record);
|
||||
formRole.value.init("edit");
|
||||
}
|
||||
|
||||
function handleDelete(record: Recordable) {}
|
||||
|
||||
async function handleMenuAuth(record: Recordable) {
|
||||
editRoleTitle.value = `分配 ${record.realname} 的角色权限`;
|
||||
Object.assign(formRoleValue, record);
|
||||
showModal.value = true;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const { data } = await getRuleList({ current: 1, size: 100 });
|
||||
roleOptions.value = data.records;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
3
types/components.d.ts
vendored
3
types/components.d.ts
vendored
@ -17,7 +17,9 @@ declare module '@vue/runtime-core' {
|
||||
Histogram: typeof import('./../src/components/Charts/Histogram.vue')['default']
|
||||
Line: typeof import('./../src/components/Charts/Line.vue')['default']
|
||||
Main: typeof import('./../src/layout/components/Main/index.vue')['default']
|
||||
MenuModal: typeof import('./../src/views/system/role/components/MenuModal.vue')['default']
|
||||
Ring: typeof import('./../src/components/Charts/Ring.vue')['default']
|
||||
RoleModal: typeof import('./../src/views/system/role/components/RoleModal.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
Sider: typeof import('./../src/layout/components/Sider/index.vue')['default']
|
||||
@ -25,5 +27,6 @@ declare module '@vue/runtime-core' {
|
||||
Table: typeof import('./../src/components/Table/src/Table.vue')['default']
|
||||
TableAction: typeof import('./../src/components/Table/src/components/TableAction.vue')['default']
|
||||
TransitionMain: typeof import('./../src/layout/components/TransitionMain/index.vue')['default']
|
||||
UserModal: typeof import('./../src/views/system/user/components/UserModal.vue')['default']
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user