Compare commits
2 Commits
master
...
feature-la
Author | SHA1 | Date | |
---|---|---|---|
d4f1f15491 | |||
60f1f0dde4 |
|
@ -1,9 +1,7 @@
|
|||
NODE_ENV=development
|
||||
VUE_APP_API_BASE_URL=http://182.92.183.230:9999
|
||||
# VUE_APP_API_BASE_URL=http://192.168.0.111:9999
|
||||
VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas
|
||||
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview
|
||||
VUE_APP_MAP_BASE_URL=https://ibasemaps-api.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}?token=AAPK2b935e8bbf564ef581ca3c6fcaa5f2a71ZH84cPqqFvyz3KplFRHP8HyAwJJkh6cnpcQ-qkWh5aiyDQsGJbsXglGx0QM2cPm
|
||||
|
||||
# 微应用列表必须VUE_APP_SUB_开头,jeecg-app-1为子应用的项目名称,也是子应用的路由父路径
|
||||
VUE_APP_SUB_jeecg-app-1 = '//localhost:8092'
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
NODE_ENV=production
|
||||
VUE_APP_API_BASE_URL=/armd
|
||||
VUE_APP_API_BASE_URL=http://localhost:8080/jeecg-boot
|
||||
VUE_APP_CAS_BASE_URL=http://localhost:8888/cas
|
||||
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview
|
||||
VUE_APP_MAP_BASE_URL=https://ibasemaps-api.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}?token=AAPK2b935e8bbf564ef581ca3c6fcaa5f2a71ZH84cPqqFvyz3KplFRHP8HyAwJJkh6cnpcQ-qkWh5aiyDQsGJbsXglGx0QM2cPm
|
||||
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
},
|
||||
"target": "ES6",
|
||||
"module": "CommonJS",
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
|
@ -11,13 +11,11 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@antv/data-set": "^0.11.4",
|
||||
"@antv/g2plot": "^2.4.23",
|
||||
"@jeecg/antd-online-mini": "3.4.3-beta2",
|
||||
"@tinymce/tinymce-vue": "2.1.0",
|
||||
"@toast-ui/editor": "^2.1.2",
|
||||
"ant-design-vue": "^1.7.2",
|
||||
"axios": "^0.18.0",
|
||||
"bignumber.js": "^9.1.2",
|
||||
"china-area-data": "^5.0.1",
|
||||
"clipboard": "^2.0.4",
|
||||
"codemirror": "^5.46.0",
|
||||
|
@ -28,9 +26,7 @@
|
|||
"echarts": "^5.4.2",
|
||||
"echarts-gl": "^2.0.9",
|
||||
"enquire.js": "^2.1.6",
|
||||
"file-saver": "^2.0.5",
|
||||
"js-cookie": "^2.2.0",
|
||||
"jszip": "^3.10.1",
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.pick": "^4.4.0",
|
||||
"md5": "^2.2.1",
|
||||
|
@ -41,10 +37,8 @@
|
|||
"viser-vue": "^2.4.8",
|
||||
"vue": "^2.6.10",
|
||||
"vue-area-linkage": "^5.1.0",
|
||||
"vue-color": "^2.8.1",
|
||||
"vue-cropper": "^0.5.4",
|
||||
"vue-i18n": "^8.7.0",
|
||||
"vue-infinite-scroll": "^2.0.2",
|
||||
"vue-loader": "^15.7.0",
|
||||
"vue-ls": "^3.2.0",
|
||||
"vue-photo-preview": "^1.1.3",
|
||||
|
@ -58,11 +52,9 @@
|
|||
"vxe-table": "2.9.13",
|
||||
"vxe-table-plugin-antd": "1.8.10",
|
||||
"xe-utils": "2.4.8",
|
||||
"xlsx": "^0.18.5",
|
||||
"xss": "^1.0.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
|
||||
"@babel/polyfill": "^7.2.5",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@vue/cli-plugin-babel": "^3.3.0",
|
||||
|
|
5
public/index.html
vendored
|
@ -5,8 +5,7 @@
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>ARMD</title>
|
||||
<!-- <title>核素监测数据自动处理与交互分析系统</title> -->
|
||||
<title>核素监测数据自动处理与交互分析系统</title>
|
||||
<link rel="icon" href="<%= BASE_URL %>logo.png">
|
||||
<script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script>
|
||||
<style>
|
||||
|
@ -252,7 +251,7 @@
|
|||
<div class="loader-section section-right"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/qtw.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
BIN
public/logo.png
vendored
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 8.7 KiB |
1
public/qtw.js
vendored
BIN
public/qtw.wasm
vendored
|
@ -7,7 +7,5 @@ window._CONFIG = {
|
|||
//单点登录地址
|
||||
VUE_APP_CAS_BASE_URL: '',
|
||||
//文件预览路径
|
||||
VUE_APP_ONLINE_BASE_URL: '',
|
||||
// 离线地图
|
||||
VUE_APP_MAP_BASE_URL_OFFLINE: 'http://localhost:8001/map/{z}/{x}/{y}.jpg'
|
||||
VUE_APP_ONLINE_BASE_URL: ''
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import Vue from 'vue'
|
||||
import { axios } from '@/utils/request'
|
||||
import signMd5Utils from '@/utils/encryption/signMd5Utils'
|
||||
import qs from "qs";
|
||||
|
||||
const api = {
|
||||
user: '/mock/api/user',
|
||||
|
@ -14,116 +13,64 @@ const api = {
|
|||
export default api
|
||||
|
||||
//post
|
||||
export function postAction(url, parameter) {
|
||||
export function postAction(url,parameter) {
|
||||
let sign = signMd5Utils.getSign(url, parameter);
|
||||
//将签名和时间戳,添加在请求接口 Header
|
||||
// update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
|
||||
let signHeader = { "X-Sign": sign, "X-TIMESTAMP": signMd5Utils.getTimestamp() };
|
||||
let signHeader = {"X-Sign": sign,"X-TIMESTAMP": signMd5Utils.getTimestamp()};
|
||||
// update-end--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
|
||||
|
||||
return axios({
|
||||
url: url,
|
||||
method: 'post',
|
||||
method:'post' ,
|
||||
data: parameter,
|
||||
headers: signHeader
|
||||
})
|
||||
}
|
||||
|
||||
//post
|
||||
export function postActionWithTimeOut(url, parameter, timeout) {
|
||||
let sign = signMd5Utils.getSign(url, parameter);
|
||||
//将签名和时间戳,添加在请求接口 Header
|
||||
// update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
|
||||
let signHeader = { "X-Sign": sign, "X-TIMESTAMP": signMd5Utils.getTimestamp() };
|
||||
// update-end--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
|
||||
|
||||
return axios({
|
||||
url: url,
|
||||
method: 'post',
|
||||
data: parameter,
|
||||
headers: signHeader,
|
||||
timeout
|
||||
})
|
||||
}
|
||||
export function postFileAction(url, parameter) {
|
||||
let sign = signMd5Utils.getSign(url, parameter);
|
||||
//将签名和时间戳,添加在请求接口 Header
|
||||
// update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
|
||||
let signHeader = { "X-Sign": sign, "X-TIMESTAMP": signMd5Utils.getTimestamp() };
|
||||
// update-end--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
|
||||
|
||||
return axios({
|
||||
url: url,
|
||||
method: 'post',
|
||||
data: parameter,
|
||||
responseType: "blob",
|
||||
headers: signHeader
|
||||
})
|
||||
}
|
||||
|
||||
//post method= {post | put}
|
||||
export function httpAction(url, parameter, method) {
|
||||
export function httpAction(url,parameter,method) {
|
||||
let sign = signMd5Utils.getSign(url, parameter);
|
||||
//将签名和时间戳,添加在请求接口 Header
|
||||
// update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
|
||||
let signHeader = { "X-Sign": sign, "X-TIMESTAMP": signMd5Utils.getTimestamp() };
|
||||
let signHeader = {"X-Sign": sign,"X-TIMESTAMP": signMd5Utils.getTimestamp()};
|
||||
// update-end--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
|
||||
|
||||
return axios({
|
||||
url: url,
|
||||
method: method,
|
||||
method:method ,
|
||||
data: parameter,
|
||||
headers: signHeader
|
||||
})
|
||||
}
|
||||
|
||||
//put
|
||||
export function putAction(url, parameter) {
|
||||
export function putAction(url,parameter) {
|
||||
return axios({
|
||||
url: url,
|
||||
method: 'put',
|
||||
method:'put',
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
//get
|
||||
export function getAction(url, parameter, cancelToken) {
|
||||
export function getAction(url,parameter) {
|
||||
let sign = signMd5Utils.getSign(url, parameter);
|
||||
//将签名和时间戳,添加在请求接口 Header
|
||||
// update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
|
||||
let signHeader = { "X-Sign": sign, "X-TIMESTAMP": signMd5Utils.getTimestamp() };
|
||||
let signHeader = {"X-Sign": sign,"X-TIMESTAMP": signMd5Utils.getTimestamp()};
|
||||
// update-end--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
|
||||
return axios({
|
||||
url: url,
|
||||
method: 'get',
|
||||
params: parameter,
|
||||
paramsSerializer: function (params) {
|
||||
return qs.stringify(params, { arrayFormat: "repeat" });
|
||||
},
|
||||
headers: signHeader,
|
||||
cancelToken
|
||||
})
|
||||
}
|
||||
|
||||
export function getFileAction(url, parameter) {
|
||||
let sign = signMd5Utils.getSign(url, parameter);
|
||||
//将签名和时间戳,添加在请求接口 Header
|
||||
// update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
|
||||
let signHeader = { "X-Sign": sign, "X-TIMESTAMP": signMd5Utils.getTimestamp() };
|
||||
// update-end--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
|
||||
return axios({
|
||||
url: url,
|
||||
method: 'get',
|
||||
params: parameter,
|
||||
responseType: "blob",
|
||||
paramsSerializer: function (params) {
|
||||
return qs.stringify(params, { arrayFormat: "repeat" });
|
||||
},
|
||||
headers: signHeader
|
||||
})
|
||||
}
|
||||
|
||||
//deleteAction
|
||||
export function deleteAction(url, parameter) {
|
||||
export function deleteAction(url,parameter) {
|
||||
return axios({
|
||||
url: url,
|
||||
method: 'delete',
|
||||
|
@ -179,15 +126,15 @@ export function saveService(parameter) {
|
|||
* @param parameter
|
||||
* @returns {*}
|
||||
*/
|
||||
export function downFile(url, parameter, method = 'get') {
|
||||
if (method == 'get') {
|
||||
export function downFile(url,parameter, method='get'){
|
||||
if(method=='get'){
|
||||
return axios({
|
||||
url: url,
|
||||
params: parameter,
|
||||
method: method,
|
||||
method: method ,
|
||||
responseType: 'blob'
|
||||
})
|
||||
} else {
|
||||
}else{
|
||||
return axios({
|
||||
url: url,
|
||||
method: method,
|
||||
|
@ -233,11 +180,11 @@ export function downloadFile(url, fileName, parameter, method) {
|
|||
* @param parameter
|
||||
* @returns {*}
|
||||
*/
|
||||
export function uploadAction(url, parameter) {
|
||||
export function uploadAction(url,parameter){
|
||||
return axios({
|
||||
url: url,
|
||||
data: parameter,
|
||||
method: 'post',
|
||||
method:'post' ,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data', // 文件上传
|
||||
},
|
||||
|
@ -250,17 +197,17 @@ export function uploadAction(url, parameter) {
|
|||
* @param subStr
|
||||
* @returns {*}
|
||||
*/
|
||||
export function getFileAccessHttpUrl(avatar, subStr) {
|
||||
if (!subStr) subStr = 'http'
|
||||
export function getFileAccessHttpUrl(avatar,subStr) {
|
||||
if(!subStr) subStr = 'http'
|
||||
try {
|
||||
if (avatar && avatar.startsWith(subStr)) {
|
||||
if(avatar && avatar.startsWith(subStr)){
|
||||
return avatar;
|
||||
} else {
|
||||
if (avatar && avatar.length > 0 && avatar.indexOf('[') == -1) {
|
||||
}else{
|
||||
if(avatar && avatar.length>0 && avatar.indexOf('[')==-1){
|
||||
return window._CONFIG['staticDomainURL'] + "/" + avatar;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
return;
|
||||
}catch(err){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1014 B |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1003 B |
Before Width: | Height: | Size: 1003 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 975 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1002 B |
Before Width: | Height: | Size: 1002 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1004 B |
Before Width: | Height: | Size: 1007 B |
BIN
src/assets/images/header/en.png
Normal file
After Width: | Height: | Size: 522 B |
BIN
src/assets/images/header/zh.png
Normal file
After Width: | Height: | Size: 446 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.6 KiB |
|
@ -1,80 +0,0 @@
|
|||
::v-deep {
|
||||
.ant-tabs{
|
||||
height: 100%;
|
||||
.ant-tabs-top-content{
|
||||
height: calc(100% - 50px);
|
||||
.ant-tabs-tabpane{
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ant-tabs-bar{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
margin: 0 0 10px 0;
|
||||
background-color: rgba(12, 235, 201, 0.05);
|
||||
border-top: 1px solid rgba(12, 235, 201, 0.3);
|
||||
border-bottom: 1px solid rgba(12, 235, 201, 0.3);
|
||||
}
|
||||
.ant-tabs-nav .ant-tabs-tab{
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
background-color: rgba(58, 236, 240, 0.22);
|
||||
font-family: BookmanOldStyle;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
font-stretch: normal;
|
||||
letter-spacing: 2px;
|
||||
color: #c9f6f6;
|
||||
margin: 0 0 0 10px;
|
||||
padding: 0 23px;
|
||||
position: relative;
|
||||
&::before{
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 7px;
|
||||
height: 29px;
|
||||
color: rgba(58, 236, 240, 0.22);
|
||||
border: 1px solid #569e9e;
|
||||
border-right: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
&::after{
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 7px;
|
||||
height: 29px;
|
||||
color: rgba(58, 236, 240, 0.22);
|
||||
border: 1px solid #569e9e;
|
||||
border-left: none;
|
||||
}
|
||||
&-active{
|
||||
&::before,
|
||||
&::after {
|
||||
border-color: #0cecca !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ant-tabs-ink-bar{
|
||||
display: none !important
|
||||
}
|
||||
.ant-tabs-nav .ant-tabs-tab-active{
|
||||
color: #2affdf;
|
||||
}
|
||||
.ant-row{
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
.ant-tabs-tab-prev, .ant-tabs-tab-next{
|
||||
color: #c9f6f6;
|
||||
}
|
||||
.ant-tabs-tab-prev:hover, .ant-tabs-tab-next:hover{
|
||||
color: #2affdf;
|
||||
}
|
||||
}
|
|
@ -1,16 +1,14 @@
|
|||
/**
|
||||
* 列表查询通用样式,移动端自适应
|
||||
*/
|
||||
.search {
|
||||
/**
|
||||
.search{
|
||||
margin-bottom: 54px;
|
||||
*/
|
||||
}
|
||||
.fold {
|
||||
.fold{
|
||||
width: calc(100% - 216px);
|
||||
display: inline-block;
|
||||
display: inline-block
|
||||
}
|
||||
.operator {
|
||||
.operator{
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
@media screen and (max-width: 900px) {
|
||||
|
@ -24,7 +22,7 @@
|
|||
i {
|
||||
cursor: pointer;
|
||||
}
|
||||
.trcolor {
|
||||
.trcolor{
|
||||
background-color: rgba(255, 192, 203, 0.31);
|
||||
color: red;
|
||||
color:red;
|
||||
}
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
<template>
|
||||
<div class="color-picker">
|
||||
<div class="color-picker-toggle" @click="togglePanel">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div class="color-picker-mask" :class="show ? 'show' : ''" @click="show = false">
|
||||
<div class="color-picker-panel" :style="style" @click.stop>
|
||||
<chrome v-model="color" disableAlpha></chrome>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Chrome } from 'vue-color'
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Chrome
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
style: {
|
||||
top: 0,
|
||||
left: 0
|
||||
},
|
||||
show: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
togglePanel(e) {
|
||||
const { x, y, offsetX, offsetY, target } = e
|
||||
this.style.top = y - offsetY + 'px'
|
||||
this.style.left = x - offsetX + target.offsetWidth + 4 + 'px'
|
||||
this.show = true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
color: {
|
||||
set(val) {
|
||||
this.$emit('input', val.hex)
|
||||
},
|
||||
get() {
|
||||
return this.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.color-picker {
|
||||
&-mask {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: transparent;
|
||||
z-index: 99999999;
|
||||
|
||||
&.show {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&-toggle {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-panel {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
</style>
|
51
src/components/Custom3DChart/index.vue
Normal file
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<div class="custom-chart" ref="containerRef" :style="{ height: height + 'px' }"></div>
|
||||
</template>
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import 'echarts-gl'
|
||||
export default {
|
||||
props: {
|
||||
option: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
mounted() {
|
||||
this.chart = echarts.init(this.$refs.containerRef)
|
||||
this.chart.setOption(this.option)
|
||||
},
|
||||
methods: {
|
||||
resize() {
|
||||
this.chart && this.chart.resize()
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
option: {
|
||||
handler() {
|
||||
if (this.chart) {
|
||||
this.chart.setOption(this.option)
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
height() {
|
||||
this.$nextTick(() => {
|
||||
this.chart && this.chart.resize()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.custom-chart {
|
||||
height: 100% !important;
|
||||
}
|
||||
</style>
|
|
@ -1,84 +0,0 @@
|
|||
<template>
|
||||
<a-select v-bind="$attrs" v-model="innerValue" show-arrow @change="onChange">
|
||||
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
|
||||
<div slot="dropdownRender" slot-scope="menu">
|
||||
<v-nodes :vnodes="menu" />
|
||||
<a-divider style="margin: 0;" />
|
||||
<div
|
||||
style="padding: 4px 12px; cursor: pointer;"
|
||||
@mousedown="e => e.preventDefault()"
|
||||
>
|
||||
<a-checkbox v-model="allVal" @change="checkedAll"><span @click.prevent="handleClick">ALL</span></a-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</a-select>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number, Array],
|
||||
},
|
||||
allChecked: {
|
||||
type: Boolean,
|
||||
default:false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
VNodes: {
|
||||
functional: true,
|
||||
render: (h, ctx) => ctx.props.vnodes,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
innerValue: this.value,
|
||||
allVal:this.allChecked
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
checkedAll(val) {
|
||||
this.$emit('changeAll', val.target.checked)
|
||||
},
|
||||
handleClick(e) {
|
||||
console.log("dfasdfasfad", e);
|
||||
this.allVal = !this.allVal
|
||||
this.$emit('changeAll', this.allVal)
|
||||
},
|
||||
onChange(val) {
|
||||
this.$emit('input', val)
|
||||
this.$emit('change', val)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(val) {
|
||||
this.innerValue = val
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
allChecked: {
|
||||
handler(val) {
|
||||
this.allVal = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.ant-select {
|
||||
width: 100%;
|
||||
.ant-select-arrow-icon {
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
}
|
||||
&-open {
|
||||
.ant-select-arrow-icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
.ant-select-dropdown-content{
|
||||
position: relative;
|
||||
background: #03353f;
|
||||
}
|
||||
</style>
|
|
@ -3,50 +3,40 @@
|
|||
</template>
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import 'echarts-gl'
|
||||
|
||||
const events = ['click', 'brushEnd', 'dataZoom']
|
||||
const zrEvents = ['mousemove', 'mousedown', 'mouseup', 'click', 'dblclick', 'contextmenu']
|
||||
const events = ['brushEnd']
|
||||
const zrEvents = ['mousemove', 'mousedown', 'mouseup']
|
||||
|
||||
export default {
|
||||
props: {
|
||||
option: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
opts: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
default: () => ({})
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
mounted() {
|
||||
this._chart = echarts.init(this.$refs.containerRef)
|
||||
this._chart.setOption(this.option, this.opts)
|
||||
this._chart.setOption(this.option)
|
||||
this.initEventListener()
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this._chart) {
|
||||
this._chart.dispose()
|
||||
this._chart = null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initEventListener() {
|
||||
events.forEach((eventName) => {
|
||||
events.forEach(eventName => {
|
||||
this._chart.on(eventName, (params) => {
|
||||
this.$emit(eventName, params)
|
||||
})
|
||||
})
|
||||
|
||||
const zr = this.getZRender()
|
||||
zrEvents.forEach((eventName) => {
|
||||
zr.on(eventName, (params) => {
|
||||
zrEvents.forEach(eventName => {
|
||||
zr.on(eventName, params => {
|
||||
this.$emit(`zr:${eventName}`, params)
|
||||
})
|
||||
})
|
||||
|
@ -63,27 +53,27 @@ export default {
|
|||
|
||||
getZRender() {
|
||||
return this._chart.getZr()
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
option: {
|
||||
handler() {
|
||||
if (this._chart) {
|
||||
this._chart.setOption(this.option, this.opts)
|
||||
this._chart.setOption(this.option)
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
deep: true
|
||||
},
|
||||
height() {
|
||||
this.$nextTick(() => {
|
||||
this._chart && this._chart.resize()
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.custom-chart {
|
||||
height: 100%;
|
||||
height: 100% !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<a-date-picker v-bind="$attrs" v-model="innerValue" @change="onChange">
|
||||
<a-date-picker v-bind="$attrs" v-model="innerValue">
|
||||
<img src="@/assets/images/global/calendar.png" slot="suffixIcon" alt="" srcset="" />
|
||||
</a-date-picker>
|
||||
</template>
|
||||
|
@ -19,12 +19,7 @@ export default {
|
|||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange(mont,date) {
|
||||
this.$emit("change",mont,date)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang=""></style>
|
||||
|
|
|
@ -1,22 +1,12 @@
|
|||
<template>
|
||||
<a-modal
|
||||
:class="'custom-modal' + (innerFullscreen ? ' fullscreen' : '')"
|
||||
v-bind="_attrs"
|
||||
v-model="visible"
|
||||
:maskClosable="false"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-modal :class="'custom-modal' + (innerFullscreen ? ' fullscreen' : '')" v-bind="_attrs" v-model="visible">
|
||||
<img slot="closeIcon" src="@/assets/images/global/close.png" />
|
||||
<div slot="title">
|
||||
<div class="custom-modal-title">
|
||||
<span>{{ title }}</span>
|
||||
<template v-if="enableFullScreen">
|
||||
<img
|
||||
v-if="innerFullscreen"
|
||||
src="@/assets/images/global/quit-fullscreen.png"
|
||||
@click="innerFullscreen = false"
|
||||
/>
|
||||
<img v-else src="@/assets/images/global/fullscreen.png" @click="innerFullscreen = true" />
|
||||
<img v-if="innerFullscreen" src="@/assets/images/global/quit-fullscreen.png" @click="innerFullscreen = false" />
|
||||
<img v-else src="@/assets/images/global/fullscreen.png" @click="innerFullscreen = true" />
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -34,24 +24,24 @@
|
|||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
type: Boolean
|
||||
},
|
||||
okHandler: {
|
||||
type: Function,
|
||||
type: Function
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
type: String
|
||||
},
|
||||
enableFullScreen: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: this.value,
|
||||
confirmLoading: false,
|
||||
innerFullscreen: false,
|
||||
innerFullscreen: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -66,17 +56,15 @@ export default {
|
|||
},
|
||||
innerFullscreen(val) {
|
||||
this.$emit('fullscreen', val)
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onSave() {
|
||||
if (this.okHandler instanceof Function) {
|
||||
try {
|
||||
this.confirmLoading = true
|
||||
const success = await this.okHandler()
|
||||
if (success !== false) {
|
||||
this.visible = false
|
||||
}
|
||||
await this.okHandler()
|
||||
this.visible = false
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
|
@ -88,10 +76,7 @@ export default {
|
|||
},
|
||||
onCancel() {
|
||||
this.visible = false
|
||||
},
|
||||
handleCancel() {
|
||||
this.$emit('cancel')
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
_attrs() {
|
||||
|
@ -106,8 +91,8 @@ export default {
|
|||
// 是否有自定义的footer
|
||||
hasCustomFooter() {
|
||||
return !!this.$slots['custom-footer']
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
<template>
|
||||
<a-table
|
||||
ref="tableRef"
|
||||
class="custom-table"
|
||||
:class="['custom-table', canSelect && multiple && mouseMoveSelect ? 'mouse-move-select' : '']"
|
||||
class="custom-table"
|
||||
v-bind="$attrs"
|
||||
:data-source="list"
|
||||
:columns="columns"
|
||||
|
@ -10,8 +8,8 @@
|
|||
:row-key="rowKey"
|
||||
:loading="loading"
|
||||
:pagination="pagination"
|
||||
:customRow="multiple && mouseMoveSelect ? customMouseMoveSelectRow : customRow"
|
||||
:rowClassName="() => (canSelect ? 'custom-table-row' : '')"
|
||||
:customRow="customRow"
|
||||
:rowClassName="() => canSelect? 'custom-table-row': ''"
|
||||
@change="handleTableChange"
|
||||
>
|
||||
<!-- 处理 scopedSlots -->
|
||||
|
@ -25,174 +23,98 @@ export default {
|
|||
props: {
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
default: () => []
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
default: () => []
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'middle',
|
||||
default: 'middle'
|
||||
},
|
||||
rowKey: {
|
||||
type: String,
|
||||
default: 'id',
|
||||
default: 'id'
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
type: Boolean
|
||||
},
|
||||
pagination: {
|
||||
type: [Object, Boolean],
|
||||
type: [Object, Boolean]
|
||||
},
|
||||
selectedRowKeys: {
|
||||
type: Array,
|
||||
type: Array
|
||||
},
|
||||
selectionRows: {
|
||||
type: Array,
|
||||
type: Array
|
||||
},
|
||||
canSelect: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: true
|
||||
},
|
||||
canDeselect: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 多选
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 鼠标移动选择
|
||||
mouseMoveSelect: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
innerSelectedRowKeys: [],
|
||||
innerSelectedRows: [],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.canSelect && this.multiple && this.mouseMoveSelect) {
|
||||
const tbody = this.$el.querySelector('.ant-table-tbody')
|
||||
tbody.addEventListener('mouseleave', () => {
|
||||
this.mouseMoveStartIndex = undefined
|
||||
})
|
||||
innerSelectedRowKeys: [],
|
||||
innerSelectedRows: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 实现单击选中/反选功能
|
||||
customRow(record, index) {
|
||||
customRow(record) {
|
||||
const key = record[this.rowKey]
|
||||
return {
|
||||
class: this.innerSelectedRowKeys.includes(key) ? 'ant-table-row-selected' : '',
|
||||
on: {
|
||||
click: () => {
|
||||
if (!this.canSelect) {
|
||||
if(!this.canSelect) {
|
||||
return
|
||||
}
|
||||
// 反选
|
||||
if (this.innerSelectedRowKeys.includes(key)) {
|
||||
if (this.multiple || this.canDeselect) {
|
||||
const findIndex = this.innerSelectedRowKeys.findIndex((k) => k == key)
|
||||
this.innerSelectedRowKeys.splice(findIndex, 1)
|
||||
}
|
||||
}
|
||||
// 选中
|
||||
else {
|
||||
if (this.multiple) {
|
||||
const findIndex = this.innerSelectedRowKeys.findIndex(k => k == key)
|
||||
this.innerSelectedRowKeys.splice(findIndex, 1)
|
||||
} else {
|
||||
if(this.multiple) {
|
||||
this.innerSelectedRowKeys.push(key)
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this.innerSelectedRowKeys = [key]
|
||||
}
|
||||
}
|
||||
this.$emit('detail', record)
|
||||
|
||||
this.$emit('rowClick', record, index)
|
||||
},
|
||||
dblclick: () => {
|
||||
this.$emit('rowDblClick', record, index)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 实现鼠标拖移动多选功能
|
||||
customMouseMoveSelectRow(record, index) {
|
||||
const key = record[this.rowKey]
|
||||
return {
|
||||
class: this.innerSelectedRowKeys.includes(key) ? 'ant-table-row-selected' : '',
|
||||
on: {
|
||||
mousedown: () => {
|
||||
this.innerSelectedRowKeys = []
|
||||
this.mouseMoveStartIndex = index
|
||||
},
|
||||
mouseenter: () => {
|
||||
if (this.mouseMoveStartIndex !== undefined) {
|
||||
const indexes = [this.mouseMoveStartIndex, index].sort((a, b) => a - b)
|
||||
this.innerSelectedRowKeys = this.list.slice(indexes[0], indexes[1] + 1).map((item) => item[this.rowKey])
|
||||
}
|
||||
},
|
||||
mouseup: () => {
|
||||
// 开始和结束在同一个,相当于click
|
||||
if (this.mouseMoveStartIndex == index) {
|
||||
this.innerSelectedRowKeys = [key]
|
||||
}
|
||||
this.mouseMoveStartIndex = undefined
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
handleTableChange(pagination, filters, sorter) {
|
||||
this.$emit('change', pagination, filters, sorter)
|
||||
},
|
||||
|
||||
// 让第index行滚动到视野范围
|
||||
scrollIntoView(index) {
|
||||
const tableEle = this.$refs.tableRef.$el
|
||||
const tableBodyEle = tableEle.querySelector('.ant-table-body')
|
||||
const prevEle = tableBodyEle.querySelector(`.ant-table-row:nth-child(${index + 1})`)
|
||||
tableBodyEle.scrollTop = prevEle.offsetTop
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selectedRowKeys(val) {
|
||||
this.innerSelectedRowKeys = val
|
||||
selectedRowKeys (val) {
|
||||
this.innerSelectedRowKeys = val
|
||||
},
|
||||
innerSelectedRowKeys() {
|
||||
innerSelectedRowKeys () {
|
||||
this.$emit('update:selectedRowKeys', this.innerSelectedRowKeys)
|
||||
this.innerSelectedRows = this.innerSelectedRowKeys.map((key) => {
|
||||
return this.list.find((item) => item[this.rowKey] === key)
|
||||
return this.list.find(item => item[this.rowKey] === key)
|
||||
})
|
||||
this.$emit('update:selectionRows', this.innerSelectedRows)
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
scopedSlotsKeys() {
|
||||
return Object.keys(this.$scopedSlots)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
::v-deep {
|
||||
.custom-table-row {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.mouse-move-select {
|
||||
user-select: none;
|
||||
|
||||
::v-deep {
|
||||
td {
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
.custom-table-row {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
<template>
|
||||
<div class="custom-time-input">
|
||||
<template v-for="(item, index) in setting">
|
||||
<a-input-number
|
||||
:key="index"
|
||||
:formatter="(value) => `${value}`"
|
||||
:precision="0"
|
||||
:parser="(value) => value.replace('.', '')"
|
||||
:step="1"
|
||||
:max="item.max"
|
||||
:min="item.min"
|
||||
v-model="innerValue[index]"
|
||||
></a-input-number>
|
||||
<span v-if="index !== setting.length - 1" :key="'_' + index">:</span>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const setting = [
|
||||
{
|
||||
min: 0,
|
||||
max: 23,
|
||||
},
|
||||
{
|
||||
min: 0,
|
||||
max: 59,
|
||||
},
|
||||
{
|
||||
min: 0,
|
||||
max: 59,
|
||||
},
|
||||
{
|
||||
min: 0,
|
||||
max: 999,
|
||||
},
|
||||
]
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
this.setting = setting
|
||||
|
||||
return {
|
||||
innerValue: this.splitValue(this.value),
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
splitValue(value) {
|
||||
if (value) {
|
||||
const arr = value.split(':')
|
||||
if (arr.length < setting.length) {
|
||||
// 如果给的值小于位数,补全
|
||||
for (let i = 0; i < setting.length - arr.length; i++) {
|
||||
arr.push(0)
|
||||
}
|
||||
}
|
||||
return arr
|
||||
} else {
|
||||
return [0, 0, 0, 0]
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
this.splitValue(val)
|
||||
},
|
||||
innerValue(val) {
|
||||
const newVal = val.join(':')
|
||||
this.$emit('input', newVal)
|
||||
this.$emit('change', newVal)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.custom-time-input {
|
||||
.ant-input-number {
|
||||
width: 25px;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
|
||||
::v-deep {
|
||||
.ant-input-number-handler-wrap {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="search-form">
|
||||
<a-form-model ref="form" :colon="false" :model="formModel" v-bind="$attrs">
|
||||
<a-form-model ref="form" :colon="false" :model="formModel" v-bind="$attrs" @keyup.enter.native="onSearch">
|
||||
<a-row v-if="type == 'single-line'" :gutter="20" style="margin-right: 0 !important;">
|
||||
<a-col
|
||||
class="search-form-item"
|
||||
|
@ -10,15 +10,12 @@
|
|||
:style="item.style"
|
||||
>
|
||||
<a-form-model-item :label="item.label" :prop="item.name" :labelCol="item.labelCol">
|
||||
<a-checkbox v-if="item.type == 'a-checkbox'" v-model="formModel[item.name]" v-on="item.on">
|
||||
{{ item.innerLabel }}
|
||||
</a-checkbox>
|
||||
<component v-else :is="item.type" v-bind="item.props" v-model="formModel[item.name]" v-on="item.on"></component>
|
||||
<component :is="item.type" v-bind="item.props" v-model="formModel[item.name]" v-on="item.on"></component>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-button class="search-btn" type="primary" @click="onSearch">
|
||||
<img src="@/assets/images/global/search.png" alt="" />
|
||||
Search
|
||||
{{$t('m.system.search')}}
|
||||
</a-button>
|
||||
<slot name="additional"></slot>
|
||||
</a-row>
|
||||
|
@ -69,15 +66,9 @@ export default {
|
|||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(val) {
|
||||
this.formModel = val
|
||||
},
|
||||
deep: true
|
||||
value(val) {
|
||||
this.formModel = val
|
||||
},
|
||||
// value(val) {
|
||||
// this.formModel = val
|
||||
// },
|
||||
formModel: {
|
||||
handler(val) {
|
||||
this.$emit('input', val)
|
||||
|
@ -96,7 +87,6 @@ export default {
|
|||
border-bottom: 1px solid rgba(12, 235, 201, 0.3);
|
||||
margin-bottom: 18px;
|
||||
background-color: rgba(12, 235, 201, 0.05);
|
||||
|
||||
&-item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
|
|
@ -1,33 +1,16 @@
|
|||
<template>
|
||||
<a-radio-group v-if="tagType == 'radio'" @change="handleInput" :value="getValueSting" :disabled="disabled">
|
||||
<a-radio-group v-if="tagType=='radio'" @change="handleInput" :value="getValueSting" :disabled="disabled">
|
||||
<a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio>
|
||||
</a-radio-group>
|
||||
|
||||
<a-radio-group
|
||||
v-else-if="tagType == 'radioButton'"
|
||||
buttonStyle="solid"
|
||||
@change="handleInput"
|
||||
:value="getValueSting"
|
||||
:disabled="disabled"
|
||||
>
|
||||
<a-radio-group v-else-if="tagType=='radioButton'" buttonStyle="solid" @change="handleInput" :value="getValueSting" :disabled="disabled">
|
||||
<a-radio-button v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio-button>
|
||||
</a-radio-group>
|
||||
|
||||
<a-select
|
||||
v-else-if="tagType == 'select'"
|
||||
:getPopupContainer="getPopupContainer"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:value="getValueSting"
|
||||
:allowClear="allowClear"
|
||||
show-arrow
|
||||
:mode="modeType"
|
||||
:maxTagCount="1"
|
||||
@change="handleInput"
|
||||
>
|
||||
<a-select v-else-if="tagType=='select'" :getPopupContainer = "getPopupContainer" :placeholder="placeholder" :disabled="disabled" :value="getValueSting" :allowClear="allowClear" @change="handleInput">
|
||||
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
|
||||
<a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value">
|
||||
<span style="display: inline-block; width: 100%" :title="item.text || item.label">
|
||||
<span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
|
||||
{{ item.text || item.label }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
|
@ -35,98 +18,97 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { ajaxGetDictItems, getDictItemsFromCache } from '@/api/api'
|
||||
import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api'
|
||||
|
||||
export default {
|
||||
name: 'JDictSelectTag',
|
||||
props: {
|
||||
modeType: String,
|
||||
dictCode: String,
|
||||
placeholder: String,
|
||||
disabled: Boolean,
|
||||
value: [String, Number, Array],
|
||||
type: String,
|
||||
getPopupContainer: {
|
||||
type: Function,
|
||||
default: (node) => node.parentNode,
|
||||
export default {
|
||||
name: "JDictSelectTag",
|
||||
props: {
|
||||
dictCode: String,
|
||||
placeholder: String,
|
||||
disabled: Boolean,
|
||||
value: [String, Number],
|
||||
type: String,
|
||||
getPopupContainer:{
|
||||
type: Function,
|
||||
default: (node) => node.parentNode
|
||||
},
|
||||
allowClear: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
allowClear: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
data() {
|
||||
return {
|
||||
dictOptions: [],
|
||||
tagType:""
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dictOptions: [],
|
||||
tagType: '',
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
dictCode: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.initDictData()
|
||||
watch:{
|
||||
dictCode:{
|
||||
immediate:true,
|
||||
handler() {
|
||||
this.initDictData()
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// console.log(this.dictCode);
|
||||
if(!this.type || this.type==="list"){
|
||||
this.tagType = "select"
|
||||
}else{
|
||||
this.tagType = this.type
|
||||
}
|
||||
//获取字典数据
|
||||
// this.initDictData();
|
||||
},
|
||||
computed: {
|
||||
getValueSting(){
|
||||
// update-begin author:wangshuai date:20200601 for: 不显示placeholder的文字 ------
|
||||
// 当有null或“” placeholder不显示
|
||||
return this.value != null ? this.value.toString() : undefined;
|
||||
// update-end author:wangshuai date:20200601 for: 不显示placeholder的文字 ------
|
||||
},
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// console.log(this.dictCode);
|
||||
if (!this.type || this.type === 'list') {
|
||||
this.tagType = 'select'
|
||||
} else {
|
||||
this.tagType = this.type
|
||||
}
|
||||
//获取字典数据
|
||||
// this.initDictData();
|
||||
},
|
||||
computed: {
|
||||
getValueSting() {
|
||||
// update-begin author:wangshuai date:20200601 for: 不显示placeholder的文字 ------
|
||||
// 当有null或“” placeholder不显示
|
||||
// return this.value != null ? this.value.toString() : undefined
|
||||
return Array.isArray(this.value) ? this.value : this.value != null ? this.value.toString() : undefined
|
||||
// update-end author:wangshuai date:20200601 for: 不显示placeholder的文字 ------
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
initDictData() {
|
||||
//优先从缓存中读取字典配置
|
||||
if (getDictItemsFromCache(this.dictCode)) {
|
||||
this.dictOptions = getDictItemsFromCache(this.dictCode)
|
||||
return
|
||||
}
|
||||
|
||||
//根据字典Code, 初始化字典数组
|
||||
ajaxGetDictItems(this.dictCode, null).then((res) => {
|
||||
if (res.success) {
|
||||
// console.log(res.result);
|
||||
this.dictOptions = res.result
|
||||
methods: {
|
||||
initDictData() {
|
||||
//优先从缓存中读取字典配置
|
||||
if(getDictItemsFromCache(this.dictCode)){
|
||||
this.dictOptions = getDictItemsFromCache(this.dictCode);
|
||||
return
|
||||
}
|
||||
})
|
||||
},
|
||||
handleInput(e = '') {
|
||||
let val
|
||||
if (Object.keys(e).includes('target')) {
|
||||
val = e.target.value
|
||||
} else {
|
||||
val = e
|
||||
|
||||
//根据字典Code, 初始化字典数组
|
||||
ajaxGetDictItems(this.dictCode, null).then((res) => {
|
||||
if (res.success) {
|
||||
// console.log(res.result);
|
||||
this.dictOptions = res.result;
|
||||
}
|
||||
})
|
||||
},
|
||||
handleInput(e='') {
|
||||
let val;
|
||||
if(Object.keys(e).includes('target')){
|
||||
val = e.target.value
|
||||
}else{
|
||||
val = e
|
||||
}
|
||||
console.log(val);
|
||||
this.$emit('change', val? val: undefined);
|
||||
//LOWCOD-2146 【菜单】数据规则,选择自定义SQL 规则值无法输入空格
|
||||
this.$emit('input', val? val: undefined);
|
||||
},
|
||||
setCurrentDictOptions(dictOptions){
|
||||
this.dictOptions = dictOptions
|
||||
},
|
||||
getCurrentDictOptions(){
|
||||
return this.dictOptions
|
||||
}
|
||||
this.$emit('change', val ? val : undefined)
|
||||
//LOWCOD-2146 【菜单】数据规则,选择自定义SQL 规则值无法输入空格
|
||||
this.$emit('input', val ? val : undefined)
|
||||
},
|
||||
setCurrentDictOptions(dictOptions) {
|
||||
this.dictOptions = dictOptions
|
||||
},
|
||||
getCurrentDictOptions() {
|
||||
return this.dictOptions
|
||||
},
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
}
|
||||
model:{
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<a-input :placeholder="placeholder" v-model="editCronValue" :disabled="disabled">
|
||||
<a slot="addonAfter" @click="showConfigDlg" class="config-btn" :disabled="disabled">
|
||||
<a-icon type="setting"></a-icon>
|
||||
Select
|
||||
选择
|
||||
</a>
|
||||
</a-input>
|
||||
<j-modal :visible.sync="show" title="Cron表达式" width="800px">
|
||||
|
@ -24,44 +24,44 @@ import EasyCron from './EasyCron.vue'
|
|||
|
||||
export default {
|
||||
name: 'input-cron',
|
||||
components: { EasyCron },
|
||||
components: {EasyCron},
|
||||
model: {
|
||||
prop: 'cronValue',
|
||||
event: 'change',
|
||||
event: 'change'
|
||||
},
|
||||
props: {
|
||||
cronValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
default: ''
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '800px',
|
||||
default: '800px'
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请输入cron表达式',
|
||||
default: '请输入cron表达式'
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
exeStartTime: {
|
||||
type: [Number, String, Object],
|
||||
default: 0,
|
||||
default: 0
|
||||
},
|
||||
hideSecond: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
hideYear: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
remote: {
|
||||
type: Function,
|
||||
default: null,
|
||||
},
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -78,20 +78,22 @@ export default {
|
|||
},
|
||||
editCronValue(newVal, oldVal) {
|
||||
this.$emit('change', newVal)
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showConfigDlg() {
|
||||
if (!this.disabled) {
|
||||
this.show = true
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.config-btn {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.config-btn {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
<div>
|
||||
<a-input-search
|
||||
v-model="textVals"
|
||||
placeholder="Please select the user first"
|
||||
placeholder="请先选择用户"
|
||||
readOnly
|
||||
unselectable="on"
|
||||
@search="onSearchDepUser">
|
||||
<a-button slot="enterButton" :disabled="disabled">Select user</a-button>
|
||||
<a-button slot="enterButton" :disabled="disabled">选择用户</a-button>
|
||||
</a-input-search>
|
||||
<j-select-user-by-dep-modal
|
||||
ref="selectModal"
|
||||
|
@ -120,7 +120,7 @@
|
|||
this.$refs.selectModal.showModal()
|
||||
},
|
||||
selectOK(rows) {
|
||||
console.log("Currently selected user", rows)
|
||||
console.log("当前选中用户", rows)
|
||||
if (!rows) {
|
||||
this.storeVals = ''
|
||||
this.textVals = ''
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<template>
|
||||
<global-layout>
|
||||
<transition name="page-transition">
|
||||
<keep-alive>
|
||||
<keep-alive v-if="keepAlive">
|
||||
<router-view />
|
||||
</keep-alive>
|
||||
<router-view v-else />
|
||||
</transition>
|
||||
</global-layout>
|
||||
</template>
|
||||
|
@ -21,6 +22,14 @@
|
|||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
keepAlive () {
|
||||
return this.$route.meta.keepAlive
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<template>
|
||||
<div class="main">
|
||||
<keep-alive>
|
||||
<router-view />
|
||||
<keep-alive :include="includedComponents">
|
||||
<router-view v-if="keepAlive" />
|
||||
</keep-alive>
|
||||
<router-view v-if="!keepAlive" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="custom-top-menu">
|
||||
<a-menu mode="horizontal" v-model="selectedKeys" @click="onMenuSelect">
|
||||
<a-menu-item v-for="(menu, index) in menus" :key="menu.name" :class="{ 'is-last': index === menus.length - 1 }">
|
||||
<a-menu-item v-for="(menu, index) in menus" :key="menu.name" :class="{ 'is-last': index === menus.length - 1}">
|
||||
<img
|
||||
v-show="menu.name === selectedKeys[0]"
|
||||
class="menu-logo"
|
||||
|
@ -15,7 +15,7 @@
|
|||
alt=""
|
||||
/>
|
||||
<span v-html="menu.meta.title.split(' ').join('<br>')"></span>
|
||||
<img v-if="index !== menus.length - 1" class="split-line" src="@/assets/images/header/split-line.png" alt="" />
|
||||
<img v-if="index !== menus.length - 1" class="split-line" src="@/assets/images/header/split-line.png" alt="">
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</div>
|
||||
|
@ -26,12 +26,12 @@ export default {
|
|||
props: {
|
||||
menus: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedKeys: [],
|
||||
selectedKeys: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
@ -40,24 +40,8 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
onMenuSelect({ key }) {
|
||||
const childPath = this.getChildrenPath(this.menuItems.find((menu) => menu.name === key))
|
||||
if (key == 'abnormal-alarm') {
|
||||
const selectedKeys = window.sessionStorage.getItem('currMenu_alarm')
|
||||
if (selectedKeys) {
|
||||
this.$router.push(selectedKeys)
|
||||
} else {
|
||||
this.$router.push(childPath)
|
||||
}
|
||||
} else if (key == 'istatistics') {
|
||||
const selectedKeys = window.sessionStorage.getItem('currMenu_web')
|
||||
if (selectedKeys) {
|
||||
this.$router.push(selectedKeys)
|
||||
} else {
|
||||
this.$router.push(childPath)
|
||||
}
|
||||
} else {
|
||||
this.$router.push(childPath)
|
||||
}
|
||||
const childPath = this.getChildrenPath(this.menuItems.find(menu => menu.name === key))
|
||||
this.$router.push(childPath)
|
||||
},
|
||||
getChildrenPath(menuItem) {
|
||||
if (menuItem.children) {
|
||||
|
@ -82,19 +66,19 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route(route) {
|
||||
const currTopMenu = this.findTopMenuByRouteName(this.menuItems, route.name)
|
||||
this.selectedKeys = [currTopMenu.name]
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
menuItems() {
|
||||
return this.menus.filter((item) => !item.hidden)
|
||||
},
|
||||
},
|
||||
return this.menus.filter(item => !item.hidden)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
:arrowPointAtCenter="true"
|
||||
overlayClassName="header-notice-wrapper"
|
||||
@visibleChange="handleHoverChange"
|
||||
:overlayStyle="{ width: '300px', top: '50px' }"
|
||||
>
|
||||
:overlayStyle="{ width: '300px', top: '50px' }">
|
||||
<template slot="content">
|
||||
<a-spin :spinning="loadding">
|
||||
<a-tabs>
|
||||
|
@ -31,21 +30,17 @@
|
|||
</a-list>-->
|
||||
<a-list>
|
||||
<a-list-item :key="index" v-for="(record, index) in announcement1">
|
||||
<div style="margin-left: 5%; width: 80%">
|
||||
<p>
|
||||
<a @click="showAnnouncement(record)">{{ record.titile }}</a>
|
||||
</p>
|
||||
<p style="color: #c9f6f6; margin-bottom: 0px">{{ record.createTime }} 发布</p>
|
||||
<div style="margin-left: 5%;width: 80%">
|
||||
<p><a @click="showAnnouncement(record)">{{ record.titile }}</a></p>
|
||||
<p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p>
|
||||
</div>
|
||||
<div style="text-align: right">
|
||||
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'L'" color="blue">一般消息</a-tag>
|
||||
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange"
|
||||
>重要消息</a-tag
|
||||
>
|
||||
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange">重要消息</a-tag>
|
||||
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'H'" color="red">紧急消息</a-tag>
|
||||
</div>
|
||||
</a-list-item>
|
||||
<div style="margin-top: 5px; text-align: center">
|
||||
<div style="margin-top: 5px;text-align: center">
|
||||
<a-button @click="toMyAnnouncement()" type="dashed" block>查看更多</a-button>
|
||||
</div>
|
||||
</a-list>
|
||||
|
@ -53,21 +48,17 @@
|
|||
<a-tab-pane :tab="msg2Title" key="2">
|
||||
<a-list>
|
||||
<a-list-item :key="index" v-for="(record, index) in announcement2">
|
||||
<div style="margin-left: 5%; width: 80%">
|
||||
<p>
|
||||
<a @click="showAnnouncement(record)">{{ record.titile }}</a>
|
||||
</p>
|
||||
<p style="color: #c9f6f6; margin-bottom: 0px">{{ record.createTime }} 发布</p>
|
||||
<div style="margin-left: 5%;width: 80%">
|
||||
<p><a @click="showAnnouncement(record)">{{ record.titile }}</a></p>
|
||||
<p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p>
|
||||
</div>
|
||||
<div style="text-align: right">
|
||||
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'L'" color="blue">一般消息</a-tag>
|
||||
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange"
|
||||
>重要消息</a-tag
|
||||
>
|
||||
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange">重要消息</a-tag>
|
||||
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'H'" color="red">紧急消息</a-tag>
|
||||
</div>
|
||||
</a-list-item>
|
||||
<div style="margin-top: 5px; text-align: center">
|
||||
<div style="margin-top: 5px;text-align: center">
|
||||
<a-button @click="toMyAnnouncement()" type="dashed" block>查看更多</a-button>
|
||||
</div>
|
||||
</a-list>
|
||||
|
@ -77,297 +68,291 @@
|
|||
</template>
|
||||
<span @click="fetchNotice" class="header-notice">
|
||||
<a-badge :count="msgTotal">
|
||||
<img src="@/assets/images/header/notice.png" alt="" />
|
||||
<img src="@/assets/images/header/notice.png" alt="">
|
||||
</a-badge>
|
||||
</span>
|
||||
<show-announcement ref="ShowAnnouncement" @ok="modalFormOk"></show-announcement>
|
||||
<dynamic-notice ref="showDynamNotice" :path="openPath" :formData="formData" />
|
||||
<dynamic-notice ref="showDynamNotice" :path="openPath" :formData="formData"/>
|
||||
</a-popover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getAction, putAction } from '@/api/manage'
|
||||
import ShowAnnouncement from './ShowAnnouncement'
|
||||
import store from '@/store/'
|
||||
import DynamicNotice from './DynamicNotice'
|
||||
import Vue from 'vue'
|
||||
import { ACCESS_TOKEN } from '@/store/mutation-types'
|
||||
import { getAction,putAction } from '@/api/manage'
|
||||
import ShowAnnouncement from './ShowAnnouncement'
|
||||
import store from '@/store/'
|
||||
import DynamicNotice from './DynamicNotice'
|
||||
import Vue from 'vue'
|
||||
import { ACCESS_TOKEN } from '@/store/mutation-types'
|
||||
|
||||
export default {
|
||||
name: 'HeaderNotice',
|
||||
components: {
|
||||
DynamicNotice,
|
||||
ShowAnnouncement,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loadding: false,
|
||||
url: {
|
||||
listCementByUser: '/sys/annountCement/listByUser',
|
||||
editCementSend: '/sys/sysAnnouncementSend/editByAnntIdAndUserId',
|
||||
queryById: '/sys/annountCement/queryById',
|
||||
},
|
||||
hovered: false,
|
||||
announcement1: [],
|
||||
announcement2: [],
|
||||
msg1Count: '0',
|
||||
msg2Count: '0',
|
||||
msg1Title: '通知(0)',
|
||||
msg2Title: '',
|
||||
stopTimer: false,
|
||||
websock: null,
|
||||
lockReconnect: false,
|
||||
//websocket错误连接次数
|
||||
wsConnectErrorTime: 1,
|
||||
heartCheck: null,
|
||||
formData: {},
|
||||
openPath: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
msgTotal() {
|
||||
return parseInt(this.msg1Count) + parseInt(this.msg2Count)
|
||||
export default {
|
||||
name: "HeaderNotice",
|
||||
components: {
|
||||
DynamicNotice,
|
||||
ShowAnnouncement,
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.loadData()
|
||||
//this.timerFun();
|
||||
this.initWebSocket()
|
||||
// this.heartCheckFun();
|
||||
},
|
||||
destroyed: function () {
|
||||
// 离开页面生命周期函数
|
||||
this.websocketOnclose()
|
||||
},
|
||||
methods: {
|
||||
timerFun() {
|
||||
this.stopTimer = false
|
||||
let myTimer = setInterval(() => {
|
||||
// 停止定时器
|
||||
if (this.stopTimer == true) {
|
||||
clearInterval(myTimer)
|
||||
data () {
|
||||
return {
|
||||
loadding: false,
|
||||
url:{
|
||||
listCementByUser:"/sys/annountCement/listByUser",
|
||||
editCementSend:"/sys/sysAnnouncementSend/editByAnntIdAndUserId",
|
||||
queryById:"/sys/annountCement/queryById",
|
||||
},
|
||||
hovered: false,
|
||||
announcement1:[],
|
||||
announcement2:[],
|
||||
msg1Count:"0",
|
||||
msg2Count:"0",
|
||||
msg1Title:"通知(0)",
|
||||
msg2Title:"",
|
||||
stopTimer:false,
|
||||
websock: null,
|
||||
lockReconnect:false,
|
||||
//websocket错误连接次数
|
||||
wsConnectErrorTime:1,
|
||||
heartCheck:null,
|
||||
formData:{},
|
||||
openPath:''
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
msgTotal () {
|
||||
return parseInt(this.msg1Count)+parseInt(this.msg2Count);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadData();
|
||||
//this.timerFun();
|
||||
this.initWebSocket();
|
||||
// this.heartCheckFun();
|
||||
},
|
||||
destroyed: function () { // 离开页面生命周期函数
|
||||
this.websocketOnclose();
|
||||
},
|
||||
methods: {
|
||||
timerFun() {
|
||||
this.stopTimer = false;
|
||||
let myTimer = setInterval(()=>{
|
||||
// 停止定时器
|
||||
if (this.stopTimer == true) {
|
||||
clearInterval(myTimer);
|
||||
return;
|
||||
}
|
||||
this.loadData()
|
||||
},6000)
|
||||
},
|
||||
loadData (){
|
||||
try {
|
||||
// 获取系统消息
|
||||
getAction(this.url.listCementByUser).then((res) => {
|
||||
if (res.success) {
|
||||
this.announcement1 = res.result.anntMsgList;
|
||||
this.msg1Count = res.result.anntMsgTotal;
|
||||
this.msg1Title = "通知(" + res.result.anntMsgTotal + ")";
|
||||
this.announcement2 = res.result.sysMsgList;
|
||||
this.msg2Count = res.result.sysMsgTotal;
|
||||
this.msg2Title = "系统消息(" + res.result.sysMsgTotal + ")";
|
||||
}
|
||||
}).catch(error => {
|
||||
console.log("系统消息通知异常",error);//这行打印permissionName is undefined
|
||||
this.stopTimer = true;
|
||||
console.log("清理timer");
|
||||
});
|
||||
} catch (err) {
|
||||
this.stopTimer = true;
|
||||
console.log("通知异常",err);
|
||||
}
|
||||
},
|
||||
fetchNotice () {
|
||||
if (this.loadding) {
|
||||
this.loadding = false
|
||||
return
|
||||
}
|
||||
this.loadData()
|
||||
}, 6000)
|
||||
},
|
||||
loadData() {
|
||||
try {
|
||||
// 获取系统消息
|
||||
getAction(this.url.listCementByUser)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.announcement1 = res.result.anntMsgList
|
||||
this.msg1Count = res.result.anntMsgTotal
|
||||
this.msg1Title = '通知(' + res.result.anntMsgTotal + ')'
|
||||
this.announcement2 = res.result.sysMsgList
|
||||
this.msg2Count = res.result.sysMsgTotal
|
||||
this.msg2Title = '系统消息(' + res.result.sysMsgTotal + ')'
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('系统消息通知异常', error) //这行打印permissionName is undefined
|
||||
this.stopTimer = true
|
||||
console.log('清理timer')
|
||||
})
|
||||
} catch (err) {
|
||||
this.stopTimer = true
|
||||
console.log('通知异常', err)
|
||||
}
|
||||
},
|
||||
fetchNotice() {
|
||||
if (this.loadding) {
|
||||
this.loadding = false
|
||||
return
|
||||
}
|
||||
this.loadding = true
|
||||
setTimeout(() => {
|
||||
this.loadding = false
|
||||
}, 200)
|
||||
},
|
||||
showAnnouncement(record) {
|
||||
putAction(this.url.editCementSend, { anntId: record.id }).then((res) => {
|
||||
if (res.success) {
|
||||
this.loadData()
|
||||
this.loadding = true
|
||||
setTimeout(() => {
|
||||
this.loadding = false
|
||||
}, 200)
|
||||
},
|
||||
showAnnouncement(record){
|
||||
putAction(this.url.editCementSend,{anntId:record.id}).then((res)=>{
|
||||
if(res.success){
|
||||
this.loadData();
|
||||
}
|
||||
});
|
||||
this.hovered = false;
|
||||
if(record.openType==='component'){
|
||||
this.openPath = record.openPage;
|
||||
this.formData = {id:record.busId};
|
||||
this.$refs.showDynamNotice.detail(record.openPage);
|
||||
}else{
|
||||
this.$refs.ShowAnnouncement.detail(record);
|
||||
}
|
||||
})
|
||||
this.hovered = false
|
||||
if (record.openType === 'component') {
|
||||
this.openPath = record.openPage
|
||||
this.formData = { id: record.busId }
|
||||
this.$refs.showDynamNotice.detail(record.openPage)
|
||||
} else {
|
||||
this.$refs.ShowAnnouncement.detail(record)
|
||||
}
|
||||
},
|
||||
toMyAnnouncement() {
|
||||
this.$router.push({
|
||||
path: '/isystem/userAnnouncement',
|
||||
})
|
||||
},
|
||||
modalFormOk() {},
|
||||
handleHoverChange(visible) {
|
||||
this.hovered = visible
|
||||
},
|
||||
},
|
||||
toMyAnnouncement(){
|
||||
this.$router.push({
|
||||
path: '/isps/userAnnouncement'
|
||||
});
|
||||
},
|
||||
modalFormOk(){
|
||||
},
|
||||
handleHoverChange (visible) {
|
||||
this.hovered = visible;
|
||||
},
|
||||
|
||||
initWebSocket: function () {
|
||||
// WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
|
||||
var userId = store.getters.userInfo.id
|
||||
var url =
|
||||
window._CONFIG['domianURL'].replace('https://', 'wss://').replace('http://', 'ws://') + '/websocket/' + userId
|
||||
//console.log(url);
|
||||
//update-begin-author:taoyan date:2022-4-22 for: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
|
||||
let token = Vue.ls.get(ACCESS_TOKEN)
|
||||
this.websock = new WebSocket(url, [token])
|
||||
//update-end-author:taoyan date:2022-4-22 for: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
|
||||
this.websock.onopen = this.websocketOnopen
|
||||
this.websock.onerror = this.websocketOnerror
|
||||
this.websock.onmessage = this.websocketOnmessage
|
||||
this.websock.onclose = this.websocketOnclose
|
||||
},
|
||||
websocketOnopen: function () {
|
||||
console.log('WebSocket连接成功')
|
||||
//心跳检测重置
|
||||
//this.heartCheck.reset().start();
|
||||
},
|
||||
websocketOnerror: function (e) {
|
||||
console.log('WebSocket连接发生错误,第%s次', this.wsConnectErrorTime)
|
||||
initWebSocket: function () {
|
||||
// WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
|
||||
var userId = store.getters.userInfo.id;
|
||||
var url = window._CONFIG['domianURL'].replace("https://","wss://").replace("http://","ws://")+"/websocket/"+userId;
|
||||
//console.log(url);
|
||||
//update-begin-author:taoyan date:2022-4-22 for: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
|
||||
let token = Vue.ls.get(ACCESS_TOKEN)
|
||||
this.websock = new WebSocket(url, [token]);
|
||||
//update-end-author:taoyan date:2022-4-22 for: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278
|
||||
this.websock.onopen = this.websocketOnopen;
|
||||
this.websock.onerror = this.websocketOnerror;
|
||||
this.websock.onmessage = this.websocketOnmessage;
|
||||
this.websock.onclose = this.websocketOnclose;
|
||||
},
|
||||
websocketOnopen: function () {
|
||||
console.log("WebSocket连接成功");
|
||||
//心跳检测重置
|
||||
//this.heartCheck.reset().start();
|
||||
},
|
||||
websocketOnerror: function (e) {
|
||||
console.log("WebSocket连接发生错误,第%s次",this.wsConnectErrorTime);
|
||||
|
||||
this.wsConnectErrorTime = this.wsConnectErrorTime + 1
|
||||
if (this.wsConnectErrorTime > 5) {
|
||||
console.log('WebSocket连接错误超过5次,就不再重新连了!')
|
||||
this.lockReconnect = true
|
||||
return
|
||||
}
|
||||
this.wsConnectErrorTime = this.wsConnectErrorTime + 1;
|
||||
if(this.wsConnectErrorTime>5){
|
||||
console.log("WebSocket连接错误超过5次,就不再重新连了!");
|
||||
this.lockReconnect = true
|
||||
return;
|
||||
}
|
||||
|
||||
this.reconnect()
|
||||
},
|
||||
websocketOnmessage: function (e) {
|
||||
console.log('-----接收消息-------', e.data)
|
||||
var data = eval('(' + e.data + ')') //解析对象
|
||||
this.voiceBroadcast(data.msgTxt)
|
||||
if (data.cmd == 'topic') {
|
||||
//系统通知
|
||||
this.loadData()
|
||||
} else if (data.cmd == 'user') {
|
||||
//用户消息
|
||||
this.loadData()
|
||||
}
|
||||
//心跳检测重置
|
||||
//this.heartCheck.reset().start();
|
||||
},
|
||||
websocketOnclose: function (e) {
|
||||
console.log('connection closed (' + e + ')')
|
||||
if (e) {
|
||||
console.log('connection closed (' + e.code + ')')
|
||||
}
|
||||
this.reconnect()
|
||||
},
|
||||
websocketSend(text) {
|
||||
// 数据发送
|
||||
try {
|
||||
this.websock.send(text)
|
||||
} catch (err) {
|
||||
console.log('send failed (' + err.code + ')')
|
||||
}
|
||||
},
|
||||
//语音播报系统通知
|
||||
voiceBroadcast(text) {
|
||||
var url = 'http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&text=' + encodeURI(text) // baidu文字转语音
|
||||
var voiceContent = new Audio(url)
|
||||
voiceContent.src = url
|
||||
voiceContent.play()
|
||||
},
|
||||
openNotification(data) {
|
||||
var text = data.msgTxt
|
||||
const key = `open${Date.now()}`
|
||||
this.$notification.open({
|
||||
message: '消息提醒',
|
||||
placement: 'bottomRight',
|
||||
description: text,
|
||||
key,
|
||||
btn: (h) => {
|
||||
return h(
|
||||
'a-button',
|
||||
{
|
||||
this.reconnect();
|
||||
},
|
||||
websocketOnmessage: function (e) {
|
||||
console.log("-----接收消息-------",e.data);
|
||||
var data = eval("(" + e.data + ")"); //解析对象
|
||||
this.voiceBroadcast(data.msgTxt)
|
||||
if(data.cmd == "topic"){
|
||||
//系统通知
|
||||
this.loadData();
|
||||
}else if(data.cmd == "user"){
|
||||
//用户消息
|
||||
this.loadData();
|
||||
}
|
||||
//心跳检测重置
|
||||
//this.heartCheck.reset().start();
|
||||
},
|
||||
websocketOnclose: function (e) {
|
||||
console.log("connection closed (" + e + ")");
|
||||
if(e){
|
||||
console.log("connection closed (" + e.code + ")");
|
||||
}
|
||||
this.reconnect();
|
||||
},
|
||||
websocketSend(text) { // 数据发送
|
||||
try {
|
||||
this.websock.send(text);
|
||||
} catch (err) {
|
||||
console.log("send failed (" + err.code + ")");
|
||||
}
|
||||
},
|
||||
//语音播报系统通知
|
||||
voiceBroadcast(text){
|
||||
var url = "http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&text=" + encodeURI(text); // baidu文字转语音
|
||||
var voiceContent = new Audio(url);
|
||||
voiceContent.src = url;
|
||||
voiceContent.play();
|
||||
},
|
||||
openNotification (data) {
|
||||
var text = data.msgTxt;
|
||||
const key = `open${Date.now()}`;
|
||||
this.$notification.open({
|
||||
message: '消息提醒',
|
||||
placement:'bottomRight',
|
||||
description: text,
|
||||
key,
|
||||
btn: (h)=>{
|
||||
return h('a-button', {
|
||||
props: {
|
||||
type: 'primary',
|
||||
size: 'small',
|
||||
},
|
||||
on: {
|
||||
click: () => this.showDetail(key, data),
|
||||
},
|
||||
},
|
||||
'查看详情'
|
||||
)
|
||||
},
|
||||
})
|
||||
},
|
||||
click: () => this.showDetail(key,data)
|
||||
}
|
||||
}, '查看详情')
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
reconnect() {
|
||||
var that = this
|
||||
if (that.lockReconnect) return
|
||||
that.lockReconnect = true
|
||||
//没连接上会一直重连,设置延迟避免请求过多
|
||||
setTimeout(function () {
|
||||
console.info('尝试重连...')
|
||||
that.initWebSocket()
|
||||
that.lockReconnect = false
|
||||
}, 20000)
|
||||
},
|
||||
heartCheckFun() {
|
||||
var that = this
|
||||
//心跳检测,每20s心跳一次
|
||||
that.heartCheck = {
|
||||
timeout: 20000,
|
||||
timeoutObj: null,
|
||||
serverTimeoutObj: null,
|
||||
reset: function () {
|
||||
clearTimeout(this.timeoutObj)
|
||||
//clearTimeout(this.serverTimeoutObj);
|
||||
return this
|
||||
},
|
||||
start: function () {
|
||||
var self = this
|
||||
this.timeoutObj = setTimeout(function () {
|
||||
//这里发送一个心跳,后端收到后,返回一个心跳消息,
|
||||
//onmessage拿到返回的心跳就说明连接正常
|
||||
that.websocketSend('HeartBeat')
|
||||
console.info('客户端发送心跳')
|
||||
//self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了
|
||||
// that.websock.close();//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
|
||||
//}, self.timeout)
|
||||
}, this.timeout)
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
showDetail(key, data) {
|
||||
this.$notification.close(key)
|
||||
var id = data.msgId
|
||||
getAction(this.url.queryById, { id: id }).then((res) => {
|
||||
if (res.success) {
|
||||
var record = res.result
|
||||
this.showAnnouncement(record)
|
||||
reconnect() {
|
||||
var that = this;
|
||||
if(that.lockReconnect) return;
|
||||
that.lockReconnect = true;
|
||||
//没连接上会一直重连,设置延迟避免请求过多
|
||||
setTimeout(function () {
|
||||
console.info("尝试重连...");
|
||||
that.initWebSocket();
|
||||
that.lockReconnect = false;
|
||||
}, 20000);
|
||||
},
|
||||
heartCheckFun(){
|
||||
var that = this;
|
||||
//心跳检测,每20s心跳一次
|
||||
that.heartCheck = {
|
||||
timeout: 20000,
|
||||
timeoutObj: null,
|
||||
serverTimeoutObj: null,
|
||||
reset: function(){
|
||||
clearTimeout(this.timeoutObj);
|
||||
//clearTimeout(this.serverTimeoutObj);
|
||||
return this;
|
||||
},
|
||||
start: function(){
|
||||
var self = this;
|
||||
this.timeoutObj = setTimeout(function(){
|
||||
//这里发送一个心跳,后端收到后,返回一个心跳消息,
|
||||
//onmessage拿到返回的心跳就说明连接正常
|
||||
that.websocketSend("HeartBeat");
|
||||
console.info("客户端发送心跳");
|
||||
//self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了
|
||||
// that.websock.close();//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
|
||||
//}, self.timeout)
|
||||
}, this.timeout)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
showDetail(key,data){
|
||||
this.$notification.close(key);
|
||||
var id = data.msgId;
|
||||
getAction(this.url.queryById,{id:id}).then((res) => {
|
||||
if (res.success) {
|
||||
var record = res.result;
|
||||
this.showAnnouncement(record);
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
.header-notice-wrapper {
|
||||
top: 50px !important;
|
||||
}
|
||||
.header-notice-wrapper {
|
||||
top: 50px !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="less" scoped>
|
||||
.header-notice {
|
||||
display: inline-block;
|
||||
transition: all 0.3s;
|
||||
.header-notice{
|
||||
display: inline-block;
|
||||
transition: all 0.3s;
|
||||
|
||||
span {
|
||||
vertical-align: initial;
|
||||
span {
|
||||
vertical-align: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -4,19 +4,18 @@ import xss from "xss"
|
|||
:title="title"
|
||||
:width="modelStyle.width"
|
||||
:visible="visible"
|
||||
:bodyStyle="bodyStyle"
|
||||
:bodyStyle ="bodyStyle"
|
||||
:switchFullscreen="switchFullscreen"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
>
|
||||
<template slot="footer">
|
||||
<a-button key="back" @click="handleCancel">Cancel</a-button>
|
||||
<a-button v-if="record.openType === 'url'" type="primary" @click="toHandle">去处理</a-button>
|
||||
<a-button key="back" @click="handleCancel">关闭</a-button>
|
||||
<a-button v-if="record.openType==='url'" type="primary" @click="toHandle">去处理</a-button>
|
||||
</template>
|
||||
<a-card class="daily-article" :loading="loading">
|
||||
<a-card-meta
|
||||
:title="record.titile"
|
||||
:description="'Sender:' + record.sender + ' Send Time: ' + record.sendTime"
|
||||
>
|
||||
:description="'发布人:'+record.sender + ' 发布时间: ' + record.sendTime">
|
||||
</a-card-meta>
|
||||
<a-divider />
|
||||
<span v-html="record.msgContent" class="article-content"></span>
|
||||
|
@ -25,141 +24,133 @@ import xss from "xss"
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { getUserList } from '@/api/api'
|
||||
import xss from 'xss'
|
||||
export default {
|
||||
name: 'SysAnnouncementModal',
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
title: 'Notification Message',
|
||||
record: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 5 },
|
||||
import {getUserList} from '@/api/api'
|
||||
import xss from 'xss'
|
||||
export default {
|
||||
name: "SysAnnouncementModal",
|
||||
components: {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
title:"通知消息",
|
||||
record: {},
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
visible: false,
|
||||
switchFullscreen: true,
|
||||
loading: false,
|
||||
bodyStyle:{
|
||||
padding: "0",
|
||||
height:(window.innerHeight*0.8)+"px",
|
||||
"overflow-y":"auto",
|
||||
|
||||
},
|
||||
modelStyle:{
|
||||
width: '60%',
|
||||
style: { top: '20px' },
|
||||
fullScreen: false
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
detail (record) {
|
||||
//update-begin---author:wangshuai ---date:20220107 for:将其它页面传递过来的用户名改成用户真实姓名
|
||||
if(record.sender){
|
||||
getUserList({"username":record.sender}).then((res) =>{
|
||||
if(res.success && res.result.records.length>0){
|
||||
record.sender = res.result.records[0].realname
|
||||
}
|
||||
})
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220107 for:将其它页面传递过来的用户名改成用户真实姓名
|
||||
this.visible = true;
|
||||
//update-begin-author:taoyan date:2022-7-14 for: VUEN-1702 【禁止问题】sql注入漏洞
|
||||
if(record.msgContent){
|
||||
record.msgContent = xss(record.msgContent)
|
||||
}
|
||||
//update-end-author:taoyan date:2022-7-14 for: VUEN-1702 【禁止问题】sql注入漏洞
|
||||
this.record = record;
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
handleCancel () {
|
||||
this.visible = false;
|
||||
},
|
||||
visible: false,
|
||||
switchFullscreen: true,
|
||||
loading: false,
|
||||
bodyStyle: {
|
||||
padding: '0',
|
||||
height: window.innerHeight * 0.8 + 'px',
|
||||
'overflow-y': 'auto',
|
||||
/** 切换全屏显示 */
|
||||
handleClickToggleFullScreen() {
|
||||
let mode = !this.modelStyle.fullScreen
|
||||
if (mode) {
|
||||
this.modelStyle.width = '100%'
|
||||
this.modelStyle.style.top = '20px'
|
||||
} else {
|
||||
this.modelStyle.width = '60%'
|
||||
this.modelStyle.style.top = '50px'
|
||||
}
|
||||
this.modelStyle.fullScreen = mode
|
||||
},
|
||||
modelStyle: {
|
||||
width: '60%',
|
||||
style: { top: '20px' },
|
||||
fullScreen: false,
|
||||
toHandle(){
|
||||
if(this.record.openType==='url'){
|
||||
this.visible = false;
|
||||
//链接跳转
|
||||
this.$router.push({path: this.record.openPage})
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
detail(record) {
|
||||
//update-begin---author:wangshuai ---date:20220107 for:将其它页面传递过来的用户名改成用户真实姓名
|
||||
if (record.sender) {
|
||||
getUserList({ username: record.sender }).then((res) => {
|
||||
if (res.success && res.result.records.length > 0) {
|
||||
record.sender = res.result.records[0].realname
|
||||
}
|
||||
})
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220107 for:将其它页面传递过来的用户名改成用户真实姓名
|
||||
this.visible = true
|
||||
//update-begin-author:taoyan date:2022-7-14 for: VUEN-1702 【禁止问题】sql注入漏洞
|
||||
if (record.msgContent) {
|
||||
record.msgContent = xss(record.msgContent)
|
||||
}
|
||||
//update-end-author:taoyan date:2022-7-14 for: VUEN-1702 【禁止问题】sql注入漏洞
|
||||
this.record = record
|
||||
},
|
||||
handleCancel() {
|
||||
this.visible = false
|
||||
},
|
||||
/** 切换全屏显示 */
|
||||
handleClickToggleFullScreen() {
|
||||
let mode = !this.modelStyle.fullScreen
|
||||
if (mode) {
|
||||
this.modelStyle.width = '100%'
|
||||
this.modelStyle.style.top = '20px'
|
||||
} else {
|
||||
this.modelStyle.width = '60%'
|
||||
this.modelStyle.style.top = '50px'
|
||||
}
|
||||
this.modelStyle.fullScreen = mode
|
||||
},
|
||||
toHandle() {
|
||||
if (this.record.openType === 'url') {
|
||||
this.visible = false
|
||||
//链接跳转
|
||||
this.$router.push({ path: this.record.openPage })
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.announcementCustomModal {
|
||||
.ant-modal-header {
|
||||
border: none;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
right: 56px;
|
||||
padding: 0;
|
||||
.ant-modal-title {
|
||||
.custom-btn {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
.announcementCustomModal{
|
||||
.ant-modal-header {
|
||||
border: none;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
right: 56px;
|
||||
padding: 0;
|
||||
.ant-modal-title{
|
||||
.custom-btn{
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.daily-article{
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="less">
|
||||
.daily-article {
|
||||
.article-button {
|
||||
font-size: 1.2rem !important;
|
||||
}
|
||||
.ant-card-body {
|
||||
padding: 18px !important;
|
||||
}
|
||||
.ant-card-head {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
.ant-card-meta {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.article-content {
|
||||
p {
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
text-overflow: initial;
|
||||
white-space: normal;
|
||||
font-size: .9rem !important;
|
||||
margin-bottom: .8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.daily-article {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
.ant-card-meta-description {
|
||||
color: #fff !important;
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="less">
|
||||
.daily-article {
|
||||
.article-button {
|
||||
font-size: 1.2rem !important;
|
||||
}
|
||||
.ant-card-body {
|
||||
padding: 18px !important;
|
||||
}
|
||||
.ant-card-head {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
.ant-card-meta {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.article-content {
|
||||
p {
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
text-overflow: initial;
|
||||
white-space: normal;
|
||||
font-size: 0.9rem !important;
|
||||
margin-bottom: 0.8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ant-card-bordered {
|
||||
border: none;
|
||||
padding: 20px;
|
||||
}
|
||||
/deep/.ant-card-meta-title {
|
||||
font-weight: 700;
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
<template>
|
||||
<div class="user-wrapper" :class="theme">
|
||||
<header-notice class="action" />
|
||||
<span class="language" @click="changeLang">
|
||||
<img :src="$i18n.locale=='zh-CN'?langIcon_en:langIcon_zh" alt="">
|
||||
<!-- <img :src=langIcon_zh alt=""> -->
|
||||
</span>
|
||||
<!-- <span @click="changeLang('zh-CN')">zh</span>
|
||||
<span style="margin-left: 10px;" @click="changeLang('en-US')">en</span> -->
|
||||
<header-notice class="action"/>
|
||||
<a-dropdown>
|
||||
<span class="action action-full ant-dropdown-link user-dropdown-menu">
|
||||
<img src="@/assets/images/header/avatar.png" alt="" />
|
||||
<img src="@/assets/images/header/avatar.png" alt="">
|
||||
</span>
|
||||
<a-menu slot="overlay" class="user-dropdown-menu-wrapper">
|
||||
<!-- <a-menu-item key="0">
|
||||
<a-menu-item key="0">
|
||||
<router-link :to="{ name: 'account-center' }">
|
||||
<a-icon type="user"/>
|
||||
<span>个人中心</span>
|
||||
|
@ -21,29 +27,24 @@
|
|||
<a-menu-item key="3" @click="systemSetting">
|
||||
<a-icon type="tool"/>
|
||||
<span>系统设置</span>
|
||||
</a-menu-item> -->
|
||||
<a-menu-item key="3">
|
||||
<a-icon type="user" />
|
||||
<span>{{ this.userInfo().username }}</span>
|
||||
</a-menu-item>
|
||||
<a-menu-divider />
|
||||
<a-menu-item key="4" @click="updatePassword">
|
||||
<a-icon type="setting" />
|
||||
<span>Change Password</span>
|
||||
<a-icon type="setting"/>
|
||||
<span>密码修改</span>
|
||||
</a-menu-item>
|
||||
<!-- <a-menu-item key="5" @click="updateCurrentDepart">
|
||||
<a-menu-item key="5" @click="updateCurrentDepart">
|
||||
<a-icon type="cluster"/>
|
||||
<span>切换部门</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="6" @click="clearCache">
|
||||
<a-icon type="sync"/>
|
||||
<span>清理缓存</span>
|
||||
</a-menu-item> -->
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</a-dropdown>
|
||||
<span class="action">
|
||||
<a class="logout_title" href="javascript:;" @click="handleLogout">
|
||||
<img src="@/assets/images/header/close.png" alt="" />
|
||||
<img src="@/assets/images/header/close.png" alt="">
|
||||
</a>
|
||||
</span>
|
||||
<user-password ref="userPassword"></user-password>
|
||||
|
@ -53,205 +54,221 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import HeaderNotice from './HeaderNotice'
|
||||
import UserPassword from './UserPassword'
|
||||
import SettingDrawer from '@/components/setting/SettingDrawer'
|
||||
import DepartSelect from './DepartSelect'
|
||||
import { mapActions, mapGetters, mapState } from 'vuex'
|
||||
import { mixinDevice } from '@/utils/mixin.js'
|
||||
import { getFileAccessHttpUrl, getAction } from '@/api/manage'
|
||||
import Vue from 'vue'
|
||||
import { UI_CACHE_DB_DICT_DATA } from '@/store/mutation-types'
|
||||
import HeaderNotice from './HeaderNotice'
|
||||
import UserPassword from './UserPassword'
|
||||
import SettingDrawer from "@/components/setting/SettingDrawer";
|
||||
import DepartSelect from './DepartSelect'
|
||||
import { mapActions, mapGetters,mapState } from 'vuex'
|
||||
import { mixinDevice } from '@/utils/mixin.js'
|
||||
import { getFileAccessHttpUrl,getAction } from "@/api/manage"
|
||||
import Vue from 'vue'
|
||||
import { UI_CACHE_DB_DICT_DATA } from "@/store/mutation-types"
|
||||
import i18nMixin from '@/store/i18n-mixin'
|
||||
|
||||
export default {
|
||||
name: 'UserMenu',
|
||||
mixins: [mixinDevice],
|
||||
data() {
|
||||
return {
|
||||
// update-begin author:sunjianlei date:20200219 for: 头部菜单搜索规范命名 --------------
|
||||
searchMenuOptions: [],
|
||||
searchMenuComp: 'span',
|
||||
searchMenuVisible: false,
|
||||
// update-begin author:sunjianlei date:20200219 for: 头部菜单搜索规范命名 --------------
|
||||
}
|
||||
},
|
||||
components: {
|
||||
HeaderNotice,
|
||||
UserPassword,
|
||||
DepartSelect,
|
||||
SettingDrawer,
|
||||
},
|
||||
props: {
|
||||
theme: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'dark',
|
||||
},
|
||||
},
|
||||
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
|
||||
created() {
|
||||
let lists = []
|
||||
this.searchMenus(lists, this.permissionMenuList)
|
||||
this.searchMenuOptions = [...lists]
|
||||
},
|
||||
mounted() {
|
||||
//如果是单点登录模式
|
||||
if (process.env.VUE_APP_SSO == 'true') {
|
||||
let depart = this.userInfo().orgCode
|
||||
if (!depart) {
|
||||
this.updateCurrentDepart()
|
||||
export default {
|
||||
name: "UserMenu",
|
||||
mixins: [mixinDevice,i18nMixin],
|
||||
data(){
|
||||
return {
|
||||
langIcon_zh:require('@/assets/images/header/zh.png'),
|
||||
langIcon_en:require('@/assets/images/header/en.png'),
|
||||
// update-begin author:sunjianlei date:20200219 for: 头部菜单搜索规范命名 --------------
|
||||
searchMenuOptions:[],
|
||||
searchMenuComp: 'span',
|
||||
searchMenuVisible: false,
|
||||
// update-begin author:sunjianlei date:20200219 for: 头部菜单搜索规范命名 --------------
|
||||
}
|
||||
},
|
||||
components: {
|
||||
HeaderNotice,
|
||||
UserPassword,
|
||||
DepartSelect,
|
||||
SettingDrawer
|
||||
},
|
||||
props: {
|
||||
theme: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'dark'
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
// 后台菜单
|
||||
permissionMenuList: (state) => state.user.permissionList,
|
||||
}),
|
||||
},
|
||||
/* update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
|
||||
watch: {
|
||||
// update-begin author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框
|
||||
device: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.searchMenuVisible = false
|
||||
this.searchMenuComp = this.isMobile() ? 'a-modal' : 'span'
|
||||
},
|
||||
},
|
||||
// update-end author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框
|
||||
},
|
||||
methods: {
|
||||
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
|
||||
showClick() {
|
||||
this.searchMenuVisible = true
|
||||
created() {
|
||||
let lists = []
|
||||
this.searchMenus(lists,this.permissionMenuList)
|
||||
this.searchMenuOptions = [...lists]
|
||||
},
|
||||
hiddenClick() {
|
||||
this.shows = false
|
||||
mounted() {
|
||||
console.log(this.$i18n.locale);
|
||||
//如果是单点登录模式
|
||||
if (process.env.VUE_APP_SSO == 'true') {
|
||||
let depart = this.userInfo().orgCode
|
||||
if (!depart) {
|
||||
this.updateCurrentDepart()
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
// 后台菜单
|
||||
permissionMenuList: state => state.user.permissionList
|
||||
|
||||
})
|
||||
},
|
||||
/* update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
|
||||
...mapActions(['Logout']),
|
||||
...mapGetters(['nickname', 'avatar', 'userInfo']),
|
||||
getAvatar() {
|
||||
return getFileAccessHttpUrl(this.avatar())
|
||||
},
|
||||
handleLogout() {
|
||||
const that = this
|
||||
|
||||
this.$confirm({
|
||||
title: 'Prompt',
|
||||
content: 'Ensure Log Out?',
|
||||
cancelButtonProps: {
|
||||
props: {
|
||||
type: 'warn',
|
||||
},
|
||||
watch: {
|
||||
// update-begin author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框
|
||||
device: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.searchMenuVisible = false
|
||||
this.searchMenuComp = this.isMobile() ? 'a-modal' : 'span'
|
||||
},
|
||||
onOk() {
|
||||
return that
|
||||
.Logout({})
|
||||
.then(() => {
|
||||
},
|
||||
// update-end author:sunjianlei date:20200219 for: 菜单搜索改为动态组件,在手机端呈现出弹出框
|
||||
},
|
||||
methods: {
|
||||
changeLang() {
|
||||
let lang = this.$i18n.locale == "zh-CN" ? "en-US" : "zh-CN"
|
||||
this.$i18n.locale = lang
|
||||
this.setLang(lang)
|
||||
},
|
||||
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
|
||||
showClick() {
|
||||
this.searchMenuVisible = true
|
||||
},
|
||||
hiddenClick(){
|
||||
this.shows = false
|
||||
},
|
||||
/* update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
|
||||
...mapActions(["Logout"]),
|
||||
...mapGetters(["nickname", "avatar","userInfo"]),
|
||||
getAvatar(){
|
||||
return getFileAccessHttpUrl(this.avatar())
|
||||
},
|
||||
handleLogout() {
|
||||
const that = this
|
||||
|
||||
this.$confirm({
|
||||
title: 'Prompt',
|
||||
content: 'Ensure Log Out?',
|
||||
cancelButtonProps: {
|
||||
props: {
|
||||
type: 'warn'
|
||||
}
|
||||
},
|
||||
onOk() {
|
||||
return that.Logout({}).then(() => {
|
||||
// update-begin author:scott date:20211223 for:【JTC-198】退出登录体验不好
|
||||
//that.$router.push({ path: '/user/login' });
|
||||
window.location.reload()
|
||||
// update-end author:scott date:20211223 for:【JTC-198】退出登录体验不好
|
||||
})
|
||||
.catch((err) => {
|
||||
}).catch(err => {
|
||||
that.$message.error({
|
||||
title: 'Error',
|
||||
description: err.message,
|
||||
description: err.message
|
||||
})
|
||||
})
|
||||
},
|
||||
onCancel() {},
|
||||
})
|
||||
},
|
||||
updatePassword() {
|
||||
let username = this.userInfo().username
|
||||
this.$refs.userPassword.show(username)
|
||||
},
|
||||
updateCurrentDepart() {
|
||||
this.$refs.departSelect.show()
|
||||
},
|
||||
systemSetting() {
|
||||
this.$refs.settingDrawer.showDrawer()
|
||||
},
|
||||
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
|
||||
searchMenus(arr, menus) {
|
||||
for (let i of menus) {
|
||||
if (!i.hidden && 'layouts/RouteView' !== i.component) {
|
||||
arr.push(i)
|
||||
},
|
||||
onCancel() {
|
||||
},
|
||||
});
|
||||
},
|
||||
updatePassword(){
|
||||
let username = this.userInfo().username
|
||||
this.$refs.userPassword.show(username)
|
||||
},
|
||||
updateCurrentDepart(){
|
||||
this.$refs.departSelect.show()
|
||||
},
|
||||
systemSetting(){
|
||||
this.$refs.settingDrawer.showDrawer()
|
||||
},
|
||||
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
|
||||
searchMenus(arr,menus){
|
||||
for(let i of menus){
|
||||
if(!i.hidden && "layouts/RouteView"!==i.component){
|
||||
arr.push(i)
|
||||
}
|
||||
if(i.children&& i.children.length>0){
|
||||
this.searchMenus(arr,i.children)
|
||||
}
|
||||
}
|
||||
if (i.children && i.children.length > 0) {
|
||||
this.searchMenus(arr, i.children)
|
||||
},
|
||||
filterOption(input, option) {
|
||||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
},
|
||||
// update_begin author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题
|
||||
searchMethods(value) {
|
||||
let route = this.searchMenuOptions.filter(item => item.id === value)[0]
|
||||
//update-begin-author:sunjianlei date:20220111 for: 【JTC-702】【菜单搜索】菜单搜索里点击跳转的菜单,无法将Token信息传递过去
|
||||
if(route.component.includes('layouts/IframePageView')){
|
||||
this.$router.push(route)
|
||||
}else{
|
||||
this.$router.push({ path: route.path })
|
||||
}
|
||||
}
|
||||
},
|
||||
filterOption(input, option) {
|
||||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
},
|
||||
// update_begin author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题
|
||||
searchMethods(value) {
|
||||
let route = this.searchMenuOptions.filter((item) => item.id === value)[0]
|
||||
//update-begin-author:sunjianlei date:20220111 for: 【JTC-702】【菜单搜索】菜单搜索里点击跳转的菜单,无法将Token信息传递过去
|
||||
if (route.component.includes('layouts/IframePageView')) {
|
||||
this.$router.push(route)
|
||||
} else {
|
||||
this.$router.push({ path: route.path })
|
||||
}
|
||||
//update-end-author:sunjianlei date:20220111 for: 【JTC-702】【菜单搜索】菜单搜索里点击跳转的菜单,无法将Token信息传递过去
|
||||
this.searchMenuVisible = false
|
||||
},
|
||||
// update_end author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题
|
||||
/*update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
|
||||
/*update_begin author:liushaoqian date:20200507 for: 刷新缓存*/
|
||||
clearCache() {
|
||||
getAction('sys/dict/refleshCache')
|
||||
.then((res) => {
|
||||
//update-end-author:sunjianlei date:20220111 for: 【JTC-702】【菜单搜索】菜单搜索里点击跳转的菜单,无法将Token信息传递过去
|
||||
this.searchMenuVisible = false
|
||||
},
|
||||
// update_end author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题
|
||||
/*update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
|
||||
/*update_begin author:liushaoqian date:20200507 for: 刷新缓存*/
|
||||
clearCache(){
|
||||
getAction("sys/dict/refleshCache").then((res) => {
|
||||
if (res.success) {
|
||||
//重新加载缓存
|
||||
getAction('sys/dict/queryAllDictItems').then((res) => {
|
||||
getAction("sys/dict/queryAllDictItems").then((res) => {
|
||||
if (res.success) {
|
||||
Vue.ls.remove(UI_CACHE_DB_DICT_DATA)
|
||||
Vue.ls.set(UI_CACHE_DB_DICT_DATA, res.result, 7 * 24 * 60 * 60 * 1000)
|
||||
}
|
||||
})
|
||||
this.$message.success('刷新缓存完成!')
|
||||
this.$message.success("刷新缓存完成!");
|
||||
}
|
||||
}).catch(e=>{
|
||||
this.$message.warn("刷新缓存失败!");
|
||||
console.log("刷新失败",e)
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.warn('刷新缓存失败!')
|
||||
console.log('刷新失败', e)
|
||||
})
|
||||
},
|
||||
/*update_end author:liushaoqian date:20200507 for: 刷新缓存*/
|
||||
},
|
||||
}
|
||||
}
|
||||
/*update_end author:liushaoqian date:20200507 for: 刷新缓存*/
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/* update_begin author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
|
||||
/* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
|
||||
.user-wrapper .search-input {
|
||||
width: 180px;
|
||||
color: inherit;
|
||||
/* update_begin author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
|
||||
/* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
|
||||
.user-wrapper .search-input {
|
||||
width: 180px;
|
||||
color: inherit;
|
||||
|
||||
/deep/ .ant-select-selection {
|
||||
background-color: inherit;
|
||||
border: 0;
|
||||
border-bottom: 1px solid white;
|
||||
&__placeholder,
|
||||
&__field__placeholder {
|
||||
color: inherit;
|
||||
/deep/ .ant-select-selection {
|
||||
background-color: inherit;
|
||||
border: 0;
|
||||
border-bottom: 1px solid white;
|
||||
&__placeholder, &__field__placeholder {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* update-end author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
|
||||
/* update_end author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
|
||||
.language{
|
||||
display: inline-block;
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
cursor: pointer;
|
||||
margin-right: 5px;
|
||||
img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
/* update-end author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
|
||||
/* update_end author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
.logout_title {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
.logout_title {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
|
@ -6,164 +6,152 @@
|
|||
:confirmLoading="confirmLoading"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
cancelText="Cancel"
|
||||
cancelText="关闭"
|
||||
>
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="Old Password">
|
||||
<a-input
|
||||
type="password"
|
||||
placeholder="Please enter your old password"
|
||||
v-decorator="['oldpassword', validatorRules.oldpassword]"
|
||||
/>
|
||||
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="旧密码">
|
||||
<a-input type="password" placeholder="请输入旧密码" v-decorator="[ 'oldpassword', validatorRules.oldpassword]" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="New Password">
|
||||
<a-input
|
||||
type="password"
|
||||
placeholder="Please enter your new password"
|
||||
v-decorator="['password', validatorRules.password]"
|
||||
/>
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="新密码">
|
||||
<a-input type="password" placeholder="请输入新密码" v-decorator="[ 'password', validatorRules.password]" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="Confirm New Password">
|
||||
<a-input
|
||||
type="password"
|
||||
@blur="handleConfirmBlur"
|
||||
placeholder="Please enter your new password"
|
||||
v-decorator="['confirmpassword', validatorRules.confirmpassword]"
|
||||
/>
|
||||
<a-form-item
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
label="确认新密码">
|
||||
<a-input type="password" @blur="handleConfirmBlur" placeholder="请确认新密码" v-decorator="[ 'confirmpassword', validatorRules.confirmpassword]"/>
|
||||
</a-form-item>
|
||||
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { putAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'UserPassword',
|
||||
data() {
|
||||
return {
|
||||
title: 'Change Password',
|
||||
modalWidth: 800,
|
||||
visible: false,
|
||||
confirmLoading: false,
|
||||
validatorRules: {
|
||||
oldpassword: {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入旧密码!',
|
||||
},
|
||||
],
|
||||
},
|
||||
password: {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入新密码!',
|
||||
},
|
||||
{
|
||||
import { putAction } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: "UserPassword",
|
||||
data () {
|
||||
return {
|
||||
title:"修改密码",
|
||||
modalWidth:800,
|
||||
visible: false,
|
||||
confirmLoading: false,
|
||||
validatorRules:{
|
||||
oldpassword:{
|
||||
rules: [{
|
||||
required: true, message: '请输入旧密码!',
|
||||
}],
|
||||
},
|
||||
password:{
|
||||
rules: [{
|
||||
required: true, message: '请输入新密码!',
|
||||
}, {
|
||||
validator: this.validateToNextPassword,
|
||||
},
|
||||
],
|
||||
},
|
||||
confirmpassword: {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请确认新密码!',
|
||||
},
|
||||
{
|
||||
}],
|
||||
},
|
||||
confirmpassword:{
|
||||
rules: [{
|
||||
required: true, message: '请确认新密码!',
|
||||
}, {
|
||||
validator: this.compareToFirstPassword,
|
||||
},
|
||||
],
|
||||
}],
|
||||
}
|
||||
},
|
||||
confirmDirty:false,
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
},
|
||||
confirmDirty: false,
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
|
||||
form: this.$form.createForm(this),
|
||||
url: 'sys/user/updatePassword',
|
||||
username: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show(uname) {
|
||||
if (!uname) {
|
||||
this.$message.warning('当前系统无登录用户!')
|
||||
return
|
||||
} else {
|
||||
this.username = uname
|
||||
this.form.resetFields()
|
||||
this.visible = true
|
||||
form:this.$form.createForm(this),
|
||||
url: "sys/user/updatePassword",
|
||||
username:"",
|
||||
}
|
||||
},
|
||||
handleCancel() {
|
||||
this.close()
|
||||
},
|
||||
close() {
|
||||
this.$emit('close')
|
||||
this.visible = false
|
||||
this.disableSubmit = false
|
||||
this.selectedRole = []
|
||||
},
|
||||
handleOk() {
|
||||
const that = this
|
||||
// 触发表单验证
|
||||
this.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
that.confirmLoading = true
|
||||
let params = Object.assign({ username: this.username }, values)
|
||||
console.log('修改密码提交数据', params)
|
||||
putAction(this.url, params)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
console.log(res)
|
||||
that.$message.success(res.message)
|
||||
that.close()
|
||||
} else {
|
||||
that.$message.warning(res.message)
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
that.confirmLoading = false
|
||||
})
|
||||
methods: {
|
||||
show(uname){
|
||||
if(!uname){
|
||||
this.$message.warning("当前系统无登录用户!");
|
||||
return
|
||||
}else{
|
||||
this.username = uname
|
||||
this.form.resetFields();
|
||||
this.visible = true;
|
||||
}
|
||||
})
|
||||
},
|
||||
validateToNextPassword(rule, value, callback) {
|
||||
const form = this.form
|
||||
if (value && this.confirmDirty) {
|
||||
form.validateFields(['confirm'], { force: true })
|
||||
},
|
||||
handleCancel () {
|
||||
this.close()
|
||||
},
|
||||
close () {
|
||||
this.$emit('close');
|
||||
this.visible = false;
|
||||
this.disableSubmit = false;
|
||||
this.selectedRole = [];
|
||||
},
|
||||
handleOk () {
|
||||
const that = this;
|
||||
// 触发表单验证
|
||||
this.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
that.confirmLoading = true;
|
||||
let params = Object.assign({username:this.username},values)
|
||||
console.log("修改密码提交数据",params)
|
||||
putAction(this.url,params).then((res)=>{
|
||||
if(res.success){
|
||||
console.log(res)
|
||||
that.$message.success(res.message);
|
||||
that.close();
|
||||
}else{
|
||||
that.$message.warning(res.message);
|
||||
}
|
||||
}).finally(() => {
|
||||
that.confirmLoading = false;
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
validateToNextPassword (rule, value, callback) {
|
||||
const form = this.form;
|
||||
if (value && this.confirmDirty) {
|
||||
form.validateFields(['confirm'], { force: true })
|
||||
}
|
||||
callback();
|
||||
},
|
||||
compareToFirstPassword (rule, value, callback) {
|
||||
const form = this.form;
|
||||
if (value && value !== form.getFieldValue('password')) {
|
||||
callback('两次输入的密码不一样!');
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
handleConfirmBlur (e) {
|
||||
const value = e.target.value
|
||||
this.confirmDirty = this.confirmDirty || !!value
|
||||
}
|
||||
callback()
|
||||
},
|
||||
compareToFirstPassword(rule, value, callback) {
|
||||
const form = this.form
|
||||
if (value && value !== form.getFieldValue('password')) {
|
||||
callback('两次输入的密码不一样!')
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
handleConfirmBlur(e) {
|
||||
const value = e.target.value
|
||||
this.confirmDirty = this.confirmDirty || !!value
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { TabLayout, RouteView, BlankLayout, PageView, BasicLayout } from '@/components/layouts'
|
||||
import { TabLayout, RouteView, BlankLayout, PageView } from '@/components/layouts'
|
||||
import Login from '@/views/user/Login'
|
||||
|
||||
/**
|
||||
|
@ -10,7 +10,7 @@ export const asyncRouterMap = [
|
|||
{
|
||||
path: '/',
|
||||
name: 'dashboard',
|
||||
component: BasicLayout,
|
||||
component: TabLayout,
|
||||
meta: { title: '首页' },
|
||||
redirect: '/station-operation',
|
||||
children: [
|
||||
|
|
15
src/locales/index.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: localStorage.getItem('APP_LANGUAGE') || 'en-US',
|
||||
//this.$i18n.locale // 通过切换locale的值来实现语言切换
|
||||
messages: {
|
||||
'zh-CN': require('./lang/zh'), // 中文语言包
|
||||
'en-US': require('./lang/en') // 英文语言包
|
||||
}
|
||||
})
|
||||
|
||||
export default i18n
|
15
src/locales/lang/en.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
export const m = {
|
||||
common: {
|
||||
search: "Search",
|
||||
},
|
||||
system: {
|
||||
user: "User",
|
||||
name: "Name",
|
||||
role: "Role",
|
||||
search: "Search",
|
||||
add: "Add",
|
||||
edit: "Edit",
|
||||
delete: "Delete",
|
||||
num: "NO"
|
||||
}
|
||||
}
|
15
src/locales/lang/zh.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
export const m = {
|
||||
common: {
|
||||
search: "搜索",
|
||||
},
|
||||
system: {
|
||||
user: "用户",
|
||||
name: "名称",
|
||||
role: "角色",
|
||||
search: "搜索",
|
||||
add: "添加",
|
||||
edit: "编辑",
|
||||
delete: "删除",
|
||||
num: "序号"
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import Storage from 'vue-ls'
|
|||
import router from './router'
|
||||
import store from './store/'
|
||||
import { VueAxios } from "@/utils/request"
|
||||
import i18n from './locales'
|
||||
|
||||
require('@jeecg/antd-online-mini')
|
||||
require('@jeecg/antd-online-mini/dist/OnlineForm.css')
|
||||
|
@ -52,7 +53,6 @@ import { rules } from '@/utils/rules'
|
|||
|
||||
import SearchForm from '@/components/SearchForm'
|
||||
import CustomSelect from '@/components/CustomSelect'
|
||||
import CustomAllSelect from '@/components/CustomAllSelect'
|
||||
import CustomTable from '@/components/CustomTable'
|
||||
import CustomModal from '@/components/CustomModal'
|
||||
import CustomDatePicker from '@/components/CustomDatePicker'
|
||||
|
@ -83,7 +83,6 @@ Vue.use(JeecgComponents);
|
|||
Vue.use(VueAreaLinkage);
|
||||
Vue.component('search-form', SearchForm)
|
||||
Vue.component('custom-select', CustomSelect)
|
||||
Vue.component('custom-all-select', CustomAllSelect)
|
||||
Vue.component('custom-table', CustomTable)
|
||||
Vue.component('custom-modal', CustomModal)
|
||||
Vue.component('custom-date-picker', CustomDatePicker)
|
||||
|
@ -97,6 +96,7 @@ function main() {
|
|||
new Vue({
|
||||
router,
|
||||
store,
|
||||
i18n,
|
||||
mounted () {
|
||||
store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true))
|
||||
store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme))
|
||||
|
|
|
@ -4,20 +4,20 @@
|
|||
* data中url定义 list为查询列表 delete为删除单条记录 deleteBatch为批量删除
|
||||
*/
|
||||
import { filterObj } from '@/utils/util';
|
||||
import { deleteAction, getAction, downFile, getFileAccessHttpUrl } from '@/api/manage'
|
||||
import { deleteAction, getAction,downFile,getFileAccessHttpUrl } from '@/api/manage'
|
||||
import Vue from 'vue'
|
||||
import { ACCESS_TOKEN, TENANT_ID } from "@/store/mutation-types"
|
||||
import store from '@/store'
|
||||
|
||||
export const JeecgListMixin = {
|
||||
data() {
|
||||
data(){
|
||||
return {
|
||||
/* 查询条件-请不要在queryParam中声明非字符串值的属性 */
|
||||
queryParam: {},
|
||||
/* 数据源 */
|
||||
dataSource: [],
|
||||
dataSource:[],
|
||||
/* 分页参数 */
|
||||
ipagination: {
|
||||
ipagination:{
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
pageSizeOptions: ['10', '20', '30'],
|
||||
|
@ -30,22 +30,22 @@ export const JeecgListMixin = {
|
|||
total: 0
|
||||
},
|
||||
/* 排序参数 */
|
||||
isorter: {
|
||||
isorter:{
|
||||
column: 'createTime',
|
||||
order: 'desc',
|
||||
},
|
||||
/* 筛选参数 */
|
||||
filters: {},
|
||||
/* table加载状态 */
|
||||
loading: false,
|
||||
loading:false,
|
||||
/* table选中keys*/
|
||||
selectedRowKeys: [],
|
||||
/* table选中records*/
|
||||
selectionRows: [],
|
||||
/* 查询折叠 */
|
||||
toggleSearchStatus: false,
|
||||
toggleSearchStatus:false,
|
||||
/* 高级查询条件生效状态 */
|
||||
superQueryFlag: false,
|
||||
superQueryFlag:false,
|
||||
/* 高级查询条件 */
|
||||
superQueryParams: '',
|
||||
/** 高级查询拼接方式 */
|
||||
|
@ -53,27 +53,27 @@ export const JeecgListMixin = {
|
|||
}
|
||||
},
|
||||
created() {
|
||||
if (!this.disableMixinCreated) {
|
||||
console.log(' -- mixin created -- ')
|
||||
this.loadData();
|
||||
//初始化字典配置 在自己页面定义
|
||||
this.initDictConfig();
|
||||
}
|
||||
if(!this.disableMixinCreated){
|
||||
console.log(' -- mixin created -- ')
|
||||
this.loadData();
|
||||
//初始化字典配置 在自己页面定义
|
||||
this.initDictConfig();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
//token header
|
||||
tokenHeader() {
|
||||
let head = { 'X-Access-Token': Vue.ls.get(ACCESS_TOKEN) }
|
||||
tokenHeader(){
|
||||
let head = {'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)}
|
||||
let tenantid = Vue.ls.get(TENANT_ID)
|
||||
if (tenantid) {
|
||||
if(tenantid){
|
||||
head['tenant-id'] = tenantid
|
||||
}
|
||||
return head;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
methods:{
|
||||
loadData(arg) {
|
||||
if (!this.url.list) {
|
||||
if(!this.url.list){
|
||||
this.$message.error("请设置url.list属性!")
|
||||
return
|
||||
}
|
||||
|
@ -82,51 +82,51 @@ export const JeecgListMixin = {
|
|||
this.ipagination.current = 1;
|
||||
}
|
||||
this.onClearSelected()
|
||||
|
||||
var params = this.getQueryParams();//查询条件
|
||||
this.loading = true;
|
||||
getAction(this.url.list, params).then((res) => {
|
||||
if (res.success) {
|
||||
//update-begin---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
|
||||
this.dataSource = res.result.records || res.result;
|
||||
if (res.result.total) {
|
||||
this.dataSource = res.result.records||res.result;
|
||||
if(res.result.total)
|
||||
{
|
||||
this.ipagination.total = res.result.total;
|
||||
} else {
|
||||
}else{
|
||||
this.ipagination.total = 0;
|
||||
}
|
||||
//update-end---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
|
||||
} else {
|
||||
}else{
|
||||
this.$message.warning(res.message)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
initDictConfig() {
|
||||
initDictConfig(){
|
||||
console.log("--这是一个假的方法!")
|
||||
},
|
||||
handleSuperQuery(params, matchType) {
|
||||
//高级查询方法
|
||||
if (!params) {
|
||||
this.superQueryParams = ''
|
||||
if(!params){
|
||||
this.superQueryParams=''
|
||||
this.superQueryFlag = false
|
||||
} else {
|
||||
}else{
|
||||
this.superQueryFlag = true
|
||||
this.superQueryParams = JSON.stringify(params)
|
||||
this.superQueryParams=JSON.stringify(params)
|
||||
this.superQueryMatchType = matchType
|
||||
}
|
||||
this.loadData(1)
|
||||
},
|
||||
getQueryParams() {
|
||||
//获取查询条件
|
||||
console.log("this.queryParamthis.queryParam", this.queryParam);
|
||||
let sqp = {}
|
||||
if (this.superQueryParams) {
|
||||
sqp['superQueryParams'] = encodeURI(this.superQueryParams)
|
||||
if(this.superQueryParams){
|
||||
sqp['superQueryParams']=encodeURI(this.superQueryParams)
|
||||
sqp['superQueryMatchType'] = this.superQueryMatchType
|
||||
}
|
||||
var param = Object.assign(sqp, this.queryParam, this.isorter, this.filters);
|
||||
// param.field = this.getQueryField();
|
||||
param.field = this.isorter.column;
|
||||
var param = Object.assign(sqp, this.queryParam, this.isorter ,this.filters);
|
||||
param.field = this.getQueryField();
|
||||
param.pageNo = this.ipagination.current;
|
||||
param.pageSize = this.ipagination.pageSize;
|
||||
return filterObj(param);
|
||||
|
@ -163,7 +163,7 @@ export const JeecgListMixin = {
|
|||
this.loadData(1);
|
||||
},
|
||||
batchDel: function () {
|
||||
if (!this.url.deleteBatch) {
|
||||
if(!this.url.deleteBatch){
|
||||
this.$message.error("请设置url.deleteBatch属性!")
|
||||
return
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ export const JeecgListMixin = {
|
|||
content: "Do You Want To Delete This Item?",
|
||||
onOk: function () {
|
||||
that.loading = true;
|
||||
deleteAction(that.url.deleteBatch, { ids: ids }).then((res) => {
|
||||
deleteAction(that.url.deleteBatch, {ids: ids}).then((res) => {
|
||||
if (res.success) {
|
||||
//重新计算分页问题
|
||||
that.reCalculatePage(that.selectedRowKeys.length)
|
||||
|
@ -199,12 +199,12 @@ export const JeecgListMixin = {
|
|||
}
|
||||
},
|
||||
handleDelete: function (id, propertyName) {
|
||||
if (!this.url.delete) {
|
||||
if(!this.url.delete){
|
||||
this.$message.error("请设置url.delete属性!")
|
||||
return
|
||||
}
|
||||
var that = this;
|
||||
deleteAction(that.url.delete, { [propertyName || 'id']: id }).then((res) => {
|
||||
deleteAction(that.url.delete, {[propertyName || 'id']: id}).then((res) => {
|
||||
if (res.success) {
|
||||
//重新计算分页问题
|
||||
that.reCalculatePage(1)
|
||||
|
@ -215,16 +215,16 @@ export const JeecgListMixin = {
|
|||
}
|
||||
});
|
||||
},
|
||||
reCalculatePage(count) {
|
||||
reCalculatePage(count){
|
||||
//总数量-count
|
||||
let total = this.ipagination.total - count;
|
||||
let total=this.ipagination.total-count;
|
||||
//获取删除后的分页数
|
||||
let currentIndex = Math.ceil(total / this.ipagination.pageSize);
|
||||
let currentIndex=Math.ceil(total/this.ipagination.pageSize);
|
||||
//删除后的分页数<所在当前页
|
||||
if (currentIndex < this.ipagination.current) {
|
||||
this.ipagination.current = currentIndex;
|
||||
if(currentIndex<this.ipagination.current){
|
||||
this.ipagination.current=currentIndex;
|
||||
}
|
||||
console.log('currentIndex', currentIndex)
|
||||
console.log('currentIndex',currentIndex)
|
||||
},
|
||||
handleEdit: function (record) {
|
||||
this.$refs.modalForm.edit(record);
|
||||
|
@ -237,7 +237,6 @@ export const JeecgListMixin = {
|
|||
this.$refs.modalForm.disableSubmit = false;
|
||||
},
|
||||
handleTableChange(pagination, filters, sorter) {
|
||||
console.log("sortersorter", sorter);
|
||||
//分页、排序、筛选变化时触发
|
||||
//TODO 筛选
|
||||
console.log(pagination)
|
||||
|
@ -248,11 +247,11 @@ export const JeecgListMixin = {
|
|||
this.ipagination = pagination;
|
||||
this.loadData();
|
||||
},
|
||||
handleToggleSearch() {
|
||||
handleToggleSearch(){
|
||||
this.toggleSearchStatus = !this.toggleSearchStatus;
|
||||
},
|
||||
// 给popup查询使用(查询区域不支持回填多个字段,限制只返回一个字段)
|
||||
getPopupField(fields) {
|
||||
getPopupField(fields){
|
||||
return fields.split(',')[0]
|
||||
},
|
||||
modalFormOk() {
|
||||
|
@ -261,39 +260,39 @@ export const JeecgListMixin = {
|
|||
//清空列表选中
|
||||
this.onClearSelected()
|
||||
},
|
||||
handleDetail: function (record) {
|
||||
handleDetail:function(record){
|
||||
this.$refs.modalForm.edit(record);
|
||||
this.$refs.modalForm.title = "Detail";
|
||||
this.$refs.modalForm.title="Detail";
|
||||
this.$refs.modalForm.disableSubmit = true;
|
||||
},
|
||||
/* 导出 */
|
||||
handleExportXls2() {
|
||||
handleExportXls2(){
|
||||
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
|
||||
let url = `${window._CONFIG['domianURL']}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`;
|
||||
window.location.href = url;
|
||||
},
|
||||
handleExportXls(fileName) {
|
||||
if (!fileName || typeof fileName != "string") {
|
||||
handleExportXls(fileName){
|
||||
if(!fileName || typeof fileName != "string"){
|
||||
fileName = "导出文件"
|
||||
}
|
||||
let param = this.getQueryParams();
|
||||
if (this.selectedRowKeys && this.selectedRowKeys.length > 0) {
|
||||
if(this.selectedRowKeys && this.selectedRowKeys.length>0){
|
||||
param['selections'] = this.selectedRowKeys.join(",")
|
||||
}
|
||||
console.log("导出参数", param)
|
||||
downFile(this.url.exportXlsUrl, param).then((data) => {
|
||||
console.log("导出参数",param)
|
||||
downFile(this.url.exportXlsUrl,param).then((data)=>{
|
||||
if (!data) {
|
||||
this.$message.warning("文件下载失败")
|
||||
return
|
||||
}
|
||||
if (typeof window.navigator.msSaveBlob !== 'undefined') {
|
||||
window.navigator.msSaveBlob(new Blob([data], { type: 'application/vnd.ms-excel' }), fileName + '.xls')
|
||||
} else {
|
||||
let url = window.URL.createObjectURL(new Blob([data], { type: 'application/vnd.ms-excel' }))
|
||||
window.navigator.msSaveBlob(new Blob([data],{type: 'application/vnd.ms-excel'}), fileName+'.xls')
|
||||
}else{
|
||||
let url = window.URL.createObjectURL(new Blob([data],{type: 'application/vnd.ms-excel'}))
|
||||
let link = document.createElement('a')
|
||||
link.style.display = 'none'
|
||||
link.href = url
|
||||
link.setAttribute('download', fileName + '.xls')
|
||||
link.setAttribute('download', fileName+'.xls')
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link); //下载完成移除元素
|
||||
|
@ -302,7 +301,7 @@ export const JeecgListMixin = {
|
|||
})
|
||||
},
|
||||
/* 导入 */
|
||||
handleImportExcel(info) {
|
||||
handleImportExcel(info){
|
||||
this.loading = true;
|
||||
if (info.file.status !== 'uploading') {
|
||||
console.log(info.file, info.fileList);
|
||||
|
@ -317,9 +316,9 @@ export const JeecgListMixin = {
|
|||
this.$warning({
|
||||
title: message,
|
||||
content: (<div>
|
||||
<span>{msg}</span><br />
|
||||
<span>具体详情请 <a href={href} target="_blank" download={fileName}>点击下载</a> </span>
|
||||
</div>
|
||||
<span>{msg}</span><br/>
|
||||
<span>具体详情请 <a href={href} target="_blank" download={fileName}>点击下载</a> </span>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
} else {
|
||||
|
@ -354,21 +353,21 @@ export const JeecgListMixin = {
|
|||
}
|
||||
},
|
||||
/* 图片预览 */
|
||||
getImgView(text) {
|
||||
if (text && text.indexOf(",") > 0) {
|
||||
text = text.substring(0, text.indexOf(","))
|
||||
getImgView(text){
|
||||
if(text && text.indexOf(",")>0){
|
||||
text = text.substring(0,text.indexOf(","))
|
||||
}
|
||||
return getFileAccessHttpUrl(text)
|
||||
},
|
||||
/* 文件下载 */
|
||||
// update--autor:lvdandan-----date:20200630------for:修改下载文件方法名uploadFile改为downloadFile------
|
||||
downloadFile(text) {
|
||||
if (!text) {
|
||||
downloadFile(text){
|
||||
if(!text){
|
||||
this.$message.warning("未知的文件")
|
||||
return;
|
||||
}
|
||||
if (text.indexOf(",") > 0) {
|
||||
text = text.substring(0, text.indexOf(","))
|
||||
if(text.indexOf(",")>0){
|
||||
text = text.substring(0,text.indexOf(","))
|
||||
}
|
||||
let url = getFileAccessHttpUrl(text)
|
||||
window.open(url);
|
||||
|
|
|
@ -1,29 +1,17 @@
|
|||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
beforeModalOpen() {}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
if (val && this.beforeModalOpen && typeof this.beforeModalOpen == 'function') {
|
||||
this.beforeModalOpen()
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
16
src/store/i18n-mixin.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { mapState } from 'vuex'
|
||||
|
||||
const i18nMixin = {
|
||||
computed: {
|
||||
...mapState({
|
||||
currentLang: state => state.app.lang
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
setLang (lang) {
|
||||
this.$store.dispatch('setLang', lang)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default i18nMixin
|
|
@ -21,6 +21,7 @@ const app = {
|
|||
device: 'desktop',
|
||||
theme: '',
|
||||
layout: '',
|
||||
lang: 'zh-CN',
|
||||
contentWidth: '',
|
||||
fixedHeader: false,
|
||||
fixSiderbar: false,
|
||||
|
@ -78,9 +79,19 @@ const app = {
|
|||
SET_MULTI_PAGE (state, multipageFlag) {
|
||||
Vue.ls.set(DEFAULT_MULTI_PAGE, multipageFlag)
|
||||
state.multipage = multipageFlag
|
||||
},
|
||||
APP_LANGUAGE: (state, lang, antd = {}) => {
|
||||
state.lang = lang
|
||||
state._antLocale = antd
|
||||
Vue.ls.set("APP_LANGUAGE", lang)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setLang ({ commit }, lang) {
|
||||
// return new Promise((resolve, reject) => {
|
||||
commit('APP_LANGUAGE', lang)
|
||||
// })
|
||||
},
|
||||
setSidebar: ({ commit }, type) => {
|
||||
commit('SET_SIDEBAR_TYPE', type)
|
||||
},
|
||||
|
|
105
src/style.less
|
@ -18,17 +18,18 @@
|
|||
|
||||
@modal-footer-border-color-split: @formInputBorderColor;
|
||||
|
||||
@disabled-color: rgba(255, 255, 255, 0.25);
|
||||
@disabled-color: rgba(255, 255, 255, .25);
|
||||
@background-color-base: darken(@primary-color, 20);
|
||||
@border-color-base: darken(@primary-color, 20);
|
||||
|
||||
@text-color: #fff;
|
||||
|
||||
@component-background: @modalBg;
|
||||
@heading-color: #fff;
|
||||
|
||||
@input-bg: @formInputBgColor;
|
||||
@input-border-color: @formInputBorderColor;
|
||||
.ant-btn:hover,
|
||||
.ant-btn:active,
|
||||
.ant-btn:focus {
|
||||
color: #fff !important;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: MicrogrammaD-MediExte;
|
||||
|
@ -64,29 +65,19 @@ body {
|
|||
}
|
||||
|
||||
// 表格样式
|
||||
@table-border-radius-base: 0;
|
||||
@table-padding-vertical-sm: 2px;
|
||||
@table-padding-vertical: 6px;
|
||||
@table-padding-horizontal: 8px;
|
||||
@table-row-hover-bg: #0e505f;
|
||||
|
||||
.ant-table {
|
||||
color: #ade6ee;
|
||||
font-size: 16px;
|
||||
border: 1px solid rgba(65, 111, 127, 0.5);
|
||||
&-header {
|
||||
background: #126b82 !important;
|
||||
box-sizing: border-box !important;
|
||||
table {
|
||||
width: calc(100% + 11px) !important;
|
||||
}
|
||||
}
|
||||
border: 1px solid rgba(65,111,127, .5);
|
||||
|
||||
&-thead {
|
||||
> tr {
|
||||
th {
|
||||
background-color: #126b82 !important;
|
||||
color: #fff;
|
||||
padding: 6px 8px !important;
|
||||
border-bottom: none;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,12 +87,15 @@ body {
|
|||
&:nth-child(2n) {
|
||||
background-color: #08373a;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 8px !important;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
td {
|
||||
background-color: #0e505f !important;
|
||||
}
|
||||
}
|
||||
&.ant-table-row-selected {
|
||||
td {
|
||||
background-color: #0d4e5c !important;
|
||||
|
@ -123,29 +117,6 @@ body {
|
|||
border-color: @formInputBorderColor;
|
||||
color: @formInputBorderColor;
|
||||
}
|
||||
|
||||
&-small {
|
||||
font-size: 14px;
|
||||
|
||||
.ant-table {
|
||||
&-tbody {
|
||||
tr td {
|
||||
padding-top: 6px !important;
|
||||
padding-bottom: 6px !important;
|
||||
}
|
||||
}
|
||||
|
||||
&-placeholder {
|
||||
.ant-empty-image {
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.ant-empty-description {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格下的分页器
|
||||
|
@ -168,7 +139,7 @@ body {
|
|||
width: 100%;
|
||||
}
|
||||
&-required::before {
|
||||
// display: none !important;
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
&-horizontal {
|
||||
|
@ -189,13 +160,6 @@ body {
|
|||
&-time-picker-inner {
|
||||
background-color: @modalBg;
|
||||
}
|
||||
&-time-picker {
|
||||
background: none;
|
||||
}
|
||||
&-time-picker-combobox {
|
||||
background-color: @modalBg !important;
|
||||
border-color: @formInputBorderColor !important;
|
||||
}
|
||||
|
||||
&-picker {
|
||||
width: 100%;
|
||||
|
@ -206,13 +170,10 @@ body {
|
|||
background-color: @formInputBgColor;
|
||||
color: #00e9fe !important;
|
||||
}
|
||||
&-select {
|
||||
background-color: @formInputBgColor !important;
|
||||
}
|
||||
}
|
||||
|
||||
&-input {
|
||||
background-color: red;
|
||||
background-color: transparent;
|
||||
&-wrap {
|
||||
border-color: @formInputBorderColor;
|
||||
height: 32px;
|
||||
|
@ -280,9 +241,6 @@ body {
|
|||
}
|
||||
}
|
||||
}
|
||||
.ant-calendar-range .ant-calendar-in-range-cell::before {
|
||||
background: #1397a3;
|
||||
}
|
||||
|
||||
// 日历
|
||||
.ant-fullcalendar {
|
||||
|
@ -346,8 +304,7 @@ body {
|
|||
|
||||
&-selected-day &-date,
|
||||
&-date:hover {
|
||||
background-color: #0b4f54 !important;
|
||||
// background-color: #072f32 !important;
|
||||
background-color: #072f32 !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,19 +312,18 @@ body {
|
|||
@time-picker-selected-bg: @primary-color;
|
||||
@item-hover-bg: @primary-color;
|
||||
.ant-time-picker {
|
||||
width: 100%;
|
||||
|
||||
&-input {
|
||||
background: @modalBg;
|
||||
border-radius: 0;
|
||||
|
||||
&::placeholder {
|
||||
color: #ccc;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&-clear,
|
||||
&-clock-icon {
|
||||
color: #01b6e3 !important;
|
||||
background-color: @modalBg !important;
|
||||
color: #01B6E3 !important;
|
||||
}
|
||||
|
||||
&-panel {
|
||||
|
@ -388,17 +344,13 @@ body {
|
|||
}
|
||||
|
||||
// 输入框样式
|
||||
.ant-calendar-input {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
.ant-calendar-range-middle {
|
||||
color: #fff;
|
||||
}
|
||||
.ant-input {
|
||||
background-color: @formInputBgColor !important;
|
||||
border-color: @formInputBorderColor !important;
|
||||
border-radius: 0;
|
||||
color: #fff;
|
||||
&::placeholder {
|
||||
color: #ccc;
|
||||
color: #fff;
|
||||
}
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
|
@ -563,7 +515,7 @@ input[type='number']::-webkit-outer-spin-button {
|
|||
&.ant-select-dropdown-placement-topLeft {
|
||||
padding-top: 0;
|
||||
padding-bottom: 7px;
|
||||
|
||||
|
||||
.ant-select-dropdown-content {
|
||||
&::before {
|
||||
top: auto;
|
||||
|
@ -645,9 +597,6 @@ input[type='number']::-webkit-outer-spin-button {
|
|||
}
|
||||
}
|
||||
}
|
||||
.ant-select-selection--multiple .ant-select-selection__choice {
|
||||
max-width: 60%;
|
||||
}
|
||||
|
||||
// 下拉菜单
|
||||
.ant-dropdown {
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/**
|
||||
* 本地文件选择
|
||||
*/
|
||||
export class FilePicker {
|
||||
/**
|
||||
* 接口是否可用
|
||||
* @returns { Boolean }
|
||||
*/
|
||||
static canUse() {
|
||||
return !!(window.showDirectoryPicker && window.showOpenFilePicker)
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择一个目录
|
||||
* @returns { Promise<FileSystemDirectoryHandle> }
|
||||
*/
|
||||
static chooseDirectory() {
|
||||
if (!this.canUse()) {
|
||||
throw new Error('Not Support showDirectoryPicker')
|
||||
}
|
||||
return window.showDirectoryPicker()
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择一个文件
|
||||
* @param { Boolean } multiple
|
||||
* @param { { description?: string; accept?: { [key: string]: string[]; } } } types
|
||||
* @returns { Promise<FileSystemFileHandle[]> }
|
||||
*/
|
||||
static chooseFile(multiple, types) {
|
||||
if (!this.canUse()) {
|
||||
throw new Error('Not Support showOpenFilePicker')
|
||||
}
|
||||
const pickerOpts = {
|
||||
multiple,
|
||||
types,
|
||||
excludeAcceptAllOption: true
|
||||
}
|
||||
return window.showOpenFilePicker(pickerOpts)
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断一个文件是否在某个目录下
|
||||
* @param {FileSystemDirectoryHandle} directoryHandle
|
||||
* @param {FileSystemFileHandle} fileHandle
|
||||
*/
|
||||
static async isFileInDirectory(directoryHandle, fileHandle) {
|
||||
const relativePaths = await directoryHandle.resolve(fileHandle)
|
||||
if (relativePaths === null || relativePaths.length > 1) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
// 所有缓存的谱
|
||||
let sampleList = []
|
||||
|
||||
/**
|
||||
* 重新设置缓存的谱
|
||||
* @param {Array} list
|
||||
*/
|
||||
const setSampleList = list => {
|
||||
sampleList = list
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存一条谱数据
|
||||
* @param {*} sampleData
|
||||
*/
|
||||
const addSampleData = sampleData => {
|
||||
const find = sampleList.find(item => item.inputFileName == sampleData.inputFileName)
|
||||
if (find) {
|
||||
find.data = sampleData.data
|
||||
} else {
|
||||
sampleList.push(sampleData)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新谱数据
|
||||
* @param {{ inputFileName: string; key: string; data: any; }} param0
|
||||
*/
|
||||
const updateSampleData = ({ inputFileName, key, data }) => {
|
||||
const find = sampleList.find(item => item.inputFileName == inputFileName)
|
||||
if (find) {
|
||||
find.data[key] = data
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除谱数据
|
||||
* @param {string} inputFileName
|
||||
*/
|
||||
const removeSampleData = inputFileName => {
|
||||
const findIndex = sampleList.findIndex(item => item.inputFileName == inputFileName)
|
||||
if (-1 !== findIndex) {
|
||||
sampleList.splice(findIndex, 1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新分析数据
|
||||
* @param {{ inputFileName: string; data: any; }} param0
|
||||
*/
|
||||
const updateSampleDataAnaly = ({ inputFileName, data }) => {
|
||||
const find = sampleList.find(item => item.inputFileName == inputFileName)
|
||||
if (find) {
|
||||
data.DetailedInformation = find.data.DetailedInformation
|
||||
find.data = data
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理缓存列表
|
||||
*/
|
||||
const clearSampleData = () => {
|
||||
sampleList = []
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件名获取谱
|
||||
* @param {string} inputFileName
|
||||
*/
|
||||
const getSampleData = inputFileName => {
|
||||
const find = sampleList.find(item => item.inputFileName == inputFileName)
|
||||
return find ? find : null
|
||||
}
|
||||
|
||||
export {
|
||||
sampleList,
|
||||
setSampleList,
|
||||
addSampleData,
|
||||
updateSampleData,
|
||||
removeSampleData,
|
||||
updateSampleDataAnaly,
|
||||
clearSampleData,
|
||||
getSampleData
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
const { UpdateBaseLine } = Module;
|
||||
export { UpdateBaseLine as updateBaseLine };
|
|
@ -8,7 +8,7 @@ export function getXAxisAndYAxisByPosition(chart, offsetX, offsetY, seriesIndex
|
|||
if (
|
||||
chart.containPixel(
|
||||
{
|
||||
seriesIndex
|
||||
seriesIndex: 0
|
||||
},
|
||||
pointInPixel
|
||||
)
|
||||
|
@ -17,102 +17,4 @@ export function getXAxisAndYAxisByPosition(chart, offsetX, offsetY, seriesIndex
|
|||
return [xAxis, yAxis]
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 将图表导出为图片
|
||||
* @param {import("echarts").ECharts} chartInstance
|
||||
* @param {'png' | 'jpeg' | 'svg'} type
|
||||
*/
|
||||
export function exportEchartImg(chartInstance, type = 'png', backgroundColor = '#022024') {
|
||||
const dataURL = chartInstance.getDataURL({
|
||||
type,
|
||||
pixelRatio: 2,
|
||||
backgroundColor
|
||||
});
|
||||
|
||||
const link = document.createElement('a')
|
||||
link.style.display = 'none'
|
||||
link.href = dataURL
|
||||
link.setAttribute('download', 'export.png')
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link) //下载完成移除元素
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 按份数分割轴线
|
||||
* @param {Number} max
|
||||
* @param {Number} min
|
||||
* @param {Number} cnt
|
||||
* @param {Number} maxBoundaryGap
|
||||
*/
|
||||
export function splitAxis(max, min, cnt, maxBoundaryGap = 1.1) {
|
||||
const _min = Math.floor(min)
|
||||
const interval = Math.ceil((Math.ceil(max * maxBoundaryGap) - _min) / cnt)
|
||||
const _max = _min + interval * cnt
|
||||
|
||||
return {
|
||||
min: _min,
|
||||
interval,
|
||||
max: _max
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建线形series
|
||||
* @param {*} name
|
||||
* @param {*} data
|
||||
* @param {*} color
|
||||
* @param {*} extra
|
||||
* @returns
|
||||
*/
|
||||
export function buildLineSeries(name, data, color, extra = {}) {
|
||||
return {
|
||||
name,
|
||||
type: 'line',
|
||||
data,
|
||||
itemStyle: {
|
||||
color
|
||||
},
|
||||
lineStyle: {
|
||||
width: 1
|
||||
},
|
||||
symbol: 'none',
|
||||
symbolSize: 1,
|
||||
emphasis: {
|
||||
disabled: true
|
||||
},
|
||||
animation: false,
|
||||
...extra
|
||||
}
|
||||
}
|
||||
|
||||
// 根据name查找series
|
||||
export function findSeriesByName(series, seriesName) {
|
||||
return series.find(item => item.name == seriesName)
|
||||
}
|
||||
|
||||
/**
|
||||
* 限定数字在一定范围
|
||||
* @param {Number} min
|
||||
* @param {Number} max
|
||||
* @returns {(num: number) => number }
|
||||
*/
|
||||
export function rangeNumber(min, max) {
|
||||
return num => {
|
||||
return num > max ? max : num < min ? min : num
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图表某条轴线的最大值
|
||||
* @param {import("echarts").ECharts} chartInstance
|
||||
* @param {'xAxis' | 'yAxis'} axis
|
||||
* @returns
|
||||
*/
|
||||
export function getAxisMax(chartInstance, axis) {
|
||||
return chartInstance.getModel().getComponent(axis).axis.scale.rawExtentInfo._dataMax
|
||||
}
|