Commit 6e324189 authored by “yiyousong”'s avatar “yiyousong”

feat: 添加角色配置资源

parent 9606b41c
......@@ -194,10 +194,11 @@ export default {
.preview-btn {
border-top: 1px solid #ccc;
height: 100px;
padding: 0px 10px;
display: flex;
flex-direction: column;
justify-content: center;
flex-shrink: 0;
}
}
</style>
\ No newline at end of file
</style>
......@@ -429,8 +429,8 @@ export default {
if (code === 1) {
this.formData.previewImagePath = res.data.url;
let result = await skinSave({
...this.curProduct,
...this.formData,
...this.curProduct,
});
let { code, msg } = result.data;
if (code === 1) {
......
import http from "../request/http";
let baseURL = process.env.VUE_APP_API_BASE_URL;
// 获取资源列表
export function getResourceList(params) {
return http.post(`${baseURL}/zwfw/resource/list`, params);
}
// 保存资源
export function saveResource(params) {
return http.post(`${baseURL}/zwfw/resource/save`, params);
}
// 删除资源
export function delResource(params) {
return http.get(`${baseURL}/zwfw/resource/delete`, params);
}
// 查询角色权限列表
export function getRoleResourceList(params) {
return http.post(`${baseURL}/zwfw/role/auth/list`, params);
}
// 保存角色资源
export function distributionSource(params) {
return http.post(`${baseURL}/zwfw/role/auth/distributionSource`, params);
}
......@@ -19,7 +19,7 @@ const routes = [
children: [
{
path: "dataAdmin",
redirect: "/",//升级前门户跳转重定向
redirect: "/", //升级前门户跳转重定向
},
{
path: "pickUp",
......@@ -31,7 +31,6 @@ const routes = [
),
meta: { title: "取件记录报表" },
children: [
{
path: "pickUpRecord",
name: "pickUpRecord",
......@@ -730,6 +729,15 @@ const routes = [
),
meta: { title: "角色权限管理" },
},
{
path: "resourceManage",
name: "resourceManage",
component: () =>
import(
/* webpackChunkName: "resourceManage" */ "@/views/thePlatformIsSet/components/permissionsModel/ResourceManage.vue"
),
meta: { title: "资源信息管理" },
},
],
},
{
......
<template>
<div class="w-full">
<!-- 头部操作 -->
<div class="header_box flex justify-between items-center">
<a-space>
<a-button type="primary" class="addclass" @click="addSresource"
>新增资源</a-button
>
<a-button type="danger" @click="delAll">批量删除</a-button>
</a-space>
<a-space>
<a-input
v-model="searchForm.name"
style="width: 250px"
placeholder="请输入资源名称搜索"
>
<a-icon slot="prefix" type="search" />
</a-input>
<a-select
v-model="searchForm.authType"
placeholder="请选择权限类型"
style="width: 150px"
>
<a-select-option value="">全部</a-select-option>
<a-select-option
v-for="(v, key) in dict.authType"
:key="key"
:value="Number(key)"
>{{ v }}</a-select-option
>
</a-select>
<a-button type="primary" class="addclass" @click="handleSerch"
>搜索</a-button
>
<a-button @click="resetList">重置</a-button>
</a-space>
</div>
<!-- 表格 -->
<a-table
:columns="columns"
:data-source="tableSourceData"
size="small"
bordered
:scroll="{ y: 590 }"
:row-key="(record) => record.id"
:pagination="tablePagination"
@change="pagTableChange"
:loading="loading"
:row-selection="{
selectedRowKeys: selectedRowKeys,
onChange: onSelectChange,
}"
>
<!-- 资源 -->
<template slot="url" slot-scope="text">
<a-tag color="blue" class="mb-[4px]" v-for="(v, i) in text" :key="i">
{{ v }}
</a-tag>
</template>
<!-- 认证类型 -->
<template slot="authType" slot-scope="text">
<a-tag> {{ dict.authType[text] }} </a-tag>
</template>
<span slot="action" slot-scope="text, record">
<a-space>
<a-button type="link" @click="handleEdit(record)">编辑</a-button>
<a-button class="delete" type="link" @click="handleDel(record.id)"
>删除</a-button
>
</a-space>
</span>
</a-table>
<!-- 新增、编辑 -->
<AddResurce
ref="AddResurce"
:title="title"
:visible.sync="visible"
:dict="dict"
@add="getResourceList"
></AddResurce>
</div>
</template>
<script>
import { getResourceList, delResource } from "@/api/resource";
import AddResurce from "./components/AddResurce.vue";
export default {
components: {
AddResurce,
},
data() {
const columns = [
{
title: "序号",
width: 80,
align: "center",
customRender: (text, record, index) => {
return (
(this.tablePagination.current - 1) * this.tablePagination.pageSize +
index +
1
);
},
},
{
title: "名称",
width: 400,
dataIndex: "name",
},
{
title: "资源",
dataIndex: "url",
scopedSlots: { customRender: "url" },
},
{
title: "认证类型",
width: 200,
dataIndex: "authType",
scopedSlots: { customRender: "authType" },
},
{
title: "操作",
width: 150,
align: "center",
scopedSlots: { customRender: "action" },
},
];
return {
loading: false,
visible: false,
title: "新增资源",
columns,
searchForm: {
name: "",
authType: "",
},
dict: {}, // 字典
selectedRowKeys: [],
tableSourceData: [],
tablePagination: {
current: 1,
pageSize: 10,
total: 0,
showQuickJumper: true, //是否可以快速跳转至某页
showSizeChanger: true, //是否可以改变 pageSize
showTotal: (total, range) => `共${total}条`,
pageSizeOptions: ["10", "20", "30"],
},
};
},
created() {
this.getResourceList();
},
methods: {
// 获取列表数据
async getResourceList() {
this.loading = true;
let res = await getResourceList({
page: this.tablePagination.current,
size: this.tablePagination.pageSize,
...this.searchForm,
name: `%${this.searchForm.name}%`,
});
this.loading = false;
if (res.code !== 1) return;
let { data, dict, total } = res.data;
if (!data.length && this.tablePagination.current > 1) {
this.tablePagination.current -= 1;
this.getResourceList();
}
data.forEach((v) => {
v.url = v.url.split(",");
});
this.tableSourceData = data;
this.dict = dict;
this.tablePagination.total = total;
},
// 新增
addSresource() {
this.title = "新增资源";
this.$refs.AddResurce.onAdd();
this.visible = true;
},
// 搜索
handleSerch() {
this.tablePagination.current = 1;
this.getResourceList();
},
// 重置搜索
resetList() {
Object.assign(this.searchForm, this.$options.data().searchForm);
this.tablePagination.current = 1;
this.getResourceList();
},
// 分页
pagTableChange({ current, pageSize }) {
this.tablePagination.current = current;
this.tablePagination.pageSize = pageSize;
this.getResourceList();
},
// 编辑
handleEdit(row) {
this.title = "编辑资源";
this.$refs.AddResurce.onEdit(row);
this.visible = true;
},
// 勾选
onSelectChange(keys) {
this.selectedRowKeys = keys;
},
// 批量删除
delAll() {
if (!this.selectedRowKeys.length) {
this.$message.warning("请先勾选数据");
return;
}
let ids = this.selectedRowKeys.join(",");
this.handleDel(ids);
},
// 删除
handleDel(id) {
let _this = this;
this.$confirm({
okType: "danger",
title: "系统提示",
content: "此操作将删除该资源信息,是否继续?",
okText: "",
cancelText: "",
centered: true,
async onOk() {
let res = await delResource({
id,
});
let { code, msg } = res;
if (code == 1) {
_this.$message.success(msg);
_this.getResourceList();
}
},
});
},
},
};
</script>
<style lang="less" scoped>
.header_box {
padding-bottom: 1rem;
}
</style>
......@@ -30,6 +30,7 @@
:dataSource="tableSourceData"
>
<template slot="operation" slot-scope="text, record, index">
<a-button type="link" @click="apportion(record)">分配资源</a-button>
<a-button type="link" @click="pushRouter(record)">功能授权</a-button>
<a-button type="link" @click="showRoleEditModal(true, record)"
>编辑</a-button
......@@ -53,20 +54,30 @@
:roleDict="roleDict"
@getRoleList="getRoleList"
/>
<!-- 分配权限 -->
<ApportionAuth
ref="ApportionAuth"
:visible.sync="authVisible"
></ApportionAuth>
</div>
</div>
</template>
<script>
import { deepClone } from "@/utils/js/common.js";
import { roleList, roleDelete } from "@/api/authorityMis.js";
import AddEditRole from "./components/addEditRole.vue";
import ApportionAuth from "./components/ApportionAuth.vue";
import { mapState } from "vuex";
export default {
name: "PortalAdminVueAuthorityMis",
components: {
AddEditRole,
ApportionAuth,
},
data() {
return {
searchRoleName: undefined,
authVisible: false,
tableLoading: false,
tablePagination: {
current: 1,
......@@ -106,7 +117,7 @@ export default {
{
title: "操作",
align: "center",
width: "200px",
width: "250px",
dataIndex: "operation",
scopedSlots: {
customRender: "operation",
......@@ -118,9 +129,7 @@ export default {
roleDict: {},
};
},
components: {
AddEditRole,
},
computed: {
...mapState("user", ["userData"]),
},
......@@ -196,6 +205,11 @@ export default {
},
});
},
// 分配资源
apportion(row) {
this.$refs.ApportionAuth.onAdd(row.id);
this.authVisible = true;
},
},
};
</script>
......
<template>
<div class="add-resurce">
<a-modal
:title="title"
:centered="true"
:visible="Visible"
@cancel="handleCancel"
width="30%"
:maskClosable="false"
>
<a-form-model
:label-col="{
span: 5,
}"
:wrapper-col="{
span: 19,
}"
ref="form"
:model="form"
:rules="rules"
>
<a-form-model-item label="资源名称" prop="name">
<a-input
placeholder="请输入资源名称"
allowClear
v-model="form.name"
/>
</a-form-model-item>
<a-form-model-item label="权限类型" prop="authType">
<a-select v-model="form.authType" placeholder="请选择权限类型">
<a-select-option
v-for="(v, key) in dict.authType"
:key="key"
:value="Number(key)"
>{{ v }}</a-select-option
>
</a-select>
</a-form-model-item>
<a-form-model-item label="链接地址" prop="url">
<a-form-model-item
class="url-params"
v-for="(v, i) in form.urls"
:key="i"
:prop="`urls.${i}.value`"
:rules="[
{ required: true, validator: validatorUrl, trigger: 'blur' },
]"
>
<a-input
class="mr-[10px]"
v-model="v.value"
placeholder="请输入链接地址"
/>
<a-space>
<a-button type="primary" @click="changeParams(i, 'add')"
><a-icon type="plus"
/></a-button>
<a-button
type="danger"
v-if="i > 0"
@click="changeParams(i, 'remove')"
><a-icon type="minus"
/></a-button>
</a-space>
</a-form-model-item>
</a-form-model-item>
</a-form-model>
<template slot="footer">
<a-button @click="resetForm">重置</a-button>
<a-button type="primary" class="addclass" @click="subForm"
>确定</a-button
>
</template>
</a-modal>
</div>
</template>
<script>
import { saveResource } from "@/api/resource";
export default {
props: {
title: {
required: true,
type: String,
default: "新增资源",
},
visible: {
required: true,
type: Boolean,
default: false,
},
dict: {
required: true,
type: Object,
default: () => {},
},
},
data() {
return {
form: {
name: "",
authType: undefined,
url: "",
urls: [
{
value: "",
},
],
},
rules: {
name: [{ required: true, message: "请输入资源名称", trigger: "blur" }],
authType: [
{ required: true, message: "请输选择权限类型", trigger: "change" },
],
},
};
},
computed: {
Visible: {
get() {
return this.visible;
},
set(val) {
this.$emit("update:visible", val);
},
},
},
methods: {
onAdd() {
Object.assign(this.form, this.$options.data().form);
this.form.id && this.$delete(this.form, "id");
},
onEdit(row) {
setTimeout(() => {
this.form = { ...row };
this.form.urls = this.form.url.map((v) => {
return {
value: v,
};
});
}, 10);
},
subForm() {
this.$refs.form.validate(async (valid) => {
if (valid) {
let res = await saveResource({
...this.form,
url: this.form.urls.map((v) => v.value).join(","),
});
let { code, msg } = res;
if (code == 1) {
this.$message.success(msg);
this.$emit("add");
this.handleCancel();
}
}
});
},
// 判断是否存在链接
isRepeat(val) {
return this.form.urls.filter((v) => v.value == val).length > 1;
},
// 校验链接地址
validatorUrl(rule, value, callback) {
if (!value) {
callback(new Error("请输入链接"));
} else if (this.isRepeat(value)) {
callback(new Error("重复的链接地址"));
} else {
callback();
}
},
changeParams(index, type) {
if (type == "add") {
let obj = {
value: "",
};
if (this.form.urls.some((v) => !v.value)) {
this.$message.warning("请先完成前面地址的填写");
return;
}
this.form.urls.splice(index + 1, 0, obj);
} else {
this.form.urls.splice(index, 1);
}
},
resetForm() {
// 重置还原表单信息内容
this.$refs.form.resetFields();
this.form.urls = [
{
value: "",
},
];
},
handleCancel() {
this.resetForm();
this.Visible = false;
},
},
};
</script>
<style lang="less" scoped>
/deep/.ant-modal-body {
max-height: 600px;
overflow-y: auto;
}
/deep/.url-params {
.ant-form-item-children {
display: flex;
align-items: center;
}
}
</style>
<template>
<div class="apportion-auth">
<a-modal
title="分配资源"
:centered="true"
:visible="Visible"
@cancel="handleCancel"
width="40%"
:maskClosable="false"
>
<div class="mb-8" v-for="(v, key) in resourceList" :key="key">
<div class="mb-2" :style="{ borderBottom: '1px solid #E9E9E9' }">
<span class="text-lg mr-2 font-bold">{{ key }}</span>
<a-checkbox
:indeterminate="v.indeterminate"
:checked="v.checkAll"
@change="onCheckAllChange($event, v)"
>
全选
</a-checkbox>
</div>
<a-checkbox-group
class="w-full"
:value="form.resourceIdList"
@change="onChange($event, v)"
>
<a-row>
<a-col :span="12" v-for="item in v.list" :key="item.id">
<a-checkbox :value="item.id">
{{ item.name }}
</a-checkbox>
</a-col>
</a-row>
</a-checkbox-group>
</div>
<template slot="footer">
<a-button @click="resetForm">重置</a-button>
<a-button type="primary" class="addclass" @click="subForm"
>确定</a-button
>
</template>
</a-modal>
</div>
</template>
<script>
import {
getRoleResourceList,
getResourceList,
distributionSource,
} from "@/api/resource";
export default {
props: {
visible: {
required: true,
type: Boolean,
default: false,
},
},
data() {
return {
form: {
resourceIdList: [],
roleId: "",
},
rules: {},
resourceList: {}, // 资源列表
userResourceList: [], // 用户资源列表
};
},
computed: {
Visible: {
get() {
return this.visible;
},
set(val) {
this.$emit("update:visible", val);
},
},
},
methods: {
// 获取资源列表
async getResourceList() {
let res = await getResourceList({
page: 1,
size: -1,
});
if (res.code == 1) {
let { data } = res.data;
this.resourceList = this.groupByAuth(data);
}
},
// 获取角色资源权限列表
async getRoleResourceList(roleId) {
let res = await getRoleResourceList({
size: -1,
page: 1,
roleId,
});
if (res.code == 1) {
let { data } = res.data;
let arr = data.filter((v) => v.resourceId);
this.form.resourceIdList = arr.map((v) => v.resourceId);
}
},
// 权限分组
groupByAuth(list) {
let group = {};
list.forEach((item) => {
let name = item.name.split("-")[0];
if (!group[name]) {
group[name] = {
indeterminate: false,
checkAll: false,
list: [],
};
}
group[name].list.push(item);
});
return group;
},
// 控制全选
onCheckAllChange(e, row) {
let rowIds = row.list.map((v) => v.id);
let checked = e.target.checked;
row.indeterminate = false;
row.checkAll = checked;
if (checked) {
this.form.resourceIdList = [
...new Set([...this.form.resourceIdList, ...rowIds]),
];
} else {
this.form.resourceIdList = this.form.resourceIdList.filter((v) => {
return !rowIds.includes(v);
});
}
},
// 控制单选
onChange(checkedList, row) {
let rowIds = row.list.map((v) => v.id);
this.form.resourceIdList = this.form.resourceIdList.filter((v) => {
return !rowIds.includes(v);
});
this.form.resourceIdList = [
...new Set([...this.form.resourceIdList, ...checkedList]),
];
row.indeterminate =
!!checkedList.length && checkedList.length < rowIds.length;
row.checkAll = checkedList.length === rowIds.length;
},
onAdd(roleId) {
Object.assign(this.form, this.$options.data().form);
this.form.roleId = roleId;
this.getResourceList();
this.getRoleResourceList(roleId);
},
async subForm() {
let res = await distributionSource(this.form);
if (res.code == 1) {
this.$message.success("添加成功");
this.handleCancel();
}
},
resetForm() {
// 重置还原表单信息内容
// this.$refs.form.resetFields();
},
handleCancel() {
this.resetForm();
this.Visible = false;
},
},
};
</script>
<style lang="less" scoped>
/deep/.ant-modal-body {
max-height: 700px;
overflow-y: auto;
}
</style>
......@@ -133,8 +133,10 @@ export default {
// 获取区域数据
async getListByParentId(parentId = 0) {
let res = await getListByParentId({ parentId });
let { data } = res.data;
this.treeData = data;
if (res.code == 1) {
let { data } = res.data;
this.treeData = data;
}
},
// 异步获取区域
......
......@@ -169,8 +169,10 @@ export default {
// 获取区域数据
async getListByParentId(parentId = 0) {
let res = await getListByParentId({ parentId });
let { data } = res.data;
this.treeData = data;
if (res.code == 1) {
let { data } = res.data;
this.treeData = data;
}
},
// 异步获取区域
......
......@@ -62,6 +62,7 @@ export default {
<style lang="less" scoped>
@headerH: 4.5rem;
.Container {
width: 100%;
height: 100% !important;
// background: #fac;
background: #f5f5f5;
......@@ -146,4 +147,4 @@ export default {
// }
}
}
</style>
\ No newline at end of file
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment