Commit d6a1144e authored by 廖旭伟's avatar 廖旭伟

Merge remote-tracking branch 'origin/master'

parents 9903e75f fd04a60e
......@@ -5,6 +5,7 @@
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"serve2": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
"build": "vue-cli-service build --mode production",
"beta": "vue-cli-service build --mode beta",
"test": "vue-cli-service build --mode test",
......
......@@ -395,12 +395,13 @@ export default {
let { uid } = info.file;
if (code === 1) {
let obj = {
uid: uid,
uid,
name: fileName,
status: "done",
materialName: this.form.materialName,
fileName: fileName,
fileUrl: this.apiUrl + url,
url,
fileUrl: url,
filetype: num,
source: 1,
};
......
......@@ -12,8 +12,8 @@
:columns="columns"
:data-source="tableData"
>
<template slot="action" slot-scope="text">
<a @click="handleClick(text)">下载</a>
<template slot="action" slot-scope="text, record">
<a :href="record.fileUrl" :download="record.fileName">下载</a>
</template>
</a-table>
</a-modal>
......@@ -21,7 +21,7 @@
</template>
<script>
import { download } from "@/services/matter";
// import { download } from "@/services/matter";
// import axios from "axios";
const columns = [
{
......@@ -70,63 +70,60 @@ export default {
},
},
methods: {
downloadByBlob(url, name) {
let image = new Image();
image.setAttribute("crossOrigin", "anonymous");
image.src = url;
image.onload = () => {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0, image.width, image.height);
canvas.toBlob((blob) => {
let url = URL.createObjectURL(blob);
this.download(url, name);
// 用完释放URL对象
URL.revokeObjectURL(url);
});
};
},
download(href, name) {
let eleLink = document.createElement("a");
eleLink.style = "display: none";
eleLink.download = name;
eleLink.href = href;
document.body.appendChild(eleLink);
eleLink.click();
eleLink.remove();
},
async downloadFile(row, type) {
let res = await download(
{ datumId: row.datumId },
{ responseType: "blob" }
);
let data = res.data;
const blob = new Blob([data], {
type: type,
});
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.setAttribute("download", row.fileName); // 设置下载文件名称
document.body.appendChild(link);
link.click();
link.remove();
},
handleClick(row) {
let index = row.fileUrl.lastIndexOf(".");
let str = row.fileUrl.slice(index + 1);
if (str === "png" || str === "jpg" || str === "jpeg") {
this.downloadByBlob(row.fileUrl, row.fileName);
} else {
this.download(row.fileUrl, row.fileName);
}
},
// downloadByBlob(url, name) {
// let image = new Image();
// image.setAttribute("crossOrigin", "anonymous");
// image.src = url;
// image.onload = () => {
// let canvas = document.createElement("canvas");
// canvas.width = image.width;
// canvas.height = image.height;
// let ctx = canvas.getContext("2d");
// ctx.drawImage(image, 0, 0, image.width, image.height);
// canvas.toBlob((blob) => {
// let url = URL.createObjectURL(blob);
// this.download(url, name);
// // 用完释放URL对象
// URL.revokeObjectURL(url);
// });
// };
// },
// download(href, name) {
// let eleLink = document.createElement("a");
// eleLink.style = "display: none";
// eleLink.download = name;
// eleLink.href = href;
// document.body.appendChild(eleLink);
// eleLink.click();
// eleLink.remove();
// },
// async downloadFile(row, type) {
// let res = await download(
// { datumId: row.datumId },
// { responseType: "blob" }
// );
// let data = res.data;
// const blob = new Blob([data], {
// type: type,
// });
// const link = document.createElement("a");
// link.href = URL.createObjectURL(blob);
// link.setAttribute("download", row.fileName); // 设置下载文件名称
// document.body.appendChild(link);
// link.click();
// link.remove();
// },
// handleClick(row) {
// let index = row.fileUrl.lastIndexOf(".");
// let str = row.fileUrl.slice(index + 1);
// if (str === "png" || str === "jpg" || str === "jpeg") {
// this.downloadByBlob(row.fileUrl, row.fileName);
// } else {
// this.download(row.fileUrl, row.fileName);
// }
// },
},
};
</script>
<style lang="less" scoped>
</style>
\ No newline at end of file
<style lang="less" scoped></style>
......@@ -8,7 +8,7 @@
width="50"
height="50"
v-if="appInfo.appIconPath"
:src="api + appInfo.appIconPath"
:src="appInfo.appIconPath"
/>
<div class="name">{{ appInfo.appName }}</div>
<div class="version">当前版本:v{{ appInfo.version }}</div>
......
......@@ -49,8 +49,8 @@
<img
class="cover"
v-if="text.cover"
:src="api2 + text.cover"
@click="handlePreview(api2 + text.cover)"
:src="text.cover"
@click="handlePreview(text.cover)"
/>
<span v-else>--</span>
</template>
......@@ -132,8 +132,6 @@ export default {
},
data() {
return {
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
columns,
siteId: local.getLocal("siteId"),
tableData: [], // 表格数据
......
......@@ -83,7 +83,7 @@
v-if="text.video"
width="50"
:src="filterRes(text.video)"
@click="handlePreview('video', api2 + text.video)"
@click="handlePreview('video', text.video)"
/>
<span v-else>--</span>
</template>
......@@ -320,7 +320,7 @@ export default {
// 过滤影音
filterRes(data) {
let resource = data.split(",").map((v) => {
return this.api2 + v;
return v;
});
return resource[0];
......@@ -328,7 +328,7 @@ export default {
// 预览
handlePreview(type, data) {
let resource = data.split(",").map((v) => {
return this.api2 + v;
return v;
});
if (type == "img") {
this.$viewerApi({
......
......@@ -56,8 +56,8 @@
class="pointer"
height="20"
width="20"
:src="api2 + text.appIconPath"
@click="handlePreview(api2 + text.appIconPath)"
:src="text.appIconPath"
@click="handlePreview(text.appIconPath)"
/>
<span v-else>--</span>
</template>
......@@ -203,7 +203,6 @@ export default {
data() {
return {
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
columns,
siteId: local.getLocal("siteId"),
tableData: [], // 表格数据
......
......@@ -56,8 +56,8 @@
class="pointer"
height="20"
width="20"
:src="api2 + text.appIconPath"
@click="handlePreview(api2 + text.appIconPath)"
:src="text.appIconPath"
@click="handlePreview(text.appIconPath)"
/>
<span v-else>--</span>
</template>
......@@ -203,7 +203,6 @@ export default {
data() {
return {
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
columns,
siteId: local.getLocal("siteId"),
tableData: [], // 表格数据
......
......@@ -182,7 +182,6 @@ export default {
return {
accept: "image/jpeg,image/png,image/svg+xml",
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
iconFileList: [],
labelCol: {
span: 3,
......@@ -307,17 +306,25 @@ export default {
return isJpgOrPng && isLt5M;
},
// 上传图标
handleChangeIcon({ fileList }) {
handleChangeIcon({ file, fileList }) {
if (
file.status &&
file.status != "removed" &&
file.response &&
file.response.code == -1
) {
this.$message.error(file.response.msg);
fileList = fileList.filter((file) => file.response.code != -1);
}
this.iconFileList = [...fileList].slice(-1);
this.iconFileList = this.iconFileList.map((v) => {
if (v.response) {
v.url2 = v.response.url;
v.url = this.api2 + v.response.url;
v.url = v.response.url;
}
return v;
});
if (this.iconFileList[0]) {
this.form.appIconPath = this.iconFileList[0].url2;
this.form.appIconPath = this.iconFileList[0].url;
} else {
this.form.appIconPath = "";
}
......@@ -330,6 +337,17 @@ export default {
},
// 上传应用
handleChangeFile(info) {
if (
info.file.status &&
info.file.status != "removed" &&
info.file.response &&
info.file.response.code == -1
) {
this.$message.error(info.file.response.msg);
info.fileList = info.fileList.filter(
(file) => file.response.code != -1
);
}
let fileList = [...info.fileList];
fileList = fileList.slice(-1);
fileList = fileList.map((file) => {
......@@ -370,8 +388,7 @@ export default {
uid: "-2",
name: this.form.appIconPath,
status: "done",
url: this.api2 + this.form.appIconPath,
url2: this.form.appIconPath,
url: this.form.appIconPath,
},
];
});
......
......@@ -141,6 +141,7 @@
:action="api + '/base/file/commonupload'"
:multiple="true"
:file-list="v.fileList"
:beforeUpload="handleBeforeUpload"
@change="
(info) => {
handleChange(info, v);
......@@ -420,8 +421,43 @@ export default {
});
this.form = { ...data };
},
// 文件上传
// 更改文件名称
renameFile(originalFile, newName) {
return new File([originalFile], newName, {
type: originalFile.type,
lastModified: originalFile.lastModified,
});
},
handleBeforeUpload(file) {
let index = file.name.lastIndexOf(".");
let fileName = file.name.slice(0, index);
let suffix = file.name.slice(index);
let uid = file.uid;
if (fileName.length >= 40) {
let newName = fileName.slice(0, 40) + "..." + suffix;
let newFile = this.renameFile(file, newName);
newFile.uid = uid;
return new Promise((resolve) => {
resolve(newFile);
});
}
},
// 文件上传状态变化
handleChange(info, row) {
if (
info.file.status &&
info.file.status != "removed" &&
info.file.response &&
info.file.response.code == -1
) {
this.$message.error(info.file.response.msg);
info.fileList = info.fileList.filter(
(file) => file.response.code != -1
);
}
let fileList = [...info.fileList];
// fileList = fileList.slice(-1);
fileList = fileList.map((file) => {
......
......@@ -69,7 +69,6 @@ export default {
return {
accept: "image/jpeg,image/png",
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
fileList: [],
form: {
siteId: local.getLocal("siteId"), // 站点id
......@@ -117,8 +116,7 @@ export default {
uid: "-2",
name: this.form.cover,
status: "done",
url: this.api2 + this.form.cover,
url2: this.form.cover,
url: this.form.cover,
},
];
}
......@@ -158,17 +156,25 @@ export default {
return isJpgOrPng && isLt10M;
},
// 上传封面
handleChangeCover({ fileList }) {
handleChangeCover({ file, fileList }) {
if (
file.status &&
file.status != "removed" &&
file.response &&
file.response.code == -1
) {
this.$message.error(file.response.msg);
fileList = fileList.filter((file) => file.response.code != -1);
}
this.fileList = [...fileList].slice(-1);
this.fileList = this.fileList.map((v) => {
if (v.response) {
v.url2 = v.response.url;
v.url = this.api2 + v.response.url;
v.url = v.response.url;
}
return v;
});
if (this.fileList[0]) {
this.form.cover = this.fileList[0].url2;
this.form.cover = this.fileList[0].url;
} else {
this.form.cover = "";
}
......
......@@ -56,16 +56,13 @@
<!-- 模块图标 -->
<template slot="modelIcon" slot-scope="text">
<div v-if="text.modelIcon">
<!-- <div class="svg-box" v-if="isSvg(text.modelIcon)">
<img width="30" height="30" :src="api2 + text.modelIcon" />
</div> -->
<div class="svg-box">
<img
class="pointer"
width="30"
height="30"
:src="api2 + text.modelIcon"
@click="handlePreview({ url: api2 + text.modelIcon })"
:src="text.modelIcon"
@click="handlePreview({ url: text.modelIcon })"
/>
</div>
</div>
......@@ -301,7 +298,6 @@ export default {
return {
pageSizeOptions,
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
accept: "image/jpeg,image/png,image/svg+xml", // 上传类型
columns,
loading: true,
......@@ -404,8 +400,7 @@ export default {
uid: -1,
status: "done",
name: this.formData.modelIcon,
url: this.api2 + this.formData.modelIcon,
url2: this.formData.modelIcon,
url: this.formData.modelIcon,
},
];
}
......@@ -471,13 +466,12 @@ export default {
this.fileList = [...fileList].slice(-1);
this.fileList = this.fileList.map((v) => {
if (v.response) {
v.url2 = v.response.url;
v.url = this.api2 + v.response.url;
v.url = v.response.url;
}
return v;
});
if (this.fileList[0]) {
this.formData.modelIcon = this.fileList[0].url2;
this.formData.modelIcon = this.fileList[0].url;
} else {
this.formData.modelIcon = "";
}
......
......@@ -347,7 +347,6 @@ export default {
// };
return {
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
accept: "image/jpeg,image/png", // 上传类型
loading: false,
options: regionData, // 地区级联数据
......@@ -634,8 +633,7 @@ export default {
uid: -1,
status: "done",
name: this.formInfo.logoPath,
url: this.api2 + this.formInfo.logoPath,
url2: this.formInfo.logoPath,
url: this.formInfo.logoPath,
},
];
}
......@@ -680,17 +678,25 @@ export default {
return isJpgOrPng && isLt10M;
},
// 上传图片
handleChange({ fileList }) {
handleChange({ file, fileList }) {
if (
file.status &&
file.status != "removed" &&
file.response &&
file.response.code == -1
) {
this.$message.error(file.response.msg);
fileList = fileList.filter((file) => file.response.code != -1);
}
this.fileList = [...fileList].slice(-1);
this.fileList = this.fileList.map((v) => {
if (v.response) {
v.url2 = v.response.url;
v.url = this.api2 + v.response.url;
v.url = v.response.url;
}
return v;
});
if (this.fileList[0]) {
this.formInfo.logoPath = this.fileList[0].url2;
this.formInfo.logoPath = this.fileList[0].url;
} else {
this.formInfo.logoPath = "";
}
......
......@@ -5,7 +5,9 @@
<h2 class="show-titlw">{{ curSkin.name }}</h2>
<p>
更新时间:<span style="margin-right: 20px">{{
curSkin.updateTime | dateFormat
curSkin.updateTime
? dateFormat(curSkin.updateTime)
: dateFormat(curSkin.createTime)
}}</span>
支持分辨率:<span
>{{ filterItems(curSkin.imageResolution, imageResolution) }}
......@@ -167,6 +169,9 @@ export default {
},
});
},
dateFormat(val) {
return this.$moment(val).format("YYYY-MM-DD HH:mm:ss");
},
},
};
</script>
......
......@@ -399,7 +399,7 @@ export default {
file.type === "image/png" ||
file.type === "image/gif";
if (!isJpgOrPng) {
this.$message.error("请上传jpeg或者png图片!");
this.$message.error("请上传jpeg,png或者gif图片!");
}
const isLt5M = file.size / 1024 / 1024 < 5;
if (!isLt5M) {
......
<template>
<div class="system flex flexc">
<a-tabs :activeKey="activeKey" @change="changeRouter">
<a-tab-pane key="/system/user">
<span slot="tab">
<a-icon type="user" />
用户管理
</span>
</a-tab-pane>
<a-tab-pane key="/system/role">
<span slot="tab">
<a-icon type="idcard" />
角色管理
</span>
</a-tab-pane>
<a-tab-pane key="/system/resource">
<span slot="tab">
<a-icon type="cloud-sync" />
资源管理
</span>
</a-tab-pane>
<a-tab-pane key="/system/dimension">
<span slot="tab">
<a-icon type="deployment-unit" />
维度管理
</span>
</a-tab-pane>
<a-tab-pane key="/system/parameter">
<span slot="tab">
<a-icon type="container" />
......@@ -53,4 +77,4 @@ export default {
border-bottom: 1px solid #f0f0f0 !important;
}
}
</style>
\ No newline at end of file
</style>
<template>
<div class="dimension-container">
<div class="control flex aic jcb mb15 pdr6">
<div>
<a-button type="primary" style="margin-right: 10px" @click="handleAdd"
>新增</a-button
>
<a-button type="danger" @click="handleDelAll">批量删除</a-button>
</div>
<div class="search-box">
<a-input-search
placeholder="请输入维度名搜索"
enter-button="搜索"
v-model="searchValue"
allowClear
@search="onSearch"
/>
</div>
</div>
<!-- 表格 -->
<div class="table-content">
<a-table
:row-selection="{
selectedRowKeys: selectedRowKeys,
onChange: onSelectChange,
}"
:loading="loading"
bordered
:scroll="{ y: 590 }"
:columns="columns"
:pagination="{
showTotal: (total) => `共 ${total} 条`,
current: current,
total: total,
pageSize: size,
showSizeChanger: true,
showQuickJumper: true,
pageSizeOptions: pageSizeOptions,
onChange: handleChange,
onShowSizeChange: showSizeChange,
}"
:data-source="tableData"
:rowKey="(record) => record.id"
>
<!-- 序号 -->
<span slot="num" slot-scope="text, record, index">{{
(current - 1) * size + index + 1
}}</span>
<!-- 操作 -->
<template slot="action" slot-scope="text">
<a-space size="middle">
<span
href="javascript:;"
class="primary pointer"
@click="handleEdit(text)"
>编辑</span
>
<span
href="javascript:;"
class="delete pointer"
@click="handleDel(text.id)"
>删除</span
>
</a-space>
</template>
</a-table>
</div>
<!-- 新增 -->
<AddDimension
ref="AddDimension"
:addVisible.sync="addVisible"
:title="title"
:dict="dict"
@addSuccess="getDimensionList"
></AddDimension>
</div>
</template>
<script>
import { getDimensionList, delDimension } from "@/services/system";
import { pageSizeOptions } from "@/config/pageConfig.js";
import AddDimension from "./modal/AddDimension";
export default {
components: { AddDimension },
data() {
const columns = [
{
title: "序号",
dataIndex: "num",
width: "65px",
scopedSlots: {
customRender: "num",
},
},
{
title: "名称",
dataIndex: "dimensionName",
},
{
title: "编码",
dataIndex: "dimensionCode",
},
{
title: "类型",
dataIndex: "dimensionType",
customRender: (text) => {
return this.dict.dimensionType[text];
},
},
{
title: "维度值",
dataIndex: "dimensionValue",
},
{
title: "创建时间",
dataIndex: "createTime",
customRender: (text) => {
return this.$moment(text).format("YYYY-MM-DD HH:mm:ss");
},
},
{
title: "操作",
width: "120px",
scopedSlots: { customRender: "action" },
},
];
return {
columns,
loading: false,
current: 1,
size: 10,
total: 0,
pageSizeOptions,
searchValue: "", // 搜索
tableData: [],
selectedRowKeys: [],
dict: {}, // 字典
addVisible: false,
title: "新增",
};
},
created() {
this.getDimensionList();
},
methods: {
// 获取列表
async getDimensionList() {
this.loading = true;
let res = await getDimensionList({
page: this.current,
size: this.size,
dimensionName: this.searchValue,
});
this.loading = false;
if (res.data.code == 1) {
let { data, total, dict } = res.data.data;
this.tableData = data;
this.total = total;
this.dict = dict;
}
},
// 新增
handleAdd() {
this.title = "新增";
this.$refs.AddDimension.onAdd();
this.addVisible = true;
},
// 搜索
onSearch() {
this.current = 1;
},
// 分页
handleChange(num) {
this.current = num;
},
// 改变每页显示数量
showSizeChange(current, size) {
this.current = current;
this.size = size;
},
// 选择
onSelectChange(keys) {
this.selectedRowKeys = keys;
},
// 批量删除
handleDelAll() {
if (!this.selectedRowKeys.length) {
this.$message.warn("请先勾选数据");
return;
}
let ids = this.selectedRowKeys.join(",");
this.handleDel(ids);
},
// 编辑
handleEdit(row) {
this.title = "编辑";
this.$refs.AddDimension.onEdit(row);
this.addVisible = true;
},
// 删除
handleDel(id) {
let _this = this;
this.$confirm({
title: "系统提示",
content: "删除不可恢复,确定要删除吗?",
okText: "确定",
okType: "danger",
cancelText: "取消",
centered: true,
icon: "exclamation-circle",
maskClosable: true,
async onOk() {
let res = await delDimension({ id });
if (res.data.code == 1) {
_this.$message.success(res.data.msg);
_this.getDimensionList();
}
console.log(id);
},
onCancel() {
console.log("Cancel");
},
});
},
},
};
</script>
<style lang="less" scoped>
.dimension-container {
width: 100%;
height: 100%;
}
</style>
<template>
<div>
<a-modal
:title="title"
:visible="Visible"
@cancel="handleCancel"
:maskClosable="false"
>
<a-button slot="footer" @click="handleReset">重置</a-button>
<a-button
slot="footer"
type="primary"
:loading="loading"
@click="handleOk"
>确定</a-button
>
<a-form-model
:model="form"
ref="form"
:rules="rules"
:label-col="{ span: 5 }"
:wrapper-col="{ span: 19 }"
>
<a-form-model-item label="名称" prop="dimensionName">
<a-input
v-model="form.dimensionName"
placeholder="请输入维度名称"
></a-input>
</a-form-model-item>
<a-form-model-item label="编号" prop="dimensionCode">
<a-input
v-model="form.dimensionCode"
placeholder="请输入维度编号"
></a-input>
</a-form-model-item>
<a-form-model-item label="类型" prop="dimensionType">
<a-select v-model="form.dimensionType" placeholder="请选择维度类型">
<a-select-option
v-for="(v, key) in dict.dimensionType"
:key="key"
:value="Number(key)"
>{{ v }}</a-select-option
>
</a-select>
</a-form-model-item>
<a-form-model-item label="维度值" prop="dimensionValue">
<a-input
v-model="form.dimensionValue"
placeholder="请输入维度值"
></a-input>
</a-form-model-item>
</a-form-model>
</a-modal>
</div>
</template>
<script>
import { saveDimension } from "@/services/system";
export default {
components: {},
props: {
addVisible: {
required: true,
type: Boolean,
default: false,
},
title: {
required: true,
type: String,
default: "",
},
dict: {
required: true,
type: Object,
default: () => {},
},
},
data() {
return {
loading: false,
form: {
dimensionName: "", // 维度名称
dimensionCode: "", // 维度编码
dimensionValue: "", // 维度值
dimensionType: undefined, // 维度类型
},
rules: {
dimensionName: [
{ required: true, message: "请输入维度名称", trigger: "blur" },
],
dimensionCode: [
{ required: true, message: "请输入维度编码", trigger: "blur" },
],
dimensionValue: [
{ required: true, message: "请输入维度值", trigger: "blur" },
],
dimensionType: [
{ required: true, message: "请选择维度类型", trigger: "change" },
],
},
};
},
computed: {
Visible: {
get() {
return this.addVisible;
},
set(val) {
this.$emit("update:addVisible", val);
},
},
},
created() {},
methods: {
// 新增
onAdd() {
Object.assign(this.form, this.$options.data().form);
this.form.id && this.$delete(this.form, "id");
},
// 编辑
onEdit(row) {
this.$nextTick(() => {
this.form = { ...row };
});
},
// 保存
handleOk() {
this.$refs.form.validate(async (valid) => {
if (valid) {
this.loading = true;
let res = await saveDimension(this.form);
let { code, msg } = res.data;
this.loading = false;
if (code == 1) {
this.$message.success(msg);
this.$emit("addSuccess");
this.handleCancel();
}
}
});
},
// 重置
handleReset() {
this.$refs.form.resetFields();
},
// 关闭
handleCancel() {
this.$refs.form.resetFields();
this.Visible = false;
},
},
};
</script>
<style lang="less" scoped></style>
......@@ -8,13 +8,20 @@
<a-button type="danger" @click="handleDelAll">批量删除</a-button>
</div>
<div class="search-box">
<a-input-search
placeholder="请输入参数名搜索"
enter-button="搜索"
v-model="searchValue"
allowClear
@search="onSearch"
/>
<a-space>
<a-input
placeholder="请输入参数名搜索"
v-model="searchForm.name"
allowClear
/>
<a-input
placeholder="请输入二级组织搜索"
v-model="searchForm.secondOrganize"
allowClear
/>
<a-button type="primary" @click="onSearch">搜索</a-button>
<a-button @click="resetSearch">重置</a-button>
</a-space>
</div>
</div>
<!-- 表格 -->
......@@ -176,6 +183,10 @@ export default {
total: 0,
pageSizeOptions,
searchValue: "", // 搜索
searchForm: {
name: "",
secondOrganize: "",
},
tableData: [],
selectedRowKeys: [],
dict: {}, // 字典
......@@ -193,7 +204,8 @@ export default {
let res = await getSystemParameterList({
page: this.current,
size: this.size,
name: `%${this.searchValue}%`,
name: `%${this.searchForm.name}%`,
secondOrganize: `%${this.searchForm.secondOrganize}%`,
});
this.loading = false;
if (res.data.code == 1) {
......@@ -217,6 +229,12 @@ export default {
this.current = 1;
this.getSystemParameterList();
},
// 重置搜索
resetSearch() {
this.current = 1;
Object.assign(this.searchForm, this.$options.data().searchForm);
this.getSystemParameterList();
},
// 分页
handleChange(num) {
this.current = num;
......@@ -292,4 +310,4 @@ export default {
width: 100%;
height: 100%;
}
</style>
\ No newline at end of file
</style>
......@@ -183,9 +183,11 @@ export default {
// 文件上传
handleUpload({ file }) {
if (file.status === "done") {
let { code, url } = file.response;
let { code, url, msg } = file.response;
if (code == 1) {
this.form.paramValue = url;
} else {
this.$message.error(msg);
}
}
},
......
<template>
<div class="resource-container">
<div class="control flex aic jcb mb15 pdr6">
<a-space>
<a-button type="primary" @click="handleAdd">新增</a-button>
<a-button
v-permission="[1]"
type="primary"
class="addclass"
@click="refSresource"
>刷新资源</a-button
>
<a-button type="danger" @click="handleDelAll">批量删除</a-button>
</a-space>
<div class="search-box">
<a-input-search
placeholder="请输入资源名搜索"
enter-button="搜索"
v-model="searchValue"
allowClear
@search="onSearch"
/>
</div>
</div>
<!-- 表格 -->
<div class="table-content">
<a-table
:row-selection="{
selectedRowKeys: selectedRowKeys,
onChange: onSelectChange,
}"
:loading="loading"
bordered
:scroll="{ y: 590 }"
:columns="columns"
:pagination="{
showTotal: (total) => `共 ${total} 条`,
current: current,
total: total,
pageSize: size,
showSizeChanger: true,
showQuickJumper: true,
pageSizeOptions: pageSizeOptions,
onChange: handleChange,
onShowSizeChange: showSizeChange,
}"
:data-source="tableData"
:rowKey="(record) => record.id"
>
<!-- 序号 -->
<span slot="num" slot-scope="text, record, index">{{
(current - 1) * size + index + 1
}}</span>
<!-- 操作 -->
<template slot="action" slot-scope="text">
<a-space size="middle">
<span
href="javascript:;"
class="primary pointer"
@click="handleEdit(text)"
>编辑</span
>
<span
href="javascript:;"
class="delete pointer"
@click="handleDel(text.id)"
>删除</span
>
</a-space>
</template>
</a-table>
</div>
<!-- 新增、编辑 -->
<AddResurce
ref="AddResurce"
:title="title"
:visible.sync="addVisible"
:dict="dict"
@add="getResourceList"
></AddResurce>
</div>
</template>
<script>
import {
getResourceList,
refreshResource,
delResource,
} from "@/services/system";
import { pageSizeOptions } from "@/config/pageConfig.js";
import AddResurce from "./modal/AddResurce.vue";
export default {
components: { AddResurce },
data() {
const columns = [
{
title: "序号",
dataIndex: "num",
width: "65px",
scopedSlots: {
customRender: "num",
},
},
{
title: "名称",
width: 400,
dataIndex: "name",
},
{
title: "资源",
dataIndex: "url",
customRender: (text) => {
if (text) {
return text.split(",").map((v) => {
return (
<a-tag style="margin-bottom:4px" color="blue">
{v}
</a-tag>
);
});
}
},
},
{
title: "认证类型",
width: 200,
dataIndex: "authType",
customRender: (text) => {
return this.dict.authType[text];
},
},
{
title: "操作",
width: "120px",
scopedSlots: { customRender: "action" },
},
];
return {
columns,
loading: false,
current: 1,
size: 10,
total: 0,
pageSizeOptions,
searchValue: "", // 搜索
tableData: [],
selectedRowKeys: [],
dict: {}, // 字典
addVisible: false,
title: "新增",
};
},
created() {
this.getResourceList();
},
methods: {
// 获取资源列表
async getResourceList() {
this.loading = true;
let res = await getResourceList({
page: this.current,
size: this.size,
name: `%${this.searchValue}%`,
});
this.loading = false;
if (res.data.code == 1) {
let { data, total, dict } = res.data.data;
this.tableData = data;
this.total = total;
this.dict = dict;
}
},
// 新增
handleAdd() {
this.title = "新增";
this.$refs.AddResurce.onAdd();
this.addVisible = true;
},
// 搜索
onSearch() {
this.current = 1;
this.getResourceList();
},
// 分页
handleChange(num) {
this.current = num;
this.getResourceList();
},
// 改变每页显示数量
showSizeChange(current, size) {
this.current = current;
this.size = size;
this.getResourceList();
},
// 选择
onSelectChange(keys) {
this.selectedRowKeys = keys;
},
// 批量删除
handleDelAll() {
if (!this.selectedRowKeys.length) {
this.$message.warn("请先勾选数据");
return;
}
let ids = this.selectedRowKeys.join(",");
this.handleDel(ids);
},
// 编辑
handleEdit(row) {
this.title = "编辑";
this.$refs.AddResurce.onEdit(row);
this.addVisible = true;
},
// 删除
handleDel(id) {
let _this = this;
this.$confirm({
title: "系统提示",
content: "删除不可恢复,确定要删除吗?",
okText: "确定",
okType: "danger",
cancelText: "取消",
centered: true,
icon: "exclamation-circle",
maskClosable: true,
async onOk() {
let res = await delResource({ id });
if (res.data.code == 1) {
let { msg } = res.data;
_this.$message.success(msg);
_this.getResourceList();
}
},
onCancel() {
console.log("Cancel");
},
});
},
// 刷新资源
async refSresource() {
let _this = this;
this.$confirm({
title: "系统提示",
content: "确定要刷新资源吗?",
okText: "",
cancelText: "",
centered: true,
async onOk() {
let res = await refreshResource();
if (res.data.code == 1) {
_this.$message.success(res.data.msg);
_this.getResourceList();
}
},
});
},
},
};
</script>
<style lang="less" scoped>
.resource-container {
width: 100%;
height: 100%;
}
</style>
<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 class="url-params-box" label="链接地址">
<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="mr10"
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"
:loading="loading"
@click="subForm"
>确定</a-button
>
</template>
</a-modal>
</div>
</template>
<script>
import { saveResource } from "@/services/system";
export default {
props: {
title: {
required: true,
type: String,
default: "新增资源",
},
visible: {
required: true,
type: Boolean,
default: false,
},
dict: {
required: true,
type: Object,
default: () => {},
},
},
data() {
return {
loading: false,
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 };
let arr = [];
if (this.form.url) {
arr = this.form.url.split(",").map((v) => {
return {
value: v,
};
});
}
this.$set(this.form, "urls", arr);
}, 10);
},
subForm() {
this.$refs.form.validate(async (valid) => {
if (valid) {
this.loading = true;
let res = await saveResource({
...this.form,
url: this.form.urls.map((v) => v.value).join(","),
});
let { code, msg } = res.data;
this.loading = false;
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);
}
// this.$forceUpdate();
},
resetForm() {
// 重置还原表单信息内容
this.$refs.form.resetFields();
this.$set(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-box {
display: block !important;
.ant-form-item-children {
display: block;
}
}
/deep/.url-params {
.ant-form-item-children {
display: flex;
align-items: center;
}
}
</style>
<template>
<div class="role-container">
<div class="control flex aic jcb mb15 pdr6">
<div>
<a-button type="primary" style="margin-right: 10px" @click="handleAdd"
>新增</a-button
>
<a-button type="danger" @click="handleDelAll">批量删除</a-button>
</div>
<div class="search-box">
<a-input-search
placeholder="请输入角色名搜索"
enter-button="搜索"
v-model="searchValue"
allowClear
@search="onSearch"
/>
</div>
</div>
<!-- 表格 -->
<div class="table-content">
<a-table
:row-selection="{
selectedRowKeys: selectedRowKeys,
onChange: onSelectChange,
}"
:loading="loading"
bordered
:scroll="{ y: 590 }"
:columns="columns"
:pagination="{
showTotal: (total) => `共 ${total} 条`,
current: current,
total: total,
pageSize: size,
showSizeChanger: true,
showQuickJumper: true,
pageSizeOptions: pageSizeOptions,
onChange: handleChange,
onShowSizeChange: showSizeChange,
}"
:data-source="tableData"
:rowKey="(record) => record.id"
>
<!-- 序号 -->
<span slot="num" slot-scope="text, record, index">{{
(current - 1) * size + index + 1
}}</span>
<!-- 操作 -->
<template slot="action" slot-scope="text">
<a-space size="middle">
<span class="primary pointer" @click="apportion(text)"
>分配资源</span
>
<span class="primary pointer" @click="handleResDim(text)"
>资源规则</span
>
<span class="primary pointer" @click="handleEdit(text)">编辑</span>
<span class="delete pointer" @click="handleDel(text.id)">删除</span>
</a-space>
</template>
</a-table>
</div>
<!-- 新增 -->
<AddRole
ref="AddRole"
:title="title"
:addVisible.sync="addVisible"
@addSuccess="getRoleList"
></AddRole>
<!-- 分配资源 -->
<ApportionRes ref="ApportionRes" :visible.sync="resVisible"></ApportionRes>
<!-- 资源规则 -->
<ResDimList ref="ResDimList" :visible.sync="resDimListVisible"></ResDimList>
</div>
</template>
<script>
import { getRoleList, delRole } from "@/services/system";
import { pageSizeOptions } from "@/config/pageConfig.js";
import AddRole from "./modal/AddRole.vue";
import ApportionRes from "./modal/ApportionRes.vue";
import ResDimList from "./modal/ResDimList.vue";
export default {
components: { AddRole, ApportionRes, ResDimList },
data() {
const columns = [
{
title: "序号",
dataIndex: "num",
width: "65px",
scopedSlots: {
customRender: "num",
},
},
{
title: "角色名称",
dataIndex: "name",
},
{
title: "备注",
dataIndex: "remark",
},
{
title: "操作",
width: "20% ",
scopedSlots: { customRender: "action" },
},
];
return {
columns,
loading: false,
current: 1,
size: 10,
total: 0,
pageSizeOptions,
searchValue: "", // 搜索
tableData: [],
selectedRowKeys: [],
dict: {}, // 字典
addVisible: false,
resVisible: false,
resDimListVisible: false,
title: "新增角色",
};
},
created() {
this.getRoleList();
},
methods: {
// 获取角色列表
async getRoleList() {
this.loading = true;
let res = await getRoleList({
current: this.current,
size: this.size,
name: this.searchValue,
});
this.loading = false;
if (res.data.code == 1) {
let { data, total } = res.data.data;
this.tableData = data;
this.total = total;
}
},
// 新增
handleAdd() {
this.title = "新增角色";
this.$refs.AddRole.onAdd();
this.addVisible = true;
},
// 搜索
onSearch() {
this.current = 1;
this.getRoleList();
},
// 分页
handleChange(num) {
this.current = num;
this.getRoleList();
},
// 改变每页显示数量
showSizeChange(current, size) {
this.current = current;
this.size = size;
this.getRoleList();
},
// 选择
onSelectChange(keys) {
this.selectedRowKeys = keys;
},
// 批量删除
handleDelAll() {
if (!this.selectedRowKeys.length) {
this.$message.warn("请先勾选数据");
return;
}
let ids = this.selectedRowKeys.join(",");
this.handleDel(ids);
},
// 编辑
handleEdit(row) {
this.title = "编辑角色";
this.$refs.AddRole.onEdit(row);
this.addVisible = true;
},
// 删除
handleDel(id) {
let _this = this;
this.$confirm({
title: "系统提示",
content: "删除不可恢复,确定要删除吗?",
okText: "确定",
okType: "danger",
cancelText: "取消",
centered: true,
icon: "exclamation-circle",
maskClosable: true,
async onOk() {
let res = await delRole({ id });
if (res.data.code == 1) {
_this.$message.success(res.data.msg);
_this.getRoleList();
}
},
onCancel() {
console.log("Cancel");
},
});
},
// 分配资源
apportion(row) {
this.$refs.ApportionRes.onAdd(row.id);
this.resVisible = true;
},
// 资源维度
handleResDim(row) {
this.$refs.ResDimList.getRoleInfo(row);
this.resDimListVisible = true;
},
},
};
</script>
<style lang="less" scoped>
.role-container {
width: 100%;
height: 100%;
}
</style>
<template>
<div>
<a-modal
:title="title"
:visible="Visible"
@cancel="handleCancel"
:maskClosable="false"
:zIndex="1001"
>
<a-form-model
:model="form"
ref="form"
:rules="rules"
:label-col="{ span: 5 }"
:wrapper-col="{ span: 19 }"
>
<a-form-model-item label="所属资源" prop="resourceId">
<a-cascader
:options="resourceList"
v-model="resource"
placeholder="请选择资源"
@change="changeRes"
/>
</a-form-model-item>
<a-form-model-item label="所属维度" prop="ruleCode">
<a-select
allowClear
v-model="form.ruleCode"
@change="changeDim"
placeholder="请选择所属维度"
>
<a-select-option
v-for="v in dimensionList"
:key="v.id"
:value="v.dimensionCode"
:dataset-row="v"
>
{{ v.dimensionName }}
</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item label="规则条件" prop="ruleCondition">
<a-select
allowClear
v-model="form.ruleCondition"
placeholder="请选择规则条件"
>
<a-select-option
v-for="(v, key) in dict.ruleCondition"
:key="key"
:value="key"
>
{{ v }}
</a-select-option>
</a-select>
</a-form-model-item>
</a-form-model>
<a-button slot="footer" @click="handleReset">重置</a-button>
<a-button
slot="footer"
type="primary"
:loading="loading"
@click="handleOk"
>确定</a-button
>
</a-modal>
</div>
</template>
<script>
import {
getDimensionList,
getResourceList,
saveDimRes,
} from "@/services/system";
export default {
components: {},
props: {
addVisible: {
required: true,
type: Boolean,
default: false,
},
title: {
required: true,
type: String,
default: "",
},
dict: {
required: true,
type: Object,
default: () => {},
},
},
data() {
return {
loading: false,
resource: [],
dimensionList: [], // 维度列表
resourceList: [], // 资源列表
form: {
roleId: "", // 角色id
resourceId: "", // 资源id
ruleCode: undefined, // 维度编码
ruleName: "", // 维度名称
ruleCondition: undefined, // 规则条件
ruleValue: "", // 维度值
ruleType: "", // 维度类型
roleName: "", // 角色名称
resourceName: "", // 资源名称
},
rules: {
resourceId: [
{ required: true, message: "请选择资源", trigger: "change" },
],
ruleCode: [
{ required: true, message: "请选择维度", trigger: "change" },
],
ruleCondition: [
{ required: true, message: "请选择规则条件", trigger: "change" },
],
},
};
},
computed: {
Visible: {
get() {
return this.addVisible;
},
set(val) {
this.$emit("update:addVisible", val);
},
},
},
created() {
this.getDimensionList();
this.getResourceList();
},
methods: {
// 获取维度列表
async getDimensionList() {
let res = await getDimensionList({
page: 1,
size: -1,
});
if (res.data.code == 1) {
let { data } = res.data.data;
this.dimensionList = data;
}
},
// 获取资源列表
async getResourceList() {
let res = await getResourceList({
page: 1,
size: -1,
});
if (res.data.code == 1) {
let { data } = res.data.data;
this.resourceList = this.groupByAuth(data);
}
},
// 资源分组
groupByAuth(list) {
let group = {};
let groupList = [];
list.forEach((item) => {
let name = item.name.split("-")[0];
if (!group[name]) {
group[name] = {
indeterminate: false,
checkAll: false,
list: [],
};
}
group[name].list.push(item);
});
groupList = Object.keys(group).map((key) => {
return {
label: key,
value: key,
children: group[key].list.map((v) => {
return {
label: v.name,
value: v.id,
};
}),
};
});
return groupList;
},
// 选择资源
changeRes(val, selectedOptions) {
if (selectedOptions.length) {
this.form.resourceId = selectedOptions[1].value;
this.form.resourceName = selectedOptions[1].label;
} else {
this.form.resourceId = "";
this.form.resourceName = "";
}
},
// 选择维度
changeDim(val, e) {
if (val && e) {
let { dimensionName, dimensionType, dimensionValue } = e.data.attrs[
"dataset-row"
];
this.form.ruleName = dimensionName;
this.form.ruleType = dimensionType;
this.form.ruleValue = dimensionValue;
} else {
this.form.ruleName = "";
this.form.ruleType = "";
this.form.ruleValue = "";
}
},
// 新增
onAdd(roleInfo) {
Object.assign(this.form, this.$options.data().form);
this.form.id && this.$delete(this.form, "id");
this.form.roleId = roleInfo.id;
this.form.roleName = roleInfo.name;
},
// 编辑
onEdit(row) {
this.$nextTick(() => {
this.form = { ...row };
let resName = this.form.resourceName.split("-")[0];
this.resource = [resName, this.form.resourceId];
});
},
// 保存
handleOk() {
this.$refs.form.validate(async (valid) => {
if (valid) {
this.loading = true;
let res = await saveDimRes(this.form);
let { code, msg } = res.data;
this.loading = false;
if (code == 1) {
this.$message.success(msg);
this.$emit("addSuccess");
this.handleCancel();
}
}
});
},
// 重置
handleReset() {
this.$refs.form.resetFields();
this.form.ruleName = "";
this.form.ruleType = "";
this.form.ruleValue = "";
this.form.resourceId = "";
this.form.resourceName = "";
this.resource = [];
},
// 关闭
handleCancel() {
this.handleReset();
this.Visible = false;
},
},
};
</script>
<style lang="less" scoped></style>
<template>
<div>
<a-modal
:title="title"
:visible="Visible"
@cancel="handleCancel"
:maskClosable="false"
>
<a-button slot="footer" @click="handleReset">重置</a-button>
<a-button
slot="footer"
type="primary"
:loading="loading"
@click="handleOk"
>确定</a-button
>
<a-form-model
:model="form"
ref="form"
:rules="rules"
:label-col="{ span: 5 }"
:wrapper-col="{ span: 19 }"
>
<a-form-model-item label="名称" prop="name">
<a-input v-model="form.name" placeholder="请输入角色名称"></a-input>
</a-form-model-item>
<a-form-model-item label="备注" prop="remark">
<a-textarea
v-model="form.remark"
placeholder="请输入备注"
></a-textarea>
</a-form-model-item>
</a-form-model>
</a-modal>
</div>
</template>
<script>
import { saveRole } from "@/services/system";
export default {
components: {},
props: {
addVisible: {
required: true,
type: Boolean,
default: false,
},
title: {
required: true,
type: String,
default: "",
},
},
data() {
return {
loading: false,
form: {
name: "",
remark: "",
roleType: 2,
},
rules: {
name: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
},
};
},
computed: {
Visible: {
get() {
return this.addVisible;
},
set(val) {
this.$emit("update:addVisible", val);
},
},
},
created() {},
methods: {
// 新增
onAdd() {
Object.assign(this.form, this.$options.data().form);
this.form.id && this.$delete(this.form, "id");
},
// 编辑
onEdit(row) {
this.$nextTick(() => {
this.form = { ...row };
});
},
// 保存
handleOk() {
this.$refs.form.validate(async (valid) => {
if (valid) {
this.loading = true;
let res = await saveRole(this.form);
let { code, msg } = res.data;
this.loading = false;
if (code == 1) {
this.$message.success(msg);
this.$emit("addSuccess");
this.handleCancel();
}
}
});
},
// 重置
handleReset() {
this.$refs.form.resetFields();
},
// 关闭
handleCancel() {
this.$refs.form.resetFields();
this.Visible = false;
},
},
};
</script>
<style lang="less" scoped></style>
<template>
<div class="apportion-res">
<a-modal
title="分配资源"
:centered="true"
:visible="Visible"
@cancel="handleCancel"
width="40%"
:maskClosable="false"
>
<div class="mb10" v-for="(v, key) in resourceList" :key="key">
<div class="mb10" :style="{ borderBottom: '1px solid #E9E9E9' }">
<span class="title">{{ key }}</span>
<a-checkbox
:indeterminate="v.indeterminate"
:checked="v.checkAll"
@change="onCheckAllChange($event, v)"
>
全选
</a-checkbox>
</div>
<a-checkbox-group
style="width:100%"
: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,
saveRoleResource,
} from "@/services/system";
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.data.code == 1) {
let { data } = res.data.data;
this.resourceList = this.groupByAuth(data);
}
},
// 获取角色资源权限列表
async getRoleResourceList(roleId) {
let res = await getRoleResourceList({
size: -1,
page: 1,
roleId,
});
if (res.data.code == 1) {
let { data } = res.data.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 saveRoleResource(this.form);
if (res.data.code == 1) {
this.$message.success("添加成功");
this.handleCancel();
}
},
resetForm() {
this.form.resourceIdList = [];
Object.keys(this.resourceList).forEach((key) => {
this.resourceList[key].checkAll = false;
this.resourceList[key].indeterminate = false;
});
// 重置还原表单信息内容
// 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;
}
.title {
margin-right: 1em;
font-size: 18px;
font-weight: bold;
}
</style>
<template>
<div>
<a-drawer
title="资源规则"
:visible="Visible"
@close="onClose"
:maskClosable="false"
:destroyOnClose="true"
width="50%"
>
<div class="mb10">
角色名称:<span class="primary">{{ roleInfo.name }}</span>
</div>
<div class="search-box flex aic jcb mb20">
<div>
<a-space>
<a-button type="primary" @click="handleAdd"> 新增 </a-button>
<a-button type="danger" @click="handleDelAll"> 批量删除 </a-button>
</a-space>
</div>
<a-input-search
style="width: 300px"
placeholder="请输入维度名称搜索"
enter-button="搜索"
v-model="searchVal"
allowClear
@search="onSearch"
/>
</div>
<!-- 表格 -->
<div class="table-content">
<a-table
:row-selection="{
selectedRowKeys: selectedRowKeys,
onChange: onSelectChange,
}"
size="small"
:loading="loading"
bordered
:scroll="{ y: 460 }"
:columns="columns"
:pagination="{
showTotal: (total) => `共 ${total} 条`,
current: current,
total: total,
pageSize: size,
showSizeChanger: true,
showQuickJumper: true,
pageSizeOptions: pageSizeOptions,
onChange: handleChange,
onShowSizeChange: showSizeChange,
}"
:data-source="tableData"
:rowKey="(record) => record.id"
>
<!-- 序号 -->
<span slot="num" slot-scope="text, record, index">{{
(current - 1) * size + index + 1
}}</span>
<!-- 操作 -->
<template slot="action" slot-scope="text">
<a-space>
<a href="javascript:;" class="edit" @click="handleEdit(text)"
>编辑</a
>
<a href="javascript:;" class="delete" @click="handleDel(text.id)"
>删除</a
>
</a-space>
</template>
</a-table>
</div>
<AddResDim
ref="AddResDim"
:addVisible.sync="addVisible"
:title="title"
:dict="dict"
@addSuccess="getDimResList"
></AddResDim>
</a-drawer>
</div>
</template>
<script>
import { pageSizeOptions } from "@/config/pageConfig.js";
import { getDimResList, delDimRes } from "@/services/system";
import AddResDim from "./AddResDim.vue";
export default {
props: {
visible: {
type: Boolean,
require: true,
default: false,
},
},
components: { AddResDim },
data() {
const columns = [
{
title: "序号",
dataIndex: "num",
width: "65px",
scopedSlots: {
customRender: "num",
},
},
{
title: "维度名称",
dataIndex: "ruleName",
},
{
title: "维度编码",
dataIndex: "ruleCode",
},
{
title: "维度类型",
dataIndex: "ruleType",
},
{
title: "维度值",
dataIndex: "ruleValue",
},
{
title: "所属资源",
dataIndex: "resourceName",
},
{
title: "规则条件",
dataIndex: "ruleCondition",
customRender: (text) => {
return this.dict.ruleCondition[text];
},
},
{
title: "创建时间",
dataIndex: "createTime",
customRender: (text) => {
return this.$moment(text).format("YYYY-MM-DD HH:mm:ss");
},
},
{
title: "操作",
width: "100px",
scopedSlots: { customRender: "action" },
},
];
return {
columns,
roleInfo: {}, // 模块信息
loading: false,
total: 0,
size: 10,
current: 1,
pageSizeOptions,
selectedRowKeys: [],
tableData: [],
addVisible: false,
title: "新增",
searchVal: "",
dict: {}, // 字典
};
},
computed: {
Visible: {
get() {
return this.visible;
},
set(val) {
this.$emit("update:visible", val);
},
},
},
methods: {
// 获取模块信息
getRoleInfo(roleInfo) {
this.roleInfo = roleInfo;
this.getDimResList();
},
// 获取列表
async getDimResList() {
this.loading = true;
let res = await getDimResList({
current: this.current,
size: this.size,
roleId: this.roleInfo.id,
ruleName: `%${this.searchVal}%`,
});
this.loading = false;
if (res.data.code == 1) {
let { data, total, dict } = res.data.data;
this.total = total;
this.tableData = data;
this.dict = dict;
}
},
handleAdd() {
this.title = "新增";
this.addVisible = true;
this.$refs.AddResDim.onAdd(this.roleInfo);
},
handleDelAll() {
if (!this.selectedRowKeys.length) {
this.$message.warning("请先勾选数据");
return;
}
let ids = this.selectedRowKeys.join(",");
this.handleDel(ids);
},
// 关闭抽屉
onClose() {
this.searchVal = "";
this.selectedRowKeys = [];
this.Visible = false;
},
// 搜索
onSearch() {
this.current = 1;
this.getDimResList();
},
// 编辑
handleEdit(row) {
this.title = "编辑";
this.addVisible = true;
this.$refs.AddResDim.onEdit(row);
},
// 翻页
handleChange(cur) {
this.current = cur;
this.getDimResList();
},
// 改变每页显示数量
showSizeChange(current, size) {
this.current = current;
this.size = size;
this.getDimResList();
},
// 删除
handleDel(id) {
let _this = this;
this.$confirm({
title: "系统提示",
content: "删除不可恢复,确定要删除吗?",
okText: "确定",
okType: "danger",
cancelText: "取消",
centered: true,
icon: "exclamation-circle",
maskClosable: true,
async onOk() {
let res = await delDimRes({ id });
if (res.data.code == 1) {
_this.$message.success(res.data.msg);
_this.getDimResList();
}
},
});
},
// 选中
onSelectChange(keys) {
this.selectedRowKeys = keys;
},
},
};
</script>
<style lang="less" scoped></style>
<template>
<div class="user-container">
<div class="control flex aic jcb mb15 pdr6">
<div>
<!-- <a-button type="primary" style="margin-right: 10px" @click="handleAdd"
>新增</a-button
>
<a-button type="danger" @click="handleDelAll">批量删除</a-button> -->
</div>
<div class="search-box">
<a-space>
<a-input
placeholder="请输入登录名搜索"
v-model="searchForm.loginName"
allowClear
/>
<a-input
placeholder="请输入用户姓名搜索"
v-model="searchForm.realName"
allowClear
/>
<a-button type="primary" @click="onSearch">搜索</a-button>
<a-button @click="resetSearch">重置</a-button>
</a-space>
</div>
</div>
<!-- 表格 -->
<div class="table-content">
<a-table
:loading="loading"
bordered
:scroll="{ y: 590 }"
:columns="columns"
:pagination="{
showTotal: (total) => `共 ${total} 条`,
current: current,
total: total,
pageSize: size,
showSizeChanger: true,
showQuickJumper: true,
pageSizeOptions: pageSizeOptions,
onChange: handleChange,
onShowSizeChange: showSizeChange,
}"
:data-source="tableData"
:rowKey="(record) => record.id"
>
<!-- 序号 -->
<span slot="num" slot-scope="text, record, index">{{
(current - 1) * size + index + 1
}}</span>
<!-- 操作 -->
<template slot="action" slot-scope="text">
<a-space size="middle">
<span class="primary pointer" @click="changeRole(text)"
>分配角色</span
>
</a-space>
</template>
</a-table>
</div>
<!-- 分配角色 -->
<AddUserRole
ref="AddUserRole"
:addVisible.sync="addVisible"
@addSuccess="getUserList"
></AddUserRole>
</div>
</template>
<script>
import { getUserList } from "@/services/system";
import { pageSizeOptions } from "@/config/pageConfig.js";
import AddUserRole from "./modal/AddUserRole.vue";
import { mapState } from "vuex";
export default {
components: { AddUserRole },
data() {
const columns = [
{
title: "序号",
dataIndex: "num",
width: "65px",
scopedSlots: {
customRender: "num",
},
},
{
title: "登录名",
dataIndex: "loginName",
},
{
title: "用户姓名",
dataIndex: "realName",
},
{
title: "所属角色",
dataIndex: "roleIds",
customRender: (text) => {
if (text && this.dict.roleIds) {
return <a-tag>{this.dict.roleIds[text]}</a-tag>;
}
},
},
{
title: "状态",
dataIndex: "status",
customRender: (text) => {
return <a-tag>{this.dict.status[text]}</a-tag>;
},
},
{
title: "操作",
width: "120px",
scopedSlots: { customRender: "action" },
},
];
return {
columns,
loading: false,
current: 1,
size: 10,
total: 0,
pageSizeOptions,
searchForm: {
loginName: "",
realName: "",
},
tableData: [],
selectedRowKeys: [],
dict: {}, // 字典
addVisible: false,
title: "新增",
loginNames: ["admin", "administrator1", "Administrator"],
};
},
computed: {
...mapState("site", ["userInfo"]),
},
created() {
this.getUserList();
},
methods: {
// 获取用户列表
async getUserList() {
this.loading = true;
let res = await getUserList({
page: this.current,
size: this.size,
...this.searchForm,
});
this.loading = false;
if (res.data.code == 1) {
let { data, total, dict } = res.data.data;
let { name } = this.userInfo;
if (this.loginNames.includes(name)) {
this.tableData = data;
this.total = total;
} else {
this.tableData = data.filter((v) => {
return !this.loginNames.includes(v.loginName);
});
this.total = total - this.loginNames.length;
}
this.dict = dict;
}
},
// 新增
handleAdd() {
this.title = "新增";
this.$refs.AddParameter.onAdd();
this.addVisible = true;
},
// 搜索
onSearch() {
this.current = 1;
this.getUserList();
},
resetSearch() {
this.current = 1;
Object.assign(this.searchForm, this.$options.data().searchForm);
this.getUserList();
},
// 分页
handleChange(num) {
this.current = num;
this.getUserList();
},
// 改变每页显示数量
showSizeChange(current, size) {
this.current = current;
this.size = size;
this.getUserList();
},
// 分配角色
changeRole(row) {
this.$refs.AddUserRole.onEdit(row);
this.addVisible = true;
},
},
};
</script>
<style lang="less" scoped>
.user-container {
width: 100%;
height: 100%;
}
</style>
<template>
<div>
<a-modal
title="分配角色"
:visible="Visible"
@cancel="handleCancel"
:maskClosable="false"
>
<a-button slot="footer" @click="handleReset">重置</a-button>
<a-button
slot="footer"
type="primary"
:loading="loading"
@click="handleOk"
>确定</a-button
>
<a-form-model
:model="form"
ref="form"
:rules="rules"
:label-col="{ span: 5 }"
:wrapper-col="{ span: 19 }"
>
<a-form-model-item label="选择角色" prop="roleIds">
<a-select
mode="multiple"
v-model="form.roleIds"
placeholder="请选择角色"
>
<a-select-option v-for="v in roleList" :key="v.id" :value="v.id">{{
v.name
}}</a-select-option>
</a-select>
</a-form-model-item>
</a-form-model>
</a-modal>
</div>
</template>
<script>
import { getRoleList, saveUser } from "@/services/system";
export default {
components: {},
props: {
addVisible: {
required: true,
type: Boolean,
default: false,
},
},
data() {
return {
loading: false,
form: {
roleIds: [],
},
roleList: [],
rules: {
roleIds: [{ required: true, message: "请选择角色", trigger: "change" }],
},
};
},
computed: {
Visible: {
get() {
return this.addVisible;
},
set(val) {
this.$emit("update:addVisible", val);
},
},
},
created() {
this.getRoleList();
},
methods: {
// 获取角色列表
async getRoleList() {
let res = await getRoleList({
page: 1,
size: -1,
});
if (res.data.code == 1) {
let { data } = res.data.data;
this.roleList = data;
}
},
// 新增
onAdd() {
Object.assign(this.form, this.$options.data().form);
this.form.id && this.$delete(this.form, "id");
},
// 编辑
onEdit(row) {
this.$nextTick(() => {
this.form = { ...row };
if (this.form.roleIds) {
this.form.roleIds = this.form.roleIds.split(",");
} else {
this.form.roleIds = [];
}
});
},
// 保存
handleOk() {
this.$refs.form.validate(async (valid) => {
if (valid) {
this.loading = true;
let { id, roleIds, lastLoginAddress, mobile } = this.form;
let res = await saveUser({
id,
lastLoginAddress,
mobile,
roleIds: roleIds.join(","),
});
this.loading = false;
let { code, msg } = res.data;
if (code == 1) {
this.$message.success(msg);
this.$emit("addSuccess");
this.handleCancel();
}
}
});
},
// 重置
handleReset() {
this.$refs.form.resetFields();
},
// 关闭
handleCancel() {
this.$refs.form.resetFields();
this.Visible = false;
},
},
};
</script>
<style lang="less" scoped></style>
......@@ -385,7 +385,6 @@ export default {
};
return {
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
accept: "image/jpeg,image/png", // 上传类型
fileList: [],
loading: false,
......@@ -541,8 +540,7 @@ export default {
uid: -1,
status: "done",
name: this.form.photoPath,
url: this.api2 + this.form.photoPath,
url2: this.form.photoPath,
url: this.form.photoPath,
},
];
}
......@@ -564,17 +562,25 @@ export default {
this.$refs.formData.resetFields();
},
// 照片上传
handleChange({ fileList }) {
handleChange({ file, fileList }) {
if (
file.status &&
file.status != "removed" &&
file.response &&
file.response.code == -1
) {
this.$message.error(file.response.msg);
fileList = fileList.filter((file) => file.response.code != -1);
}
this.fileList = [...fileList].slice(-1);
this.fileList = this.fileList.map((v) => {
if (v.response) {
v.url2 = v.response.url;
v.url = this.api2 + v.response.url;
v.url = v.response.url;
}
return v;
});
if (this.fileList[0]) {
this.form.photoPath = this.fileList[0].url2;
this.form.photoPath = this.fileList[0].url;
} else {
this.form.photoPath = "";
}
......
......@@ -582,8 +582,7 @@ export default {
uid: -1,
status: "done",
name: this.form.photoPath,
url: this.api2 + this.form.photoPath,
url2: this.form.photoPath,
url: this.form.photoPath,
},
];
}
......@@ -599,17 +598,25 @@ export default {
},
// 照片上传
handleChange({ fileList }) {
handleChange({ file, fileList }) {
if (
file.status &&
file.status != "removed" &&
file.response &&
file.response.code == -1
) {
this.$message.error(file.response.msg);
fileList = fileList.filter((file) => file.response.code != -1);
}
this.fileList = [...fileList].slice(-1);
this.fileList = this.fileList.map((v) => {
if (v.response) {
v.url2 = v.response.url;
v.url = this.api2 + v.response.url;
v.url = v.response.url;
}
return v;
});
if (this.fileList[0]) {
this.form.photoPath = this.fileList[0].url2;
this.form.photoPath = this.fileList[0].url;
} else {
this.form.photoPath = "";
}
......
......@@ -228,8 +228,8 @@
<template slot="pic" slot-scope="text">
<img
v-if="text.photoPath"
:src="api2 + text.photoPath"
@click="handlePreview(api2 + text.photoPath)"
:src="text.photoPath"
@click="handlePreview(text.photoPath)"
class="pht"
/>
......@@ -408,7 +408,6 @@ export default {
visibleEditPwd: false,
editVisible: false,
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
siteId: local.getLocal("siteId"),
deptData: [], // 部门数据
windowData: [], // 窗口数据
......
......@@ -306,8 +306,34 @@ const options = {
meta: {
icon: "global",
},
redirect: "system/parameter",
redirect: "system/user",
children: [
{
path: "user",
name: "用户管理",
component: () => import("@/pages/basicset/system/user/User"),
meta: { invisible: true },
},
{
path: "role",
name: "角色管理",
component: () => import("@/pages/basicset/system/role/Role"),
meta: { invisible: true },
},
{
path: "resource",
name: "资源管理",
component: () =>
import("@/pages/basicset/system/resourceManage/Resource"),
meta: { invisible: true },
},
{
path: "dimension",
name: "维度管理",
component: () =>
import("@/pages/basicset/system/dimension/Dimension"),
meta: { invisible: true },
},
{
path: "parameter",
name: "系统参数",
......
......@@ -349,6 +349,44 @@ module.exports = {
save: `${BASE_URL}/base/task/save`,
delete: `${BASE_URL}/base/task/delete`,
},
// 维度
dimension: {
list: `${BASE_URL}/base/dimension/list`,
info: `${BASE_URL}/base/dimension/info`,
save: `${BASE_URL}/base/dimension/save`,
delete: `${BASE_URL}/base/dimension/delete`,
},
// 角色资源维度
dimensionResource: {
list: `${BASE_URL}/base/dimension/resource/rule/list`,
info: `${BASE_URL}/base/dimension/resource/rule/info`,
save: `${BASE_URL}/base/dimension/resource/rule/save`,
delete: `${BASE_URL}/base/dimension/resource/rule/delete`,
},
// 用户
user: {
list: `${BASE_URL}/base/user/list`,
info: `${BASE_URL}/base/user/info`,
save: `${BASE_URL}/base/user/save`,
delete: `${BASE_URL}/base/user/delete`,
},
// 角色
role: {
list: `${BASE_URL}/base/role/list`,
info: `${BASE_URL}/base/role/info`,
save: `${BASE_URL}/base/role/save`,
delete: `${BASE_URL}/base/role/delete`,
authList: `${BASE_URL}/base/role/auth/list`,
distributionSource: `${BASE_URL}/base/role/auth/distributionSource`,
},
// 资源
resource: {
list: `${BASE_URL}/base/resource/list`,
info: `${BASE_URL}/base/resource/info`,
save: `${BASE_URL}/base/resource/save`,
delete: `${BASE_URL}/base/resource/delete`,
refreshUrl: `${BASE_URL}/base/resource/refreshUrl`,
},
},
// 站点大厅
hall: {
......
import userService from './user'
import userService from "./user";
export {
userService
import { upload } from "@/services/basicsetApi";
import { request, METHOD } from "@/utils/request";
// 上传文件
export async function uploadFile(data) {
return request(upload.file, METHOD.POST, data);
}
export { userService };
......@@ -46,3 +46,112 @@ export async function saveSystemTask(data) {
export async function delSystemTask(data) {
return request(system.task.delete, METHOD.GET, data);
}
/*
* 用户管理
*/
// 获取用户列表
export async function getUserList(data) {
return request(system.user.list, METHOD.POST, data);
}
// 获取用户信息
export async function getUserInfo(data) {
return request(system.user.info, METHOD.GET, data);
}
// 保存用户信息
export async function saveUser(data) {
return request(system.user.save, METHOD.POST, data);
}
// 删除用户信息
export async function delUser(data) {
return request(system.user.delete, METHOD.GET, data);
}
/*
* 角色管理
*/
// 获取角色列表
export async function getRoleList(data) {
return request(system.role.list, METHOD.POST, data);
}
// 获取角色信息
export async function getRoleInfo(data) {
return request(system.role.info, METHOD.GET, data);
}
// 保存角色信息
export async function saveRole(data) {
return request(system.role.save, METHOD.POST, data);
}
// 删除角色信息
export async function delRole(data) {
return request(system.role.delete, METHOD.GET, data);
}
// 获取角色资源列表
export async function getRoleResourceList(data) {
return request(system.role.authList, METHOD.POST, data);
}
// 保存角色资源信息
export async function saveRoleResource(data) {
return request(system.role.distributionSource, METHOD.POST, data);
}
/*
* 资源管理
*/
// 获取资源列表
export async function getResourceList(data) {
return request(system.resource.list, METHOD.POST, data);
}
// 获取资源信息
export async function getResourceInfo(data) {
return request(system.resource.info, METHOD.GET, data);
}
// 保存资源信息
export async function saveResource(data) {
return request(system.resource.save, METHOD.POST, data);
}
// 删除资源信息
export async function delResource(data) {
return request(system.resource.delete, METHOD.GET, data);
}
// 刷新资源
export async function refreshResource(data) {
return request(system.resource.refreshUrl, METHOD.POST, data);
}
/*
* 维度管理
*/
// 获取维度列表
export async function getDimensionList(data) {
return request(system.dimension.list, METHOD.POST, data);
}
// 获取维度信息
export async function getDimensionInfo(data) {
return request(system.dimension.info, METHOD.GET, data);
}
// 保存维度信息
export async function saveDimension(data) {
return request(system.dimension.save, METHOD.POST, data);
}
// 删除维度信息
export async function delDimension(data) {
return request(system.dimension.delete, METHOD.GET, data);
}
// 获取角色资源维度列表
export async function getDimResList(data) {
return request(system.dimensionResource.list, METHOD.POST, data);
}
// 获取角色资源维度信息
export async function getDimResInfo(data) {
return request(system.dimensionResource.info, METHOD.GET, data);
}
// 保存角色资源维度信息
export async function saveDimRes(data) {
return request(system.dimensionResource.save, METHOD.POST, data);
}
// 删除角色资源维度信息
export async function delDimRes(data) {
return request(system.dimensionResource.delete, METHOD.GET, data);
}
......@@ -49,6 +49,11 @@ module.exports = {
},
// cookieDomainRewrite: 'localhost',
},
"/file": {
//此处要与 /services/api.js 中的 API_PROXY_PREFIX 值保持一致
target: process.env.VUE_APP_API_BASE_URL,
changeOrigin: true,
},
},
},
pluginOptions: {
......
This diff is collapsed.
......@@ -348,5 +348,6 @@ PRIMARY KEY (`id`)
ALTER TABLE mortals_sys_dept ADD COLUMN `inNum` int(9) DEFAULT '0' COMMENT '入驻事项数量' AFTER updateTime;
INSERT INTO mortals_xhx_task VALUES (null, '同步全部站点事项材料附件', 'SyncMatterDaumFileTask', 0, 'SyncMatterDaumFileTask', '', '', 1, 3600, '16:05', '', '192.168.1.107', '2024-05-18 16:05:00', 0, '2024-03-01 10:59:53', 1, '系统管理员');
-- ----------------------------
-- 数据授权权限表
-- ----------------------------
DROP TABLE IF EXISTS `mortals_xhx_dimension`;
CREATE TABLE `mortals_xhx_dimension` (
`id` bigint(20) AUTO_INCREMENT COMMENT '序号,主键,自增长',
`dimension_code` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '维度编码',
`dimension_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '维度名称',
`dimension_value` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '维度值',
`dimension_type` tinyint(2) DEFAULT '1' COMMENT '维度类型(1.固定值,2.系统上下问变量)',
`createTime` datetime COMMENT '创建时间',
`createUserId` bigint(20) COMMENT '创建用户',
`updateUserId` bigint(20) COMMENT '更新用户',
`updateTime` datetime COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=DYNAMIC COMMENT='授权维度';
-- ----------------------------
-- 角色资源授权规则表
-- ----------------------------
DROP TABLE IF EXISTS `mortals_xhx_dimension_resource_rule`;
CREATE TABLE `mortals_xhx_dimension_resource_rule` (
`id` bigint(20) AUTO_INCREMENT COMMENT '序号,主键,自增长',
`role_id` bigint(20) DEFAULT NULL COMMENT '角色ID',
`role_name` varchar(64) DEFAULT NULL COMMENT '角色名称',
`resource_id` bigint(20) DEFAULT NULL COMMENT '资源ID',
`resource_name` varchar(64) DEFAULT NULL COMMENT '资源名称',
`rule_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '规则编码',
`rule_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '规则名称',
`rule_condition` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT 'IN' COMMENT '规则条件(IN.属于,<.小于,>.大于,=.等于,!=.不等于,>=.大于等于,<=.小于等于,like %.左模糊,like %.右模糊)',
`rule_value` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '规则值,固定值或者系统变量',
`rule_type` tinyint(2) DEFAULT '1' COMMENT '规则值类型(1.固定值,2.系统上下问变量)',
`create_time` datetime COMMENT '创建时间',
`create_user_id` bigint(20) COMMENT '创建用户',
`update_user_id` bigint(20) COMMENT '更新用户',
`update_time` datetime COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=DYNAMIC COMMENT='角色资源维度规则表';
This diff is collapsed.
package com.mortals.xhx.annotation;
import java.lang.annotation.*;
/**
*
* @author: zxfei
* @date: 2024/5/15 16:09
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
public @interface DataPermission {
/**
* 数据权限类型
* 1 上下级授权 2 数据范围授权
*/
String permissionType() default "2";
/**
* 配置菜单的组件路径,用于数据权限
*/
String componentRoute() default "";
}
package com.mortals.xhx.base.framework.aspect;
import com.mortals.framework.service.IAuthTokenService;
import com.mortals.framework.service.IUser;
import com.mortals.xhx.annotation.DataPermission;
import com.mortals.xhx.common.utils.RuleQueryGenerator;
import com.mortals.xhx.module.dimension.model.DimensionResourceRuleEntity;
import com.mortals.xhx.module.dimension.service.DimensionResourceRuleService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.List;
@Aspect
@Slf4j
//@Component
public class DataPermissionAspect {
@Autowired
private DimensionResourceRuleService dimensionResourceRuleService;
@Autowired
private IAuthTokenService authTokenService;
public static final String DATA_PERMISSION_SEARCH_SQL = "DATA_PERMISSION_SEARCH_SQL";
@Pointcut("@annotation(com.mortals.xhx.annotation.DataPermission)")
public void pointCut() {
}
@Around("pointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String componentRoute = request.getServletPath();
IUser loginUser = authTokenService.getLoginUser(request);
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
DataPermission permissionData = method.getAnnotation(DataPermission.class);
if (!ObjectUtils.isEmpty(permissionData)&&!ObjectUtils.isEmpty(componentRoute)) {
//获取授权方式
String permissionType = permissionData.permissionType();
//获取组件路由 通过controller 获取
// String componentRoute = permissionData.componentRoute();
// 查找当前用户此资源路径下的所有规则
List<DimensionResourceRuleEntity> componentRules = dimensionResourceRuleService.getRoleComponentRule(loginUser.getId(), componentRoute);
if (!ObjectUtils.isEmpty(componentRules)) {
//在request添加属性
//todo 构建数据权限sql 并设置到request中。
String permissionSql = RuleQueryGenerator.getPermissionSql(componentRules, loginUser);
log.info("permissionSql:{}", permissionSql);
request.setAttribute(DATA_PERMISSION_SEARCH_SQL, permissionSql);
}
}
return point.proceed();
}
}
......@@ -20,6 +20,7 @@ import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
......@@ -44,6 +45,7 @@ import java.util.Set;
public class AuthTokenServiceImpl implements IAuthTokenService {
@Autowired
@Lazy
private UserService userService;
// 令牌自定义标识
......
......@@ -32,6 +32,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -61,7 +62,6 @@ public class LoginController extends BaseCRUDJsonBodyMappingController<UserServi
@Autowired
private IUserFeign userFeign;
private static Log logger = LogFactory.getLog(LoginController.class);
@RequestMapping("login")
public String login(@RequestBody LoginForm loginForm) throws Exception {
......
......@@ -25,6 +25,7 @@ import com.mortals.xhx.base.system.role.service.RoleAuthService;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.common.utils.ControllerScanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
......@@ -49,6 +50,7 @@ public class ResourceServiceImpl extends AbstractCRUDServiceImpl<ResourceDao, Re
private ICacheService cacheService;
@Autowired
@Lazy
private RoleAuthService roleAuthService;
@Override
......
......@@ -7,7 +7,6 @@ import com.mortals.framework.common.code.UserType;
import com.mortals.framework.model.Context;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.framework.web.BasePhpCRUDJsonMappingController;
import com.mortals.xhx.base.system.role.model.RoleQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
......
......@@ -58,6 +58,10 @@ public class UploadServiceImpl implements UploadService {
throw new AppException("文件上传大小超过限制!");
}
if (null != fileName && fileName.length() > 50) {
throw new AppException("文件名称过长,无法上传!");
}
String rootPath = this.filePath.endsWith("/") ? this.filePath : this.filePath + "/";
String filePath = rootPath + (StringUtils.isEmpty(prePath) ? "" : prePath + "/");
......@@ -170,4 +174,14 @@ public class UploadServiceImpl implements UploadService {
}
}
public static void main(String[] args) {
String fileName="好.txt";
System.out.println(fileName.length());
}
}
\ No newline at end of file
......@@ -77,6 +77,7 @@ public class UserServiceImpl extends AbstractCRUDCacheServiceImpl<UserDao, UserE
@Autowired
private RoleUserService roleUserService;
@Autowired
@Lazy
private SiteService siteService;
@Lazy
......@@ -122,6 +123,29 @@ public class UserServiceImpl extends AbstractCRUDCacheServiceImpl<UserDao, UserE
this.doHandlerUser(entity);
}
@Override
protected void saveAfter(UserEntity entity, Context context) throws AppException {
//新增角色
updateUserRole(entity);
super.saveAfter(entity, context);
}
@Override
protected void updateAfter(UserEntity entity, Context context) throws AppException {
updateUserRole(entity);
super.updateAfter(entity, context);
}
private void updateUserRole(UserEntity entity) {
if (!ObjectUtils.isEmpty(entity.getId()) && entity.getId().longValue() != SysConstains.ADMIN_ID && !ObjectUtils.isEmpty(entity.getRoleIds())) {
RoleUserQuery roleUserQuery = new RoleUserQuery();
roleUserQuery.setUserId(entity.getId());
List<Long> idList = Arrays.asList(entity.getRoleIds().split(",")).stream().map(Long::parseLong).collect(Collectors.toList());
roleUserQuery.setRoleIdList(idList);
roleUserService.doDistributionRole(roleUserQuery);
}
}
@Override
protected UserEntity findBefore(UserEntity params, Context context) throws AppException {
// if (StringUtils.isNotEmpty(params.getDeptIds())) {
......
......@@ -17,6 +17,7 @@ import com.mortals.xhx.common.code.UserStatus;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
......@@ -58,13 +59,13 @@ public class UserController extends BaseCRUDJsonBodyMappingController<UserServic
}
}
@Override
/* @Override
protected void saveBefore(UserEntity entity, Map<String, Object> model, Context context) throws AppException {
if (service.existUser(entity.getLoginName(), entity.getId())) {
if (!ObjectUtils.isEmpty(entity.getLoginName())&&service.existUser(entity.getLoginName(), entity.getId())) {
throw new AppException("登录名已存在!");
}
super.saveBefore(entity, model, context);
}
}*/
@RequestMapping(value = "change/password", method = RequestMethod.POST)
......
......@@ -9,6 +9,10 @@ import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.ParamDto;
import com.mortals.framework.model.Result;
import com.mortals.xhx.common.code.SourceEnum;
import com.mortals.xhx.module.app.model.AppDatasetEntity;
import com.mortals.xhx.module.app.model.AppDatasetQuery;
import com.mortals.xhx.module.app.service.AppDatasetService;
import com.mortals.xhx.module.app.service.AppInfoFieldService;
import com.mortals.xhx.module.business.model.BusinessMatterEntity;
import com.mortals.xhx.module.business.model.BusinessMatterQuery;
import com.mortals.xhx.module.business.service.BusinessMatterService;
......@@ -41,10 +45,7 @@ import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -74,13 +75,13 @@ public class DemoWebApiController {
@Autowired
private MatterService matterService;
@Autowired
private SiteThemeService siteThemeService;
@Autowired
private SiteThemeMatterService siteThemeMatterService;
@Autowired
private BusinessMatterService businessMatterService;
@Autowired
private AppDatasetService appDatasetService;
@Autowired
private AppInfoFieldService appInfoFieldService;
@PostMapping(value = "testGov")
......@@ -327,7 +328,7 @@ public class DemoWebApiController {
public Rest<String> limit() {
log.info("limit in");
try {
String tableName="mortals_sys_area";
String tableName = "mortals_sys_area";
//CacheDataUtil.getInstance().getBaseData()
return Rest.ok();
......@@ -338,6 +339,33 @@ public class DemoWebApiController {
}
@GetMapping(value = "genApp")
@UnAuth
public Rest<String> genApp() {
try {
AppDatasetQuery appDatasetQuery = new AppDatasetQuery();
appDatasetQuery.setAppId(304L);
List<AppDatasetEntity> appDatasetEntities = appDatasetService.find(appDatasetQuery);
StringBuilder sb = new StringBuilder();
for (AppDatasetEntity appDatasetEntity : appDatasetEntities) {
sb.append(String.format("INSERT INTO `mortals_sys_app_info_field`(`id`, `datasetId`, `fieldCode`, `fieldName`, `fieldType`, `fieldTypeValue`, `dataType`, `fieldValue`, `defaultValue`, `fieldLen`, `fieldNull`, `isList`, `fieldOrderNo`, `remark`, `createTime`, `createUserId`, `updateTime`, `updateUserId`, `serviceApi`, `serviceApiParams`) VALUES (null, %s, 'name', '政策全称', 'input', '', 'string', '', '', 128, 0, 1, 99, '', '2024-05-29 17:55:38', 1, '2024-05-29 17:55:38', 1, '', '');", appDatasetEntity.getId()));
sb.append("\n");
}
log.info("sql:{}",sb.toString());
//INSERT INTO `mortals_sys_app_info_field`(`id`, `datasetId`, `fieldCode`, `fieldName`, `fieldType`, `fieldTypeValue`, `dataType`, `fieldValue`, `defaultValue`, `fieldLen`, `fieldNull`, `isList`, `fieldOrderNo`, `remark`, `createTime`, `createUserId`, `updateTime`, `updateUserId`, `serviceApi`, `serviceApiParams`) VALUES (null, 755, 'name', '政策全称', 'input', '', 'string', '', '', 128, 0, 1, 99, '', '2024-05-29 17:55:38', 1, '2024-05-29 17:55:38', 1, '', '');
return Rest.ok();
} catch (Exception e) {
log.error("异常:", e.getMessage());
return Rest.fail(e.getMessage());
}
}
public static void main(String[] args) {
System.out.println(1001 / 500);
......
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 维度类型(1.固定值,2.系统上下问变量)枚举类
*
* @author zxfei
*/
public enum DimensionTypeEnum {
固定值(1, "固定值"),
系统上下问变量(2, "系统上下问变量");
private Integer value;
private String desc;
DimensionTypeEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
public Integer getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static DimensionTypeEnum getByValue(Integer value) {
for (DimensionTypeEnum dimensionTypeEnum : DimensionTypeEnum.values()) {
if (dimensionTypeEnum.getValue() == value) {
return dimensionTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(Integer... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (DimensionTypeEnum item : DimensionTypeEnum.values()) {
try {
boolean hasE = false;
for (Integer e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 规则条件(IN.属于,<.小于,>.大于,=.等于,!=.不等于,>=.大于等于,<=.小于等于,like %.左模糊,like %.右模糊)枚举类
*
* @author zxfei
*/
public enum RuleConditionEnum {
属于("IN", "属于"),
小于("<", "小于"),
大于(">", "大于"),
等于("=", "等于"),
不等于("!=", "不等于"),
大于等于(">=", "大于等于"),
小于等于("<=", "小于等于"),
左模糊("like %", "左模糊"),
右模糊("like %", "右模糊");
private String value;
private String desc;
RuleConditionEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static RuleConditionEnum getByValue(String value) {
for (RuleConditionEnum ruleConditionEnum : RuleConditionEnum.values()) {
if (ruleConditionEnum.getValue() == value) {
return ruleConditionEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(String... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (RuleConditionEnum item : RuleConditionEnum.values()) {
try {
boolean hasE = false;
for (String e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 规则值类型(1.固定值,2.系统上下问变量)枚举类
*
* @author zxfei
*/
public enum RuleTypeEnum {
固定值(1, "固定值"),
系统上下问变量(2, "系统上下问变量");
private Integer value;
private String desc;
RuleTypeEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
public Integer getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static RuleTypeEnum getByValue(Integer value) {
for (RuleTypeEnum ruleTypeEnum : RuleTypeEnum.values()) {
if (ruleTypeEnum.getValue() == value) {
return ruleTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(Integer... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (RuleTypeEnum item : RuleTypeEnum.values()) {
try {
boolean hasE = false;
for (Integer e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.utils;
import com.mortals.framework.service.IUser;
import com.mortals.xhx.module.dimension.model.DimensionResourceRuleEntity;
import org.apache.commons.compress.utils.Lists;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
public class DataPermissionUtils {
public static final String COMPONENT_DATA_RULES = "COMPONENT_DATA_RULES";
public static final String SYS_USER_INFO = "SYS_USER_INFO";
/**
* 往链接请求里面,传入数据查询条件
*
* @param request
* @param componentRules
*/
public static void installDataSearchConditon(HttpServletRequest request, List<DimensionResourceRuleEntity> componentRules) {
// 1.先从request获取MENU_DATA_AUTHOR_RULES,如果存则获取到LIST
List<DimensionResourceRuleEntity> list = loadDataSearchCondition(request);
if (list == null) {
// 2.如果不存在,则new一个list
list = Lists.newArrayList();
}
list.addAll(componentRules);
// 3.往list里面增量存指
request.setAttribute(COMPONENT_DATA_RULES, list);
}
/**
* 往链接请求里面,传入数据查询条件
*
* @param request
* @param searchSql
*/
public static void installSearchSql(HttpServletRequest request,String searchSql) {
// 1.先从request获取MENU_DATA_AUTHOR_RULES,如果存则获取到LIST
// 3.往list里面增量存指
// request.setAttribute(DATA_PERMISSION_SEARCH_SQL, searchSql);
}
/**
* 获取请求对应的数据权限规则
*/
@SuppressWarnings("unchecked")
public static synchronized List<DimensionResourceRuleEntity> loadDataSearchCondition(HttpServletRequest request) {
return (List<DimensionResourceRuleEntity>) request.getAttribute(COMPONENT_DATA_RULES);
}
public static synchronized void installUserInfo(HttpServletRequest request, IUser userinfo) {
request.setAttribute(SYS_USER_INFO, userinfo);
}
}
......@@ -111,7 +111,7 @@ public class MatterDetailHtmlParseUtil {
List<String> allGroup = ReUtil.findAllGroup1("'(.*?)'", onclickStr);
if (!ObjectUtils.isEmpty(allGroup)) {
String encryUrl = "http://www.sczwfw.gov.cn/jiq/interface/item/annex/encryptUrl?id=" + allGroup.get(0);
/* String encryUrl = "http://www.sczwfw.gov.cn/jiq/interface/item/annex/encryptUrl?id=" + allGroup.get(0);
String resp = HttpUtil.get(encryUrl);
JSONObject obj = JSON.parseObject(resp);
......@@ -120,7 +120,8 @@ public class MatterDetailHtmlParseUtil {
if ("0".equals(code)) {
fileEntity.setFileUrl(data);
fileEntity.setLocalFileUrl(data);
}
}*/
fileEntity.setFileUrl(allGroup.get(0));
}
// fileEntity.setFileUrl(node.firstChild().attr("href").trim());
......@@ -150,7 +151,7 @@ public class MatterDetailHtmlParseUtil {
List<String> allGroup = ReUtil.findAllGroup1("'(.*?)'", onclickStr);
if (!ObjectUtils.isEmpty(allGroup)) {
String encryUrl = "http://www.sczwfw.gov.cn/jiq/interface/item/annex/encryptUrl?id=" + allGroup.get(0);
/* String encryUrl = "http://www.sczwfw.gov.cn/jiq/interface/item/annex/encryptUrl?id=" + allGroup.get(0);
String resp = HttpUtil.get(encryUrl);
JSONObject obj = JSON.parseObject(resp);
......@@ -159,7 +160,8 @@ public class MatterDetailHtmlParseUtil {
if ("0".equals(code)) {
fileEntity.setFileUrl(data);
fileEntity.setLocalFileUrl(data);
}
}*/
fileEntity.setFileUrl(allGroup.get(0));
}
// fileEntity.setFileUrl(node.firstChild().attr("href").trim());
datumSampleFileEntities.add(fileEntity);
......
package com.mortals.xhx.common.utils;
import cn.hutool.core.util.ReflectUtil;
import com.google.common.collect.Maps;
import com.mortals.framework.service.IUser;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.common.code.RuleConditionEnum;
import com.mortals.xhx.common.code.RuleTypeEnum;
import com.mortals.xhx.module.dimension.model.DimensionResourceRuleEntity;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 权限sql 查询语句实现
*
* @author: zxfei
* @date: 2024/5/15 10:44
*/
@Slf4j
@UtilityClass
public class RuleQueryGenerator {
private static final String SQL_AND = " and ";
private static final String SQL_OR = " or ";
private static final String SQL_JOINT = " (%s) ";
public static String getPermissionSql(List<DimensionResourceRuleEntity> conditionList, IUser loginUser) {
//存在权限
//对当前身份根据规则编码分组-去除不同角色中相同编码且规则值为ALL的规则 并根据角色id分组
Map<Long, List<DimensionResourceRuleEntity>> ruleMap = getRuleMapByRoleId(conditionList);
StringBuilder sb = new StringBuilder();
String roleSql;
if (MapUtils.isNotEmpty(ruleMap)) {
//按角色拼接SQL
for (Map.Entry<Long, List<DimensionResourceRuleEntity>> entry : ruleMap.entrySet()) {
List<DimensionResourceRuleEntity> lists = entry.getValue();
// 同角色之间使用 AND
roleSql = buildRoleSql(lists, loginUser);
//角色之间使用 OR
if (StringUtils.isNotEmpty(roleSql)) {
jointSqlByRoles(sb, roleSql);
}
}
}
return sb.toString();
}
/**
* 获取带有数据权限的SQL
*
* @param identityId 身份ID
*/
public String getPermissionSql(String identityId) {
//------------------------获取当前身份的数据规则------------------------------------
List<DimensionResourceRuleEntity> conditionList = getCurrentIdentyPermission(identityId);
if (ObjectUtils.isEmpty(conditionList)) {
//没有权限
return "1 = 0";
}
//存在权限
//对当前身份根据规则编码分组-去除不同角色中相同编码且规则值为ALL的规则 并根据角色id分组
Map<Long, List<DimensionResourceRuleEntity>> ruleMap = getRuleMapByRoleId(conditionList);
StringBuilder sb = new StringBuilder();
String roleSql;
if (MapUtils.isNotEmpty(ruleMap)) {
//按角色拼接SQL
for (Map.Entry<Long, List<DimensionResourceRuleEntity>> entry : ruleMap.entrySet()) {
List<DimensionResourceRuleEntity> lists = entry.getValue();
// 同角色之间使用 AND
roleSql = buildRoleSql(lists, null);
//角色之间使用 OR
if (StringUtils.isNotEmpty(roleSql)) {
jointSqlByRoles(sb, roleSql);
}
}
}
return sb.toString();
}
private static List<DimensionResourceRuleEntity> getCurrentIdentyPermission(String identityId) {
return null;
/* //----------------------------获取所有数据规则-----------------------------
List<DimensionResourceRuleEntity> roleRuleList = DataPermissionUtils.loadDataSearchCondition();
if(ObjectUtils.isEmpty(roleRuleList)){
return null;
}
//-----------------------------过滤掉不属于当前身份的规则-----------------------------------
return roleRuleList.stream()
// .filter(item -> item.getIdentityId().equals(identityId))
.collect(Collectors.toList());*/
}
/**
* 构建单角色SQL
*/
private static String buildRoleSql(List<DimensionResourceRuleEntity> lists, IUser loginUser) {
StringBuilder roleSql = new StringBuilder();
for (DimensionResourceRuleEntity item : lists) {
//如果出现全选 则 代表全部,不需要限定范围
if ("ALL".equals(item.getRuleValue())) {
continue;
}
//将规则转换成SQL
String filedSql = convertRuleToSql(item, loginUser);
if(!ObjectUtils.isEmpty(filedSql)){
roleSql.append(SQL_AND).append(filedSql);
}
}
return roleSql.toString();
}
/**
* 将单一规则转化成SQL,默认全部使用 In
* ruleCode : area_test
* ruleValue : 区域1,区域2,区域3
*
* @param rule 规则值
*/
private static String convertRuleToSql(DimensionResourceRuleEntity rule, IUser loginUser) {
//判断规则类型
String ruleValueConvert = "";
if (RuleConditionEnum.属于.getValue().equalsIgnoreCase(rule.getRuleCondition())) {
String whereCondition = " in ";
if(RuleTypeEnum.系统上下问变量.getValue()==rule.getRuleType()){
ruleValueConvert = getInConditionValue(rule.getRuleValue(),loginUser);
if(ObjectUtils.isEmpty(ruleValueConvert)) return null;
return rule.getRuleCode() + whereCondition + ruleValueConvert;
}else{
ruleValueConvert = getInConditionValue(rule.getRuleValue());
if(ObjectUtils.isEmpty(ruleValueConvert)) return null;
return rule.getRuleCode() + whereCondition + ruleValueConvert;
}
} else if (RuleConditionEnum.大于.getValue().equalsIgnoreCase(rule.getRuleCondition())) {
String whereCondition = " > ";
ruleValueConvert = getGreaterConditionValue(rule.getRuleValue());
return rule.getRuleCode() + whereCondition + ruleValueConvert;
} else {
//todo
//不支持的类型
}
return null;
}
/**
* IN字符串转换
* 区域1, 区域2, 区域3 --> ("区域1","区域2","区域3")
* 江西大区 --> ("江西大区")
*/
private static String getInConditionValue(String ruleValue) {
String[] temp = ruleValue.split(",");
StringBuilder res = new StringBuilder();
for (String string : temp) {
res.append(",'").append(string).append("'");
}
return "(" + res.substring(1) + ")";
}
/**
* IN字符串转换
* 区域1, 区域2, 区域3 --> ("区域1","区域2","区域3")
* 江西大区 --> ("江西大区")
*/
private static String getInConditionValue(String ruleValue,IUser loginUser) {
//el表达式 提取变量 再通过反射获取值,最终设置值
Object fieldValue = ReflectUtil.getFieldValue(loginUser, ruleValue);
if(fieldValue!=null){
return "(" + fieldValue + ")";
}
return null;
}
/**
* > 字符串转换
* 区域1, 区域2, 区域3 --> ("区域1","区域2","区域3")
* 江西大区 --> ("江西大区")
*/
private static String getGreaterConditionValue(String ruleValue) {
return ruleValue;
}
/**
* 拼接单角色的SQL
*
* @param sqlBuilder 总的SQL
* @param roleSql 单角色SQL
*/
private static void jointSqlByRoles(StringBuilder sqlBuilder, String roleSql) {
roleSql = roleSql.replaceFirst(SQL_AND, "");
if (StringUtils.isEmpty(sqlBuilder.toString())) {
sqlBuilder.append(String.format(SQL_JOINT, roleSql));
} else {
sqlBuilder.append(SQL_OR).append(String.format(SQL_JOINT, roleSql));
}
}
/**
* 1. 对当前身份根据规则编码分组-去除不同角色中相同编码且规则值为ALL的规则
* 2. 对角色进行分组
*
* @param conditionList 数据规则
* @return 分组后的规则list
*/
public static Map<Long, List<DimensionResourceRuleEntity>> getRuleMapByRoleId(List<DimensionResourceRuleEntity> conditionList) {
//--------过滤掉不属于当前身份的规则,并对条件编码进行分组-----------------------------------
Map<String, List<DimensionResourceRuleEntity>> conditionMap = conditionList.stream().collect(Collectors.groupingBy(DimensionResourceRuleEntity::getRuleCode));
//--------相同编码分组中存在ALL的排除掉-----------------------------------------------
List<DimensionResourceRuleEntity> newRoleRuleList = new ArrayList<>();
if (MapUtils.isNotEmpty(conditionMap)) {
for (Map.Entry<String, List<DimensionResourceRuleEntity>> entry : conditionMap.entrySet()) {
boolean flag = true;
List<DimensionResourceRuleEntity> lists = entry.getValue();
for (DimensionResourceRuleEntity item : lists) {
if ("ALL".equals(item.getRuleValue())) {
flag = false;
break;
}
}
if (flag) {
newRoleRuleList.addAll(lists);
}
}
}
if (CollectionUtils.isNotEmpty(newRoleRuleList)) {
return newRoleRuleList.stream().collect(Collectors.groupingBy(DimensionResourceRuleEntity::getRoleId));
}
return Maps.newHashMap();
}
}
package com.mortals.xhx.daemon.applicationservice;
import com.mortals.framework.common.Rest;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.util.ThreadPool;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.key.Constant;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.common.pdu.RespData;
import com.mortals.xhx.common.pdu.user.UserPdu;
import com.mortals.xhx.common.utils.SendTaskThreadPool;
import com.mortals.xhx.feign.user.IUserFeign;
import com.mortals.framework.springcloud.service.IApplicationService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.mortals.framework.springcloud.service.IApplicationService;
import org.springframework.util.ObjectUtils;
import java.util.List;
@Component
//@Component
public class DemoStartService implements IApplicationService {
private static Log logger = LogFactory.getLog(DemoStartService.class);
@Autowired
private ICacheService cacheService;
@Autowired
private IUserFeign userFeign;
@Autowired
private UserService userService;
@Override
public void start() {
// ThreadPool.getInstance().init(10);
logger.info("开始服务..[配置已加载完成,但部分框架还未初始化,比如:Kafka]");
/* Rest<String> rest = userFeign.synchSiteAuth();
if (rest.getCode().equals(YesNoEnum.YES.getValue())) {
UserPdu userPdu = new UserPdu();
userPdu.setPage(1);
userPdu.setSize(-1);
Rest<RespData<List<UserPdu>>> list = userFeign.list(userPdu);
if(!ObjectUtils.isEmpty(list.getData().getData())){
//初始化更新门户用户站点树
cacheService.del(Constant.USER_SITE_TREE);
userService.updateUserList(list.getData().getData());
}
}*/
}
@Override
......
package com.mortals.xhx.daemon.applicationservice;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.IUser;
import com.mortals.framework.springcloud.config.web.BaseWebMvcConfigurer;
import com.mortals.framework.springcloud.service.IApplicationStartedService;
import com.mortals.framework.util.ThreadPool;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.model.UserQuery;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.common.pdu.user.UserPdu;
import com.mortals.xhx.common.utils.BeanUtil;
import com.mortals.xhx.common.utils.SyncTreeSiteThread;
import com.mortals.xhx.feign.user.IUserFeign;
import com.mortals.xhx.module.site.model.SiteEntity;
import com.mortals.xhx.module.site.model.SiteTreeSelect;
import com.mortals.xhx.module.site.service.SiteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import com.mortals.framework.springcloud.service.IApplicationStartedService;
import org.springframework.util.ObjectUtils;
import java.util.List;
import static com.mortals.xhx.common.key.Constant.USER_SITE_TREE;
@Component
@Slf4j
public class DemoStartedService implements IApplicationStartedService {
private static Log logger = LogFactory.getLog(DemoStartedService.class);
@Autowired
private IUserFeign userFeign;
@Autowired
private UserService userService;
@Autowired
private ICacheService cacheService;
@Autowired
......@@ -47,54 +25,16 @@ public class DemoStartedService implements IApplicationStartedService {
@Override
public void start() {
ThreadPool.getInstance().init(6);
logger.info("开始服务..[初始化用户站点树]");
ThreadPool.getInstance().init(10);
log.info("开始服务..[初始化用户站点树]");
//删除redis 中的 站点树
cacheService.del(USER_SITE_TREE);
siteService.updateAllSiteTree(null);
//测试获取站点
/*
int i=0;
while (true) {
SiteEntity siteCache = siteService.getCache("1");
if (ObjectUtils.isEmpty(siteCache)) {
log.error("siteCache is null");
}else {
log.info("count==>"+i);
}
try {
Thread.sleep(50);
i++;
} catch (InterruptedException e) {
}
}*/
/* UserEntity userEntity = new UserEntity();
userEntity.initAttrValue();
userEntity.setId(0L);
Context contextTemp = new Context();
contextTemp.setUser(userEntity);
SyncTreeSiteThread syncTreeSiteThread = new SyncTreeSiteThread(contextTemp);
ThreadPool.getInstance().execute(syncTreeSiteThread);
userEntity = new UserEntity();
userEntity.initAttrValue();
userEntity.setId(1L);
contextTemp = new Context();
contextTemp.setUser(userEntity);
syncTreeSiteThread = new SyncTreeSiteThread(contextTemp);
ThreadPool.getInstance().execute(syncTreeSiteThread);*/
}
@Override
public void stop() {
logger.info("停止服务..");
log.info("停止服务..");
}
@Override
......
......@@ -50,6 +50,11 @@ public class SyncMatterTaskImpl implements ITaskExcuteService {
stopWatch.stop();
log.info("同步站点部门完成,耗时:{}s", stopWatch.getLastTaskTimeMillis() / 1000);
log.info("开始同步事项==》{}", siteEntity.getSiteName());
stopWatch.start("同步删除本地多余的政务事项");
log.info("同步删除本地多余的政务事项");
matterExtService.syncDelMatterBySiteId(siteEntity, null);
stopWatch.stop();
log.info("同步删除本地多余的政务事项完成,耗时:{}s", stopWatch.getLastTaskTimeMillis() / 1000);
stopWatch.start("开始同步事项方法");
matterExtService.syncMatterBySiteId(siteEntity, null);
......
......@@ -30,11 +30,6 @@ import java.util.stream.Collectors;
@Service("areaService")
public class AreaServiceImpl extends AbstractCRUDCacheServiceImpl<AreaDao, AreaEntity, Long> implements AreaService {
@Autowired
private SiteService siteService;
@Autowired
private BaseAreaService baseAreaService;
@Override
public void putCache(String key, AreaEntity data) {
......
package com.mortals.xhx.module.dept.dao;
import com.mortals.framework.dao.ICRUDDao;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.xhx.module.dept.model.DeptEntity;
......@@ -20,9 +21,12 @@ public interface DeptDao extends ICRUDDao<DeptEntity,Long>{
String GET_DEPT_LIST_BY_BUSINESS = "getDeptListByBusiness";
String GET_BUSINESS_BY_DEPT = "getBusinessByDept";
String GET_DEPTLIST_BY_EXISTBUSINESS = "getDeptListByExistBusiness";
List<DeptVo> getDeptListByBusiness(DeptQuery deptQuery);
List<DeptVo> getBusinessByDept(DeptQuery deptQuery);
List<DeptEntity> getDeptListByExistBusiness(DeptQuery deptQuery);
}
package com.mortals.xhx.module.dept.dao.ibatis;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.ParamDto;
import com.mortals.framework.model.Result;
import com.mortals.xhx.module.dept.model.DeptQuery;
......@@ -9,17 +10,21 @@ import com.mortals.xhx.module.matter.model.MatterEntity;
import org.springframework.stereotype.Repository;
import com.mortals.xhx.module.dept.dao.DeptDao;
import com.mortals.xhx.module.dept.model.DeptEntity;
import java.util.Date;
import com.mortals.framework.dao.ibatis.BaseCRUDDaoMybatis;
import java.util.List;
/**
* 部门DaoImpl DAO接口
*
* @author zxfei
* @date 2022-01-12
*/
* 部门DaoImpl DAO接口
*
* @author zxfei
* @date 2022-01-12
*/
@Repository("deptDao")
public class DeptDaoImpl extends BaseCRUDDaoMybatis<DeptEntity,Long> implements DeptDao {
public class DeptDaoImpl extends BaseCRUDDaoMybatis<DeptEntity, Long> implements DeptDao {
/**
* @param deptQuery
* @return
......@@ -41,4 +46,13 @@ public class DeptDaoImpl extends BaseCRUDDaoMybatis<DeptEntity,Long> implements
List list = this.getSqlSession().selectList(this.getSqlId(GET_BUSINESS_BY_DEPT), paramDto);
return list;
}
/**
* @return
*/
@Override
public List<DeptEntity> getDeptListByExistBusiness(DeptQuery deptQuery) {
ParamDto paramDto = this.getQueryParam(deptQuery);
return this.getSqlSession().selectList(this.getSqlId(GET_DEPTLIST_BY_EXISTBUSINESS),paramDto);
}
}
......@@ -49,6 +49,6 @@ public interface DeptService extends ICRUDCacheService<DeptEntity, Long> {
Rest<Map<String,List<DeptVo>>> getDeptListByBusiness(DeptQuery deptQuery, Context context);
List<DeptEntity> getDeptListByExistBusiness(DeptQuery deptQuery, Context context);
}
\ No newline at end of file
......@@ -213,6 +213,14 @@ public class DeptServiceImpl extends AbstractCRUDCacheServiceImpl<DeptDao, DeptE
return Rest.ok(collect);
}
/**
* @return
*/
@Override
public List<DeptEntity> getDeptListByExistBusiness(DeptQuery deptQuery, Context context) {
return this.dao.getDeptListByExistBusiness(deptQuery);
}
/**
* @param entity
......
......@@ -23,10 +23,7 @@ import com.mortals.xhx.module.site.service.SiteService;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.HashMap;
......@@ -145,6 +142,36 @@ public class DeptController extends BaseCRUDJsonBodyMappingController<DeptServic
}
/**
* 根据部门查询业务
*/
@GetMapping(value = "getDeptListByExistBusiness")
@UnAuth
public String getDeptListByExistBusiness(@RequestParam("siteId") Long siteId) {
JSONObject jsonObject = new JSONObject();
String busiDesc = "根据业务查询存在的部门列表" + this.getModuleDesc();
try {
if (ObjectUtils.isEmpty(siteId)) {
throw new AppException("站点id不能为空!");
}
DeptQuery query = new DeptQuery();
query.setSiteId(siteId);
List<DeptEntity> deptList = this.service.getDeptListByExistBusiness(query, getContext());
if (!ObjectUtils.isEmpty(getContext()) && !ObjectUtils.isEmpty(getContext().getUser())) {
recordSysLog(request, busiDesc + " 【成功】");
}
jsonObject.put(KEY_RESULT_DATA, deptList);
jsonObject.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
jsonObject.put(KEY_RESULT_MSG, busiDesc + "成功!");
} catch (Exception e) {
log.error("获取异常", e);
jsonObject.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
jsonObject.put(KEY_RESULT_MSG, super.convertException(e));
}
return jsonObject.toJSONString();
}
/**
* 根据部门查询业务
*/
......
package com.mortals.xhx.module.dimension.dao;
import com.mortals.framework.dao.ICRUDDao;
import com.mortals.xhx.module.dimension.model.DimensionEntity;
/**
* 授权维度Dao
* 授权维度 DAO接口
*
* @author zxfei
* @date 2024-05-16
*/
public interface DimensionDao extends ICRUDDao<DimensionEntity,Long>{
}
package com.mortals.xhx.module.dimension.dao;
import com.mortals.framework.dao.ICRUDDao;
import com.mortals.xhx.module.dimension.model.DimensionResourceRuleEntity;
import java.util.List;
/**
* 角色资源维度规则Dao
* 角色资源维度规则 DAO接口
*
* @author zxfei
* @date 2024-05-16
*/
public interface DimensionResourceRuleDao extends ICRUDDao<DimensionResourceRuleEntity,Long>{
List<DimensionResourceRuleEntity> getRoleComponentRule(Long userId,String route);
}
package com.mortals.xhx.module.dimension.dao.ibatis;
import com.mortals.framework.dao.ibatis.BaseCRUDDaoMybatis;
import com.mortals.xhx.module.dimension.dao.DimensionDao;
import com.mortals.xhx.module.dimension.model.DimensionEntity;
import org.springframework.stereotype.Repository;
/**
* 授权维度DaoImpl DAO接口
*
* @author zxfei
* @date 2024-05-16
*/
@Repository("dimensionDao")
public class DimensionDaoImpl extends BaseCRUDDaoMybatis<DimensionEntity,Long> implements DimensionDao {
}
package com.mortals.xhx.module.dimension.dao.ibatis;
import com.mortals.framework.dao.ibatis.BaseCRUDDaoMybatis;
import com.mortals.xhx.module.dimension.dao.DimensionResourceRuleDao;
import com.mortals.xhx.module.dimension.model.DimensionResourceRuleEntity;
import org.springframework.stereotype.Repository;
import java.util.HashMap;
import java.util.List;
/**
* 角色资源维度规则DaoImpl DAO接口
*
* @author zxfei
* @date 2024-05-16
*/
@Repository("dimensionResourceRuleDao")
public class DimensionResourceRuleDaoImpl extends BaseCRUDDaoMybatis<DimensionResourceRuleEntity,Long> implements DimensionResourceRuleDao {
/**
* @param userId
* @param route
* @return
*/
@Override
public List<DimensionResourceRuleEntity> getRoleComponentRule(Long userId, String route) {
return getSqlSession().selectList(getSqlId("getRoleComponentRule"), new HashMap<String, Object>() {
{
put("userId", userId);
put("route", route);
}
});
}
}
package com.mortals.xhx.module.dimension.model;
import com.mortals.xhx.module.dimension.model.vo.DimensionVo;
import lombok.Data;
/**
* 授权维度实体对象
*
* @author zxfei
* @date 2024-05-16
*/
@Data
public class DimensionEntity extends DimensionVo {
private static final long serialVersionUID = 1L;
/**
* 维度编码
*/
private String dimensionCode;
/**
* 维度名称
*/
private String dimensionName;
/**
* 维度值
*/
private String dimensionValue;
/**
* 维度类型(1.固定值,2.系统上下问变量)
*/
private Integer dimensionType;
@Override
public int hashCode() {
return this.getId().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (obj instanceof DimensionEntity) {
DimensionEntity tmp = (DimensionEntity) obj;
if (this.getId() == tmp.getId()) {
return true;
}
}
return false;
}
public void initAttrValue(){
this.dimensionCode = "";
this.dimensionName = "";
this.dimensionValue = "";
this.dimensionType = 1;
}
}
\ No newline at end of file
package com.mortals.xhx.module.dimension.model;
import com.mortals.xhx.module.dimension.model.vo.DimensionResourceRuleVo;
import lombok.Data;
/**
* 角色资源维度规则实体对象
*
* @author zxfei
* @date 2024-05-22
*/
@Data
public class DimensionResourceRuleEntity extends DimensionResourceRuleVo {
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
private Long roleId;
/**
* 资源ID
*/
private Long resourceId;
/**
* 规则编码
*/
private String ruleCode;
/**
* 规则名称
*/
private String ruleName;
/**
* 规则条件(IN.属于,<.小于,>.大于,=.等于,!=.不等于,>=.大于等于,<=.小于等于,like %.左模糊,like %.右模糊)
*/
private String ruleCondition;
/**
* 规则值,固定值或者系统变量
*/
private String ruleValue;
/**
* 规则值类型(1.固定值,2.系统上下问变量)
*/
private Integer ruleType;
/**
* 角色名称
*/
private String roleName;
/**
* 资源名称
*/
private String resourceName;
@Override
public int hashCode() {
return this.getId().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (obj instanceof DimensionResourceRuleEntity) {
DimensionResourceRuleEntity tmp = (DimensionResourceRuleEntity) obj;
if (this.getId() == tmp.getId()) {
return true;
}
}
return false;
}
public void initAttrValue(){
this.roleId = null;
this.resourceId = null;
this.ruleCode = "";
this.ruleName = "";
this.ruleCondition = "IN";
this.ruleValue = "";
this.ruleType = 1;
this.roleName = "";
this.resourceName = "";
}
}
\ No newline at end of file
package com.mortals.xhx.module.dimension.model.vo;
import com.mortals.framework.model.BaseEntityLong;
import lombok.Data;
import java.util.List;
/**
* 角色资源维度规则视图对象
*
* @author zxfei
* @date 2024-05-16
*/
@Data
public class DimensionResourceRuleVo extends BaseEntityLong {
/** 序号,主键,自增长列表 */
private List <Long> idList;
}
\ No newline at end of file
package com.mortals.xhx.module.dimension.model.vo;
import com.mortals.framework.model.BaseEntityLong;
import lombok.Data;
import java.util.List;
/**
* 授权维度视图对象
*
* @author zxfei
* @date 2024-05-16
*/
@Data
public class DimensionVo extends BaseEntityLong {
/** 序号,主键,自增长列表 */
private List <Long> idList;
}
\ No newline at end of file
package com.mortals.xhx.module.dimension.service;
import com.mortals.framework.service.ICRUDService;
import com.mortals.xhx.module.dimension.dao.DimensionResourceRuleDao;
import com.mortals.xhx.module.dimension.model.DimensionResourceRuleEntity;
import java.util.List;
/**
* DimensionResourceRuleService
*
* 角色资源维度规则 service接口
*
* @author zxfei
* @date 2024-05-16
*/
public interface DimensionResourceRuleService extends ICRUDService<DimensionResourceRuleEntity,Long>{
DimensionResourceRuleDao getDao();
/**
* 根据当前controller路由获取用户角色资源维度规则
* @param userId
* @param route 当前controller路由
* @return
*/
List<DimensionResourceRuleEntity> getRoleComponentRule(Long userId,String route);
}
\ No newline at end of file
package com.mortals.xhx.module.dimension.service;
import com.mortals.framework.service.ICRUDService;
import com.mortals.xhx.module.dimension.dao.DimensionDao;
import com.mortals.xhx.module.dimension.model.DimensionEntity;
/**
* DimensionService
*
* 授权维度 service接口
*
* @author zxfei
* @date 2024-05-16
*/
public interface DimensionService extends ICRUDService<DimensionEntity,Long>{
DimensionDao getDao();
}
\ No newline at end of file
package com.mortals.xhx.module.dimension.service.impl;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.xhx.module.dimension.dao.DimensionResourceRuleDao;
import com.mortals.xhx.module.dimension.model.DimensionResourceRuleEntity;
import com.mortals.xhx.module.dimension.service.DimensionResourceRuleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* DimensionResourceRuleService
* 角色资源维度规则 service实现
*
* @author zxfei
* @date 2024-05-16
*/
@Service("dimensionResourceRuleService")
@Slf4j
public class DimensionResourceRuleServiceImpl extends AbstractCRUDServiceImpl<DimensionResourceRuleDao, DimensionResourceRuleEntity, Long> implements DimensionResourceRuleService {
/**
* @param userId
* @param route 当前controller路由
* @return
*/
@Override
public List<DimensionResourceRuleEntity> getRoleComponentRule(Long userId, String route) {
return this.getDao().getRoleComponentRule(userId, route);
}
}
\ No newline at end of file
package com.mortals.xhx.module.dimension.service.impl;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.xhx.module.dimension.dao.DimensionDao;
import com.mortals.xhx.module.dimension.model.DimensionEntity;
import com.mortals.xhx.module.dimension.service.DimensionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* DimensionService
* 授权维度 service实现
*
* @author zxfei
* @date 2024-05-16
*/
@Service("dimensionService")
@Slf4j
public class DimensionServiceImpl extends AbstractCRUDServiceImpl<DimensionDao, DimensionEntity, Long> implements DimensionService {
}
\ No newline at end of file
package com.mortals.xhx.module.dimension.web;
import com.mortals.framework.model.Context;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.common.code.DimensionTypeEnum;
import com.mortals.xhx.module.dimension.model.DimensionEntity;
import com.mortals.xhx.module.dimension.service.DimensionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
*
* 授权维度
*
* @author zxfei
* @date 2024-05-16
*/
@RestController
@RequestMapping("dimension")
public class DimensionController extends BaseCRUDJsonBodyMappingController<DimensionService,DimensionEntity,Long> {
@Autowired
private ParamService paramService;
public DimensionController(){
super.setModuleDesc( "授权维度");
}
@Override
protected void init(Map<String, Object> model, Context context) {
this.addDict(model, "dimensionType", DimensionTypeEnum.getEnumMap());
super.init(model, context);
}
}
\ No newline at end of file
package com.mortals.xhx.module.dimension.web;
import com.mortals.framework.model.Context;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.common.code.RuleConditionEnum;
import com.mortals.xhx.common.code.RuleTypeEnum;
import com.mortals.xhx.module.dimension.model.DimensionResourceRuleEntity;
import com.mortals.xhx.module.dimension.service.DimensionResourceRuleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
*
* 角色资源维度规则
*
* @author zxfei
* @date 2024-05-16
*/
@RestController
@RequestMapping("dimension/resource/rule")
public class DimensionResourceRuleController extends BaseCRUDJsonBodyMappingController<DimensionResourceRuleService,DimensionResourceRuleEntity,Long> {
@Autowired
private ParamService paramService;
public DimensionResourceRuleController(){
super.setModuleDesc( "角色资源维度规则");
}
@Override
protected void init(Map<String, Object> model, Context context) {
this.addDict(model, "ruleCondition", RuleConditionEnum.getEnumMap());
this.addDict(model, "ruleType", RuleTypeEnum.getEnumMap());
super.init(model, context);
}
}
\ No newline at end of file
......@@ -2,7 +2,6 @@ package com.mortals.xhx.module.holiday.web;
import com.mortals.framework.model.Context;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.framework.web.BasePhpCRUDJsonMappingController;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.module.holiday.model.HolidayEntity;
import com.mortals.xhx.module.holiday.service.HolidayService;
......
......@@ -21,4 +21,7 @@ public class MatterVo extends BaseEntityLong {
*/
private List <String> eventTypeShowNotList;
}
\ No newline at end of file
......@@ -4,7 +4,6 @@ import com.mortals.framework.annotation.UnAuth;
import com.mortals.framework.common.Rest;
import com.mortals.framework.model.Context;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.framework.web.BasePhpCRUDJsonMappingController;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.module.matter.model.MatterAcceptEntity;
import com.mortals.xhx.module.matter.service.MatterAcceptService;
......
This diff is collapsed.
This diff is collapsed.
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