Commit 60b2ec91 authored by 赵啸非's avatar 赵啸非

Merge branch 'master' into 'reg'

Master

See merge request !1
parents 9bc81fbb 61c33a07
......@@ -25,6 +25,7 @@
"china-division": "^2.5.0",
"clipboard": "^2.0.6",
"core-js": "^3.6.5",
"crypto-js": "^4.1.1",
"date-fns": "^2.14.0",
"echarts": "^5.2.2",
"element-china-area-data": "^5.0.2",
......@@ -34,6 +35,7 @@
"highlight.js": "^10.2.1",
"html2canvas": "^1.4.1",
"js-cookie": "^2.2.1",
"lodash": "^4.17.21",
"mockjs": "^1.1.0",
"moment": "^2.24.0",
"nanoid": "^4.0.0",
......
File added
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<!-- <title><%= process.env.VUE_APP_NAME %></title> -->
<title></title>
<!-- require cdn assets css -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" />
<% } %>
<style>
@font-face {
font-family: Source Han Sans CN;
src: url("./SourceHanSansSC-Regular-2.otf");
}
</style>
</head>
</head>
<body>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to
continue.</strong>
</noscript>
<div id="popContainer">
<div id="app"></div>
......@@ -25,5 +34,6 @@
<script type="text/javascript" src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
<!-- built files will be auto injected -->
</body>
</body>
</html>
\ No newline at end of file
......@@ -31,16 +31,17 @@
border-bottom: 1px solid rgb(224, 224, 224) !important;
}
.ant-tabs-tab{
.ant-tabs-tab {
font-weight: bold;
color: rgba(0, 0, 0, 0.65);
i{
color:#1890ff
i {
color: #1890ff;
}
}
.ant-spin-nested-loading,.ant-spin-container{
width:100%;
height:100%;
.ant-spin-nested-loading,
.ant-spin-container {
width: 100%;
height: 100%;
}
/* 溢出表格滚动条 */
/* 表格 */
......@@ -56,10 +57,9 @@
tr:only-child > th:last-child {
border-right-color: #f0f0f0 !important;
}
}
.ant-table-placeholder{
width:calc(100% - 6px)
.ant-table-placeholder {
width: calc(100% - 6px);
}
.ant-table-header {
background: #fff;
......@@ -99,9 +99,14 @@
resize: none;
}
.ant-btn-primary {
background: linear-gradient(90deg, #5ab6ff, #2e9aff) !important;
border: none !important;
border-color: transparent !important;
background: linear-gradient(90deg, #5ab6ff, #2e9aff) ;
border: none ;
border-color: transparent ;
&:hover,&:focus{
background: linear-gradient(90deg, #5ab6ff, #2e9aff) ;
border: none ;
border-color: transparent ;
}
}
.ant-form-explain {
......@@ -119,3 +124,10 @@
// justify-content:space-between;
// margin-bottom: 20px;
// }
// 统一设置表格为空时的展示
.ant-table-tbody {
td:empty::after {
content: "--";
}
}
base-manager-ui/admin/src/assets/img/sms_bg.jpg

41.5 KB

<template>
<div class="y-button" :style="{ '--w': width + 'px' }">
<button
type="button"
:style="{ '--w': width + 'px' }"
:class="{ animating: active, active: value }"
@click="clickHandler"
@animationend="animationend"
>
<span>
<b></b>
<svg viewBox="-5.5 -5.5 71 71" id="circle">
<circle
cx="30"
cy="30"
r="30"
stroke="white"
stroke-width="11"
fill="transparent"
></circle>
</svg>
</span>
</button>
<div :class="['text', { active: value }]">
<!-- <span class="on">
<span>
{{ activeText }}
</span>
</span>
<span class="off">
<span>
{{ unActiveText }}
</span>
</span> -->
{{ value ? activeText : unActiveText }}
</div>
</div>
</template>
<script>
export default {
model: {
prop: "checked",
event: "change",
},
props: {
width: {
type: Number,
default: 84,
},
checked: {
required: true,
},
activeText: {
default: "ON",
},
unActiveText: {
default: "OFF",
},
},
data() {
return {
active: false,
};
},
computed: {
value() {
return this.checked === 1 || this.checked === "1";
},
},
methods: {
clickHandler() {
this.active = true;
},
animationend() {
this.active = false;
this.$emit("change", this.checked ? 0 : 1);
},
},
};
</script>
<style lang="less" scoped>
@keyframes c {
to {
transform: none;
}
}
.y-button {
--timing: cubic-bezier(0.645, 0.045, 0.355, 1);
--primary: #f4f7f5;
width: var(--w);
button {
--bg: rgb(var(--rgb));
--bga: rgba(var(--rgb), 0.4);
/* Safari fix */
-webkit-appearance: none;
border: none;
font-size: 100%;
width: var(--w);
height: var(--w);
background: var(--bg);
box-shadow: 0 3px 12px 2px var(--bga);
border-radius: 50%;
position: relative;
overflow: hidden;
cursor: pointer;
transition: 0.1s transform, 0.3s box-shadow;
will-change: transform, box-shadow;
backface-visibility: hidden;
}
button > * {
pointer-events: none;
}
button:focus {
outline: none;
}
button:active {
transform: scale(0.97);
}
button:after {
--bg: rgb(var(--rgb));
content: "";
position: absolute;
top: -15%;
left: -15%;
width: 200%;
height: 200%;
background: var(--bg);
border-radius: inherit;
transform: translate(5%, 5%) scale(0.03);
pointer-events: none;
}
button.animating:after {
animation: c 0.5s cubic-bezier(0.5, 0, 0.5, 1) backwards;
}
button.active,
button:not(.active):after {
--rgb: 64, 227, 120;
}
button:not(.active),
button.active:after {
--rgb: 229, 55, 94;
}
button span {
display: inline-block;
position: relative;
margin-top: 5px;
}
button b {
--w: 7px;
overflow: hidden;
border-radius: var(--w);
display: grid;
width: var(--w);
height: 35px;
top: 0;
left: 50%;
position: absolute;
transform: translateX(-50%);
z-index: 3;
will-change: transform;
}
button b:before {
content: "";
background: #fff;
width: 100%;
height: 100%;
border-radius: var(--w);
transform: translateY(-15px);
transition-timing-function: var(--timing);
transition: 0.5s;
}
button.active b:before {
transform: translateY(12px);
transition-delay: 0.27s;
transition-timing-function: cubic-bezier(0.25, 0.25, 0.25, 1.25);
}
button svg {
--dash: 190;
stroke-linecap: round;
stroke-dasharray: var(--dash);
stroke-dashoffset: var(--dash);
width: 46px;
height: 46px;
transform: scaleX(-1) rotate(-89deg);
transition: 0.4s;
transition-timing-function: var(--timing);
margin: auto;
position: relative;
z-index: 1;
will-change: transform, stroke-dashoffset;
}
button:not(.active) svg {
stroke-dashoffset: 40;
transform: scaleX(-1) rotate(-52deg);
transition: 0.5s 0.25s;
}
aside {
position: absolute;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
text-align: center;
width: 100%;
padding: 0 2em 2em;
font-family: "Pacifico", cursive;
}
aside a {
text-decoration: underline;
color: #e65289;
display: flex;
align-items: center;
}
aside a:hover,
aside a:focus {
color: #000;
text-decoration: none;
}
.dribbble-logo {
width: 18px;
height: 18px;
margin-right: 5px;
}
.text {
width: 100%;
margin-top: 10px;
font-size: 22px;
font-family: Source Han Sans CN;
font-weight: 500;
color: #c9c9c9;
text-align: center;
}
}
</style>
......@@ -2,13 +2,16 @@
<div style="margin-bottom: 25px" class="y-quill" :style="{ height: height }">
<!-- 图片上传组件辅助-->
<a-upload
name="uploadFile"
name="file"
:multiple="true"
:headers="headers"
:headers="{
Authorization: token,
}"
:show-upload-list="false"
:action="serverUrl"
@change="handleChange"
:before-upload="beforeUpload"
:accept="accept"
>
</a-upload>
<!-- 富文本 -->
......@@ -24,7 +27,7 @@
</div>
</template>
<script>
import local from "@/utils/local";
import { mapGetters } from "vuex";
// 工具栏配置
const toolbarOptions = [
["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
......@@ -104,6 +107,7 @@ export default {
data() {
return {
accept: "image/png,image/gif,image/jpeg,video/mp4",
quillUpdateImg: false, // 根据图片上传状态来确定是否显示loading动画,刚开始是false,不显示
api: process.env.VUE_APP_API_BASE_URL + "/",
editorOption: {
......@@ -142,10 +146,7 @@ export default {
},
},
},
serverUrl: process.env.VUE_APP_API_BASE_URL + "/file/commonupload", // 这里写你要上传的图片服务器地址
headers: {
Authorization: local.getLocal("token"),
},
serverUrl: process.env.VUE_APP_API_BASE_URL + "/base/file/commonupload", // 这里写你要上传的图片服务器地址
};
},
computed: {
......@@ -157,6 +158,7 @@ export default {
this.$emit("input", val);
},
},
...mapGetters("site", ["token"]),
},
methods: {
onEditorBlur() {
......
......@@ -2,14 +2,15 @@
<div class="sitetree">
<!-- <span style="font-weight: 600">站点结构</span> -->
<div class="box">
<a-spin :spinning="loading">
<a-tree
:load-data="onLoadData"
:tree-data="treeData"
:expandedKeys.sync="expandedKeys"
:replaceFields="{ title: 'label', key: 'id' }"
@select="onSelect"
>
</a-tree>
</a-spin>
</div>
</div>
</template>
......@@ -18,6 +19,7 @@
// api
import {
getListByParentId,
authAreaTree,
// areaList,
// getSiteList
} from "@/services/basicsetFun";
......@@ -28,43 +30,73 @@ export default {
treeData: [], //树结构
id: "",
expandedKeys: [],
loading: false,
};
},
created() {
this.getAreaList();
this.authAreaTree();
this.getTopArea();
},
methods: {
// 获取区域
async getAreaList() {
editLeaf(arr) {
return arr.map((v) => {
if (v.children && v.children.length > 0) {
this.editLeaf(v.children);
} else {
v.isLeaf = true;
}
return v;
});
},
// 获取个人区域数据
async authAreaTree() {
this.loading = true;
let res = await authAreaTree();
if (res.data.code == 1) {
let { data } = res.data.data;
if (data.length) {
let firstData = data[0];
if (firstData.areaLevel > 2 || data.length > 1) {
let TopParent = await this.getTopArea();
TopParent.selectable = false;
TopParent.children = this.editLeaf(data);
this.treeData = [TopParent];
} else {
this.treeData = this.editLeaf(data);
}
this.expandedKeys = [this.treeData[0].id];
}
}
this.loading = false;
},
// 获取顶层区域
async getTopArea() {
let res = await getListByParentId({ parentId: 0 });
const { data, code } = res.data;
if (code === 1) {
this.treeData = data.data;
// let obj = {
// dataRef: {
// id: data.data[0].id,
// },
// };
// this.onLoadData(obj);
this.expandedKeys = [data.data[0].id];
return data.data[0];
} else {
return {};
}
},
// 异步获取子区域
onLoadData(treeNode) {
return new Promise((resolve) => {
getListByParentId({
parentId: treeNode.dataRef.id,
}).then((res) => {
const { data } = res.data;
treeNode.dataRef.children = data.data;
this.treeData = [...this.treeData];
resolve();
});
});
},
// onLoadData(treeNode) {
// return new Promise((resolve) => {
// getListByParentId({
// parentId: treeNode.dataRef.id,
// }).then((res) => {
// const { data } = res.data;
// treeNode.dataRef.children = data.data;
// this.treeData = [...this.treeData];
// resolve();
// });
// });
// },
// 选中区域
onSelect(num, node) {
if (num && node.selectedNodes.length > 0) {
......
......@@ -5,8 +5,7 @@
<div class="flex aic">
<router-link to="/" class="flex aic">
<img
class="mr10"
width="32"
class="mr10 logo"
:src="sysLogo ? api + sysLogo : require('@/assets/img/logo.png')"
/>
<h1 class="title">
......@@ -22,7 +21,9 @@
初始化区域数据
</a>
<a-tooltip class="header-item" title="返回门户" placement="bottom">
<a :href="portalUrl + path"> <a-icon type="home" /> 返回门户 </a>
<a :href="portalUrl + (path ? path : '')">
<a-icon type="home" /> 返回门户
</a>
</a-tooltip>
</a-space>
</div>
......@@ -102,6 +103,10 @@ export default {
line-height: normal;
}
}
.logo {
height: 32px;
object-fit: contain;
}
.main {
height: calc(100vh - 64px);
padding: 0px 24px 24px;
......
......@@ -46,7 +46,9 @@
>初始化区域数据</a-button
>
<a-tooltip class="header-item" title="返回门户" placement="bottom">
<a :href="portalUrl + path"> <a-icon type="home" /> 返回门户 </a>
<a :href="portalUrl + (path ? path : '')">
<a-icon type="home" /> 返回门户
</a>
</a-tooltip>
<!-- <a-tooltip class="header-item" title="数据可视化" placement="bottom">
<a href="" target="_blank"> <a-icon type="setting" /> 数据可视化 </a>
......@@ -96,7 +98,7 @@ export default {
{ key: "US", name: "English", alias: "English" },
],
searchActive: false,
portalUrl: process.env.VUE_APP_API_portal_URL,
portalUrl: process.env.VUE_APP_API_portal_URL + "/#",
};
},
computed: {
......
......@@ -134,7 +134,7 @@ export default {
const { siteTree } = data;
this.sitelist = siteTree;
let arr = [];
const treeFn = function (e) {
const treeFn = function(e) {
e.forEach((element) => {
arr.push(element);
if (element.children && element.children.length > 0) {
......
import Vue from "vue";
import App from "./App.vue";
import { initRouter } from "./router";
import "./theme/index.less";
import Antd from "ant-design-vue";
// import Viser from 'viser-vue'
// import '@/mock'
import store from "./store";
import "animate.css/source/animate.css";
import "./assets/css/common.less";
import "./assets/css/relas.less";
import "./assets/css/use.less";
import Plugins from "@/plugins";
import { initI18n } from "@/utils/i18n";
import { router } from "@/router";
import { i18n } from "@/utils/i18n";
import bootstrap from "@/bootstrap";
import "moment/locale/zh-cn";
import VueResource from "vue-resource";
......@@ -48,6 +46,9 @@ Vue.use(Viewer);
// moment 时间处理
import moment from "moment";
Vue.prototype.$moment = moment;
// 引入lodash
import lodash from "lodash";
Vue.prototype.$_ = lodash;
// nanoid
import { nanoid } from "nanoid";
Vue.prototype.$nanoid = nanoid;
......@@ -55,14 +56,11 @@ Vue.prototype.$nanoid = nanoid;
import * as echarts from "echarts";
Vue.prototype.$echarts = echarts;
export const router = initRouter(store.state.setting.asyncRoutes);
const i18n = initI18n("CN", "US");
Vue.use(Antd);
Vue.config.productionTip = false;
// Vue.use(Viser)
Vue.use(Plugins);
Vue.use(VueResource);
bootstrap({ router, store, i18n, message: Vue.prototype.$message });
new Vue({
......
......@@ -16,49 +16,49 @@
<a-tab-pane key="ApplyMaterial">
<span slot="tab">
<a-icon type="container" />
<a-icon type="file" />
申请材料
</span>
</a-tab-pane>
<a-tab-pane key="AcceptMaterial">
<span slot="tab">
<a-icon type="container" />
<a-icon type="interaction" />
受理材料
</span>
</a-tab-pane>
<a-tab-pane key="Flow">
<span slot="tab">
<a-icon type="container" />
<a-icon type="cluster" />
办理流程
</span>
</a-tab-pane>
<a-tab-pane key="Rates">
<span slot="tab">
<a-icon type="container" />
<a-icon type="audit" />
收费标准
</span>
</a-tab-pane>
<a-tab-pane key="Pursuant">
<span slot="tab">
<a-icon type="container" />
<a-icon type="file-done" />
设定依据
</span>
</a-tab-pane>
<a-tab-pane key="Agency">
<span slot="tab">
<a-icon type="container" />
<a-icon type="solution" />
中介服务
</span>
</a-tab-pane>
<a-tab-pane key="Question">
<span slot="tab">
<a-icon type="container" />
<a-icon type="file-unknown" />
常见问题
</span>
</a-tab-pane>
......@@ -116,7 +116,7 @@ export default {
},
};
</script>
<style lang='less' scoped>
<style lang="less" scoped>
.addmatter {
width: 100%;
height: 100%;
......
......@@ -112,7 +112,9 @@ export default {
this.form.id && this.$delete(this.form, "id");
},
onEdit(data) {
this.$nextTick(() => {
this.form = { ...data };
});
},
handleReset() {
this.$refs.form.resetFields();
......@@ -125,5 +127,4 @@ export default {
};
</script>
<style lang="less" scoped>
</style>
\ No newline at end of file
<style lang="less" scoped></style>
......@@ -154,7 +154,9 @@ export default {
},
// 编辑
onEdit(data) {
this.$nextTick(() => {
this.form = { ...data };
});
},
// 关闭对话框
handleClose() {
......
......@@ -471,7 +471,9 @@ export default {
};
});
}
this.$nextTick(() => {
this.form = { ...data };
});
},
// 过滤附件数组
filterArr(arr, file) {
......
......@@ -20,7 +20,7 @@
:wrapper-col="{ span: 22 }"
>
<a-form-model-item label="应用主题">
{{ filterItems(appInfo.appThemeName, appDict.appThemeName) }}
{{ filterItems(appInfo.appThemeName) }}
</a-form-model-item>
<a-form-model-item label="应用简介">
{{ appInfo.summary }}
......@@ -117,10 +117,10 @@ import {
getVersionList,
usedVersion,
previewVersion,
getCategoryList,
} from "@/services/market";
import CheckSite from "../modal/CheckSite.vue";
import { pageSizeOptions } from "@/config/pageConfig.js";
import { filterItems } from "@/utils";
import { mapGetters } from "vuex";
export default {
props: {
......@@ -153,9 +153,7 @@ export default {
{
title: "更新说明",
width: "40%",
customRender: (text) => {
return <span>{text.notes ? text.notes : "--"}</span>;
},
dataIndex: "notes",
},
{
title: "应用包",
......@@ -172,7 +170,6 @@ export default {
},
];
return {
filterItems,
api: process.env.VUE_APP_API_BASE_URL + "/",
columns,
appId: this.$route.query.id,
......@@ -185,16 +182,30 @@ export default {
form: {},
tableData: [],
siteVisible: false,
categoryList: [],
};
},
computed: {
...mapGetters("site", ["appDict"]),
},
created() {
this.getCategoryList();
this.getAppInfo();
this.getVersions();
},
methods: {
// 获取分类列表
async getCategoryList() {
let res = await getCategoryList({
page: 1,
size: -1,
siteId: this.siteId,
});
if (res.data.code === 1) {
let { data } = res.data.data;
this.categoryList = data;
}
},
// 获取应用详情
async getAppInfo() {
let res = await getAppInfo({ id: this.appId });
......@@ -275,6 +286,15 @@ export default {
this.$refs.CheckSite.getSiteList(siteList);
this.siteVisible = true;
},
filterItems(appThemeName) {
if (!appThemeName) return;
let arr = this.categoryList.find((v) => v.id == appThemeName);
if (arr) {
return arr.categoryName;
} else {
return "--";
}
},
},
};
</script>
......
......@@ -75,11 +75,6 @@
:addVisile.sync="addVisile"
@addSuccess="getCategoryList"
></AddTheme>
<!-- 预览 -->
<PrevieModal
:previewData="previewData"
:previewVisible.sync="previewVisible"
></PrevieModal>
</div>
</template>
......@@ -88,7 +83,6 @@ import { getCategoryList, deleteCategory } from "@/services/market";
import AddTheme from "../modal/AddTheme";
import local from "@/utils/local";
import { pageSizeOptions } from "@/config/pageConfig.js";
import PrevieModal from "@/components/PrevieModal.vue";
const columns = [
{
title: "序号",
......@@ -135,15 +129,12 @@ const columns = [
export default {
components: {
AddTheme,
PrevieModal,
},
data() {
return {
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
columns,
previewData: {}, // 预览
previewVisible: false,
siteId: local.getLocal("siteId"),
tableData: [], // 表格数据
loading: false,
......@@ -254,11 +245,9 @@ export default {
},
// 预览封面
handlePreview(url) {
this.previewData = {
type: "img",
url: url,
};
this.previewVisible = true;
this.$viewerApi({
images: [url],
});
},
},
};
......
......@@ -2,7 +2,10 @@
<div class="data-update">
<!-- 头部 -->
<div class="header flex aic jcb mb20 pdr6">
<a-space>
<a-button type="primary" @click="handleAdd">新增</a-button>
<a-button type="danger" @click="handleDelAll">批量删除</a-button>
</a-space>
<div class="search-box">
<a-input-group compact>
<a-select style="min-width: 100px" v-model="fieldCode">
......@@ -54,6 +57,10 @@
onShowSizeChange: showSizeChange,
}"
:data-source="tableData"
:row-selection="{
selectedRowKeys: selectedRowKeys,
onChange: onSelectChange,
}"
:rowKey="(record) => record.id"
>
<!-- 序号 -->
......@@ -65,9 +72,9 @@
<template slot="img" slot-scope="text">
<img
v-if="text.img"
width="50"
:src="api2 + text.img"
@click="handlePreview('img', api2 + text.img)"
class="pre-item"
:src="filterRes(text.img)"
@click="handlePreview('img', text.img)"
/>
<span v-else>--</span>
</template>
......@@ -76,8 +83,8 @@
<video
v-if="text.video"
width="50"
:src="api2 + text.video"
@click="handlePreview('vidoe', api2 + text.video)"
:src="filterRes(text.video)"
@click="handlePreview('video', api2 + text.video)"
/>
<span v-else>--</span>
</template>
......@@ -147,6 +154,7 @@ export default {
previewVisible: false,
previewData: {}, // 预览信息
appTemplate: [], // 字段模板列表
selectedRowKeys: [],
};
},
computed: {
......@@ -241,13 +249,14 @@ export default {
return;
}
this.title = "新增";
let arr = JSON.parse(JSON.stringify(this.appTemplate));
let arr = this.$_.cloneDeep(this.appTemplate);
this.$refs.AddData.onAdd(arr);
this.AddVisible = true;
},
// 搜索
onSearch() {
this.current = 1;
this.selectedRowKeys = [];
this.getDatasetList();
},
// 翻页
......@@ -267,6 +276,19 @@ export default {
this.$refs.AddData.onEdit(row);
this.AddVisible = true;
},
// 选择
onSelectChange(keys) {
this.selectedRowKeys = keys;
},
// 批量删除
handleDelAll() {
if (!this.selectedRowKeys.length) {
this.$message.warn("请先勾选数据");
return;
}
let ids = this.selectedRowKeys.join(",");
this.handleDel(ids);
},
// 删除
handleDel(id) {
let _this = this;
......@@ -284,6 +306,7 @@ export default {
let { code, msg } = res.data;
if (code === 1) {
_this.$message.success(msg);
_this.selectedRowKeys = [];
_this.getDatasetList();
}
},
......@@ -292,13 +315,30 @@ export default {
},
});
},
// 过滤影音
filterRes(data) {
let resource = data.split(",").map((v) => {
return this.api2 + v;
});
return resource[0];
},
// 预览
handlePreview(type, url) {
handlePreview(type, data) {
let resource = data.split(",").map((v) => {
return this.api2 + v;
});
if (type == "img") {
this.$viewerApi({
images: resource,
});
} else {
this.previewData = {
type,
url,
url: resource[0],
};
this.previewVisible = true;
}
},
},
};
......@@ -311,6 +351,7 @@ export default {
}
img,
video {
width: 50px;
cursor: pointer;
}
</style>
\ No newline at end of file
......@@ -2,7 +2,10 @@
<div class="field-config">
<!-- 头部 -->
<div class="header flex aic jcb mb20 pdr6">
<a-space>
<a-button type="primary" @click="handleAdd">新增字段</a-button>
<a-button type="danger" @click="handleDelAll">批量删除</a-button>
</a-space>
<a-input-search
style="width: 300px"
placeholder="请输入字段名称搜索"
......@@ -31,6 +34,10 @@
onShowSizeChange: showSizeChange,
}"
:data-source="tableData"
:row-selection="{
selectedRowKeys: selectedRowKeys,
onChange: onSelectChange,
}"
:rowKey="(record) => record.id"
>
<!-- 序号 -->
......@@ -131,6 +138,7 @@ export default {
tableData: [],
fieldVisible: false,
title: "",
selectedRowKeys: [],
};
},
created() {
......@@ -168,6 +176,7 @@ export default {
// 搜索
onSearch() {
this.current = 1;
this.selectedRowKeys = [];
this.getTempleteList();
},
// 翻页
......@@ -187,6 +196,19 @@ export default {
this.$refs.AddField.onEdit(row);
this.fieldVisible = true;
},
// 选择
onSelectChange(keys) {
this.selectedRowKeys = keys;
},
// 批量删除
handleDelAll() {
if (!this.selectedRowKeys.length) {
this.$message.warn("请先勾选数据");
return;
}
let ids = this.selectedRowKeys.join(",");
this.handleDel(ids);
},
// 删除
handleDel(id) {
let _this = this;
......@@ -204,6 +226,7 @@ export default {
let { code, msg } = res.data;
if (code === 1) {
_this.$message.success(msg);
_this.selectedRowKeys = [];
_this.getTempleteList();
}
},
......
......@@ -23,7 +23,7 @@
}"
:loading="loading"
bordered
:scroll="{ y: 580 }"
:scroll="{ y: 560 }"
:columns="columns"
:pagination="{
showTotal: (total) => `共 ${total} 条`,
......@@ -47,9 +47,11 @@
<template slot="appIconPath" slot-scope="text">
<img
v-if="text.appIconPath"
class="pointer"
height="20"
width="20"
:src="api2 + text.appIconPath"
@click="handlePreview(api2 + text.appIconPath)"
/>
<span v-else>--</span>
</template>
......@@ -374,9 +376,18 @@ export default {
},
// 过滤分类展示
filterItems(appThemeName) {
return (
this.categoryList.find((v) => v.id == appThemeName).categoryName || "--"
);
let row = this.categoryList.find((v) => v.id == appThemeName);
let str = "--";
if (row) {
str = row.categoryName;
}
return str;
},
// 预览图片
handlePreview(url) {
this.$viewerApi({
images: [url],
});
},
},
};
......
......@@ -23,7 +23,7 @@
}"
:loading="loading"
bordered
:scroll="{ y: 580 }"
:scroll="{ y: 560 }"
:columns="columns"
:pagination="{
showTotal: (total) => `共 ${total} 条`,
......@@ -47,9 +47,11 @@
<template slot="appIconPath" slot-scope="text">
<img
v-if="text.appIconPath"
class="pointer"
height="20"
width="20"
:src="api2 + text.appIconPath"
@click="handlePreview(api2 + text.appIconPath)"
/>
<span v-else>--</span>
</template>
......@@ -213,7 +215,6 @@ export default {
...mapMutations("site", ["SET_appDict"]),
// 获取分类列表
async getCategoryList() {
this.loading = true;
let res = await getCategoryList({
page: 1,
size: -1,
......@@ -359,9 +360,18 @@ export default {
},
// 过滤分类展示
filterItems(appThemeName) {
return (
this.categoryList.find((v) => v.id == appThemeName).categoryName || "--"
);
let row = this.categoryList.find((v) => v.id == appThemeName);
let str = "--";
if (row) {
str = row.categoryName;
}
return str;
},
// 预览图片
handlePreview(url) {
this.$viewerApi({
images: [url],
});
},
},
};
......
......@@ -143,15 +143,10 @@
}"
>
<a-space size="middle">
<a-button @click="onClose"> 取消 </a-button>
<a-button @click="resetForm"> 重置 </a-button>
<a-button type="primary" @click="onSubmit"> 确定 </a-button>
</a-space>
</div>
<!-- 预览 -->
<PrevieModal
:previewData="previewData"
:previewVisible.sync="previewVisible"
></PrevieModal>
</a-drawer>
</div>
</template>
......@@ -162,11 +157,9 @@ import { saveApp } from "@/services/market";
import { mapGetters } from "vuex";
import { changeCodeNumber } from "@/utils/validate";
// import local from "@/utils/local";
import PrevieModal from "@/components/PrevieModal.vue";
export default {
components: {
YSwitch,
PrevieModal,
},
props: {
title: {
......@@ -190,8 +183,6 @@ export default {
accept: "image/jpeg,image/png,image/svg+xml",
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
previewData: {}, // 预览
previewVisible: false,
iconFileList: [],
labelCol: {
span: 3,
......@@ -278,8 +269,14 @@ export default {
onClose() {
this.$refs.form.resetFields();
this.fileList = [];
this.iconFileList = [];
this.Visible = false;
},
resetForm() {
this.fileList = [];
this.iconFileList = [];
this.$refs.form.resetFields();
},
// 提交
onSubmit() {
this.$refs.form.validate(async (valid) => {
......@@ -311,15 +308,6 @@ export default {
},
// 上传图标
handleChangeIcon({ fileList }) {
// if (info.file.status === "uploading") {
// this.loading = true;
// return;
// }
// if (info.file.status === "done") {
// this.form.appIconPath = info.file.response.url;
// this.loading = false;
// }
this.iconFileList = [...fileList].slice(-1);
this.iconFileList = this.iconFileList.map((v) => {
if (v.response) {
......@@ -336,11 +324,9 @@ export default {
},
// 预览
handlePreview(info) {
this.previewData = {
type: "img",
url: info.url,
};
this.previewVisible = true;
this.$viewerApi({
images: [info.url],
});
},
// 上传应用
handleChangeFile(info) {
......@@ -369,6 +355,7 @@ export default {
},
// 编辑
onEdit(data) {
this.$nextTick(() => {
this.form = { ...data };
this.fileList = [
{
......@@ -387,7 +374,9 @@ export default {
url2: this.form.appIconPath,
},
];
});
},
// 选中站点
changeSite(value, label) {
this.form.siteName = label[0];
......@@ -397,6 +386,10 @@ export default {
let val = e.target.value;
if (val == 1) {
this.form.url = "";
} else {
this.form.filePath = "";
this.form.fileName = "";
this.fileList = [];
}
},
},
......
......@@ -5,13 +5,8 @@
:maskClosable="false"
:title="title"
@cancel="handleClose"
destroyOnClose
centered
>
<template slot="footer">
<a-button @click="handleReset">重置</a-button>
<a-button type="primary" @click="handleOk">确定</a-button>
</template>
<a-form-model
ref="form"
:model="form"
......@@ -46,11 +41,10 @@
<a-input-number v-model="form.sort" :min="1" />
</a-form-model-item>
</a-form-model>
<!-- 预览 -->
<PrevieModal
:previewData="previewData"
:previewVisible.sync="previewVisible"
></PrevieModal>
<template slot="footer">
<a-button @click="handleReset">重置</a-button>
<a-button type="primary" @click="handleOk">确定</a-button>
</template>
</a-modal>
</div>
</template>
......@@ -58,7 +52,6 @@
<script>
import { saveCategory } from "@/services/market";
import local from "@/utils/local";
import PrevieModal from "@/components/PrevieModal.vue";
export default {
props: {
addVisile: {
......@@ -71,17 +64,13 @@ export default {
default: "新增分类",
},
},
components: {
PrevieModal,
},
components: {},
data() {
return {
accept: "image/jpeg,image/png",
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
fileList: [],
previewData: {}, // 预览
previewVisible: false,
form: {
siteId: local.getLocal("siteId"), // 站点id
siteName: local.getLocal("siteName"), // 站点名称
......@@ -120,6 +109,7 @@ export default {
},
// 编辑
onEdit(data) {
this.$nextTick(() => {
this.form = { ...data };
if (this.form.cover) {
this.fileList = [
......@@ -132,6 +122,7 @@ export default {
},
];
}
});
},
// 关闭弹窗
handleClose() {
......@@ -184,14 +175,13 @@ export default {
},
// 预览
handlePreview(info) {
this.previewData = {
type: "img",
url: info.url,
};
this.previewVisible = true;
this.$viewerApi({
images: [info.url],
});
},
// 重置
handleReset() {
this.fileList = [];
this.$refs.form.resetFields();
},
},
......
......@@ -157,11 +157,13 @@ export default {
},
// 编辑
onEdit(data) {
this.$nextTick(() => {
this.getBusinessData();
this.form = { ...data };
if (this.form.parentId == 0) {
this.form.parentId = undefined;
}
});
},
// 切换业务级别
changeIsBusiness() {
......
......@@ -30,7 +30,7 @@
:loading="loading"
bordered
:columns="columns"
:scroll="{ y: 580 }"
:scroll="{ y: 560 }"
:pagination="{
showTotal: (total) => `共 ${total} 条`,
current: current,
......@@ -60,7 +60,13 @@
<img width="30" height="30" :src="api2 + text.modelIcon" />
</div> -->
<div class="svg-box">
<img width="30" height="30" :src="api2 + text.modelIcon" />
<img
class="pointer"
width="30"
height="30"
:src="api2 + text.modelIcon"
@click="handlePreview({ url: api2 + text.modelIcon })"
/>
</div>
</div>
<span v-else>--</span>
......@@ -220,11 +226,6 @@
</a-col>
</a-row>
</a-form-model>
<!-- 预览 -->
<PrevieModal
:previewData="previewData"
:previewVisible.sync="previewVisible"
></PrevieModal>
</a-modal>
<!-- 报表管理 -->
<StatementManage
......@@ -236,7 +237,6 @@
<script>
import { modelList, addMode, delMode } from "@/services/basicsetFun";
import PrevieModal from "@/components/PrevieModal.vue";
import StatementManage from "./components/StatementManage.vue";
import TabHeader from "@/components/TabHeader";
import { pageSizeOptions } from "@/config/pageConfig.js";
......@@ -294,7 +294,6 @@ const columns = [
];
export default {
components: {
PrevieModal,
StatementManage,
TabHeader,
},
......@@ -304,8 +303,6 @@ export default {
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
accept: "image/jpeg,image/png,image/svg+xml", // 上传类型
previewData: {}, // 预览
previewVisible: false,
columns,
loading: true,
title: "新增模块",
......@@ -502,11 +499,9 @@ export default {
},
// 预览
handlePreview(info) {
this.previewData = {
type: "img",
url: info.url,
};
this.previewVisible = true;
this.$viewerApi({
images: [info.url],
});
},
// 关闭对话框
......
......@@ -119,8 +119,10 @@ export default {
},
// 编辑
onEdit(data, modelInfo) {
this.$nextTick(() => {
this.modelInfo = modelInfo;
this.formData = { ...data };
});
},
// 关闭弹窗
handleClose() {
......@@ -149,5 +151,4 @@ export default {
};
</script>
<style lang="less" scoped>
</style>
\ No newline at end of file
<style lang="less" scoped></style>
......@@ -92,6 +92,12 @@
</a-col>
</a-row>
</a-form-model>
<div slot="footer">
<a-button @click="resetForm">重置</a-button>
<a-button :loading="loading" type="primary" @click="handleOk"
>确定</a-button
>
</div>
</a-modal>
</template>
......@@ -114,6 +120,7 @@ export default {
// }
// };
return {
loading: false,
labelCol: { span: 6 },
wrapperCol: { span: 14 },
siteInfo: {
......@@ -179,9 +186,11 @@ export default {
},
// 编辑
onEdit(data) {
this.$nextTick(() => {
this.siteInfo.siteName = data.siteName;
this.siteInfo.siteId = data.siteId;
this.form = { ...data };
});
},
// 保存
handleOk() {
......@@ -206,6 +215,10 @@ export default {
this.$refs.formData.resetFields();
this.Visible = false;
},
// 重置
resetForm() {
this.$refs.formData.resetFields();
},
},
};
</script>
......
<template>
<a-modal
:title="WindowTitle"
@ok="handleAdd"
:visible="Visible"
@cancel="handleClose"
:maskClosable="false"
......@@ -188,6 +187,12 @@
</a-col>
</a-row>
</a-form-model>
<div slot="footer">
<a-button @click="resetForm">重置</a-button>
<a-button :loading="loading" type="primary" @click="handleOk"
>确定</a-button
>
</div>
</a-modal>
</template>
......@@ -202,6 +207,7 @@ export default {
},
data() {
return {
loading: false,
labelCol: { span: 6 },
wrapperCol: { span: 14 },
siteInfo: {
......@@ -288,18 +294,22 @@ export default {
},
// 编辑
onEdit(row) {
this.$nextTick(() => {
this.siteInfo.siteName = row.siteName;
this.siteInfo.siteId = row.siteId;
this.form = { ...row };
});
},
// 保存
async handleAdd() {
async handleOk() {
this.$refs.formData.validate(async (valid) => {
if (valid) {
this.loading = true;
let res = await addWindow({
...this.form,
...this.siteInfo,
});
this.loading = false;
let { code, msg } = res.data;
if (code === 1) {
this.$message.success(msg);
......@@ -314,6 +324,10 @@ export default {
this.$refs.formData.resetFields();
this.Visible = false;
},
// 重置
resetForm() {
this.$refs.formData.resetFields();
},
// 改变无人值守
changeDuty(val) {
if (!val) {
......
......@@ -59,9 +59,7 @@
</div>
</div>
<div>
<div class="department_span">
简称:{{ v.deptAbb ? v.deptAbb : "--" }}
</div>
<div>简称:{{ v.deptAbb ? v.deptAbb : "--" }}</div>
<div>
联系电话:{{ v.deptTelphone ? v.deptTelphone : "--" }}
</div>
......@@ -127,7 +125,7 @@
<div class="table-content">
<!-- 表格 -->
<a-table
:scroll="{ y: 560 }"
:scroll="{ y: 550 }"
:loading="loading"
bordered
:columns="columns"
......@@ -687,7 +685,6 @@ export default {
}
.department_span {
margin-right: 3px;
font-size: 5px;
}
.department_off {
// margin-left: 20px;
......
......@@ -5,12 +5,7 @@
:maskClosable="false"
:title="title"
@cancel="handleClose"
destroyOnClose
>
<template slot="footer">
<a-button @click="handleReset">重置</a-button>
<a-button type="primary" @click="handleOk">确定</a-button>
</template>
<a-form-model
ref="form"
:model="form"
......@@ -44,11 +39,15 @@
/>
</a-form-model-item>
</a-form-model>
<template slot="footer">
<a-button @click="handleReset">重置</a-button>
<a-button type="primary" @click="handleOk">确定</a-button>
</template>
</a-modal>
</div>
</template>
<script>
<script>
import { saveHall } from "@/services/hall";
import loacl from "@/utils/local";
export default {
......@@ -100,7 +99,9 @@ export default {
},
// 编辑
onEdit(data) {
this.$nextTick(() => {
this.form = { ...data };
});
},
// 关闭弹窗
handleClose() {
......
......@@ -5,7 +5,6 @@
:maskClosable="false"
title="新增大厅窗口"
@cancel="handleClose"
destroyOnClose
centered
>
<template slot="footer">
......@@ -36,7 +35,8 @@
</div>
</template>
<script>
<script>
import local from "@/utils/local";
import {
// saveWindowHall,
batchSaveWindowHall,
......@@ -60,6 +60,7 @@ export default {
data() {
return {
selectInfo: undefined,
siteId: local.getLocal("siteId"), // 站点id
form: {
windowId: "", // 窗口id
windowName: "", // 窗口名称
......@@ -94,7 +95,9 @@ export default {
},
// 新增
onAdd(rows) {
this.$nextTick(() => {
this.windowList = rows;
});
// this.form.windowId = rows.id;
// this.form.windowName = rows.name;
},
......@@ -115,6 +118,7 @@ export default {
windowName: v.name, // 窗口名称
hallId: this.form.hallId, // 大厅id
hallName: this.form.hallName, // 大厅名称
siteId: this.siteId,
};
});
let res = await batchSaveWindowHall(arr);
......@@ -136,5 +140,4 @@ export default {
};
</script>
<style lang="less" scoped>
</style>
\ No newline at end of file
<style lang="less" scoped></style>
......@@ -2,7 +2,6 @@
<a-modal
:maskClosable="false"
:title="title"
@ok="handleOk"
:visible="Visible"
@cancel="handleClose"
>
......@@ -34,6 +33,12 @@
<a-textarea v-model="form.summary" placeholder allow-clear />
</a-form-model-item>
</a-form-model>
<div slot="footer">
<a-button @click="resetForm">重置</a-button>
<a-button :loading="loading" type="primary" @click="handleOk"
>确定</a-button
>
</div>
</a-modal>
</template>
......@@ -41,8 +46,15 @@
import { addHoliday } from "@/services/festival";
import locale from "ant-design-vue/es/date-picker/locale/zh_CN";
export default {
props: {
visibleDay: {
type: Boolean,
default: false,
},
},
data() {
return {
loading: false,
locale,
title: "选择节假日",
date: [], // 日期
......@@ -71,10 +83,15 @@ export default {
},
};
},
props: {
visibleDay: {
type: Boolean,
default: false,
computed: {
Visible: {
get() {
return this.visibleDay;
},
set(val) {
this.$emit("update:visibleDay", val);
},
},
},
methods: {
......@@ -82,6 +99,7 @@ export default {
handleOk() {
this.$refs.ruleForm.validate(async (valid) => {
if (valid) {
this.loading = true;
let year = new Date(parseInt(this.form.startTime)).getFullYear();
let res = await addHoliday({
...this.form,
......@@ -95,6 +113,7 @@ export default {
this.handleClose();
this.$parent.getHolidayData();
}
this.loading = false;
}
});
},
......@@ -114,22 +133,19 @@ export default {
// 编辑
onEdit(data) {
this.title = "编辑节假日";
this.$nextTick(() => {
this.date = [String(data.startTime), String(data.endTime)];
this.form = { ...data };
});
},
handleClose() {
this.Visible = false;
this.$refs.ruleForm.resetFields();
},
},
computed: {
Visible: {
get() {
return this.visibleDay;
},
set(val) {
this.$emit("update:visibleDay", val);
},
// 重置
resetForm() {
this.date = [];
this.$refs.ruleForm.resetFields();
},
},
};
......
......@@ -7,6 +7,7 @@
<script>
import local from "@/utils/local";
import { mapMutations } from "vuex";
import { createMenus } from "@/router";
export default {
data() {
return {};
......@@ -26,8 +27,15 @@ export default {
]),
// 获取token
getToken() {
let { token, userInfo, siteid, siteName, sysName, sysLogo, path } =
this.$route.query;
let {
token,
userInfo,
siteid,
siteName,
sysName,
sysLogo,
path,
} = this.$route.query;
if (token && userInfo) {
userInfo = JSON.parse(userInfo);
this.SET_userInfo(userInfo);
......@@ -39,6 +47,8 @@ export default {
this.SET_path(path);
local.setLocal("siteId", siteid);
local.setLocal("siteName", siteName);
// 动态菜单
createMenus();
this.$router.push("/website");
} else {
this.$message.warning("跳转失败,请重新登录");
......
......@@ -36,10 +36,10 @@
</a-form-model-item>
</a-col>
<a-col :span="8">
<a-form-model-item label="区域编号" prop="areaCode">
<a-form-model-item label="区域编号">
<a-input
v-model="areaInfo.areaCode"
readOnly
disabled
type="text"
placeholder="请输入区域编号"
/> </a-form-model-item
......@@ -282,8 +282,9 @@
</a-form-model-item>
</a-col>
</a-row>
<div class="color_title">部署板块</div>
<div v-permission="[1]" class="color_title">部署板块</div>
<a-form-model-item
v-permission="[1]"
:label-col="{ span: 2 }"
:wrapper-col="{ span: 22 }"
class="model-id"
......@@ -299,11 +300,6 @@
</a-form-model>
</div>
</a-modal>
<!-- 预览 -->
<PrevieModal
:previewData="previewData"
:previewVisible.sync="previewVisible"
></PrevieModal>
</div>
</template>
<script>
......@@ -312,7 +308,6 @@ import YCheckbox from "@/components/ycheckbox/YCheckbox.vue";
import YSwitch from "@/components/yswitch/YSwitch.vue";
// import options from "@/utils/city";
import { regionData } from "element-china-area-data";
import PrevieModal from "@/components/PrevieModal.vue";
export default {
props: {
formVisible: {
......@@ -326,7 +321,6 @@ export default {
},
components: {
YCheckbox,
PrevieModal,
YSwitch,
},
data() {
......@@ -356,8 +350,6 @@ export default {
api2: process.env.VUE_APP_API_IMG_URL,
accept: "image/jpeg,image/png", // 上传类型
loading: false,
previewData: {}, // 预览logo信息
previewVisible: false,
options: regionData, // 地区级联数据
tablename: "", //接口名称
modelIds: [], // 板块数据
......@@ -575,7 +567,6 @@ export default {
},
created() {
this.getModel();
console.log(process.env.NODE_ENV);
},
computed: {
Visible: {
......@@ -605,6 +596,7 @@ export default {
//重置
resetForm() {
this.fileList = [];
this.cityData = [];
this.$refs.ruleForm.resetFields();
},
// 关闭对话框
......@@ -621,6 +613,7 @@ export default {
},
// 编辑
onEdit(data) {
this.$nextTick(() => {
this.formInfo = { ...data };
this.areaInfo.areaID = this.formInfo.areaID;
this.areaInfo.areaCode = this.formInfo.areaCode;
......@@ -646,6 +639,7 @@ export default {
},
];
}
});
},
// 保存
handleOk() {
......@@ -711,11 +705,9 @@ export default {
},
// 预览logo
handlePreview(info) {
this.previewData = {
type: "img",
url: info.url,
};
this.previewVisible = true;
this.$viewerApi({
images: [info.url],
});
},
// 删除logo
// handleRemove() {
......@@ -740,8 +732,10 @@ export default {
})
.then((res) => {
let { location } = res.geocodes[0];
[this.formInfo.longitude, this.formInfo.latitude] =
location.split(",");
[
this.formInfo.longitude,
this.formInfo.latitude,
] = location.split(",");
})
.catch(() => {
this.$message.error("经纬度获取失败,请输入正确的地址");
......@@ -822,7 +816,7 @@ export default {
}
.ant-checkbox-group {
display: grid;
grid-template-columns: 260px 260px 260px 260px;
grid-template-columns: repeat(3, 320px);
}
.ant-checkbox-wrapper {
margin-left: 0px;
......
<template>
<div class="configurat">
<div class="title">短信全局配置</div>
<div class="set-configurat">
<y-switch
v-model="setInfo.messageoff"
checkedChildren="开"
unCheckedChildren="关"
@change="changeClose"
></y-switch>
<div class="des">
全局配置,一键控制
</div>
<div class="des">
轻松管理政务短信通知的全局设置,确保信息的准确传递
</div>
<div class="tag-list">
<div class="tag-item" v-for="v in tagList" :key="v">
{{ v }}
</div>
</div>
<YButton v-model="setInfo.messageoff" @change="changeClose"></YButton>
</div>
</template>
<script>
import YSwitch from "@/components/yswitch/YSwitch.vue";
import YButton from "@/components/YButton";
import { getSmssetList, saveSmssetList } from "@/services/configurat";
import local from "@/utils/local";
export default {
components: {
YSwitch,
YButton,
},
data() {
return {
tagList: ["全局管控", "精准到达", "远程监管", "贴心服务"],
setInfo: {
siteId: local.getLocal("siteId"),
messageoff: "",
......@@ -53,6 +58,8 @@ export default {
let { code, msg } = res.data;
if (code === 1) {
this.$message.success(msg);
} else {
this.getSmssetList();
}
},
},
......@@ -63,36 +70,41 @@ export default {
.configurat {
width: 100%;
height: 100%;
padding: 20px;
.main {
height: 100%;
display: flex;
.set-configurat {
margin-left: 20px;
}
.left {
width: 224px;
margin-right: 20px;
}
.right {
height: 200px;
padding: 15px;
flex: 1;
background-color: #fff;
padding: 115px 80px;
background: url("~@/assets/img/sms_bg.jpg") no-repeat center/100% 100%;
.title {
margin-bottom: 35px;
font-size: 44px;
font-family: Source Han Sans CN;
font-weight: bold;
color: #0857e8;
}
.des {
font-size: 20px;
font-family: Source Han Sans CN;
font-weight: 500;
color: #365182;
line-height: 35px;
}
.title {
margin-left: 15px;
position: relative;
margin-bottom: 15px;
&::before {
content: "";
width: 4px;
height: 20px;
position: absolute;
top: 1px;
left: -16px;
background-color: rgba(5, 149, 253, 1);
.tag-list {
margin-top: 38px;
margin-bottom: 40px;
display: flex;
align-items: center;
gap: 26px;
.tag-item {
width: 138px;
height: 50px;
background: rgba(8, 87, 232, 0.05);
border-radius: 24px;
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
font-family: Source Han Sans CN;
font-weight: 500;
color: #232323;
}
}
}
......
......@@ -245,6 +245,10 @@ const rightColumns = [
title: "字段名称",
dataIndex: "fieldName",
},
{
title: "字段编码",
dataIndex: "fieldCode",
},
{
title: "数据类型",
scopedSlots: {
......
......@@ -2,7 +2,7 @@
<div class="skin-box">
<!-- 评价器 横板皮肤 -->
<div
:id="conponentsId"
:id="componentsId"
class="call-out-skin-across"
v-if="imageResolution === '1'"
:style="{
......@@ -125,7 +125,7 @@ export default {
required: true,
default: "1",
},
conponentsId: {
componentsId: {
required: true,
type: String,
},
......
......@@ -2,7 +2,7 @@
<div class="skin-box">
<!-- 呼叫器 横板皮肤 -->
<div
:id="conponentsId"
:id="componentsId"
class="call-out-skin-across"
v-if="imageResolution === '1'"
:style="{
......@@ -151,7 +151,7 @@ export default {
required: true,
default: "1",
},
conponentsId: {
componentsId: {
required: true,
type: String,
},
......
......@@ -3,7 +3,7 @@
<!-- 集中显示屏 横板 -->
<div
class="centralize-across"
:id="conponentsId"
:id="componentsId"
v-if="imageResolution === '1'"
:style="{
background: filterItem('1', 0),
......@@ -160,7 +160,7 @@
<!-- 集中显示屏 竖版 -->
<div
class="vertical-skin"
:id="conponentsId"
:id="componentsId"
v-else-if="imageResolution === '2'"
:style="{
background: filterItem('1', 0),
......@@ -301,7 +301,7 @@ export default {
required: true,
default: "1",
},
conponentsId: {
componentsId: {
required: true,
type: String,
},
......
......@@ -13,23 +13,42 @@
:class="{ active: i === isActive }"
v-for="(v, i) in productList"
:key="v.id"
@click="changeMenu(i, v)"
@click.self="changeMenu(i, v)"
style="width: 50%; text-align: center"
>
<div class="control" v-permission="[1]">
<a-space>
<a-icon type="edit" @click="handleEdit(v)" />
<a-icon type="delete" @click="handleDel(v.id)" />
</a-space>
</div>
{{ v.productName }}
</a-card-grid>
</div>
<!-- 编辑产品 -->
<AddDev
ref="AddDev"
:visible.sync="visible"
:title="title"
@addDev="getProductList"
></AddDev>
</div>
</template>
<script>
import { getProductList } from "@/services/surface";
import { getProductList, deleteProduct } from "@/services/surface";
import { mapMutations } from "vuex";
import AddDev from "../modal/AddDev.vue";
export default {
components: {
AddDev,
},
data() {
return {
productList: [], //产品列表
isActive: "",
visible: false,
title: "编辑产品",
};
},
created() {
......@@ -62,6 +81,38 @@ export default {
};
this.SET_curProduct(obj);
},
// 编辑产品
handleEdit(row) {
this.title = "编辑产品";
this.$refs.AddDev.onEdit(row);
this.visible = 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 deleteProduct({ id });
let { code, msg } = res.data;
if (code === 1) {
_this.$message.success(msg);
_this.getProductList();
}
},
onCancel() {
console.log("Cancel");
},
});
console.log(id);
},
},
beforeDestroy() {
this.SET_curProduct({});
......@@ -74,6 +125,7 @@ export default {
height: 100%;
background-color: #fff;
}
.search-box {
padding: 15px 15px 0px;
}
......@@ -85,6 +137,9 @@ export default {
.active {
background-color: #1890ff;
color: #fff;
.anticon {
color: inherit;
}
}
}
/deep/.ant-card-grid {
......@@ -93,5 +148,23 @@ export default {
align-items: center;
justify-content: center;
cursor: pointer;
position: relative;
&:hover {
.control {
display: block;
}
}
}
.control {
position: absolute;
right: 10px;
top: 0px;
display: none;
.anticon-edit {
color: #03d76f;
}
.anticon-delete {
color: #fa4d4c;
}
}
</style>
\ No newline at end of file
......@@ -194,6 +194,7 @@ export default {
.preview-btn {
border-top: 1px solid #ccc;
height: 100px;
padding: 0px 10px;
display: flex;
flex-direction: column;
justify-content: center;
......
......@@ -14,7 +14,7 @@
</div>
<div class="show-skin flex aic jcc">
<component
conponentsId="skinInfo"
componentsId="skinInfo"
:is="component"
:imageResolution="curSkin.imageResolution"
:skinFieldList="curSkin.skinFieldList"
......
......@@ -2,7 +2,7 @@
<div class="skin-box">
<!-- 桌面自助服务终端 横板 -->
<div
:id="conponentsId"
:id="componentsId"
v-if="imageResolution === '1'"
class="across-skin flex flexc aic"
:style="{
......@@ -108,7 +108,7 @@ export default {
required: true,
default: "1",
},
conponentsId: {
componentsId: {
required: true,
type: String,
},
......
......@@ -2,7 +2,7 @@
<div class="skin-box">
<!-- 信息发布 横板皮肤 -->
<div
:id="conponentsId"
:id="componentsId"
class="across-skin flex flexc"
v-if="imageResolution === '1'"
>
......@@ -45,7 +45,7 @@
</div>
<!-- 信息发布 竖版皮肤 -->
<div
:id="conponentsId"
:id="componentsId"
class="vertical-skin flex flexc"
v-else-if="imageResolution === '2'"
>
......@@ -114,7 +114,7 @@ export default {
required: true,
default: "1",
},
conponentsId: {
componentsId: {
required: true,
type: String,
},
......
<template>
<div>
<a-modal
v-model="Visible"
title="新增设备"
@ok="handleOk"
@cancel="handleClose"
>
<a-modal v-model="Visible" :title="title" @cancel="handleClose">
<a-form-model
:model="form"
ref="form"
......@@ -17,11 +12,7 @@
<a-input placeholder="请输入设备名称" v-model="form.productName" />
</a-form-model-item>
<a-form-model-item label="设备编号" prop="productCode">
<a-input
type="password"
placeholder="请输入设备编号"
v-model="form.productCode"
/>
<a-input placeholder="请输入设备编号" v-model="form.productCode" />
</a-form-model-item>
<a-form-model-item label="备注" prop="productRemark">
<a-textarea
......@@ -31,6 +22,10 @@
/>
</a-form-model-item>
</a-form-model>
<div slot="footer">
<a-button @click="resetForm">重置</a-button>
<a-button type="primary" @click="handleOk">确定</a-button>
</div>
</a-modal>
</div>
</template>
......@@ -44,6 +39,11 @@ export default {
type: Boolean,
default: false,
},
title: {
required: true,
type: String,
default: "新增设备",
},
},
data() {
return {
......@@ -91,6 +91,20 @@ export default {
this.$refs.form.resetFields();
this.Visible = false;
},
resetForm() {
this.$refs.form.resetFields();
},
// 新增
onAdd() {
Object.assign(this.form, this.$options.data().form);
this.form.id && this.$delete(this.form, "id");
},
// 编辑
onEdit(row) {
setTimeout(() => {
this.form = { ...row };
}, 10);
},
},
};
</script>
......
<template>
<div>
<a-modal
v-model="Visible"
:title="titleField"
@ok="handleOk"
@cancel="handleClose"
>
<a-modal v-model="Visible" :title="titleField" @cancel="handleClose">
<a-form-model
:model="formData"
ref="formData"
......@@ -54,6 +49,10 @@
<a-input-number v-model="formData.fieldOrderNo" :min="0" />
</a-form-model-item>
</a-form-model>
<div slot="footer">
<a-button @click="resetForm">重置</a-button>
<a-button type="primary" @click="handleOk">确定</a-button>
</div>
</a-modal>
</div>
</template>
......@@ -152,7 +151,10 @@ export default {
});
},
handleClose() {
this.$refs.formData.resetFields();
this.Visible = false;
},
resetForm() {
this.$refs.formData.resetFields();
},
changeTemplate(val, e) {
......@@ -166,7 +168,9 @@ export default {
},
// 编辑
onEdit(row) {
this.$nextTick(() => {
this.formData = { ...row };
});
},
},
};
......
......@@ -6,7 +6,7 @@
<div class="add-surface-preview">
<div ref="content" class="add-surface-preview-content">
<component
conponentsId="conponentsId"
componentsId="componentsId"
:is="component"
:skinFieldList="formData.skinFieldList"
:imageResolution="formData.imageResolution"
......@@ -351,9 +351,11 @@ export default {
item.fieldOrderNo = 1000;
}
}
v.skinFieldList.sort((a, b) => {
v.skinFieldList = v.skinFieldList
.sort((a, b) => {
return a.fieldOrderNo - b.fieldOrderNo;
});
})
.filter((v) => v.enabled != 0);
});
this.skinTemplate = data;
// this.formData.skinFieldList = this.skinTemplate[0].skinFieldList;
......@@ -401,11 +403,11 @@ export default {
this.$refs.formData.validate((valid) => {
if (valid) {
this.loading = true;
let conponentsId = document.getElementById("conponentsId");
let info = conponentsId.getBoundingClientRect();
let componentsId = document.getElementById("componentsId");
let info = componentsId.getBoundingClientRect();
let width = info.width;
let height = info.height;
html2canvas(conponentsId, {
html2canvas(componentsId, {
backgroundColor: null,
useCORS: true,
width: width,
......@@ -429,8 +431,8 @@ export default {
if (code === 1) {
this.formData.previewImagePath = res.data.url;
let result = await skinSave({
...this.curProduct,
...this.formData,
...this.curProduct,
});
let { code, msg } = result.data;
if (code === 1) {
......@@ -529,9 +531,9 @@ export default {
}
.upload-btn,
.select-color-btn {
background-color: #04cb8f;
background: #04cb8f !important;
color: #fff;
border: 1px solid #04cb8f;
border: 1px solid #04cb8f !important;
}
.color-ipt {
width: 100%;
......
<template>
<div>
<a-modal
v-model="Visible"
:title="titleTemplate"
@ok="handleOk"
@cancel="handleClose"
>
<a-modal v-model="Visible" :title="titleTemplate" @cancel="handleClose">
<a-form-model
:model="formData"
ref="formData"
......@@ -31,6 +26,10 @@
/>
</a-form-model-item>
</a-form-model>
<div slot="footer">
<a-button @click="resetForm">重置</a-button>
<a-button type="primary" @click="handleOk">确定</a-button>
</div>
</a-modal>
</div>
</template>
......@@ -108,8 +107,8 @@ export default {
this.formData.productName = text;
},
handleClose() {
this.Visible = false;
this.$refs.formData.resetFields();
this.Visible = false;
},
// 新增
onAdd() {
......@@ -118,8 +117,12 @@ export default {
},
// 编辑
onEdit(row) {
this.$nextTick(() => {
this.formData = { ...row };
console.log(row);
});
},
resetForm() {
this.$refs.formData.resetFields();
},
handleOk() {
this.$refs.formData.validate(async (valid) => {
......
......@@ -302,6 +302,7 @@ export default {
<style lang="less" scoped>
/deep/.ant-drawer-body {
height: 90%;
padding: 0px;
}
.classify {
height: 100%;
......@@ -310,6 +311,7 @@ export default {
.classify-list {
flex: 1;
margin-bottom: 10px;
padding: 20px;
overflow-y: auto;
}
.footer-btn {
......@@ -326,6 +328,7 @@ export default {
}
.skin-name {
margin-bottom: 0px;
align-items: flex-start;
/deep/ .ant-form-item-label {
line-height: 20px !important;
}
......
......@@ -2,7 +2,7 @@
<div class="skin-box">
<!-- 排号机 1920*1080 -->
<div
:id="conponentsId"
:id="componentsId"
class="across-skin"
v-if="imageResolution === '1'"
:style="{
......@@ -75,7 +75,7 @@
<!-- 排号机竖版 1080*1920 -->
<div
class="vertical-skin"
:id="conponentsId"
:id="componentsId"
v-else-if="imageResolution === '2'"
:style="{
background: filterItem('1', 0),
......@@ -173,7 +173,7 @@ export default {
required: true,
default: "1",
},
conponentsId: {
componentsId: {
required: true,
type: String,
},
......
......@@ -2,7 +2,7 @@
<div class="skin-box">
<!-- 样表机 横板 -->
<div
:id="conponentsId"
:id="componentsId"
v-if="imageResolution === '1'"
class="sample_form_skin flex flexc aic"
:style="{
......@@ -140,7 +140,7 @@ export default {
required: true,
default: "1",
},
conponentsId: {
componentsId: {
required: true,
type: String,
},
......
......@@ -2,7 +2,7 @@
<div class="skin-box">
<!-- 自助服务终端 横板 -->
<div
:id="conponentsId"
:id="componentsId"
v-if="imageResolution === '1'"
class="across-skin flex flexc aic"
:style="{
......@@ -108,7 +108,7 @@ export default {
required: true,
default: "1",
},
conponentsId: {
componentsId: {
required: true,
type: String,
},
......
......@@ -2,7 +2,7 @@
<div class="skin-box">
<!-- 导视机 横板 -->
<div
:id="conponentsId"
:id="componentsId"
v-if="imageResolution === '1'"
class="across-skin flex flexc aic"
>
......@@ -87,7 +87,7 @@ export default {
required: true,
default: "1",
},
conponentsId: {
componentsId: {
required: true,
type: String,
},
......
......@@ -3,7 +3,7 @@
<TabHeader label="皮肤管理">
<a-space>
<a-button v-permission="[1]" icon="plus" @click="addDev"
>新增设备</a-button
>新增产品</a-button
>
<a-button
type="primary"
......@@ -48,7 +48,12 @@
@addSkinSuccess="addSkinSuccess"
></AddSurface>
<!-- 新增设备 -->
<AddDev :visible.sync="addDevVisible" @addDev="addDevSuccess"></AddDev>
<AddDev
ref="AddDev"
:visible.sync="addDevVisible"
@addDev="addDevSuccess"
:title="title"
></AddDev>
</div>
</template>
......@@ -77,6 +82,7 @@ export default {
visible: false,
addDevVisible: false,
classifyList: [], //皮肤分类数据
title: "新增产品",
};
},
created() {
......@@ -113,8 +119,8 @@ export default {
},
// 编辑皮肤
editSkin(row) {
this.isShow = true;
this.$refs.AddSurface.onEdit(row);
this.isShow = true;
},
// 新增分类成功刷新数据
addCategorySuccess() {
......@@ -126,6 +132,8 @@ export default {
},
// 新增设备
addDev() {
this.title = "新增产品";
this.$refs.AddDev.onAdd();
this.addDevVisible = true;
},
// 新增设备成功
......
......@@ -2,7 +2,7 @@
<div class="skin-box">
<!-- 窗口屏 横板 -->
<div
:id="conponentsId"
:id="componentsId"
class="window-skin-across flex jcb aic"
v-if="imageResolution === '1'"
:style="{
......@@ -84,7 +84,7 @@ export default {
required: true,
default: "1",
},
conponentsId: {
componentsId: {
required: true,
type: String,
},
......
......@@ -2,7 +2,7 @@
<div class="skin-box">
<!-- 样表机 横板 -->
<div
:id="conponentsId"
:id="componentsId"
v-if="imageResolution === '1'"
class="sample_form_skin flex flexc aic"
:style="{
......@@ -179,7 +179,7 @@ export default {
required: true,
default: "1",
},
conponentsId: {
componentsId: {
required: true,
type: String,
},
......
......@@ -148,7 +148,9 @@ export default {
},
// 编辑
onEdit(row) {
this.$nextTick(() => {
this.form = { ...row };
});
},
// 保存
handleOk() {
......@@ -168,5 +170,4 @@ export default {
};
</script>
<style lang="less" scoped>
</style>
\ No newline at end of file
<style lang="less" scoped></style>
......@@ -209,7 +209,9 @@ export default {
},
// 编辑
onEdit(row) {
this.$nextTick(() => {
this.form = { ...row };
});
},
// 保存
handleOk() {
......@@ -229,5 +231,4 @@ export default {
};
</script>
<style lang="less" scoped>
</style>
\ No newline at end of file
<style lang="less" scoped></style>
......@@ -334,18 +334,12 @@
<a-button @click="handleReset">重置</a-button>
<a-button type="primary" @click="hideModal">确定</a-button>
</div>
<!-- 预览 -->
<PrevieModal
:previewData="previewData"
:previewVisible.sync="previewVisible"
></PrevieModal>
</a-modal>
</template>
<script>
import { getWindowList, saveWorkman } from "@/services/dept";
import { modelList } from "@/services/basicsetFun";
import PrevieModal from "@/components/PrevieModal.vue";
// import { changePhone, changeLandline } from "@/utils/validate";
export default {
props: {
......@@ -374,9 +368,7 @@ export default {
},
},
},
components: {
PrevieModal,
},
components: {},
data() {
const checkIdCard = (rule, value, callback) => {
if (!value) {
......@@ -395,8 +387,6 @@ export default {
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
accept: "image/jpeg,image/png", // 上传类型
previewData: {}, // 预览
previewVisible: false,
fileList: [],
loading: false,
imageUrl: "",
......@@ -537,11 +527,14 @@ export default {
},
// 编辑
onEdit(data) {
this.$nextTick(() => {
// this.editWindow(data.deptId);
this.form = { ...data };
this.form.loginName && this.$delete(this.form, "loginName");
this.form.loginPwd && this.$delete(this.form, "loginPwd");
this.form.windowId = this.form.windowId ? this.form.windowId : undefined;
this.form.windowId = this.form.windowId
? this.form.windowId
: undefined;
if (this.form.photoPath) {
this.fileList = [
{
......@@ -553,6 +546,7 @@ export default {
},
];
}
});
},
// 关闭对话框
handleClose() {
......@@ -566,6 +560,7 @@ export default {
// 重置
handleReset() {
// this.form.windowName = "";
this.fileList = [];
this.$refs.formData.resetFields();
},
// 照片上传
......@@ -586,11 +581,9 @@ export default {
},
// 预览
handlePreview(info) {
this.previewData = {
type: "img",
url: info.url,
};
this.previewVisible = true;
this.$viewerApi({
images: [info.url],
});
},
// 照片大小格式限制
beforeUpload(file) {
......
......@@ -13,7 +13,7 @@
:label-col="{ span: 5 }"
:wrapper-col="{ span: 19 }"
>
<a-form-model-item label="账号" prop="loginName">
<a-form-model-item label="账号">
<a-input disabled placeholder="请输入账号" v-model="form.loginName" />
</a-form-model-item>
<!-- <a-form-model-item label="旧密码" prop="oldPwd">
......@@ -115,12 +115,15 @@ export default {
},
// 关闭对话框
handleClose() {
this.form.loginName = "";
this.$refs.form.resetFields();
this.Visible = false;
},
// 获取用户账号信息
getUserInfo(account) {
this.$nextTick(() => {
this.form.loginName = account;
});
},
},
};
......
......@@ -366,11 +366,6 @@
<a-button @click="handleReset">重置</a-button>
<a-button type="primary" @click="hideModal">确定</a-button>
</div>
<!-- 预览 -->
<PrevieModal
:previewData="previewData"
:previewVisible.sync="previewVisible"
></PrevieModal>
</a-modal>
</template>
......@@ -378,7 +373,6 @@
import { changeAccount, changePassWord } from "@/utils/validate";
import { getWindowList, saveWorkman } from "@/services/dept";
import { modelList } from "@/services/basicsetFun";
import PrevieModal from "@/components/PrevieModal.vue";
// import { changePhone, changeLandline } from "@/utils/validate";
import local from "@/utils/local";
export default {
......@@ -408,9 +402,7 @@ export default {
},
},
},
components: {
PrevieModal,
},
components: {},
data() {
const checkIdCard = (rule, value, callback) => {
if (!value) {
......@@ -429,8 +421,6 @@ export default {
api: process.env.VUE_APP_API_BASE_URL + "/",
api2: process.env.VUE_APP_API_IMG_URL,
accept: "image/jpeg,image/png", // 上传类型
previewData: {}, // 预览
previewVisible: false,
fileList: [],
loading: false,
imageUrl: "",
......@@ -626,11 +616,9 @@ export default {
},
// 预览
handlePreview(info) {
this.previewData = {
type: "img",
url: info.url,
};
this.previewVisible = true;
this.$viewerApi({
images: [info.url],
});
},
// 照片大小格式限制
beforeUpload(file) {
......
<template>
<a-spin tip="正在上传中..." :spinning="spinning">
<div class="website flex flexc">
<div class="personnel flex flexc">
<TabHeader label="工作人员管理"></TabHeader>
<div class="pd15 flex1 auto-scroll-y">
<div class="person_chang flex aic mb10">
......@@ -21,6 +21,7 @@
{{ curDept }}
</div>
<a-popover
overlayClassName="personnel-popover"
arrowPointAtCenter
placement="rightTop"
title="部门列表"
......@@ -80,6 +81,7 @@
{{ curWindow }}
</div>
<a-popover
overlayClassName="personnel-popover"
arrowPointAtCenter
placement="rightTop"
title="窗口列表"
......@@ -204,7 +206,7 @@
onShowSizeChange: showSizeChange,
}"
bordered
:scroll="{ y: 510 }"
:scroll="{ y: 500 }"
:loading="loading"
:columns="columns"
:data-source="WorkmanData"
......@@ -219,6 +221,7 @@
<img
v-if="text.photoPath"
:src="api2 + text.photoPath"
@click="handlePreview(api2 + text.photoPath)"
class="pht"
/>
......@@ -651,12 +654,24 @@ export default {
}
return fromnum;
},
// 预览照片
handlePreview(url) {
this.$viewerApi({
images: [url],
});
},
},
};
</script>
<style lang="less">
.personnel-popover {
.ant-popover-inner-content {
padding: 0px !important;
}
}
</style>
<style lang="less" scoped>
.website {
.personnel {
width: 100%;
height: 100%;
.right {
......@@ -690,6 +705,7 @@ export default {
width: 56px;
height: 74px;
object-fit: cover;
cursor: pointer;
}
div.person_gruop1 {
......@@ -775,10 +791,12 @@ export default {
}
}
}
.dept-list {
width: 500px;
width: 620px;
min-height: 50px;
max-height: 400px;
padding: 12px 16px;
overflow-y: auto;
.ant-radio-group {
display: grid;
......
......@@ -6,21 +6,6 @@ import Layouts from "@/layouts/Layouts";
// 路由配置
const options = {
routes: [
{
path: "/jump",
name: "跳转页面",
component: () => import("@/pages/basicset/jump/jump"),
},
{
path: "*",
name: "404",
component: () => import("@/pages/exception/404"),
},
{
path: "/403",
name: "403",
component: () => import("@/pages/exception/403"),
},
{
path: "/apppreview",
name: "预览页面",
......@@ -33,7 +18,7 @@ const options = {
redirect: "/website",
children: [
{
path: "website",
path: "/website",
name: "站点管理",
meta: {
icon: "bank",
......@@ -41,7 +26,7 @@ const options = {
component: () => import("@/pages/basicset/site/website"),
},
{
path: "business",
path: "/business",
meta: {
icon: "book",
},
......@@ -118,7 +103,7 @@ const options = {
],
},
{
path: "department",
path: "/department",
meta: {
icon: "audit",
},
......@@ -141,7 +126,7 @@ const options = {
],
},
{
path: "personnel",
path: "/personnel",
name: "工作人员管理",
meta: {
icon: "idcard",
......@@ -149,7 +134,7 @@ const options = {
component: () => import("@/pages/basicset/workman/personnel"),
},
{
path: "festival",
path: "/festival",
name: "节假日管理",
meta: {
icon: "carry-out",
......@@ -157,16 +142,17 @@ const options = {
component: () => import("@/pages/basicset/holiday/festival"),
},
{
path: "deploy",
path: "/deploy",
name: "部署模块管理",
meta: {
icon: "appstore",
roles: ["admin"],
},
component: () => import("@/pages/basicset/deploy/deploy"),
},
{
path: "hall",
path: "/hall",
name: "大厅管理",
meta: {
icon: "gateway",
......@@ -196,7 +182,7 @@ const options = {
},
{
path: "surface",
path: "/surface",
component: () => import("@/pages/basicset/surface/index"),
meta: {
icon: "skin",
......@@ -210,7 +196,7 @@ const options = {
},
{
path: "addsurfacetemplate",
name: "新增皮肤m模板",
name: "新增皮肤模板",
component: () =>
import("@/pages/basicset/surface/AddSurfaceTemplate"),
meta: { invisible: true },
......@@ -218,7 +204,7 @@ const options = {
],
},
{
path: "configurat",
path: "/configurat",
name: "短信配置",
meta: {
icon: "mail",
......@@ -227,7 +213,7 @@ const options = {
},
{
path: "appmarket",
path: "/appmarket",
component: () => import("@/pages/basicset/appmarket/Index"),
meta: {
icon: "shop",
......@@ -314,7 +300,7 @@ const options = {
],
},
{
path: "system",
path: "/system",
name: "系统设置",
component: () => import("@/pages/basicset/system/System"),
meta: {
......
import Vue from 'vue'
import Router from 'vue-router'
import {formatRoutes} from '@/utils/routerUtil'
Vue.use(Router)
import Vue from "vue";
import VueRouter from "vue-router";
import { formatRoutes } from "@/utils/routerUtil";
import { i18n } from "@/utils/i18n";
import store from "@/store";
import { mergeI18nFromRoutes } from "@/utils/i18n";
Vue.use(VueRouter);
//解决重复路由报错
const originalPush = Router.prototype.push
const originalPush = VueRouter.prototype.push;
// 修改原型对象中的push方法
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch((err) => err);
};
const routes = [
{
path: "/jump",
name: "跳转页面",
component: () => import("@/pages/basicset/jump/jump"),
},
{
path: "*",
name: "404",
component: () => import("@/pages/exception/404"),
},
{
path: "/403",
name: "403",
component: () => import("@/pages/exception/403"),
},
];
formatRoutes(routes);
const router = new VueRouter({
routes,
});
// 不需要登录拦截的路由配置
const loginIgnore = {
names: ['404', '403'], //根据路由名称匹配
paths: ['/login'], //根据路由fullPath匹配
names: ["404", "403"], //根据路由名称匹配
paths: ["/login", "/jump"], //根据路由fullPath匹配
/**
* 判断路由是否包含在该配置中
* @param route vue-router 的 route 对象
* @returns {boolean}
*/
includes(route) {
return this.names.includes(route.name) || this.paths.includes(route.path)
}
}
return this.names.includes(route.name) || this.paths.includes(route.path);
},
};
/**
* 初始化路由实例
* @param isAsync 是否异步路由模式
* @returns {VueRouter}
*/
function initRouter(isAsync) {
const options = isAsync ? require('./async/config.async').default : require('./config').default
formatRoutes(options.routes)
return new Router(options)
function initRouter() {
// 是否异步路由模式
const options = store.state.setting.asyncRoutes
? require("./async/config.async").default
: require("./config").default;
formatRoutes(options.routes);
return options;
}
// 判断权限
function permission(router, role) {
if (router.meta && router.meta.roles) {
return router.meta.roles.includes(role);
} else {
return true;
}
}
// 计算动态路由
function calcRouters(dynamicRouter, role) {
// 过滤
let res = dynamicRouter.filter((v) => {
// 判断是否有权限访问此路由
if (permission(v, role)) {
// 判断有没有子路由
if (v.children) {
// 递归
v.children = calcRouters(v.children, role);
}
return true;
} else {
return false;
}
});
return res;
}
// 动态菜单
function createMenus() {
let role = store.getters["site/userInfo"].name;
if (!role) return;
let options = initRouter();
let routesArr = calcRouters(options.routes, role);
const rootRoute = routesArr.find((item) => item.path === "/");
const menuRoutes = rootRoute && rootRoute.children;
mergeI18nFromRoutes(i18n, menuRoutes);
if (menuRoutes) {
routesArr.forEach((v) => {
router.addRoute(v);
});
store.commit("setting/setMenuData", menuRoutes);
}
}
export {loginIgnore, initRouter}
createMenus();
export { loginIgnore, initRouter, createMenus, router };
......@@ -30,7 +30,8 @@ module.exports = {
treeselect: `${BASE_URL}/base/area/treeselect`,
save: `${BASE_URL}/base/area/save`,
delete: `${BASE_URL}/base/area/delete`,
init: `${BASE_URL}/base/base/area/genSubAreaByAreaName `,
init: `${BASE_URL}/base/area/genSubAreaByAreaName`,
authAreaTree: `${BASE_URL}/base/area/authAreaTree`,
},
// 站点
site: {
......@@ -294,6 +295,7 @@ module.exports = {
list: `${BASE_URL}/base/app/dataset/list`,
info: `${BASE_URL}/base/app/dataset/info`,
save: `${BASE_URL}/base/app/dataset/save`,
batchSave: `${BASE_URL}/base/app/dataset/batchSave`,
delete: `${BASE_URL}/base/app/dataset/delete`,
},
// 应用信息字段配置
......
......@@ -19,6 +19,10 @@ export async function getListByParentId(data) {
export async function treeselect(data) {
return request(area.treeselect, METHOD.POST, data);
}
// 查看个人区域列表
export async function authAreaTree(data) {
return request(area.authAreaTree, METHOD.POST, data);
}
// 查看站点列表
export async function getSiteList(data) {
return request(site.list, METHOD.POST, data);
......
......@@ -61,6 +61,10 @@ export async function getDatasetInfo(data) {
export async function saveDataset(data) {
return request(dataset.save, METHOD.POST, data);
}
// 批量保存数据
export async function batchSaveDataset(data) {
return request(dataset.batchSave, METHOD.POST, data);
}
// 删除数据
export async function deleteDataset(data) {
return request(dataset.delete, METHOD.GET, data);
......
......@@ -2,8 +2,9 @@ import Vue from "vue";
import Vuex from "vuex";
import modules from "./modules";
import createPersistedState from "vuex-persistedstate";
import SecureLS from "secure-ls";
var ls = new SecureLS({ isCompression: false });
// import SecureLS from "secure-ls";
// var ls = new SecureLS({ isCompression: false });
import { SessionCrypto } from "@/utils/util";
Vue.use(Vuex);
const store = new Vuex.Store({
modules,
......@@ -15,9 +16,9 @@ const store = new Vuex.Store({
createPersistedState({
key: "info",
storage: {
getItem: (key) => ls.get(key),
setItem: (key, value) => ls.set(key, value),
removeItem: (key) => ls.remove(key),
getItem: (key) => SessionCrypto.getItem(key),
setItem: (key, value) => SessionCrypto.setItem(key, value),
removeItem: (key) => SessionCrypto.remove(key),
},
}),
],
......
import config from '@/config'
import { ADMIN } from '@/config/default'
import { formatFullPath } from '@/utils/i18n'
import { filterMenu } from '@/utils/authority-utils'
import { getLocalSetting } from '@/utils/themeUtil'
import deepClone from 'lodash.clonedeep'
const localSetting = getLocalSetting(true)
import config from "@/config";
import { ADMIN } from "@/config/default";
import { formatFullPath } from "@/utils/i18n";
import { filterMenu } from "@/utils/authority-utils";
import { getLocalSetting } from "@/utils/themeUtil";
import deepClone from "lodash.clonedeep";
const localSetting = getLocalSetting(true);
// console.log(localSetting)
const customTitlesStr = sessionStorage.getItem(process.env.VUE_APP_TBAS_TITLES_KEY)
const customTitles = (customTitlesStr && JSON.parse(customTitlesStr)) || []
const customTitlesStr = sessionStorage.getItem(
process.env.VUE_APP_TBAS_TITLES_KEY
);
const customTitles = (customTitlesStr && JSON.parse(customTitlesStr)) || [];
export default {
namespaced: true,
......@@ -20,96 +22,99 @@ export default {
activatedFirst: undefined,
customTitles,
...config,
...localSetting
...localSetting,
},
getters: {
menuData (state, getters, rootState) {
menuData(state, getters, rootState) {
if (state.filterMenu) {
const { permissions, roles } = rootState.account
return filterMenu(deepClone(state.menuData), permissions, roles)
const { permissions, roles } = rootState.account;
return filterMenu(deepClone(state.menuData), permissions, roles);
}
return state.menuData
return state.menuData;
},
firstMenu (state, getters) {
const { menuData } = getters
firstMenu(state, getters) {
const { menuData } = getters;
if (menuData.length > 0 && !menuData[0].fullPath) {
formatFullPath(menuData)
formatFullPath(menuData);
}
return menuData.map(item => {
const menuItem = { ...item }
delete menuItem.children
return menuItem
})
},
subMenu (state) {
const { menuData, activatedFirst } = state
return menuData.map((item) => {
const menuItem = { ...item };
delete menuItem.children;
return menuItem;
});
},
subMenu(state) {
const { menuData, activatedFirst } = state;
if (menuData.length > 0 && !menuData[0].fullPath) {
formatFullPath(menuData)
}
const current = menuData.find(menu => menu.fullPath === activatedFirst)
return current && current.children || []
formatFullPath(menuData);
}
const current = menuData.find((menu) => menu.fullPath === activatedFirst);
return (current && current.children) || [];
},
},
mutations: {
setDevice (state, isMobile) {
state.isMobile = isMobile
setDevice(state, isMobile) {
state.isMobile = isMobile;
},
setTheme (state, theme) {
setTheme(state, theme) {
// console.log(theme)
state.theme = theme
state.theme = theme;
},
setLayout (state, layout) {
state.layout = layout
setLayout(state, layout) {
state.layout = layout;
},
setMultiPage (state, multiPage) {
state.multiPage = multiPage
setMultiPage(state, multiPage) {
state.multiPage = multiPage;
},
setAnimate (state, animate) {
state.animate = animate
setAnimate(state, animate) {
state.animate = animate;
},
setWeekMode (state, weekMode) {
state.weekMode = weekMode
setWeekMode(state, weekMode) {
state.weekMode = weekMode;
},
setFixedHeader (state, fixedHeader) {
state.fixedHeader = fixedHeader
setFixedHeader(state, fixedHeader) {
state.fixedHeader = fixedHeader;
},
setFixedSideBar (state, fixedSideBar) {
state.fixedSideBar = fixedSideBar
setFixedSideBar(state, fixedSideBar) {
state.fixedSideBar = fixedSideBar;
},
setLang (state, lang) {
state.lang = lang
setLang(state, lang) {
state.lang = lang;
},
setHideSetting (state, hideSetting) {
state.hideSetting = hideSetting
setHideSetting(state, hideSetting) {
state.hideSetting = hideSetting;
},
correctPageMinHeight (state, minHeight) {
state.pageMinHeight += minHeight
correctPageMinHeight(state, minHeight) {
state.pageMinHeight += minHeight;
},
setMenuData (state, menuData) {
state.menuData = menuData
setMenuData(state, menuData) {
state.menuData = menuData;
},
setAsyncRoutes (state, asyncRoutes) {
state.asyncRoutes = asyncRoutes
setAsyncRoutes(state, asyncRoutes) {
state.asyncRoutes = asyncRoutes;
},
setPageWidth (state, pageWidth) {
state.pageWidth = pageWidth
setPageWidth(state, pageWidth) {
state.pageWidth = pageWidth;
},
setActivatedFirst (state, activatedFirst) {
state.activatedFirst = activatedFirst
setActivatedFirst(state, activatedFirst) {
state.activatedFirst = activatedFirst;
},
setFixedTabs (state, fixedTabs) {
state.fixedTabs = fixedTabs
setFixedTabs(state, fixedTabs) {
state.fixedTabs = fixedTabs;
},
setCustomTitle (state, { path, title }) {
setCustomTitle(state, { path, title }) {
if (title) {
const obj = state.customTitles.find(item => item.path === path)
const obj = state.customTitles.find((item) => item.path === path);
if (obj) {
obj.title = title
obj.title = title;
} else {
state.customTitles.push({ path, title })
}
sessionStorage.setItem(process.env.VUE_APP_TBAS_TITLES_KEY, JSON.stringify(state.customTitles))
state.customTitles.push({ path, title });
}
sessionStorage.setItem(
process.env.VUE_APP_TBAS_TITLES_KEY,
JSON.stringify(state.customTitles)
);
}
}
}
},
},
};
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import routesI18n from '@/router/i18n'
import './Objects'
import { getI18nKey } from '@/utils/routerUtil'
import Vue from "vue";
import VueI18n from "vue-i18n";
import routesI18n from "@/router/i18n";
import "./Objects";
import { getI18nKey } from "@/utils/routerUtil";
/**
* 创建 i18n 配置
......@@ -10,16 +10,18 @@ import { getI18nKey } from '@/utils/routerUtil'
* @param fallback 回退语言
* @returns {VueI18n}
*/
function initI18n (locale, fallback) {
Vue.use(VueI18n)
function initI18n(locale, fallback) {
Vue.use(VueI18n);
let i18nOptions = {
locale,
fallbackLocale: fallback,
silentFallbackWarn: true,
}
return new VueI18n(i18nOptions)
};
return new VueI18n(i18nOptions);
}
const i18n = initI18n("CN", "US");
/**
* 根据 router options 配置生成 国际化语言
* @param lang
......@@ -27,16 +29,22 @@ function initI18n (locale, fallback) {
* @param valueKey
* @returns {*}
*/
function generateI18n (lang, routes, valueKey) {
routes.forEach(route => {
let keys = getI18nKey(route.fullPath).split('.')
let value = valueKey === 'path' ? route[valueKey].split('/').filter(item => !item.startsWith(':') && item != '').join('.') : route[valueKey]
lang.assignProps(keys, value)
function generateI18n(lang, routes, valueKey) {
routes.forEach((route) => {
let keys = getI18nKey(route.fullPath).split(".");
let value =
valueKey === "path"
? route[valueKey]
.split("/")
.filter((item) => !item.startsWith(":") && item != "")
.join(".")
: route[valueKey];
lang.assignProps(keys, value);
if (route.children) {
generateI18n(lang, route.children, valueKey)
generateI18n(lang, route.children, valueKey);
}
})
return lang
});
return lang;
}
/**
......@@ -44,14 +52,18 @@ function generateI18n (lang, routes, valueKey) {
* @param routes
* @param parentPath
*/
function formatFullPath (routes, parentPath = '') {
routes.forEach(route => {
let isFullPath = route.path.substring(0, 1) === '/'
route.fullPath = isFullPath ? route.path : (parentPath === '/' ? parentPath + route.path : parentPath + '/' + route.path)
function formatFullPath(routes, parentPath = "") {
routes.forEach((route) => {
let isFullPath = route.path.substring(0, 1) === "/";
route.fullPath = isFullPath
? route.path
: parentPath === "/"
? parentPath + route.path
: parentPath + "/" + route.path;
if (route.children) {
formatFullPath(route.children, route.fullPath)
formatFullPath(route.children, route.fullPath);
}
})
});
}
/**
......@@ -59,20 +71,16 @@ function formatFullPath (routes, parentPath = '') {
* @param i18n
* @param routes
*/
function mergeI18nFromRoutes (i18n, routes) {
formatFullPath(routes)
const CN = generateI18n(new Object(), routes, 'name')
const US = generateI18n(new Object(), routes, 'path')
i18n.mergeLocaleMessage('CN', CN)
i18n.mergeLocaleMessage('US', US)
const messages = routesI18n.messages
Object.keys(messages).forEach(lang => {
i18n.mergeLocaleMessage(lang, messages[lang])
})
function mergeI18nFromRoutes(i18n, routes) {
formatFullPath(routes);
const CN = generateI18n(new Object(), routes, "name");
const US = generateI18n(new Object(), routes, "path");
i18n.mergeLocaleMessage("CN", CN);
i18n.mergeLocaleMessage("US", US);
const messages = routesI18n.messages;
Object.keys(messages).forEach((lang) => {
i18n.mergeLocaleMessage(lang, messages[lang]);
});
}
export {
initI18n,
mergeI18nFromRoutes,
formatFullPath
}
export { initI18n, mergeI18nFromRoutes, formatFullPath, i18n };
......@@ -136,11 +136,11 @@ function loadRoutes(routesConfig) {
// 提取路由国际化数据
mergeI18nFromRoutes(i18n, router.options.routes);
// 初始化Admin后台菜单数据
const rootRoute = router.options.routes.find((item) => item.path === "/");
const menuRoutes = rootRoute && rootRoute.children;
if (menuRoutes) {
store.commit("setting/setMenuData", menuRoutes);
}
// const rootRoute = router.options.routes.find((item) => item.path === "/");
// const menuRoutes = rootRoute && rootRoute.children;
// if (menuRoutes) {
// store.commit("setting/setMenuData", menuRoutes);
// }
}
/**
......
import enquireJs from "enquire.js";
import CryptoJS from "crypto-js";
export function isDef(v) {
return v !== undefined && v !== null;
}
......@@ -62,3 +62,52 @@ export const extractTree = (arrs, childs, attrArr) => {
};
return getObj(arrs);
};
/**
* 加密存储临时数据并解析对象
*/
const aseKey = "**_FXxx_1234_KEY";
const KEY = "KEY_EXTRA";
export class SessionCrypto {
// 加密
static setItem(key = KEY, value = "") {
if (typeof key === "string") {
const stringify = JSON.stringify(value);
const encrypt = CryptoJS.AES.encrypt(
stringify,
CryptoJS.enc.Utf8.parse(aseKey),
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}
).toString();
window.sessionStorage.setItem(key, encrypt);
return encrypt;
}
}
// 解密
static getItem(key = KEY) {
const ssStr = window.sessionStorage.getItem(key) || "";
try {
if (ssStr) {
const decrypt = CryptoJS.AES.decrypt(
ssStr,
CryptoJS.enc.Utf8.parse(aseKey),
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}
).toString(CryptoJS.enc.Utf8);
const parseStr = JSON.parse(decrypt);
return parseStr;
}
return "";
} catch (e) {
return "";
}
}
// 删除
static remove(key) {
window.sessionStorage.removeItem(key);
}
}
......@@ -3676,6 +3676,11 @@ crypto-js@^3.1.6:
resolved "https://registry.npmmirror.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b"
integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==
crypto-js@^4.1.1:
version "4.1.1"
resolved "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf"
integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==
crypto-random-string@^2.0.0:
version "2.0.0"
resolved "https://registry.npm.taobao.org/crypto-random-string/download/crypto-random-string-2.0.0.tgz?cache=0&sync_timestamp=1583560482221&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcrypto-random-string%2Fdownload%2Fcrypto-random-string-2.0.0.tgz"
......@@ -7215,6 +7220,11 @@ lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz"
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
log-symbols@^2.2.0:
version "2.2.0"
resolved "https://registry.npm.taobao.org/log-symbols/download/log-symbols-2.2.0.tgz?cache=0&sync_timestamp=1587898912367&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flog-symbols%2Fdownload%2Flog-symbols-2.2.0.tgz"
......@@ -10999,7 +11009,7 @@ uuid@^8.3.2:
v-viewer@^1.6.4:
version "1.6.4"
resolved "https://registry.npmmirror.com/v-viewer/-/v-viewer-1.6.4.tgz"
resolved "https://registry.npmmirror.com/v-viewer/-/v-viewer-1.6.4.tgz#39e36b534baab34076fb816704c6a734de0dc72f"
integrity sha512-LVkiUHpmsbsZXebeNXnu8krRCi5i2n07FeLFxoIVGhw8lVvTBO0ffpbDC6mLEuacCjrIh09HjIqpciwUtWE8lQ==
dependencies:
throttle-debounce "^2.0.1"
......
......@@ -18,6 +18,8 @@ ALTER TABLE mortals_sys_workman ADD COLUMN `operatorId` varchar (128) default "
-- ----------------------------
2023-3-28
-- ----------------------------
......@@ -197,3 +199,22 @@ ALTER TABLE mortals_sys_app_category ADD COLUMN `remark` varchar(256) DEFAULT
2023-08-29
-- ----------------------------
ALTER TABLE `mortals_sys_model` ADD COLUMN `type` tinyint(2) DEFAULT '1' COMMENT '模块分类' AFTER `sort`;
-- ----------------------------
2023-9-11
-- ----------------------------
ALTER TABLE mortals_sys_app_info_field ADD COLUMN `serviceApi` varchar(255) default '' COMMENT '事件服务接口请求地址';
ALTER TABLE mortals_sys_app_info_field ADD COLUMN `serviceApiParams` varchar(1024) default '' COMMENT '事件服务接口请求参数';
ALTER TABLE mortals_sys_app_info_templete_field ADD COLUMN `serviceApi` varchar(255) default '' COMMENT '事件服务接口请求地址';
ALTER TABLE mortals_sys_app_info_templete_field ADD COLUMN `serviceApiParams` varchar(1024) default '' COMMENT '事件服务接口请求参数';
-- ----------------------------
2023-10-17
-- ----------------------------
ALTER TABLE mortals_sys_window_hall ADD COLUMN `siteId` bigint(20) default '1' COMMENT '站点Id';
......@@ -40,6 +40,7 @@
<package.environment>test</package.environment>
<skipUi>false</skipUi>
<showSql>false</showSql>
<profiles.holidayUrl>https://timor.tech/api/holiday/year/</profiles.holidayUrl>
</properties>
</profile>
<profile>
......@@ -60,6 +61,7 @@
<profiles.log.level>info</profiles.log.level>
<package.environment>test</package.environment>
<skipUi>false</skipUi>
<profiles.holidayUrl>https://timor.tech/api/holiday/year/</profiles.holidayUrl>
</properties>
</profile>
......@@ -81,6 +83,7 @@
<profiles.log.level>info</profiles.log.level>
<package.environment>build</package.environment>
<skipUi>false</skipUi>
<profiles.holidayUrl>https://timor.tech/api/holiday/year/</profiles.holidayUrl>
</properties>
</profile>
......@@ -104,6 +107,7 @@
<profiles.log.level>INFO</profiles.log.level>
<package.environment>yibin</package.environment>
<skipUi>false</skipUi>
<profiles.holidayUrl>https://timor.tech/api/holiday/year/</profiles.holidayUrl>
</properties>
</profile>
......
......@@ -7,9 +7,12 @@ import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.IUser;
import com.mortals.framework.util.DateUtils;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.base.system.resource.service.ResourceService;
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.key.RedisKey;
import com.mortals.xhx.common.utils.MenuEncodeUtil;
import com.mortals.xhx.feign.user.IUserFeign;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
......@@ -26,6 +29,7 @@ import javax.servlet.http.HttpServletRequest;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* token验证处理
......@@ -78,6 +82,10 @@ public class AuthTokenServiceImpl implements IAuthTokenService {
@Autowired
private ICacheService cacheService;
@Autowired
private ResourceService resourceService;
/**
* 获取信息
*
......@@ -90,28 +98,43 @@ public class AuthTokenServiceImpl implements IAuthTokenService {
String token = getToken(request);
if (StringUtils.isNotEmpty(token)) {
try {
boolean signed = Jwts.parser().isSigned(token);
if (!signed) {
log.error("token非法!=>{}", token);
return null;
}
Claims claims = parseToken(token);
String uuid = (String) claims.get(SysConstains.LOGIN_USER_KEY);
String userKey = getTokenKey(uuid);
cacheService.select(portalDb);
String userStr = cacheService.get(userKey);
cacheService.select(db);
// Rest<String> rest = userFeign.getToken(userKey);
// String userStr = rest.getData();
if (StringUtils.isNotEmpty(userStr)) {
//刷新token时间
UserEntity userEntity = JSONObject.parseObject(userStr, UserEntity.class);
userEntity.setToken(token);
UserEntity temp = userService.selectOne(new UserQuery().loginName(userEntity.getLoginName()));
if(!ObjectUtils.isEmpty(temp)){
if (!ObjectUtils.isEmpty(userEntity)) {
verifyToken(userEntity);
}
cacheService.select(db);
if (!ObjectUtils.isEmpty(userEntity)) {
// UserEntity temp = userService.selectOne(new UserQuery().loginName(userEntity.getLoginName()));
// if(!ObjectUtils.isEmpty(temp)){
// userEntity.setId(temp.getId());
// }
UserEntity temp = userService.getExtCache(userEntity.getLoginName());
if (!ObjectUtils.isEmpty(temp)) {
userEntity.setId(temp.getId());
}
//更新resource 路径
String menuUrlCode = cacheService.hget(RedisKey.KEY_USER_MENU_CACHE, userEntity.getId().toString(), String.class);
if (ObjectUtils.isEmpty(menuUrlCode)) {
Set<String> urls = resourceService.findUrlSetByUserId(userEntity.getId());
menuUrlCode = MenuEncodeUtil.generateMenuUrlCode(urls);
cacheService.hset(RedisKey.KEY_USER_MENU_CACHE, userEntity.getId().toString(), menuUrlCode);
}
userEntity.setMenuUrl(menuUrlCode);
return userEntity;
}
} catch (Exception e) {
log.error("解析jwt token异常!", e);
log.error("解析jwt token异常!,token:{}",token, e);
return null;
}
}
......@@ -165,8 +188,8 @@ public class AuthTokenServiceImpl implements IAuthTokenService {
public void verifyToken(IUser user) {
long expireTime = user.getExpireTime();
long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= SECOND_MINUTE_TEN) {
log.info("不足十分钟,刷新过期时间");
if (expireTime - currentTime <= SECOND_MINUTE_TEN*1000) {
log.info("不足十分钟,刷新过期时间");
refreshToken(user);
}
}
......@@ -178,7 +201,7 @@ public class AuthTokenServiceImpl implements IAuthTokenService {
*/
public void refreshToken(IUser user) {
//user.setLoginTime(System.currentTimeMillis());
user.setExpireTime(user.getLoginTime() == null ? System.currentTimeMillis() : user.getLoginTime() + expireTime * SECOND_MINUTE);
user.setExpireTime(user.getLoginTime() == null ? System.currentTimeMillis() : user.getLoginTime() + expireTime * SECOND_MINUTE*1000);
// 根据uuid将user缓存
String userKey = getTokenKey(user.getToken());
//设置有效时间 单位秒
......@@ -245,4 +268,11 @@ public class AuthTokenServiceImpl implements IAuthTokenService {
private String getTokenKey(String uuid) {
return SysConstains.LOGIN_TOKEN_KEY + uuid;
}
public static void main(String[] args) {
// boolean signed = Jwts.parser().isSigned("123");
boolean signed = Jwts.parser().isSigned("eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc");
System.out.println(signed);
}
}
......@@ -4,6 +4,7 @@ import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.util.ThreadPool;
import com.mortals.xhx.base.system.message.MessageService;
import com.mortals.xhx.common.utils.SendTask;
import com.mortals.xhx.common.utils.SendTaskThreadPool;
......@@ -22,14 +23,11 @@ import org.springframework.stereotype.Service;
@Slf4j
public class MessageServiceImpl implements MessageService {
@Autowired
private SendTaskThreadPool sendTaskThreadPool;
@Override
public void sendThirdParty(String sendUrl, String content) {
SendTask sendTask = new SendTask(sendUrl, content);
sendTaskThreadPool.execute(sendTask);
ThreadPool.getInstance().execute(sendTask);
}
public static void main(String[] args) {
......
......@@ -9,7 +9,9 @@
package com.mortals.xhx.base.system.resource.service;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.ICRUDService;
import com.mortals.xhx.base.system.resource.model.ResourceEntity;
......@@ -31,7 +33,7 @@ public interface ResourceService extends ICRUDService<ResourceEntity,Long> {
* @return
* @throws AppException
*/
public List<ResourceEntity> findAllEnable() throws AppException;
List<ResourceEntity> findAllEnable() throws AppException;
/**
* 根据用户查询可用资源
......@@ -39,7 +41,7 @@ public interface ResourceService extends ICRUDService<ResourceEntity,Long> {
* @return
* @throws AppException
*/
public List<ResourceEntity> findListByUserId(Long userId) throws AppException;
List<ResourceEntity> findListByUserId(Long userId) throws AppException;
/**
* 查询用户可用资源
......@@ -47,7 +49,7 @@ public interface ResourceService extends ICRUDService<ResourceEntity,Long> {
* @return 字符串,多个以逗号分隔
* @throws AppException
*/
public String findUrlByUserId(Long userId) throws AppException;
String findUrlByUserId(Long userId) throws AppException;
/**
* 查询用户用资源集合
......@@ -55,7 +57,7 @@ public interface ResourceService extends ICRUDService<ResourceEntity,Long> {
* @return
* @throws AppException
*/
public Set<String> findUrlSetByUserId(Long userId) throws AppException;
Set<String> findUrlSetByUserId(Long userId) throws AppException;
/**
* 获取所有资源,不分页
......@@ -64,4 +66,7 @@ public interface ResourceService extends ICRUDService<ResourceEntity,Long> {
*/
List<ResourceEntity> findAll(int userType);
Rest<String> refreshResourceUrl(String packageName, Context context);
}
\ No newline at end of file
/**
* 文件:ResourceServiceImpl.java
* 版本:1.0.0
* 日期:
* Copyright &reg;
* All right reserved.
*/
* 文件:ResourceServiceImpl.java
* 版本:1.0.0
* 日期:
* Copyright &reg;
* All right reserved.
*/
package com.mortals.xhx.base.system.resource.service.impl;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.util.DataUtil;
import com.mortals.framework.util.StringUtils;
import com.mortals.framework.util.ThreadPool;
import com.mortals.xhx.base.system.resource.dao.ResourceDao;
import com.mortals.xhx.base.system.resource.model.ResourceEntity;
import com.mortals.xhx.base.system.resource.model.ResourceQuery;
import com.mortals.xhx.base.system.resource.service.ResourceService;
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.RespData;
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.service.SiteService;
import org.springframework.beans.BeanUtils;
import com.mortals.xhx.base.system.role.model.RoleAuthEntity;
import com.mortals.xhx.base.system.role.model.RoleAuthQuery;
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.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import static com.mortals.xhx.common.utils.MenuEncodeUtil.generateMenuUrlCode;
/**
* <p>Title: 资源信息</p>
* <p>Description: ResourceServiceImpl service接口 </p>
* <p>Copyright: Copyright &reg; </p>
* <p>Company: </p>
*
* @author
* @version 1.0.0
*/
@Service("resourceService")
public class ResourceServiceImpl extends AbstractCRUDServiceImpl<ResourceDao,ResourceEntity,Long> implements ResourceService {
public class ResourceServiceImpl extends AbstractCRUDServiceImpl<ResourceDao, ResourceEntity, Long> implements ResourceService {
@Autowired
private ICacheService cacheService;
@Autowired
private RoleAuthService roleAuthService;
@Override
public List<ResourceEntity> findAllEnable() throws AppException {
......@@ -85,6 +88,106 @@ public class ResourceServiceImpl extends AbstractCRUDServiceImpl<ResourceDao,Res
return dao.getAll(userType);
}
@Override
public Rest<String> refreshResourceUrl(String packageName, Context context) {
List<Class<?>> classList = ControllerScanUtil.getAllClassByPackageName(packageName);
//System.out.println(classList); //获取到了所有的类
List<ResourceEntity> newResourcelist = ControllerScanUtil.getAnnotationInfo(classList).stream().filter(f->!ObjectUtils.isEmpty(f.getUrl())).collect(Collectors.toList());
Map<String, List<ResourceEntity>> localResourceMap = this.find(new ResourceQuery()).stream().collect(Collectors.groupingBy(x -> x.getName()));
Map<String, List<ResourceEntity>> newResourceMap = newResourcelist.stream().collect(Collectors.groupingBy(x -> x.getName()));
//更新 与新增 新加的;
newResourceMap.entrySet().forEach(item -> {
List<ResourceEntity> resourceEntities = item.getValue();
if (ObjectUtils.isEmpty(resourceEntities)) return;
if (resourceEntities.size() == 1) {
ResourceEntity resourceEntity = resourceEntities.get(0);
saveUpdateResourceEntity(context, localResourceMap, resourceEntity);
} else if (resourceEntities.size() > 1) {
//原始扫描 有多个资源列表针对一个名称的
for (ResourceEntity resourceEntity : resourceEntities) {
saveUpdateResourceEntity(context, localResourceMap, resourceEntity);
}
}
});
return Rest.ok();
}
private void saveUpdateResourceEntity(Context context, Map<String, List<ResourceEntity>> localResourceMap, ResourceEntity resourceEntity) {
//查找 本地是否已经存在了
List<ResourceEntity> tempResourceList = localResourceMap.getOrDefault(resourceEntity.getName(), new ArrayList<>());
if (tempResourceList.size() == 0) {
//新增 resource;
resourceEntity.setCreateUserId(this.getContextUserId(context));
resourceEntity.setCreateTime(new Date());
this.save(resourceEntity, context);
} else if (tempResourceList.size() == 1) {
//更新
ResourceEntity tempResource = tempResourceList.get(0);
Set<String> setUrl = Arrays.stream(resourceEntity.getUrl().split(",")).collect(Collectors.toSet());
Arrays.stream(tempResource.getUrl().split(",")).forEach(i -> {
setUrl.add(i);
});
tempResource.setUrl(setUrl.stream().collect(Collectors.joining(",")));
this.update(tempResource, context);
} else if (tempResourceList.size() > 1) {
//找到多个同名的 资源配置
for (ResourceEntity tempResource : tempResourceList) {
//模糊匹配到路径有一个存在的
Set<String> setUrl = Arrays.stream(resourceEntity.getUrl().split(",")).collect(Collectors.toSet());
String[] splitUrl = tempResource.getUrl().split(",");
Boolean bool = false;
for (int i = 0; i < splitUrl.length; i++) {
if (setUrl.contains(splitUrl[i])) {
bool = true;
break;
}
}
if (bool) {
//匹配到了,更新当前这个资源
Arrays.stream(tempResource.getUrl().split(",")).forEach(i -> {
setUrl.add(i);
});
tempResource.setUrl(setUrl.stream().collect(Collectors.joining(",")));
this.update(tempResource, context);
}
}
}
}
@Override
protected void updateAfter(ResourceEntity entity, Context context) throws AppException {
updateUserMenuUrlCache();
}
@Override
protected void saveAfter(ResourceEntity entity, Context context) throws AppException {
updateUserMenuUrlCache();
}
@Override
protected void removeAfter(Long[] ids, Context context, int result) throws AppException {
//删除关联表中数据
if (!ObjectUtils.isEmpty(ids)) {
RoleAuthQuery query = new RoleAuthQuery();
query.setResourceIdList(Arrays.asList(ids));
List<RoleAuthEntity> roleAuthEntities = roleAuthService.find(query);
if (!ObjectUtils.isEmpty(roleAuthEntities)) {
roleAuthService.remove(roleAuthEntities.stream().map(m -> m.getId()).toArray(Long[]::new), context);
updateUserMenuUrlCache();
}
}
}
private void updateUserMenuUrlCache() {
//更新用户菜单
Set<String> hkeys = cacheService.hkeys(RedisKey.KEY_USER_MENU_CACHE);
for (String userId : hkeys) {
Set<String> urls = this.findUrlSetByUserId(DataUtil.converStr2Long(userId, 0L));
String menuUrlCode = generateMenuUrlCode(urls);
cacheService.hset(RedisKey.KEY_USER_MENU_CACHE, userId, menuUrlCode);
}
}
}
\ No newline at end of file
package com.mortals.xhx.base.system.resource.web;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.annotation.UnAuth;
import com.mortals.framework.common.IBaseEnum;
import com.mortals.framework.common.Rest;
import com.mortals.framework.common.code.UserType;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.resource.model.ResourceEntity;
import com.mortals.xhx.base.system.resource.service.ResourceService;
import com.mortals.xhx.common.code.AuthType;
import com.mortals.xhx.common.code.SourceType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.model.Context;
import com.mortals.framework.web.BaseCRUDJsonMappingController;
import com.mortals.xhx.base.system.resource.model.ResourceEntity;
import com.mortals.xhx.base.system.resource.service.ResourceService;
import com.mortals.xhx.common.code.AuthType;
import com.mortals.xhx.common.code.SourceType;
import java.util.HashMap;
import java.util.Map;
/**
* 资源信息
......@@ -32,10 +31,9 @@ import com.mortals.xhx.common.code.SourceType;
@Slf4j
@RestController
@RequestMapping("resource")
public class ResourceController extends BaseCRUDJsonBodyMappingController<ResourceService,ResourceEntity,Long> {
public class ResourceController extends BaseCRUDJsonBodyMappingController<ResourceService, ResourceEntity, Long> {
public ResourceController(){
super.setFormClass(ResourceForm.class);
public ResourceController() {
super.setModuleDesc("资源信息");
}
......@@ -66,4 +64,30 @@ public class ResourceController extends BaseCRUDJsonBodyMappingController<Resour
return ret.toJSONString();
}
@Override
protected void doListBefore(ResourceEntity query, Map<String, Object> model, Context context) throws AppException {
super.doListBefore(query, model, context);
}
/**
* 资源路径刷新
*/
@PostMapping(value = "refreshUrl")
@UnAuth
public Rest<String> refreshUrl(@RequestParam(name = "packageName", defaultValue = "com.mortals.xhx") String packageName) {
log.info("刷新资源路径,packageName", packageName);
String busiDesc = this.getModuleDesc() + "资源路径刷新";
Rest<String> rest = Rest.ok(busiDesc + " 【成功】");
try {
this.service.refreshResourceUrl(packageName, getContext());
recordSysLog(request, busiDesc + " 【成功】");
} catch (Exception e) {
log.error(busiDesc, e);
rest = Rest.fail(super.convertException(e));
}
return rest;
}
}
\ No newline at end of file
......@@ -29,7 +29,6 @@ import javax.servlet.http.HttpServletResponse;
public class RoleAuthController extends BaseCRUDJsonBodyMappingController<RoleAuthService, RoleAuthEntity, Long> {
public RoleAuthController() {
super.setFormClass(RoleAuthForm.class);
super.setModuleDesc("角色资源权限");
}
......
......@@ -39,7 +39,6 @@ public class RoleController extends BaseCRUDJsonBodyMappingController<RoleServic
private RoleUserService roleUserService;
public RoleController(){
super.setFormClass(RoleForm.class);
super.setModuleDesc("角色信息");
}
......
......@@ -49,7 +49,6 @@ public class RoleUserController extends BaseCRUDJsonBodyMappingController<RoleUs
private UserService userService;
public RoleUserController() {
super.setFormClass(RoleUserForm.class);
super.setModuleDesc("角色用户");
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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