Compare commits

..

2 Commits

Author SHA1 Message Date
d4f1f15491 多语言切换icon及切换方式代码调整 2023-08-23 10:02:52 +08:00
60f1f0dde4 系统多语言逻辑实现 2023-08-22 17:23:30 +08:00
312 changed files with 7374 additions and 1018151 deletions

View File

@ -1,9 +1,7 @@
NODE_ENV=development NODE_ENV=development
VUE_APP_API_BASE_URL=http://182.92.183.230:9999 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_CAS_BASE_URL=http://cas.example.org:8443/cas
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview 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为子应用的项目名称,也是子应用的路由父路径
VUE_APP_SUB_jeecg-app-1 = '//localhost:8092' VUE_APP_SUB_jeecg-app-1 = '//localhost:8092'

View File

@ -1,5 +1,4 @@
NODE_ENV=production 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_CAS_BASE_URL=http://localhost:8888/cas
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview 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

View File

@ -1,13 +0,0 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
"target": "ES6",
"module": "CommonJS",
"allowSyntheticDefaultImports": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}

View File

@ -11,13 +11,11 @@
}, },
"dependencies": { "dependencies": {
"@antv/data-set": "^0.11.4", "@antv/data-set": "^0.11.4",
"@antv/g2plot": "^2.4.23",
"@jeecg/antd-online-mini": "3.4.3-beta2", "@jeecg/antd-online-mini": "3.4.3-beta2",
"@tinymce/tinymce-vue": "2.1.0", "@tinymce/tinymce-vue": "2.1.0",
"@toast-ui/editor": "^2.1.2", "@toast-ui/editor": "^2.1.2",
"ant-design-vue": "^1.7.2", "ant-design-vue": "^1.7.2",
"axios": "^0.18.0", "axios": "^0.18.0",
"bignumber.js": "^9.1.2",
"china-area-data": "^5.0.1", "china-area-data": "^5.0.1",
"clipboard": "^2.0.4", "clipboard": "^2.0.4",
"codemirror": "^5.46.0", "codemirror": "^5.46.0",
@ -28,9 +26,7 @@
"echarts": "^5.4.2", "echarts": "^5.4.2",
"echarts-gl": "^2.0.9", "echarts-gl": "^2.0.9",
"enquire.js": "^2.1.6", "enquire.js": "^2.1.6",
"file-saver": "^2.0.5",
"js-cookie": "^2.2.0", "js-cookie": "^2.2.0",
"jszip": "^3.10.1",
"lodash.get": "^4.4.2", "lodash.get": "^4.4.2",
"lodash.pick": "^4.4.0", "lodash.pick": "^4.4.0",
"md5": "^2.2.1", "md5": "^2.2.1",
@ -41,10 +37,8 @@
"viser-vue": "^2.4.8", "viser-vue": "^2.4.8",
"vue": "^2.6.10", "vue": "^2.6.10",
"vue-area-linkage": "^5.1.0", "vue-area-linkage": "^5.1.0",
"vue-color": "^2.8.1",
"vue-cropper": "^0.5.4", "vue-cropper": "^0.5.4",
"vue-i18n": "^8.7.0", "vue-i18n": "^8.7.0",
"vue-infinite-scroll": "^2.0.2",
"vue-loader": "^15.7.0", "vue-loader": "^15.7.0",
"vue-ls": "^3.2.0", "vue-ls": "^3.2.0",
"vue-photo-preview": "^1.1.3", "vue-photo-preview": "^1.1.3",
@ -58,11 +52,9 @@
"vxe-table": "2.9.13", "vxe-table": "2.9.13",
"vxe-table-plugin-antd": "1.8.10", "vxe-table-plugin-antd": "1.8.10",
"xe-utils": "2.4.8", "xe-utils": "2.4.8",
"xlsx": "^0.18.5",
"xss": "^1.0.13" "xss": "^1.0.13"
}, },
"devDependencies": { "devDependencies": {
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
"@babel/polyfill": "^7.2.5", "@babel/polyfill": "^7.2.5",
"@types/crypto-js": "^4.1.1", "@types/crypto-js": "^4.1.1",
"@vue/cli-plugin-babel": "^3.3.0", "@vue/cli-plugin-babel": "^3.3.0",

5
public/index.html vendored
View File

@ -5,8 +5,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <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"> <link rel="icon" href="<%= BASE_URL %>logo.png">
<script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script> <script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script>
<style> <style>
@ -252,7 +251,7 @@
<div class="loader-section section-right"></div> <div class="loader-section section-right"></div>
</div> </div>
</div> </div>
<script src="/qtw.js"></script>
</body> </body>
</html> </html>

BIN
public/logo.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

1
public/qtw.js vendored

File diff suppressed because one or more lines are too long

BIN
public/qtw.wasm vendored

Binary file not shown.

View File

@ -7,7 +7,5 @@ window._CONFIG = {
//单点登录地址 //单点登录地址
VUE_APP_CAS_BASE_URL: '', VUE_APP_CAS_BASE_URL: '',
//文件预览路径 //文件预览路径
VUE_APP_ONLINE_BASE_URL: '', VUE_APP_ONLINE_BASE_URL: ''
// 离线地图
VUE_APP_MAP_BASE_URL_OFFLINE: 'http://localhost:8001/map/{z}/{x}/{y}.jpg'
} }

View File

@ -1,7 +1,6 @@
import Vue from 'vue' import Vue from 'vue'
import { axios } from '@/utils/request' import { axios } from '@/utils/request'
import signMd5Utils from '@/utils/encryption/signMd5Utils' import signMd5Utils from '@/utils/encryption/signMd5Utils'
import qs from "qs";
const api = { const api = {
user: '/mock/api/user', user: '/mock/api/user',
@ -14,116 +13,64 @@ const api = {
export default api export default api
//post //post
export function postAction(url, parameter) { export function postAction(url,parameter) {
let sign = signMd5Utils.getSign(url, parameter); let sign = signMd5Utils.getSign(url, parameter);
//将签名和时间戳,添加在请求接口 Header //将签名和时间戳,添加在请求接口 Header
// update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯 // 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牵扯 // update-end--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
return axios({ return axios({
url: url, url: url,
method: 'post', method:'post' ,
data: parameter, data: parameter,
headers: signHeader 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} //post method= {post | put}
export function httpAction(url, parameter, method) { export function httpAction(url,parameter,method) {
let sign = signMd5Utils.getSign(url, parameter); let sign = signMd5Utils.getSign(url, parameter);
//将签名和时间戳,添加在请求接口 Header //将签名和时间戳,添加在请求接口 Header
// update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯 // 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牵扯 // update-end--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
return axios({ return axios({
url: url, url: url,
method: method, method:method ,
data: parameter, data: parameter,
headers: signHeader headers: signHeader
}) })
} }
//put //put
export function putAction(url, parameter) { export function putAction(url,parameter) {
return axios({ return axios({
url: url, url: url,
method: 'put', method:'put',
data: parameter data: parameter
}) })
} }
//get //get
export function getAction(url, parameter, cancelToken) { export function getAction(url,parameter) {
let sign = signMd5Utils.getSign(url, parameter); let sign = signMd5Utils.getSign(url, parameter);
//将签名和时间戳,添加在请求接口 Header //将签名和时间戳,添加在请求接口 Header
// update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯 // 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牵扯 // 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({ return axios({
url: url, url: url,
method: 'get', method: 'get',
params: parameter, params: parameter,
responseType: "blob",
paramsSerializer: function (params) {
return qs.stringify(params, { arrayFormat: "repeat" });
},
headers: signHeader headers: signHeader
}) })
} }
//deleteAction //deleteAction
export function deleteAction(url, parameter) { export function deleteAction(url,parameter) {
return axios({ return axios({
url: url, url: url,
method: 'delete', method: 'delete',
@ -179,15 +126,15 @@ export function saveService(parameter) {
* @param parameter * @param parameter
* @returns {*} * @returns {*}
*/ */
export function downFile(url, parameter, method = 'get') { export function downFile(url,parameter, method='get'){
if (method == 'get') { if(method=='get'){
return axios({ return axios({
url: url, url: url,
params: parameter, params: parameter,
method: method, method: method ,
responseType: 'blob' responseType: 'blob'
}) })
} else { }else{
return axios({ return axios({
url: url, url: url,
method: method, method: method,
@ -233,11 +180,11 @@ export function downloadFile(url, fileName, parameter, method) {
* @param parameter * @param parameter
* @returns {*} * @returns {*}
*/ */
export function uploadAction(url, parameter) { export function uploadAction(url,parameter){
return axios({ return axios({
url: url, url: url,
data: parameter, data: parameter,
method: 'post', method:'post' ,
headers: { headers: {
'Content-Type': 'multipart/form-data', // 文件上传 'Content-Type': 'multipart/form-data', // 文件上传
}, },
@ -250,17 +197,17 @@ export function uploadAction(url, parameter) {
* @param subStr * @param subStr
* @returns {*} * @returns {*}
*/ */
export function getFileAccessHttpUrl(avatar, subStr) { export function getFileAccessHttpUrl(avatar,subStr) {
if (!subStr) subStr = 'http' if(!subStr) subStr = 'http'
try { try {
if (avatar && avatar.startsWith(subStr)) { if(avatar && avatar.startsWith(subStr)){
return avatar; return avatar;
} else { }else{
if (avatar && avatar.length > 0 && avatar.indexOf('[') == -1) { if(avatar && avatar.length>0 && avatar.indexOf('[')==-1){
return window._CONFIG['staticDomainURL'] + "/" + avatar; return window._CONFIG['staticDomainURL'] + "/" + avatar;
} }
} }
} catch (err) { }catch(err){
return; return;
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1003 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1003 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 975 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1002 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1002 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1007 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -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;
}
}

View File

@ -1,16 +1,14 @@
/** /**
* 列表查询通用样式,移动端自适应 * 列表查询通用样式,移动端自适应
*/ */
.search { .search{
/**
margin-bottom: 54px; margin-bottom: 54px;
*/
} }
.fold { .fold{
width: calc(100% - 216px); width: calc(100% - 216px);
display: inline-block; display: inline-block
} }
.operator { .operator{
margin-bottom: 18px; margin-bottom: 18px;
} }
@media screen and (max-width: 900px) { @media screen and (max-width: 900px) {
@ -24,7 +22,7 @@
i { i {
cursor: pointer; cursor: pointer;
} }
.trcolor { .trcolor{
background-color: rgba(255, 192, 203, 0.31); background-color: rgba(255, 192, 203, 0.31);
color: red; color:red;
} }

View File

@ -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>

View 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>

View File

@ -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>

View File

@ -3,50 +3,40 @@
</template> </template>
<script> <script>
import * as echarts from 'echarts' import * as echarts from 'echarts'
import 'echarts-gl'
const events = ['click', 'brushEnd', 'dataZoom'] const events = ['brushEnd']
const zrEvents = ['mousemove', 'mousedown', 'mouseup', 'click', 'dblclick', 'contextmenu'] const zrEvents = ['mousemove', 'mousedown', 'mouseup']
export default { export default {
props: { props: {
option: { option: {
type: Object, type: Object,
default: () => ({}), default: () => ({})
},
opts: {
type: Object,
default: () => {},
}, },
height: { height: {
type: Number, type: Number,
default: null, default: 0
}, }
}, },
data() { data() {
return {} return {}
}, },
mounted() { mounted() {
this._chart = echarts.init(this.$refs.containerRef) this._chart = echarts.init(this.$refs.containerRef)
this._chart.setOption(this.option, this.opts) this._chart.setOption(this.option)
this.initEventListener() this.initEventListener()
}, },
beforeDestroy() {
if (this._chart) {
this._chart.dispose()
this._chart = null
}
},
methods: { methods: {
initEventListener() { initEventListener() {
events.forEach((eventName) => { events.forEach(eventName => {
this._chart.on(eventName, (params) => { this._chart.on(eventName, (params) => {
this.$emit(eventName, params) this.$emit(eventName, params)
}) })
}) })
const zr = this.getZRender() const zr = this.getZRender()
zrEvents.forEach((eventName) => { zrEvents.forEach(eventName => {
zr.on(eventName, (params) => { zr.on(eventName, params => {
this.$emit(`zr:${eventName}`, params) this.$emit(`zr:${eventName}`, params)
}) })
}) })
@ -63,27 +53,27 @@ export default {
getZRender() { getZRender() {
return this._chart.getZr() return this._chart.getZr()
}, }
}, },
watch: { watch: {
option: { option: {
handler() { handler() {
if (this._chart) { if (this._chart) {
this._chart.setOption(this.option, this.opts) this._chart.setOption(this.option)
} }
}, },
deep: true, deep: true
}, },
height() { height() {
this.$nextTick(() => { this.$nextTick(() => {
this._chart && this._chart.resize() this._chart && this._chart.resize()
}) })
}, }
}, }
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.custom-chart { .custom-chart {
height: 100%; height: 100% !important;
} }
</style> </style>

View File

@ -1,5 +1,5 @@
<template> <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="" /> <img src="@/assets/images/global/calendar.png" slot="suffixIcon" alt="" srcset="" />
</a-date-picker> </a-date-picker>
</template> </template>
@ -19,12 +19,7 @@ export default {
this.$emit('input', val) this.$emit('input', val)
} }
} }
}, }
methods: {
onChange(mont,date) {
this.$emit("change",mont,date)
}
},
} }
</script> </script>
<style lang=""></style> <style lang=""></style>

View File

@ -1,22 +1,12 @@
<template> <template>
<a-modal <a-modal :class="'custom-modal' + (innerFullscreen ? ' fullscreen' : '')" v-bind="_attrs" v-model="visible">
:class="'custom-modal' + (innerFullscreen ? ' fullscreen' : '')"
v-bind="_attrs"
v-model="visible"
:maskClosable="false"
@cancel="handleCancel"
>
<img slot="closeIcon" src="@/assets/images/global/close.png" /> <img slot="closeIcon" src="@/assets/images/global/close.png" />
<div slot="title"> <div slot="title">
<div class="custom-modal-title"> <div class="custom-modal-title">
<span>{{ title }}</span> <span>{{ title }}</span>
<template v-if="enableFullScreen"> <template v-if="enableFullScreen">
<img <img v-if="innerFullscreen" src="@/assets/images/global/quit-fullscreen.png" @click="innerFullscreen = false" />
v-if="innerFullscreen" <img v-else src="@/assets/images/global/fullscreen.png" @click="innerFullscreen = true" />
src="@/assets/images/global/quit-fullscreen.png"
@click="innerFullscreen = false"
/>
<img v-else src="@/assets/images/global/fullscreen.png" @click="innerFullscreen = true" />
</template> </template>
</div> </div>
</div> </div>
@ -34,24 +24,24 @@
export default { export default {
props: { props: {
value: { value: {
type: Boolean, type: Boolean
}, },
okHandler: { okHandler: {
type: Function, type: Function
}, },
title: { title: {
type: String, type: String
}, },
enableFullScreen: { enableFullScreen: {
type: Boolean, type: Boolean,
default: false, default: false
}, }
}, },
data() { data() {
return { return {
visible: this.value, visible: this.value,
confirmLoading: false, confirmLoading: false,
innerFullscreen: false, innerFullscreen: false
} }
}, },
watch: { watch: {
@ -66,17 +56,15 @@ export default {
}, },
innerFullscreen(val) { innerFullscreen(val) {
this.$emit('fullscreen', val) this.$emit('fullscreen', val)
}, }
}, },
methods: { methods: {
async onSave() { async onSave() {
if (this.okHandler instanceof Function) { if (this.okHandler instanceof Function) {
try { try {
this.confirmLoading = true this.confirmLoading = true
const success = await this.okHandler() await this.okHandler()
if (success !== false) { this.visible = false
this.visible = false
}
} catch (error) { } catch (error) {
console.error(error) console.error(error)
} finally { } finally {
@ -88,10 +76,7 @@ export default {
}, },
onCancel() { onCancel() {
this.visible = false this.visible = false
}, }
handleCancel() {
this.$emit('cancel')
},
}, },
computed: { computed: {
_attrs() { _attrs() {
@ -106,8 +91,8 @@ export default {
// footer // footer
hasCustomFooter() { hasCustomFooter() {
return !!this.$slots['custom-footer'] return !!this.$slots['custom-footer']
}, }
}, }
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@ -1,8 +1,6 @@
<template> <template>
<a-table <a-table
ref="tableRef" class="custom-table"
class="custom-table"
:class="['custom-table', canSelect && multiple && mouseMoveSelect ? 'mouse-move-select' : '']"
v-bind="$attrs" v-bind="$attrs"
:data-source="list" :data-source="list"
:columns="columns" :columns="columns"
@ -10,8 +8,8 @@
:row-key="rowKey" :row-key="rowKey"
:loading="loading" :loading="loading"
:pagination="pagination" :pagination="pagination"
:customRow="multiple && mouseMoveSelect ? customMouseMoveSelectRow : customRow" :customRow="customRow"
:rowClassName="() => (canSelect ? 'custom-table-row' : '')" :rowClassName="() => canSelect? 'custom-table-row': ''"
@change="handleTableChange" @change="handleTableChange"
> >
<!-- 处理 scopedSlots --> <!-- 处理 scopedSlots -->
@ -25,174 +23,98 @@ export default {
props: { props: {
list: { list: {
type: Array, type: Array,
default: () => [], default: () => []
}, },
columns: { columns: {
type: Array, type: Array,
default: () => [], default: () => []
}, },
size: { size: {
type: String, type: String,
default: 'middle', default: 'middle'
}, },
rowKey: { rowKey: {
type: String, type: String,
default: 'id', default: 'id'
}, },
loading: { loading: {
type: Boolean, type: Boolean
}, },
pagination: { pagination: {
type: [Object, Boolean], type: [Object, Boolean]
}, },
selectedRowKeys: { selectedRowKeys: {
type: Array, type: Array
}, },
selectionRows: { selectionRows: {
type: Array, type: Array
}, },
canSelect: { canSelect: {
type: Boolean, type: Boolean,
default: true, default: true
}, },
canDeselect: {
type: Boolean,
default: true,
},
//
multiple: { multiple: {
type: Boolean, type: Boolean,
default: false, default: false
}, }
//
mouseMoveSelect: {
type: Boolean,
default: true,
},
}, },
data() { data() {
return { return {
innerSelectedRowKeys: [], innerSelectedRowKeys: [],
innerSelectedRows: [], innerSelectedRows: []
}
},
mounted() {
if (this.canSelect && this.multiple && this.mouseMoveSelect) {
const tbody = this.$el.querySelector('.ant-table-tbody')
tbody.addEventListener('mouseleave', () => {
this.mouseMoveStartIndex = undefined
})
} }
}, },
methods: { methods: {
// / // /
customRow(record, index) { customRow(record) {
const key = record[this.rowKey] const key = record[this.rowKey]
return { return {
class: this.innerSelectedRowKeys.includes(key) ? 'ant-table-row-selected' : '', class: this.innerSelectedRowKeys.includes(key) ? 'ant-table-row-selected' : '',
on: { on: {
click: () => { click: () => {
if (!this.canSelect) { if(!this.canSelect) {
return return
} }
//
if (this.innerSelectedRowKeys.includes(key)) { if (this.innerSelectedRowKeys.includes(key)) {
if (this.multiple || this.canDeselect) { const findIndex = this.innerSelectedRowKeys.findIndex(k => k == key)
const findIndex = this.innerSelectedRowKeys.findIndex((k) => k == key) this.innerSelectedRowKeys.splice(findIndex, 1)
this.innerSelectedRowKeys.splice(findIndex, 1) } else {
} if(this.multiple) {
}
//
else {
if (this.multiple) {
this.innerSelectedRowKeys.push(key) this.innerSelectedRowKeys.push(key)
} else { }
else {
this.innerSelectedRowKeys = [key] 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) { handleTableChange(pagination, filters, sorter) {
this.$emit('change', 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: { watch: {
selectedRowKeys(val) { selectedRowKeys (val) {
this.innerSelectedRowKeys = val this.innerSelectedRowKeys = val
}, },
innerSelectedRowKeys() { innerSelectedRowKeys () {
this.$emit('update:selectedRowKeys', this.innerSelectedRowKeys) this.$emit('update:selectedRowKeys', this.innerSelectedRowKeys)
this.innerSelectedRows = this.innerSelectedRowKeys.map((key) => { 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) this.$emit('update:selectionRows', this.innerSelectedRows)
}, }
}, },
computed: { computed: {
scopedSlotsKeys() { scopedSlotsKeys() {
return Object.keys(this.$scopedSlots) 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> </style>

View File

@ -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>

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="search-form"> <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-row v-if="type == 'single-line'" :gutter="20" style="margin-right: 0 !important;">
<a-col <a-col
class="search-form-item" class="search-form-item"
@ -10,15 +10,12 @@
:style="item.style" :style="item.style"
> >
<a-form-model-item :label="item.label" :prop="item.name" :labelCol="item.labelCol"> <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"> <component :is="item.type" v-bind="item.props" v-model="formModel[item.name]" v-on="item.on"></component>
{{ item.innerLabel }}
</a-checkbox>
<component v-else :is="item.type" v-bind="item.props" v-model="formModel[item.name]" v-on="item.on"></component>
</a-form-model-item> </a-form-model-item>
</a-col> </a-col>
<a-button class="search-btn" type="primary" @click="onSearch"> <a-button class="search-btn" type="primary" @click="onSearch">
<img src="@/assets/images/global/search.png" alt="" /> <img src="@/assets/images/global/search.png" alt="" />
Search {{$t('m.system.search')}}
</a-button> </a-button>
<slot name="additional"></slot> <slot name="additional"></slot>
</a-row> </a-row>
@ -69,15 +66,9 @@ export default {
} }
}, },
watch: { watch: {
value: { value(val) {
handler(val) { this.formModel = val
this.formModel = val
},
deep: true
}, },
// value(val) {
// this.formModel = val
// },
formModel: { formModel: {
handler(val) { handler(val) {
this.$emit('input', val) this.$emit('input', val)
@ -96,7 +87,6 @@ export default {
border-bottom: 1px solid rgba(12, 235, 201, 0.3); border-bottom: 1px solid rgba(12, 235, 201, 0.3);
margin-bottom: 18px; margin-bottom: 18px;
background-color: rgba(12, 235, 201, 0.05); background-color: rgba(12, 235, 201, 0.05);
&-item { &-item {
margin-bottom: 10px; margin-bottom: 10px;
} }

View File

@ -1,33 +1,16 @@
<template> <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 v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio>
</a-radio-group> </a-radio-group>
<a-radio-group <a-radio-group v-else-if="tagType=='radioButton'" buttonStyle="solid" @change="handleInput" :value="getValueSting" :disabled="disabled">
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-button v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio-button>
</a-radio-group> </a-radio-group>
<a-select <a-select v-else-if="tagType=='select'" :getPopupContainer = "getPopupContainer" :placeholder="placeholder" :disabled="disabled" :value="getValueSting" :allowClear="allowClear" @change="handleInput">
v-else-if="tagType == 'select'"
:getPopupContainer="getPopupContainer"
:placeholder="placeholder"
:disabled="disabled"
:value="getValueSting"
:allowClear="allowClear"
show-arrow
:mode="modeType"
:maxTagCount="1"
@change="handleInput"
>
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" /> <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"> <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 }} {{ item.text || item.label }}
</span> </span>
</a-select-option> </a-select-option>
@ -35,98 +18,97 @@
</template> </template>
<script> <script>
import { ajaxGetDictItems, getDictItemsFromCache } from '@/api/api' import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api'
export default { export default {
name: 'JDictSelectTag', name: "JDictSelectTag",
props: { props: {
modeType: String, dictCode: String,
dictCode: String, placeholder: String,
placeholder: String, disabled: Boolean,
disabled: Boolean, value: [String, Number],
value: [String, Number, Array], type: String,
type: String, getPopupContainer:{
getPopupContainer: { type: Function,
type: Function, default: (node) => node.parentNode
default: (node) => node.parentNode, },
allowClear: {
type: Boolean,
default: true
}
}, },
allowClear: { data() {
type: Boolean, return {
default: true, dictOptions: [],
tagType:""
}
}, },
}, watch:{
data() { dictCode:{
return { immediate:true,
dictOptions: [], handler() {
tagType: '', this.initDictData()
} },
}, }
watch: { },
dictCode: { created() {
immediate: true, // console.log(this.dictCode);
handler() { if(!this.type || this.type==="list"){
this.initDictData() 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 ------
}, },
}, },
}, methods: {
created() { initDictData() {
// console.log(this.dictCode); //
if (!this.type || this.type === 'list') { if(getDictItemsFromCache(this.dictCode)){
this.tagType = 'select' this.dictOptions = getDictItemsFromCache(this.dictCode);
} else { return
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
} }
})
}, //Code,
handleInput(e = '') { ajaxGetDictItems(this.dictCode, null).then((res) => {
let val if (res.success) {
if (Object.keys(e).includes('target')) { // console.log(res.result);
val = e.target.value this.dictOptions = res.result;
} else { }
val = e })
},
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) { model:{
this.dictOptions = dictOptions prop: 'value',
}, event: 'change'
getCurrentDictOptions() { }
return this.dictOptions }
},
},
model: {
prop: 'value',
event: 'change',
},
}
</script> </script>
<style scoped> <style scoped>

View File

@ -3,7 +3,7 @@
<a-input :placeholder="placeholder" v-model="editCronValue" :disabled="disabled"> <a-input :placeholder="placeholder" v-model="editCronValue" :disabled="disabled">
<a slot="addonAfter" @click="showConfigDlg" class="config-btn" :disabled="disabled"> <a slot="addonAfter" @click="showConfigDlg" class="config-btn" :disabled="disabled">
<a-icon type="setting"></a-icon> <a-icon type="setting"></a-icon>
Select 选择
</a> </a>
</a-input> </a-input>
<j-modal :visible.sync="show" title="Cron表达式" width="800px"> <j-modal :visible.sync="show" title="Cron表达式" width="800px">
@ -24,44 +24,44 @@ import EasyCron from './EasyCron.vue'
export default { export default {
name: 'input-cron', name: 'input-cron',
components: { EasyCron }, components: {EasyCron},
model: { model: {
prop: 'cronValue', prop: 'cronValue',
event: 'change', event: 'change'
}, },
props: { props: {
cronValue: { cronValue: {
type: String, type: String,
default: '', default: ''
}, },
width: { width: {
type: String, type: String,
default: '800px', default: '800px'
}, },
placeholder: { placeholder: {
type: String, type: String,
default: '请输入cron表达式', default: '请输入cron表达式'
}, },
disabled: { disabled: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
exeStartTime: { exeStartTime: {
type: [Number, String, Object], type: [Number, String, Object],
default: 0, default: 0
}, },
hideSecond: { hideSecond: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
hideYear: { hideYear: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
remote: { remote: {
type: Function, type: Function,
default: null, default: null
}, }
}, },
data() { data() {
return { return {
@ -78,20 +78,22 @@ export default {
}, },
editCronValue(newVal, oldVal) { editCronValue(newVal, oldVal) {
this.$emit('change', newVal) this.$emit('change', newVal)
}, }
}, },
methods: { methods: {
showConfigDlg() { showConfigDlg() {
if (!this.disabled) { if (!this.disabled) {
this.show = true this.show = true
} }
}, }
}, }
} }
</script> </script>
<style scoped> <style scoped>
.config-btn {
cursor: pointer; .config-btn {
} cursor: pointer;
}
</style> </style>

View File

@ -2,11 +2,11 @@
<div> <div>
<a-input-search <a-input-search
v-model="textVals" v-model="textVals"
placeholder="Please select the user first" placeholder="请先选择用户"
readOnly readOnly
unselectable="on" unselectable="on"
@search="onSearchDepUser"> @search="onSearchDepUser">
<a-button slot="enterButton" :disabled="disabled">Select user</a-button> <a-button slot="enterButton" :disabled="disabled">选择用户</a-button>
</a-input-search> </a-input-search>
<j-select-user-by-dep-modal <j-select-user-by-dep-modal
ref="selectModal" ref="selectModal"
@ -120,7 +120,7 @@
this.$refs.selectModal.showModal() this.$refs.selectModal.showModal()
}, },
selectOK(rows) { selectOK(rows) {
console.log("Currently selected user", rows) console.log("当前选中用户", rows)
if (!rows) { if (!rows) {
this.storeVals = '' this.storeVals = ''
this.textVals = '' this.textVals = ''

View File

@ -1,9 +1,10 @@
<template> <template>
<global-layout> <global-layout>
<transition name="page-transition"> <transition name="page-transition">
<keep-alive> <keep-alive v-if="keepAlive">
<router-view /> <router-view />
</keep-alive> </keep-alive>
<router-view v-else />
</transition> </transition>
</global-layout> </global-layout>
</template> </template>
@ -21,6 +22,14 @@
} }
}, },
computed: {
keepAlive () {
return this.$route.meta.keepAlive
}
},
methods: {
},
} }
</script> </script>

View File

@ -1,8 +1,9 @@
<template> <template>
<div class="main"> <div class="main">
<keep-alive> <keep-alive :include="includedComponents">
<router-view /> <router-view v-if="keepAlive" />
</keep-alive> </keep-alive>
<router-view v-if="!keepAlive" />
</div> </div>
</template> </template>

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="custom-top-menu"> <div class="custom-top-menu">
<a-menu mode="horizontal" v-model="selectedKeys" @click="onMenuSelect"> <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 <img
v-show="menu.name === selectedKeys[0]" v-show="menu.name === selectedKeys[0]"
class="menu-logo" class="menu-logo"
@ -15,7 +15,7 @@
alt="" alt=""
/> />
<span v-html="menu.meta.title.split(' ').join('<br>')"></span> <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-item>
</a-menu> </a-menu>
</div> </div>
@ -26,12 +26,12 @@ export default {
props: { props: {
menus: { menus: {
type: Array, type: Array,
default: () => [], default: () => []
}, }
}, },
data() { data() {
return { return {
selectedKeys: [], selectedKeys: []
} }
}, },
created() { created() {
@ -40,24 +40,8 @@ export default {
}, },
methods: { methods: {
onMenuSelect({ key }) { onMenuSelect({ key }) {
const childPath = this.getChildrenPath(this.menuItems.find((menu) => menu.name === key)) const childPath = this.getChildrenPath(this.menuItems.find(menu => menu.name === key))
if (key == 'abnormal-alarm') { this.$router.push(childPath)
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)
}
}, },
getChildrenPath(menuItem) { getChildrenPath(menuItem) {
if (menuItem.children) { if (menuItem.children) {
@ -82,19 +66,19 @@ export default {
} }
} }
} }
}, }
}, },
watch: { watch: {
$route(route) { $route(route) {
const currTopMenu = this.findTopMenuByRouteName(this.menuItems, route.name) const currTopMenu = this.findTopMenuByRouteName(this.menuItems, route.name)
this.selectedKeys = [currTopMenu.name] this.selectedKeys = [currTopMenu.name]
}, }
}, },
computed: { computed: {
menuItems() { menuItems() {
return this.menus.filter((item) => !item.hidden) return this.menus.filter(item => !item.hidden)
}, }
}, }
} }
</script> </script>

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,7 @@
:arrowPointAtCenter="true" :arrowPointAtCenter="true"
overlayClassName="header-notice-wrapper" overlayClassName="header-notice-wrapper"
@visibleChange="handleHoverChange" @visibleChange="handleHoverChange"
:overlayStyle="{ width: '300px', top: '50px' }" :overlayStyle="{ width: '300px', top: '50px' }">
>
<template slot="content"> <template slot="content">
<a-spin :spinning="loadding"> <a-spin :spinning="loadding">
<a-tabs> <a-tabs>
@ -31,21 +30,17 @@
</a-list>--> </a-list>-->
<a-list> <a-list>
<a-list-item :key="index" v-for="(record, index) in announcement1"> <a-list-item :key="index" v-for="(record, index) in announcement1">
<div style="margin-left: 5%; width: 80%"> <div style="margin-left: 5%;width: 80%">
<p> <p><a @click="showAnnouncement(record)">{{ record.titile }}</a></p>
<a @click="showAnnouncement(record)">{{ record.titile }}</a> <p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p>
</p>
<p style="color: #c9f6f6; margin-bottom: 0px">{{ record.createTime }} 发布</p>
</div> </div>
<div style="text-align: right"> <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 === 'L'" color="blue">一般消息</a-tag>
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange" <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange">重要消息</a-tag>
>重要消息</a-tag
>
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'H'" color="red">紧急消息</a-tag> <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'H'" color="red">紧急消息</a-tag>
</div> </div>
</a-list-item> </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> <a-button @click="toMyAnnouncement()" type="dashed" block>查看更多</a-button>
</div> </div>
</a-list> </a-list>
@ -53,21 +48,17 @@
<a-tab-pane :tab="msg2Title" key="2"> <a-tab-pane :tab="msg2Title" key="2">
<a-list> <a-list>
<a-list-item :key="index" v-for="(record, index) in announcement2"> <a-list-item :key="index" v-for="(record, index) in announcement2">
<div style="margin-left: 5%; width: 80%"> <div style="margin-left: 5%;width: 80%">
<p> <p><a @click="showAnnouncement(record)">{{ record.titile }}</a></p>
<a @click="showAnnouncement(record)">{{ record.titile }}</a> <p style="color: rgba(0,0,0,.45);margin-bottom: 0px">{{ record.createTime }} 发布</p>
</p>
<p style="color: #c9f6f6; margin-bottom: 0px">{{ record.createTime }} 发布</p>
</div> </div>
<div style="text-align: right"> <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 === 'L'" color="blue">一般消息</a-tag>
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange" <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'M'" color="orange">重要消息</a-tag>
>重要消息</a-tag
>
<a-tag @click="showAnnouncement(record)" v-if="record.priority === 'H'" color="red">紧急消息</a-tag> <a-tag @click="showAnnouncement(record)" v-if="record.priority === 'H'" color="red">紧急消息</a-tag>
</div> </div>
</a-list-item> </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> <a-button @click="toMyAnnouncement()" type="dashed" block>查看更多</a-button>
</div> </div>
</a-list> </a-list>
@ -77,297 +68,291 @@
</template> </template>
<span @click="fetchNotice" class="header-notice"> <span @click="fetchNotice" class="header-notice">
<a-badge :count="msgTotal"> <a-badge :count="msgTotal">
<img src="@/assets/images/header/notice.png" alt="" /> <img src="@/assets/images/header/notice.png" alt="">
</a-badge> </a-badge>
</span> </span>
<show-announcement ref="ShowAnnouncement" @ok="modalFormOk"></show-announcement> <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> </a-popover>
</template> </template>
<script> <script>
import { getAction, putAction } from '@/api/manage' import { getAction,putAction } from '@/api/manage'
import ShowAnnouncement from './ShowAnnouncement' import ShowAnnouncement from './ShowAnnouncement'
import store from '@/store/' import store from '@/store/'
import DynamicNotice from './DynamicNotice' import DynamicNotice from './DynamicNotice'
import Vue from 'vue' import Vue from 'vue'
import { ACCESS_TOKEN } from '@/store/mutation-types' import { ACCESS_TOKEN } from '@/store/mutation-types'
export default { export default {
name: 'HeaderNotice', name: "HeaderNotice",
components: { components: {
DynamicNotice, DynamicNotice,
ShowAnnouncement, 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)
}, },
}, data () {
mounted() { return {
this.loadData() loadding: false,
//this.timerFun(); url:{
this.initWebSocket() listCementByUser:"/sys/annountCement/listByUser",
// this.heartCheckFun(); editCementSend:"/sys/sysAnnouncementSend/editByAnntIdAndUserId",
}, queryById:"/sys/annountCement/queryById",
destroyed: function () { },
// hovered: false,
this.websocketOnclose() announcement1:[],
}, announcement2:[],
methods: { msg1Count:"0",
timerFun() { msg2Count:"0",
this.stopTimer = false msg1Title:"通知(0)",
let myTimer = setInterval(() => { msg2Title:"",
// stopTimer:false,
if (this.stopTimer == true) { websock: null,
clearInterval(myTimer) 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 return
} }
this.loadData() this.loadding = true
}, 6000) setTimeout(() => {
}, this.loadding = false
loadData() { }, 200)
try { },
// showAnnouncement(record){
getAction(this.url.listCementByUser) putAction(this.url.editCementSend,{anntId:record.id}).then((res)=>{
.then((res) => { if(res.success){
if (res.success) { this.loadData();
this.announcement1 = res.result.anntMsgList }
this.msg1Count = res.result.anntMsgTotal });
this.msg1Title = '通知(' + res.result.anntMsgTotal + ')' this.hovered = false;
this.announcement2 = res.result.sysMsgList if(record.openType==='component'){
this.msg2Count = res.result.sysMsgTotal this.openPath = record.openPage;
this.msg2Title = '系统消息(' + res.result.sysMsgTotal + ')' this.formData = {id:record.busId};
} this.$refs.showDynamNotice.detail(record.openPage);
}) }else{
.catch((error) => { this.$refs.ShowAnnouncement.detail(record);
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.hovered = false toMyAnnouncement(){
if (record.openType === 'component') { this.$router.push({
this.openPath = record.openPage path: '/isps/userAnnouncement'
this.formData = { id: record.busId } });
this.$refs.showDynamNotice.detail(record.openPage) },
} else { modalFormOk(){
this.$refs.ShowAnnouncement.detail(record) },
} handleHoverChange (visible) {
}, this.hovered = visible;
toMyAnnouncement() { },
this.$router.push({
path: '/isystem/userAnnouncement',
})
},
modalFormOk() {},
handleHoverChange(visible) {
this.hovered = visible
},
initWebSocket: function () { initWebSocket: function () {
// WebSocketwshttpwsshttps // WebSocketwshttpwsshttps
var userId = store.getters.userInfo.id var userId = store.getters.userInfo.id;
var url = var url = window._CONFIG['domianURL'].replace("https://","wss://").replace("http://","ws://")+"/websocket/"+userId;
window._CONFIG['domianURL'].replace('https://', 'wss://').replace('http://', 'ws://') + '/websocket/' + userId //console.log(url);
//console.log(url); //update-begin-author:taoyan date:2022-4-22 for: v2.4.6 websocket #3278
//update-begin-author:taoyan date:2022-4-22 for: v2.4.6 websocket #3278 let token = Vue.ls.get(ACCESS_TOKEN)
let token = Vue.ls.get(ACCESS_TOKEN) this.websock = new WebSocket(url, [token]);
this.websock = new WebSocket(url, [token]) //update-end-author:taoyan date:2022-4-22 for: v2.4.6 websocket #3278
//update-end-author:taoyan date:2022-4-22 for: v2.4.6 websocket #3278 this.websock.onopen = this.websocketOnopen;
this.websock.onopen = this.websocketOnopen this.websock.onerror = this.websocketOnerror;
this.websock.onerror = this.websocketOnerror this.websock.onmessage = this.websocketOnmessage;
this.websock.onmessage = this.websocketOnmessage this.websock.onclose = this.websocketOnclose;
this.websock.onclose = this.websocketOnclose },
}, websocketOnopen: function () {
websocketOnopen: function () { console.log("WebSocket连接成功");
console.log('WebSocket连接成功') //
// //this.heartCheck.reset().start();
//this.heartCheck.reset().start(); },
}, websocketOnerror: function (e) {
websocketOnerror: function (e) { console.log("WebSocket连接发生错误第%s次",this.wsConnectErrorTime);
console.log('WebSocket连接发生错误第%s次', this.wsConnectErrorTime)
this.wsConnectErrorTime = this.wsConnectErrorTime + 1 this.wsConnectErrorTime = this.wsConnectErrorTime + 1;
if (this.wsConnectErrorTime > 5) { if(this.wsConnectErrorTime>5){
console.log('WebSocket连接错误超过5次就不再重新连了') console.log("WebSocket连接错误超过5次就不再重新连了");
this.lockReconnect = true this.lockReconnect = true
return return;
} }
this.reconnect() this.reconnect();
}, },
websocketOnmessage: function (e) { websocketOnmessage: function (e) {
console.log('-----接收消息-------', e.data) console.log("-----接收消息-------",e.data);
var data = eval('(' + e.data + ')') // var data = eval("(" + e.data + ")"); //
this.voiceBroadcast(data.msgTxt) this.voiceBroadcast(data.msgTxt)
if (data.cmd == 'topic') { if(data.cmd == "topic"){
// //
this.loadData() this.loadData();
} else if (data.cmd == 'user') { }else if(data.cmd == "user"){
// //
this.loadData() this.loadData();
} }
// //
//this.heartCheck.reset().start(); //this.heartCheck.reset().start();
}, },
websocketOnclose: function (e) { websocketOnclose: function (e) {
console.log('connection closed (' + e + ')') console.log("connection closed (" + e + ")");
if (e) { if(e){
console.log('connection closed (' + e.code + ')') console.log("connection closed (" + e.code + ")");
} }
this.reconnect() this.reconnect();
}, },
websocketSend(text) { websocketSend(text) { //
// try {
try { this.websock.send(text);
this.websock.send(text) } catch (err) {
} catch (err) { console.log("send failed (" + err.code + ")");
console.log('send failed (' + err.code + ')') }
} },
}, //
// voiceBroadcast(text){
voiceBroadcast(text) { var url = "http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&text=" + encodeURI(text); // baidu
var url = 'http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&text=' + encodeURI(text) // baidu var voiceContent = new Audio(url);
var voiceContent = new Audio(url) voiceContent.src = url;
voiceContent.src = url voiceContent.play();
voiceContent.play() },
}, openNotification (data) {
openNotification(data) { var text = data.msgTxt;
var text = data.msgTxt const key = `open${Date.now()}`;
const key = `open${Date.now()}` this.$notification.open({
this.$notification.open({ message: '消息提醒',
message: '消息提醒', placement:'bottomRight',
placement: 'bottomRight', description: text,
description: text, key,
key, btn: (h)=>{
btn: (h) => { return h('a-button', {
return h(
'a-button',
{
props: { props: {
type: 'primary', type: 'primary',
size: 'small', size: 'small',
}, },
on: { on: {
click: () => this.showDetail(key, data), click: () => this.showDetail(key,data)
}, }
}, }, '查看详情')
'查看详情' },
) });
}, },
})
},
reconnect() { reconnect() {
var that = this var that = this;
if (that.lockReconnect) return if(that.lockReconnect) return;
that.lockReconnect = true that.lockReconnect = true;
// //
setTimeout(function () { setTimeout(function () {
console.info('尝试重连...') console.info("尝试重连...");
that.initWebSocket() that.initWebSocket();
that.lockReconnect = false that.lockReconnect = false;
}, 20000) }, 20000);
}, },
heartCheckFun() { heartCheckFun(){
var that = this var that = this;
//,20s //,20s
that.heartCheck = { that.heartCheck = {
timeout: 20000, timeout: 20000,
timeoutObj: null, timeoutObj: null,
serverTimeoutObj: null, serverTimeoutObj: null,
reset: function () { reset: function(){
clearTimeout(this.timeoutObj) clearTimeout(this.timeoutObj);
//clearTimeout(this.serverTimeoutObj); //clearTimeout(this.serverTimeoutObj);
return this return this;
}, },
start: function () { start: function(){
var self = this var self = this;
this.timeoutObj = setTimeout(function () { this.timeoutObj = setTimeout(function(){
// //
//onmessage //onmessage
that.websocketSend('HeartBeat') that.websocketSend("HeartBeat");
console.info('客户端发送心跳') console.info("客户端发送心跳");
//self.serverTimeoutObj = setTimeout(function(){// //self.serverTimeoutObj = setTimeout(function(){//
// that.websock.close();//onclosereconnectws.close().reconnect onclose // that.websock.close();//onclosereconnectws.close().reconnect onclose
//}, self.timeout) //}, self.timeout)
}, this.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)
} }
}) },
},
},
} 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> </script>
<style lang="css"> <style lang="css">
.header-notice-wrapper { .header-notice-wrapper {
top: 50px !important; top: 50px !important;
} }
</style> </style>
<style lang="less" scoped> <style lang="less" scoped>
.header-notice { .header-notice{
display: inline-block; display: inline-block;
transition: all 0.3s; transition: all 0.3s;
span { span {
vertical-align: initial; vertical-align: initial;
}
} }
}
</style> </style>

View File

@ -4,19 +4,18 @@ import xss from "xss"
:title="title" :title="title"
:width="modelStyle.width" :width="modelStyle.width"
:visible="visible" :visible="visible"
:bodyStyle="bodyStyle" :bodyStyle ="bodyStyle"
:switchFullscreen="switchFullscreen" :switchFullscreen="switchFullscreen"
@cancel="handleCancel" @cancel="handleCancel"
> >
<template slot="footer"> <template slot="footer">
<a-button key="back" @click="handleCancel">Cancel</a-button> <a-button key="back" @click="handleCancel">关闭</a-button>
<a-button v-if="record.openType === 'url'" type="primary" @click="toHandle">去处理</a-button> <a-button v-if="record.openType==='url'" type="primary" @click="toHandle">去处理</a-button>
</template> </template>
<a-card class="daily-article" :loading="loading"> <a-card class="daily-article" :loading="loading">
<a-card-meta <a-card-meta
:title="record.titile" :title="record.titile"
:description="'Sender' + record.sender + ' Send Time ' + record.sendTime" :description="'发布人:'+record.sender + ' 发布时间: ' + record.sendTime">
>
</a-card-meta> </a-card-meta>
<a-divider /> <a-divider />
<span v-html="record.msgContent" class="article-content"></span> <span v-html="record.msgContent" class="article-content"></span>
@ -25,141 +24,133 @@ import xss from "xss"
</template> </template>
<script> <script>
import { getUserList } from '@/api/api' import {getUserList} from '@/api/api'
import xss from 'xss' import xss from 'xss'
export default { export default {
name: 'SysAnnouncementModal', name: "SysAnnouncementModal",
components: {}, components: {
data() { },
return { data () {
title: 'Notification Message', return {
record: {}, title:"通知消息",
labelCol: { record: {},
xs: { span: 24 }, labelCol: {
sm: { span: 5 }, 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: { handleCancel () {
xs: { span: 24 }, this.visible = false;
sm: { span: 16 },
}, },
visible: false, /** 切换全屏显示 */
switchFullscreen: true, handleClickToggleFullScreen() {
loading: false, let mode = !this.modelStyle.fullScreen
bodyStyle: { if (mode) {
padding: '0', this.modelStyle.width = '100%'
height: window.innerHeight * 0.8 + 'px', this.modelStyle.style.top = '20px'
'overflow-y': 'auto', } else {
this.modelStyle.width = '60%'
this.modelStyle.style.top = '50px'
}
this.modelStyle.fullScreen = mode
}, },
modelStyle: { toHandle(){
width: '60%', if(this.record.openType==='url'){
style: { top: '20px' }, this.visible = false;
fullScreen: 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> </script>
<style lang="less"> <style lang="less">
.announcementCustomModal { .announcementCustomModal{
.ant-modal-header { .ant-modal-header {
border: none; border: none;
display: inline-block; display: inline-block;
position: absolute; position: absolute;
z-index: 1; z-index: 1;
right: 56px; right: 56px;
padding: 0; padding: 0;
.ant-modal-title { .ant-modal-title{
.custom-btn { .custom-btn{
width: 56px; width: 56px;
height: 56px; height: 56px;
border: none; border: none;
box-shadow: 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> </style>

View File

@ -1,12 +1,18 @@
<template> <template>
<div class="user-wrapper" :class="theme"> <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> <a-dropdown>
<span class="action action-full ant-dropdown-link user-dropdown-menu"> <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> </span>
<a-menu slot="overlay" class="user-dropdown-menu-wrapper"> <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' }"> <router-link :to="{ name: 'account-center' }">
<a-icon type="user"/> <a-icon type="user"/>
<span>个人中心</span> <span>个人中心</span>
@ -21,29 +27,24 @@
<a-menu-item key="3" @click="systemSetting"> <a-menu-item key="3" @click="systemSetting">
<a-icon type="tool"/> <a-icon type="tool"/>
<span>系统设置</span> <span>系统设置</span>
</a-menu-item> -->
<a-menu-item key="3">
<a-icon type="user" />
<span>{{ this.userInfo().username }}</span>
</a-menu-item> </a-menu-item>
<a-menu-divider />
<a-menu-item key="4" @click="updatePassword"> <a-menu-item key="4" @click="updatePassword">
<a-icon type="setting" /> <a-icon type="setting"/>
<span>Change Password</span> <span>密码修改</span>
</a-menu-item> </a-menu-item>
<!-- <a-menu-item key="5" @click="updateCurrentDepart"> <a-menu-item key="5" @click="updateCurrentDepart">
<a-icon type="cluster"/> <a-icon type="cluster"/>
<span>切换部门</span> <span>切换部门</span>
</a-menu-item> </a-menu-item>
<a-menu-item key="6" @click="clearCache"> <a-menu-item key="6" @click="clearCache">
<a-icon type="sync"/> <a-icon type="sync"/>
<span>清理缓存</span> <span>清理缓存</span>
</a-menu-item> --> </a-menu-item>
</a-menu> </a-menu>
</a-dropdown> </a-dropdown>
<span class="action"> <span class="action">
<a class="logout_title" href="javascript:;" @click="handleLogout"> <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> </a>
</span> </span>
<user-password ref="userPassword"></user-password> <user-password ref="userPassword"></user-password>
@ -53,205 +54,221 @@
</template> </template>
<script> <script>
import HeaderNotice from './HeaderNotice' import HeaderNotice from './HeaderNotice'
import UserPassword from './UserPassword' import UserPassword from './UserPassword'
import SettingDrawer from '@/components/setting/SettingDrawer' import SettingDrawer from "@/components/setting/SettingDrawer";
import DepartSelect from './DepartSelect' import DepartSelect from './DepartSelect'
import { mapActions, mapGetters, mapState } from 'vuex' import { mapActions, mapGetters,mapState } from 'vuex'
import { mixinDevice } from '@/utils/mixin.js' import { mixinDevice } from '@/utils/mixin.js'
import { getFileAccessHttpUrl, getAction } from '@/api/manage' import { getFileAccessHttpUrl,getAction } from "@/api/manage"
import Vue from 'vue' import Vue from 'vue'
import { UI_CACHE_DB_DICT_DATA } from '@/store/mutation-types' import { UI_CACHE_DB_DICT_DATA } from "@/store/mutation-types"
import i18nMixin from '@/store/i18n-mixin'
export default { export default {
name: 'UserMenu', name: "UserMenu",
mixins: [mixinDevice], mixins: [mixinDevice,i18nMixin],
data() { data(){
return { return {
// update-begin author:sunjianlei date:20200219 for: -------------- langIcon_zh:require('@/assets/images/header/zh.png'),
searchMenuOptions: [], langIcon_en:require('@/assets/images/header/en.png'),
searchMenuComp: 'span', // update-begin author:sunjianlei date:20200219 for: --------------
searchMenuVisible: false, searchMenuOptions:[],
// update-begin author:sunjianlei date:20200219 for: -------------- searchMenuComp: 'span',
} searchMenuVisible: false,
}, // update-begin author:sunjianlei date:20200219 for: --------------
components: { }
HeaderNotice, },
UserPassword, components: {
DepartSelect, HeaderNotice,
SettingDrawer, UserPassword,
}, DepartSelect,
props: { SettingDrawer
theme: { },
type: String, props: {
required: false, theme: {
default: 'dark', 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()
} }
}
},
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: 做头部菜单栏导航*/ /* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
showClick() { created() {
this.searchMenuVisible = true let lists = []
this.searchMenus(lists,this.permissionMenuList)
this.searchMenuOptions = [...lists]
}, },
hiddenClick() { mounted() {
this.shows = false 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: 做头部菜单栏导航*/ /* update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
...mapActions(['Logout']), watch: {
...mapGetters(['nickname', 'avatar', 'userInfo']), // update-begin author:sunjianlei date:20200219 for:
getAvatar() { device: {
return getFileAccessHttpUrl(this.avatar()) immediate: true,
}, handler() {
handleLogout() { this.searchMenuVisible = false
const that = this this.searchMenuComp = this.isMobile() ? 'a-modal' : 'span'
this.$confirm({
title: 'Prompt',
content: 'Ensure Log Out?',
cancelButtonProps: {
props: {
type: 'warn',
},
}, },
onOk() { },
return that // update-end author:sunjianlei date:20200219 for:
.Logout({}) },
.then(() => { 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退 // update-begin author:scott date:20211223 for:JTC-198退
//that.$router.push({ path: '/user/login' }); //that.$router.push({ path: '/user/login' });
window.location.reload() window.location.reload()
// update-end author:scott date:20211223 for:JTC-198退 // update-end author:scott date:20211223 for:JTC-198退
}) }).catch(err => {
.catch((err) => {
that.$message.error({ that.$message.error({
title: 'Error', title: 'Error',
description: err.message, description: err.message
}) })
}) })
}, },
onCancel() {}, onCancel() {
}) },
}, });
updatePassword() { },
let username = this.userInfo().username updatePassword(){
this.$refs.userPassword.show(username) let username = this.userInfo().username
}, this.$refs.userPassword.show(username)
updateCurrentDepart() { },
this.$refs.departSelect.show() updateCurrentDepart(){
}, this.$refs.departSelect.show()
systemSetting() { },
this.$refs.settingDrawer.showDrawer() systemSetting(){
}, this.$refs.settingDrawer.showDrawer()
/* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/ },
searchMenus(arr, menus) { /* update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
for (let i of menus) { searchMenus(arr,menus){
if (!i.hidden && 'layouts/RouteView' !== i.component) { for(let i of menus){
arr.push(i) 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-702Token
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-702Token
}, this.searchMenuVisible = false
filterOption(input, option) { },
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0 // update_end author:sunjianlei date:20191230 for:
}, /*update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
// update_begin author:sunjianlei date:20191230 for: /*update_begin author:liushaoqian date:20200507 for: 刷新缓存*/
searchMethods(value) { clearCache(){
let route = this.searchMenuOptions.filter((item) => item.id === value)[0] getAction("sys/dict/refleshCache").then((res) => {
//update-begin-author:sunjianlei date:20220111 for: JTC-702Token
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-702Token
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) { if (res.success) {
// //
getAction('sys/dict/queryAllDictItems').then((res) => { getAction("sys/dict/queryAllDictItems").then((res) => {
if (res.success) { if (res.success) {
Vue.ls.remove(UI_CACHE_DB_DICT_DATA) Vue.ls.remove(UI_CACHE_DB_DICT_DATA)
Vue.ls.set(UI_CACHE_DB_DICT_DATA, res.result, 7 * 24 * 60 * 60 * 1000) 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('刷新缓存失败!') /*update_end author:liushaoqian date:20200507 for: 刷新缓存*/
console.log('刷新失败', e) }
}) }
},
/*update_end author:liushaoqian date:20200507 for: 刷新缓存*/
},
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
/* update_begin author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/ /* update_begin author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
/* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */ /* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
.user-wrapper .search-input { .user-wrapper .search-input {
width: 180px; width: 180px;
color: inherit; color: inherit;
/deep/ .ant-select-selection { /deep/ .ant-select-selection {
background-color: inherit; background-color: inherit;
border: 0; border: 0;
border-bottom: 1px solid white; border-bottom: 1px solid white;
&__placeholder, &__placeholder, &__field__placeholder {
&__field__placeholder { color: inherit;
color: inherit; }
} }
} }
} .language{
/* update-end author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */ display: inline-block;
/* update_end author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/ 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>
<style scoped> <style scoped>
.logout_title { .logout_title {
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
} }
</style> </style>

View File

@ -6,164 +6,152 @@
:confirmLoading="confirmLoading" :confirmLoading="confirmLoading"
@ok="handleOk" @ok="handleOk"
@cancel="handleCancel" @cancel="handleCancel"
cancelText="Cancel" cancelText="关闭"
> >
<a-spin :spinning="confirmLoading"> <a-spin :spinning="confirmLoading">
<a-form :form="form"> <a-form :form="form">
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="Old Password">
<a-input <a-form-item
type="password" :labelCol="labelCol"
placeholder="Please enter your old password" :wrapperCol="wrapperCol"
v-decorator="['oldpassword', validatorRules.oldpassword]" label="旧密码">
/> <a-input type="password" placeholder="请输入旧密码" v-decorator="[ 'oldpassword', validatorRules.oldpassword]" />
</a-form-item> </a-form-item>
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="New Password"> <a-form-item
<a-input :labelCol="labelCol"
type="password" :wrapperCol="wrapperCol"
placeholder="Please enter your new password" label="新密码">
v-decorator="['password', validatorRules.password]" <a-input type="password" placeholder="请输入新密码" v-decorator="[ 'password', validatorRules.password]" />
/>
</a-form-item> </a-form-item>
<a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="Confirm New Password"> <a-form-item
<a-input :labelCol="labelCol"
type="password" :wrapperCol="wrapperCol"
@blur="handleConfirmBlur" label="确认新密码">
placeholder="Please enter your new password" <a-input type="password" @blur="handleConfirmBlur" placeholder="请确认新密码" v-decorator="[ 'confirmpassword', validatorRules.confirmpassword]"/>
v-decorator="['confirmpassword', validatorRules.confirmpassword]"
/>
</a-form-item> </a-form-item>
</a-form> </a-form>
</a-spin> </a-spin>
</a-modal> </a-modal>
</template> </template>
<script> <script>
import { putAction } from '@/api/manage'
export default { import { putAction } from '@/api/manage'
name: 'UserPassword',
data() { export default {
return { name: "UserPassword",
title: 'Change Password', data () {
modalWidth: 800, return {
visible: false, title:"修改密码",
confirmLoading: false, modalWidth:800,
validatorRules: { visible: false,
oldpassword: { confirmLoading: false,
rules: [ validatorRules:{
{ oldpassword:{
required: true, rules: [{
message: '请输入旧密码!', required: true, message: '请输入旧密码!',
}, }],
], },
}, password:{
password: { rules: [{
rules: [ required: true, message: '请输入新密码!',
{ }, {
required: true,
message: '请输入新密码!',
},
{
validator: this.validateToNextPassword, validator: this.validateToNextPassword,
}, }],
], },
}, confirmpassword:{
confirmpassword: { rules: [{
rules: [ required: true, message: '请确认新密码!',
{ }, {
required: true,
message: '请确认新密码!',
},
{
validator: this.compareToFirstPassword, 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), form:this.$form.createForm(this),
url: 'sys/user/updatePassword', url: "sys/user/updatePassword",
username: '', username:"",
}
},
methods: {
show(uname) {
if (!uname) {
this.$message.warning('当前系统无登录用户!')
return
} else {
this.username = uname
this.form.resetFields()
this.visible = true
} }
}, },
handleCancel() { methods: {
this.close() show(uname){
}, if(!uname){
close() { this.$message.warning("当前系统无登录用户!");
this.$emit('close') return
this.visible = false }else{
this.disableSubmit = false this.username = uname
this.selectedRole = [] this.form.resetFields();
}, this.visible = true;
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
})
} }
}) },
}, handleCancel () {
validateToNextPassword(rule, value, callback) { this.close()
const form = this.form },
if (value && this.confirmDirty) { close () {
form.validateFields(['confirm'], { force: true }) 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> </script>
<style scoped> <style scoped>
</style> </style>

View File

@ -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' import Login from '@/views/user/Login'
/** /**
@ -10,7 +10,7 @@ export const asyncRouterMap = [
{ {
path: '/', path: '/',
name: 'dashboard', name: 'dashboard',
component: BasicLayout, component: TabLayout,
meta: { title: '首页' }, meta: { title: '首页' },
redirect: '/station-operation', redirect: '/station-operation',
children: [ children: [

15
src/locales/index.js Normal file
View 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
View 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
View File

@ -0,0 +1,15 @@
export const m = {
common: {
search: "搜索",
},
system: {
user: "用户",
name: "名称",
role: "角色",
search: "搜索",
add: "添加",
edit: "编辑",
delete: "删除",
num: "序号"
}
}

View File

@ -7,6 +7,7 @@ import Storage from 'vue-ls'
import router from './router' import router from './router'
import store from './store/' import store from './store/'
import { VueAxios } from "@/utils/request" import { VueAxios } from "@/utils/request"
import i18n from './locales'
require('@jeecg/antd-online-mini') require('@jeecg/antd-online-mini')
require('@jeecg/antd-online-mini/dist/OnlineForm.css') require('@jeecg/antd-online-mini/dist/OnlineForm.css')
@ -52,7 +53,6 @@ import { rules } from '@/utils/rules'
import SearchForm from '@/components/SearchForm' import SearchForm from '@/components/SearchForm'
import CustomSelect from '@/components/CustomSelect' import CustomSelect from '@/components/CustomSelect'
import CustomAllSelect from '@/components/CustomAllSelect'
import CustomTable from '@/components/CustomTable' import CustomTable from '@/components/CustomTable'
import CustomModal from '@/components/CustomModal' import CustomModal from '@/components/CustomModal'
import CustomDatePicker from '@/components/CustomDatePicker' import CustomDatePicker from '@/components/CustomDatePicker'
@ -83,7 +83,6 @@ Vue.use(JeecgComponents);
Vue.use(VueAreaLinkage); Vue.use(VueAreaLinkage);
Vue.component('search-form', SearchForm) Vue.component('search-form', SearchForm)
Vue.component('custom-select', CustomSelect) Vue.component('custom-select', CustomSelect)
Vue.component('custom-all-select', CustomAllSelect)
Vue.component('custom-table', CustomTable) Vue.component('custom-table', CustomTable)
Vue.component('custom-modal', CustomModal) Vue.component('custom-modal', CustomModal)
Vue.component('custom-date-picker', CustomDatePicker) Vue.component('custom-date-picker', CustomDatePicker)
@ -97,6 +96,7 @@ function main() {
new Vue({ new Vue({
router, router,
store, store,
i18n,
mounted () { mounted () {
store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true)) store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true))
store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme)) store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme))

View File

@ -4,20 +4,20 @@
* data中url定义 list为查询列表 delete为删除单条记录 deleteBatch为批量删除 * data中url定义 list为查询列表 delete为删除单条记录 deleteBatch为批量删除
*/ */
import { filterObj } from '@/utils/util'; 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 Vue from 'vue'
import { ACCESS_TOKEN, TENANT_ID } from "@/store/mutation-types" import { ACCESS_TOKEN, TENANT_ID } from "@/store/mutation-types"
import store from '@/store' import store from '@/store'
export const JeecgListMixin = { export const JeecgListMixin = {
data() { data(){
return { return {
/* 查询条件-请不要在queryParam中声明非字符串值的属性 */ /* 查询条件-请不要在queryParam中声明非字符串值的属性 */
queryParam: {}, queryParam: {},
/* 数据源 */ /* 数据源 */
dataSource: [], dataSource:[],
/* 分页参数 */ /* 分页参数 */
ipagination: { ipagination:{
current: 1, current: 1,
pageSize: 10, pageSize: 10,
pageSizeOptions: ['10', '20', '30'], pageSizeOptions: ['10', '20', '30'],
@ -30,22 +30,22 @@ export const JeecgListMixin = {
total: 0 total: 0
}, },
/* 排序参数 */ /* 排序参数 */
isorter: { isorter:{
column: 'createTime', column: 'createTime',
order: 'desc', order: 'desc',
}, },
/* 筛选参数 */ /* 筛选参数 */
filters: {}, filters: {},
/* table加载状态 */ /* table加载状态 */
loading: false, loading:false,
/* table选中keys*/ /* table选中keys*/
selectedRowKeys: [], selectedRowKeys: [],
/* table选中records*/ /* table选中records*/
selectionRows: [], selectionRows: [],
/* 查询折叠 */ /* 查询折叠 */
toggleSearchStatus: false, toggleSearchStatus:false,
/* 高级查询条件生效状态 */ /* 高级查询条件生效状态 */
superQueryFlag: false, superQueryFlag:false,
/* 高级查询条件 */ /* 高级查询条件 */
superQueryParams: '', superQueryParams: '',
/** 高级查询拼接方式 */ /** 高级查询拼接方式 */
@ -53,27 +53,27 @@ export const JeecgListMixin = {
} }
}, },
created() { created() {
if (!this.disableMixinCreated) { if(!this.disableMixinCreated){
console.log(' -- mixin created -- ') console.log(' -- mixin created -- ')
this.loadData(); this.loadData();
//初始化字典配置 在自己页面定义 //初始化字典配置 在自己页面定义
this.initDictConfig(); this.initDictConfig();
} }
}, },
computed: { computed: {
//token header //token header
tokenHeader() { tokenHeader(){
let head = { 'X-Access-Token': Vue.ls.get(ACCESS_TOKEN) } let head = {'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)}
let tenantid = Vue.ls.get(TENANT_ID) let tenantid = Vue.ls.get(TENANT_ID)
if (tenantid) { if(tenantid){
head['tenant-id'] = tenantid head['tenant-id'] = tenantid
} }
return head; return head;
} }
}, },
methods: { methods:{
loadData(arg) { loadData(arg) {
if (!this.url.list) { if(!this.url.list){
this.$message.error("请设置url.list属性!") this.$message.error("请设置url.list属性!")
return return
} }
@ -82,51 +82,51 @@ export const JeecgListMixin = {
this.ipagination.current = 1; this.ipagination.current = 1;
} }
this.onClearSelected() this.onClearSelected()
var params = this.getQueryParams();//查询条件 var params = this.getQueryParams();//查询条件
this.loading = true; this.loading = true;
getAction(this.url.list, params).then((res) => { getAction(this.url.list, params).then((res) => {
if (res.success) { if (res.success) {
//update-begin---author:zhangyafei Date:20201118 for适配不分页的数据列表------------ //update-begin---author:zhangyafei Date:20201118 for适配不分页的数据列表------------
this.dataSource = res.result.records || res.result; this.dataSource = res.result.records||res.result;
if (res.result.total) { if(res.result.total)
{
this.ipagination.total = res.result.total; this.ipagination.total = res.result.total;
} else { }else{
this.ipagination.total = 0; this.ipagination.total = 0;
} }
//update-end---author:zhangyafei Date:20201118 for适配不分页的数据列表------------ //update-end---author:zhangyafei Date:20201118 for适配不分页的数据列表------------
} else { }else{
this.$message.warning(res.message) this.$message.warning(res.message)
} }
}).finally(() => { }).finally(() => {
this.loading = false this.loading = false
}) })
}, },
initDictConfig() { initDictConfig(){
console.log("--这是一个假的方法!") console.log("--这是一个假的方法!")
}, },
handleSuperQuery(params, matchType) { handleSuperQuery(params, matchType) {
//高级查询方法 //高级查询方法
if (!params) { if(!params){
this.superQueryParams = '' this.superQueryParams=''
this.superQueryFlag = false this.superQueryFlag = false
} else { }else{
this.superQueryFlag = true this.superQueryFlag = true
this.superQueryParams = JSON.stringify(params) this.superQueryParams=JSON.stringify(params)
this.superQueryMatchType = matchType this.superQueryMatchType = matchType
} }
this.loadData(1) this.loadData(1)
}, },
getQueryParams() { getQueryParams() {
//获取查询条件 //获取查询条件
console.log("this.queryParamthis.queryParam", this.queryParam);
let sqp = {} let sqp = {}
if (this.superQueryParams) { if(this.superQueryParams){
sqp['superQueryParams'] = encodeURI(this.superQueryParams) sqp['superQueryParams']=encodeURI(this.superQueryParams)
sqp['superQueryMatchType'] = this.superQueryMatchType sqp['superQueryMatchType'] = this.superQueryMatchType
} }
var param = Object.assign(sqp, this.queryParam, this.isorter, this.filters); var param = Object.assign(sqp, this.queryParam, this.isorter ,this.filters);
// param.field = this.getQueryField(); param.field = this.getQueryField();
param.field = this.isorter.column;
param.pageNo = this.ipagination.current; param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize; param.pageSize = this.ipagination.pageSize;
return filterObj(param); return filterObj(param);
@ -163,7 +163,7 @@ export const JeecgListMixin = {
this.loadData(1); this.loadData(1);
}, },
batchDel: function () { batchDel: function () {
if (!this.url.deleteBatch) { if(!this.url.deleteBatch){
this.$message.error("请设置url.deleteBatch属性!") this.$message.error("请设置url.deleteBatch属性!")
return return
} }
@ -181,7 +181,7 @@ export const JeecgListMixin = {
content: "Do You Want To Delete This Item?", content: "Do You Want To Delete This Item?",
onOk: function () { onOk: function () {
that.loading = true; that.loading = true;
deleteAction(that.url.deleteBatch, { ids: ids }).then((res) => { deleteAction(that.url.deleteBatch, {ids: ids}).then((res) => {
if (res.success) { if (res.success) {
//重新计算分页问题 //重新计算分页问题
that.reCalculatePage(that.selectedRowKeys.length) that.reCalculatePage(that.selectedRowKeys.length)
@ -199,12 +199,12 @@ export const JeecgListMixin = {
} }
}, },
handleDelete: function (id, propertyName) { handleDelete: function (id, propertyName) {
if (!this.url.delete) { if(!this.url.delete){
this.$message.error("请设置url.delete属性!") this.$message.error("请设置url.delete属性!")
return return
} }
var that = this; var that = this;
deleteAction(that.url.delete, { [propertyName || 'id']: id }).then((res) => { deleteAction(that.url.delete, {[propertyName || 'id']: id}).then((res) => {
if (res.success) { if (res.success) {
//重新计算分页问题 //重新计算分页问题
that.reCalculatePage(1) that.reCalculatePage(1)
@ -215,16 +215,16 @@ export const JeecgListMixin = {
} }
}); });
}, },
reCalculatePage(count) { reCalculatePage(count){
//总数量-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) { if(currentIndex<this.ipagination.current){
this.ipagination.current = currentIndex; this.ipagination.current=currentIndex;
} }
console.log('currentIndex', currentIndex) console.log('currentIndex',currentIndex)
}, },
handleEdit: function (record) { handleEdit: function (record) {
this.$refs.modalForm.edit(record); this.$refs.modalForm.edit(record);
@ -237,7 +237,6 @@ export const JeecgListMixin = {
this.$refs.modalForm.disableSubmit = false; this.$refs.modalForm.disableSubmit = false;
}, },
handleTableChange(pagination, filters, sorter) { handleTableChange(pagination, filters, sorter) {
console.log("sortersorter", sorter);
//分页、排序、筛选变化时触发 //分页、排序、筛选变化时触发
//TODO 筛选 //TODO 筛选
console.log(pagination) console.log(pagination)
@ -248,11 +247,11 @@ export const JeecgListMixin = {
this.ipagination = pagination; this.ipagination = pagination;
this.loadData(); this.loadData();
}, },
handleToggleSearch() { handleToggleSearch(){
this.toggleSearchStatus = !this.toggleSearchStatus; this.toggleSearchStatus = !this.toggleSearchStatus;
}, },
// 给popup查询使用(查询区域不支持回填多个字段,限制只返回一个字段) // 给popup查询使用(查询区域不支持回填多个字段,限制只返回一个字段)
getPopupField(fields) { getPopupField(fields){
return fields.split(',')[0] return fields.split(',')[0]
}, },
modalFormOk() { modalFormOk() {
@ -261,39 +260,39 @@ export const JeecgListMixin = {
//清空列表选中 //清空列表选中
this.onClearSelected() this.onClearSelected()
}, },
handleDetail: function (record) { handleDetail:function(record){
this.$refs.modalForm.edit(record); this.$refs.modalForm.edit(record);
this.$refs.modalForm.title = "Detail"; this.$refs.modalForm.title="Detail";
this.$refs.modalForm.disableSubmit = true; this.$refs.modalForm.disableSubmit = true;
}, },
/* 导出 */ /* 导出 */
handleExportXls2() { handleExportXls2(){
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams())); let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
let url = `${window._CONFIG['domianURL']}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`; let url = `${window._CONFIG['domianURL']}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`;
window.location.href = url; window.location.href = url;
}, },
handleExportXls(fileName) { handleExportXls(fileName){
if (!fileName || typeof fileName != "string") { if(!fileName || typeof fileName != "string"){
fileName = "导出文件" fileName = "导出文件"
} }
let param = this.getQueryParams(); let param = this.getQueryParams();
if (this.selectedRowKeys && this.selectedRowKeys.length > 0) { if(this.selectedRowKeys && this.selectedRowKeys.length>0){
param['selections'] = this.selectedRowKeys.join(",") param['selections'] = this.selectedRowKeys.join(",")
} }
console.log("导出参数", param) console.log("导出参数",param)
downFile(this.url.exportXlsUrl, param).then((data) => { downFile(this.url.exportXlsUrl,param).then((data)=>{
if (!data) { if (!data) {
this.$message.warning("文件下载失败") this.$message.warning("文件下载失败")
return return
} }
if (typeof window.navigator.msSaveBlob !== 'undefined') { if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data], { type: 'application/vnd.ms-excel' }), fileName + '.xls') window.navigator.msSaveBlob(new Blob([data],{type: 'application/vnd.ms-excel'}), fileName+'.xls')
} else { }else{
let url = window.URL.createObjectURL(new Blob([data], { type: 'application/vnd.ms-excel' })) let url = window.URL.createObjectURL(new Blob([data],{type: 'application/vnd.ms-excel'}))
let link = document.createElement('a') let link = document.createElement('a')
link.style.display = 'none' link.style.display = 'none'
link.href = url link.href = url
link.setAttribute('download', fileName + '.xls') link.setAttribute('download', fileName+'.xls')
document.body.appendChild(link) document.body.appendChild(link)
link.click() link.click()
document.body.removeChild(link); //下载完成移除元素 document.body.removeChild(link); //下载完成移除元素
@ -302,7 +301,7 @@ export const JeecgListMixin = {
}) })
}, },
/* 导入 */ /* 导入 */
handleImportExcel(info) { handleImportExcel(info){
this.loading = true; this.loading = true;
if (info.file.status !== 'uploading') { if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList); console.log(info.file, info.fileList);
@ -317,9 +316,9 @@ export const JeecgListMixin = {
this.$warning({ this.$warning({
title: message, title: message,
content: (<div> content: (<div>
<span>{msg}</span><br /> <span>{msg}</span><br/>
<span>具体详情请 <a href={href} target="_blank" download={fileName}>点击下载</a> </span> <span>具体详情请 <a href={href} target="_blank" download={fileName}>点击下载</a> </span>
</div> </div>
) )
}) })
} else { } else {
@ -354,21 +353,21 @@ export const JeecgListMixin = {
} }
}, },
/* 图片预览 */ /* 图片预览 */
getImgView(text) { getImgView(text){
if (text && text.indexOf(",") > 0) { if(text && text.indexOf(",")>0){
text = text.substring(0, text.indexOf(",")) text = text.substring(0,text.indexOf(","))
} }
return getFileAccessHttpUrl(text) return getFileAccessHttpUrl(text)
}, },
/* 文件下载 */ /* 文件下载 */
// update--autor:lvdandan-----date:20200630------for修改下载文件方法名uploadFile改为downloadFile------ // update--autor:lvdandan-----date:20200630------for修改下载文件方法名uploadFile改为downloadFile------
downloadFile(text) { downloadFile(text){
if (!text) { if(!text){
this.$message.warning("未知的文件") this.$message.warning("未知的文件")
return; return;
} }
if (text.indexOf(",") > 0) { if(text.indexOf(",")>0){
text = text.substring(0, text.indexOf(",")) text = text.substring(0,text.indexOf(","))
} }
let url = getFileAccessHttpUrl(text) let url = getFileAccessHttpUrl(text)
window.open(url); window.open(url);

View File

@ -1,29 +1,17 @@
export default { export default {
props: { props: {
value: { value: {
type: Boolean type: Boolean
} }
}, },
data() { computed: {
return { visible: {
isLoading: false get() {
} return this.value
}, },
set(val) {
methods: { this.$emit('input', val)
beforeModalOpen() {} }
},
computed: {
visible: {
get() {
return this.value
},
set(val) {
if (val && this.beforeModalOpen && typeof this.beforeModalOpen == 'function') {
this.beforeModalOpen()
} }
this.$emit('input', val)
}
} }
} }
}

16
src/store/i18n-mixin.js Normal file
View 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

View File

@ -21,6 +21,7 @@ const app = {
device: 'desktop', device: 'desktop',
theme: '', theme: '',
layout: '', layout: '',
lang: 'zh-CN',
contentWidth: '', contentWidth: '',
fixedHeader: false, fixedHeader: false,
fixSiderbar: false, fixSiderbar: false,
@ -78,9 +79,19 @@ const app = {
SET_MULTI_PAGE (state, multipageFlag) { SET_MULTI_PAGE (state, multipageFlag) {
Vue.ls.set(DEFAULT_MULTI_PAGE, multipageFlag) Vue.ls.set(DEFAULT_MULTI_PAGE, multipageFlag)
state.multipage = multipageFlag state.multipage = multipageFlag
},
APP_LANGUAGE: (state, lang, antd = {}) => {
state.lang = lang
state._antLocale = antd
Vue.ls.set("APP_LANGUAGE", lang)
} }
}, },
actions: { actions: {
setLang ({ commit }, lang) {
// return new Promise((resolve, reject) => {
commit('APP_LANGUAGE', lang)
// })
},
setSidebar: ({ commit }, type) => { setSidebar: ({ commit }, type) => {
commit('SET_SIDEBAR_TYPE', type) commit('SET_SIDEBAR_TYPE', type)
}, },

View File

@ -18,17 +18,18 @@
@modal-footer-border-color-split: @formInputBorderColor; @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); @background-color-base: darken(@primary-color, 20);
@border-color-base: darken(@primary-color, 20); @border-color-base: darken(@primary-color, 20);
@text-color: #fff; @text-color: #fff;
@component-background: @modalBg; .ant-btn:hover,
@heading-color: #fff; .ant-btn:active,
.ant-btn:focus {
@input-bg: @formInputBgColor; color: #fff !important;
@input-border-color: @formInputBorderColor; border-color: transparent;
}
@font-face { @font-face {
font-family: MicrogrammaD-MediExte; 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 { .ant-table {
color: #ade6ee; color: #ade6ee;
font-size: 16px; font-size: 16px;
border: 1px solid rgba(65, 111, 127, 0.5); border: 1px solid rgba(65,111,127, .5);
&-header {
background: #126b82 !important;
box-sizing: border-box !important;
table {
width: calc(100% + 11px) !important;
}
}
&-thead { &-thead {
> tr { > tr {
th { th {
background-color: #126b82 !important; background-color: #126b82 !important;
color: #fff; color: #fff;
padding: 6px 8px !important;
border-bottom: none; border-bottom: none;
border-radius: 0 !important;
} }
} }
} }
@ -96,12 +87,15 @@ body {
&:nth-child(2n) { &:nth-child(2n) {
background-color: #08373a; background-color: #08373a;
} }
td { td {
padding: 10px 8px !important; padding: 10px 8px !important;
border-bottom: none; border-bottom: none;
} }
&:hover {
td {
background-color: #0e505f !important;
}
}
&.ant-table-row-selected { &.ant-table-row-selected {
td { td {
background-color: #0d4e5c !important; background-color: #0d4e5c !important;
@ -123,29 +117,6 @@ body {
border-color: @formInputBorderColor; border-color: @formInputBorderColor;
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%; width: 100%;
} }
&-required::before { &-required::before {
// display: none !important; display: none !important;
} }
} }
&-horizontal { &-horizontal {
@ -189,13 +160,6 @@ body {
&-time-picker-inner { &-time-picker-inner {
background-color: @modalBg; background-color: @modalBg;
} }
&-time-picker {
background: none;
}
&-time-picker-combobox {
background-color: @modalBg !important;
border-color: @formInputBorderColor !important;
}
&-picker { &-picker {
width: 100%; width: 100%;
@ -206,13 +170,10 @@ body {
background-color: @formInputBgColor; background-color: @formInputBgColor;
color: #00e9fe !important; color: #00e9fe !important;
} }
&-select {
background-color: @formInputBgColor !important;
}
} }
&-input { &-input {
background-color: red; background-color: transparent;
&-wrap { &-wrap {
border-color: @formInputBorderColor; border-color: @formInputBorderColor;
height: 32px; height: 32px;
@ -280,9 +241,6 @@ body {
} }
} }
} }
.ant-calendar-range .ant-calendar-in-range-cell::before {
background: #1397a3;
}
// 日历 // 日历
.ant-fullcalendar { .ant-fullcalendar {
@ -346,8 +304,7 @@ body {
&-selected-day &-date, &-selected-day &-date,
&-date:hover { &-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; @time-picker-selected-bg: @primary-color;
@item-hover-bg: @primary-color; @item-hover-bg: @primary-color;
.ant-time-picker { .ant-time-picker {
width: 100%;
&-input { &-input {
background: @modalBg;
border-radius: 0; border-radius: 0;
&::placeholder { &::placeholder {
color: #ccc; color: #fff;
} }
} }
&-clear, &-clear,
&-clock-icon { &-clock-icon {
color: #01b6e3 !important; background-color: @modalBg !important;
color: #01B6E3 !important;
} }
&-panel { &-panel {
@ -388,17 +344,13 @@ body {
} }
// 输入框样式 // 输入框样式
.ant-calendar-input {
background-color: transparent !important;
}
.ant-calendar-range-middle {
color: #fff;
}
.ant-input { .ant-input {
background-color: @formInputBgColor !important;
border-color: @formInputBorderColor !important;
border-radius: 0; border-radius: 0;
color: #fff; color: #fff;
&::placeholder { &::placeholder {
color: #ccc; color: #fff;
} }
&:focus { &:focus {
box-shadow: none; box-shadow: none;
@ -563,7 +515,7 @@ input[type='number']::-webkit-outer-spin-button {
&.ant-select-dropdown-placement-topLeft { &.ant-select-dropdown-placement-topLeft {
padding-top: 0; padding-top: 0;
padding-bottom: 7px; padding-bottom: 7px;
.ant-select-dropdown-content { .ant-select-dropdown-content {
&::before { &::before {
top: auto; 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 { .ant-dropdown {

View File

@ -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
}
}
}

View File

@ -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
}

View File

@ -1,2 +0,0 @@
const { UpdateBaseLine } = Module;
export { UpdateBaseLine as updateBaseLine };

View File

@ -8,7 +8,7 @@ export function getXAxisAndYAxisByPosition(chart, offsetX, offsetY, seriesIndex
if ( if (
chart.containPixel( chart.containPixel(
{ {
seriesIndex seriesIndex: 0
}, },
pointInPixel pointInPixel
) )
@ -17,102 +17,4 @@ export function getXAxisAndYAxisByPosition(chart, offsetX, offsetY, seriesIndex
return [xAxis, yAxis] return [xAxis, yAxis]
} }
return null 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
} }

Some files were not shown because too many files have changed in this diff Show More