Merge remote-tracking branch 'origin/master-dev'

This commit is contained in:
orgin 2024-06-04 14:15:34 +08:00
commit 5327bac762
83 changed files with 3866 additions and 2599 deletions
public
src
api
assets/images/station-operation
components
store
style.less
utils
views

3
public/index.html vendored
View File

@ -5,7 +5,8 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>核素监测数据自动处理与交互分析系统</title>
<title>ARMD</title>
<!-- <title>核素监测数据自动处理与交互分析系统</title> -->
<link rel="icon" href="<%= BASE_URL %>logo.png">
<script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script>
<style>

BIN
public/logo.png vendored

Binary file not shown.

Before

(image error) Size: 8.7 KiB

After

(image error) Size: 30 KiB

View File

@ -28,6 +28,23 @@ export function postAction(url, parameter) {
headers: signHeader
})
}
//post
export function postActionWithTimeOut(url, parameter, timeout) {
let sign = signMd5Utils.getSign(url, parameter);
//将签名和时间戳,添加在请求接口 Header
// update-begin--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
let signHeader = { "X-Sign": sign, "X-TIMESTAMP": signMd5Utils.getTimestamp() };
// update-end--author:taoyan---date:20220421--for: VUEN-410【签名改造】 X-TIMESTAMP牵扯
return axios({
url: url,
method: 'post',
data: parameter,
headers: signHeader,
timeout
})
}
export function postFileAction(url, parameter) {
let sign = signMd5Utils.getSign(url, parameter);
//将签名和时间戳,添加在请求接口 Header

Binary file not shown.

After

(image error) Size: 1.5 KiB

Binary file not shown.

After

(image error) Size: 1.4 KiB

Binary file not shown.

After

(image error) Size: 1.4 KiB

View File

@ -30,9 +30,10 @@ export default {
this._chart.setOption(this.option, this.opts)
this.initEventListener()
},
destroyed() {
beforeDestroy() {
if (this._chart) {
this._chart.dispose()
this._chart = null
}
},
methods: {

View File

@ -2,6 +2,7 @@
<a-table
ref="tableRef"
class="custom-table"
:class="['custom-table', canSelect && multiple && mouseMoveSelect ? 'mouse-move-select' : '']"
v-bind="$attrs"
:data-source="list"
:columns="columns"
@ -9,7 +10,7 @@
:row-key="rowKey"
:loading="loading"
:pagination="pagination"
:customRow="customRow"
:customRow="multiple && mouseMoveSelect ? customMouseMoveSelectRow : customRow"
:rowClassName="() => (canSelect ? 'custom-table-row' : '')"
@change="handleTableChange"
>
@ -58,10 +59,16 @@ export default {
type: Boolean,
default: true,
},
//
multiple: {
type: Boolean,
default: false,
},
//
mouseMoveSelect: {
type: Boolean,
default: true,
},
},
data() {
return {
@ -69,6 +76,14 @@ export default {
innerSelectedRows: [],
}
},
mounted() {
if (this.canSelect && this.multiple && this.mouseMoveSelect) {
const tbody = this.$el.querySelector('.ant-table-tbody')
tbody.addEventListener('mouseleave', () => {
this.mouseMoveStartIndex = undefined
})
}
},
methods: {
// /
customRow(record, index) {
@ -105,6 +120,34 @@ export default {
},
}
},
//
customMouseMoveSelectRow(record, index) {
const key = record[this.rowKey]
return {
class: this.innerSelectedRowKeys.includes(key) ? 'ant-table-row-selected' : '',
on: {
mousedown: () => {
this.innerSelectedRowKeys = []
this.mouseMoveStartIndex = index
},
mouseenter: () => {
if (this.mouseMoveStartIndex !== undefined) {
const indexes = [this.mouseMoveStartIndex, index].sort((a, b) => a - b)
this.innerSelectedRowKeys = this.list.slice(indexes[0], indexes[1] + 1).map((item) => item[this.rowKey])
}
},
mouseup: () => {
// click
if (this.mouseMoveStartIndex == index) {
this.innerSelectedRowKeys = [key]
}
this.mouseMoveStartIndex = undefined
},
},
}
},
handleTableChange(pagination, filters, sorter) {
this.$emit('change', pagination, filters, sorter)
},
@ -136,8 +179,20 @@ export default {
},
}
</script>
<style lang="less">
.custom-table-row {
cursor: pointer;
<style lang="less" scoped>
::v-deep {
.custom-table-row {
cursor: pointer;
}
}
.mouse-move-select {
user-select: none;
::v-deep {
td {
transition: none !important;
}
}
}
</style>

View File

@ -105,14 +105,12 @@ export default {
})
},
handleInput(e = '') {
console.log('qweq', 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)

View File

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

View File

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

View File

@ -839,6 +839,6 @@ body {
</style>
<style lang="less" scoped>
.ant-menu {
width: 1750px;
max-width: calc(100% - 200px);
}
</style>

View File

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

View File

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

View File

@ -6,7 +6,6 @@ import user from './modules/user'
import permission from './modules/permission'
import enhance from './modules/enhance'
import online from './modules/online'
import sample from './modules/sample'
import getters from './getters'
Vue.use(Vuex)
@ -18,7 +17,6 @@ export default new Vuex.Store({
permission,
enhance,
online,
sample
},
state: {

View File

@ -1,50 +0,0 @@
const sample = {
state: {
sampleList: [] // [{ inputFileName: String; data: Object; }]
},
mutations: {
SET_SAMPLE_LIST: (state, sampleList) => {
state.sampleList = sampleList
},
ADD_SAMPLE_DATA: (state, sampleData) => {
const find = state.sampleList.find(item => item.inputFileName == sampleData.inputFileName)
if (find) {
find.data = sampleData.data
} else {
state.sampleList.push(sampleData)
}
},
UPDATE_SAMPLE_DATA: (state, { inputFileName, key, data }) => {
const find = state.sampleList.find(item => item.inputFileName == inputFileName)
if (find) {
find.data[key] = data
}
},
UPDATE_SAMPLE_DATA_ANALY: (state, { inputFileName, data }) => {
const find = state.sampleList.find(item => item.inputFileName == inputFileName)
if (find) {
data.DetailedInformation = find.data.DetailedInformation
find.data = data
}
},
REMOVE_SAMPLE_DATA: (state, inputFileName) => {
const findIndex = state.sampleList.findIndex(item => item.inputFileName == inputFileName)
state.sampleList.splice(findIndex, 1)
},
CLEAR_SAMPLE_DATA: (state) => {
state.sampleList = []
}
},
actions: {
GET_SAMPLE_DATA: ({ state }, inputFileName) => {
const find = state.sampleList.find(item => item.inputFileName == inputFileName)
return find ? find : null
}
}
}
export default sample

View File

@ -74,7 +74,13 @@ body {
color: #ade6ee;
font-size: 16px;
border: 1px solid rgba(65, 111, 127, 0.5);
&-header {
background: #126b82 !important;
box-sizing: border-box !important;
table {
width: calc(100% + 11px) !important;
}
}
&-thead {
> tr {
th {
@ -355,7 +361,7 @@ body {
border-radius: 0;
&::placeholder {
color: #fff;
color: #ccc;
}
}
@ -392,7 +398,7 @@ body {
border-radius: 0;
color: #fff;
&::placeholder {
color: #fff;
color: #ccc;
}
&:focus {
box-shadow: none;

84
src/utils/SampleStore.js Normal file
View File

@ -0,0 +1,84 @@
// 所有缓存的谱
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

@ -87,7 +87,7 @@ export const zipFile = async (fileList, zipName) => {
result.forEach(res => {
zip.file(res.fileName, res.data)
})
const content = await zip.generateAsync({ type: 'blob' })
const content = await zip.generateAsync({ type: 'blob', compression: 'DEFLATE' })
return new File([content], zipName, { type: content.type })
}

View File

@ -28,9 +28,9 @@
</a-layout-sider>
<a-layout style="background-color: aliceblue">
<keep-alive>
<router-view v-if="keepAlive" />
<router-view />
</keep-alive>
<router-view v-if="!keepAlive" />
<!-- <router-view v-if="!keepAlive" /> -->
</a-layout>
</a-layout>
</a-card>
@ -72,11 +72,11 @@ const SubMenu = {
export default {
name: 'menuTree',
components: { 'sub-menu': SubMenu },
computed: {
keepAlive() {
return this.$route.meta.keepAlive
},
},
// computed: {
// keepAlive() {
// return this.$route.meta.keepAlive
// },
// },
data() {
const collapsed = false
return {

View File

@ -13,13 +13,15 @@
:list="dataSource"
:loading="loading"
:canSelect="false"
:scroll="{ y: 390 }"
>
<template slot="info" slot-scope="{ record }">
<div class="info-alarm">{{ record.alarmValue }}{{ JSON.parse(record.operator).units }}</div>
<div>
{{ JSON.parse(record.operator).name }} {{ JSON.parse(record.operator).operator }}
{{ JSON.parse(record.operator).threshold }}{{ JSON.parse(record.operator).units }}
</div>
<a-popover>
<template slot="content">
{{ JSON.parse(record.alarmInfo) }}{{ JSON.parse(record.operator).units }}
</template>
{{ JSON.parse(record.alarmInfo) }}{{ JSON.parse(record.operator).units }}
</a-popover>
</template>
</custom-table>
</div>
@ -91,6 +93,7 @@ const columns = [
{
title: 'ALARM INFO',
align: 'left',
ellipsis: true,
dataIndex: 'alarmInfo',
scopedSlots: {
customRender: 'info',

View File

@ -521,7 +521,7 @@ export default {
if (res.success) {
this.itemOptions = res.result.map((item) => {
return {
label: item.name,
label: item.units ? `${item.name}(${item.units})` : item.name,
value: item.itemId,
units: item.units,
valueType: item.valueType,

View File

@ -1,16 +1,20 @@
<template>
<div style="height: 100%">
<SearchBar type="alarmAnalysis" @search="handleSearch"></SearchBar>
<div class="chart-layout" id="analysisChartBar"></div>
<div class="chart-box">
<div class="chart-box-left">
<BoxTitle title="Station Alarm number"></BoxTitle>
<div class="chart-box-left-bar" id="chartLeft"></div>
</div>
<div class="chart-box-right">
<BoxTitle title="Anaysis Sources Alarms"></BoxTitle>
<div class="chart-box-right-pie" id="chartRight"></div>
</div>
<div style="width: 100%; height: calc(100% - 50px)">
<a-spin :spinning="spinning">
<div class="chart-layout" id="analysisChartBar"></div>
<div class="chart-box">
<div class="chart-box-left">
<BoxTitle title="Station Alarm number"></BoxTitle>
<div class="chart-box-left-bar" id="chartLeft"></div>
</div>
<div class="chart-box-right">
<BoxTitle title="Anaysis Sources Alarms"></BoxTitle>
<div class="chart-box-right-pie" id="chartRight"></div>
</div>
</div>
</a-spin>
</div>
</div>
</template>
@ -29,6 +33,7 @@ export default {
},
data() {
return {
spinning: false,
xData: [],
yData: [],
xData_left: [],
@ -36,6 +41,7 @@ export default {
pieData: [],
pieColors: ['#00bcd4', '#14b2a3', '#97b94b', '#47b55d'],
pieTotal: 0,
sourceChart: null,
}
},
mounted() {
@ -50,6 +56,7 @@ export default {
endDate,
types,
}
this.spinning = true
this.getAnalysisLogBar({ startDate, endDate })
this.getStationNum({ startDate, endDate })
this.getAnalysisSource({ startDate, endDate })
@ -59,45 +66,64 @@ export default {
startDate: obj.startDate,
endDate: obj.endDate,
}
getAction('/alarmAnalysisLog/byTime', params).then((res) => {
if (res.success) {
this.xData = res.result.xData
this.yData = res.result.yData
this.drawAnalysis_bar()
} else {
this.$message.warning('This operation fails. Contact your system administrator')
}
})
getAction('/alarmAnalysisLog/byTime', params)
.then((res) => {
this.spinning = false
if (res.success) {
this.xData = res.result.xData
this.yData = res.result.yData
this.drawAnalysis_bar()
} else {
this.$message.warning('This operation fails. Contact your system administrator')
}
})
.finally(() => {
this.spinning = false
})
},
getStationNum(obj) {
let params = {
startDate: obj.startDate,
endDate: obj.endDate,
}
getAction('/alarmAnalysisLog/byStatoin', params).then((res) => {
if (res.success) {
this.xData_left = res.result.xData
this.yData_left = res.result.yData
this.drawLeftChart()
} else {
this.$message.warning('This operation fails. Contact your system administrator')
}
})
getAction('/alarmAnalysisLog/byStatoin', params)
.then((res) => {
this.spinning = false
if (res.success) {
this.xData_left = res.result.xData
this.yData_left = res.result.yData
this.drawLeftChart()
} else {
this.$message.warning('This operation fails. Contact your system administrator')
}
})
.finally(() => {
this.spinning = false
})
},
getAnalysisSource(obj) {
let params = {
startDate: obj.startDate,
endDate: obj.endDate,
}
getAction('/alarmAnalysisLog/bySource', params).then((res) => {
if (res.success) {
this.pieData = res.result.pieData
this.pieTotal = res.result.pieTotal
this.drawRightChart()
} else {
this.$message.warning('This operation fails. Contact your system administrator')
}
})
getAction('/alarmAnalysisLog/bySource', params)
.then((res) => {
this.spinning = false
if (res.success) {
if (res.result.pieTotal > 0) {
this.pieData = res.result.pieData
this.pieTotal = res.result.pieTotal
this.drawRightChart()
} else {
this.sourceChart.clear()
}
} else {
this.$message.warning('This operation fails. Contact your system administrator')
}
})
.finally(() => {
this.spinning = false
})
},
drawAnalysis_bar() {
let myChart = echarts.init(document.getElementById('analysisChartBar'))
@ -224,7 +250,7 @@ export default {
})
},
drawRightChart() {
let myChart = echarts.init(document.getElementById('chartRight'))
this.sourceChart = echarts.init(document.getElementById('chartRight'))
let options = {
tooltip: {
trigger: 'item',
@ -285,9 +311,9 @@ export default {
},
],
}
myChart.setOption(options)
this.sourceChart.setOption(options)
window.addEventListener('resize', function () {
myChart.resize()
this.sourceChart.resize()
})
},
},
@ -295,12 +321,18 @@ export default {
</script>
<style lang="less" scoped>
::v-deep.ant-spin-nested-loading {
height: 100%;
.ant-spin-container {
height: 100%;
}
}
.chart-layout {
height: 400px;
margin-left: 20px;
}
.chart-box {
height: calc(100% - 450px);
height: calc(100% - 400px);
margin-left: 20px;
display: flex;
justify-content: space-between;

View File

@ -10,6 +10,7 @@
:list="dataSource"
:loading="loading"
:pagination="false"
:scroll="{ y: 655 }"
@rowDbclick="rowClick"
>
<!-- <template slot="stationList" slot-scope="{ text }">

View File

@ -5,13 +5,43 @@
<a-col flex="108px">
<a-button class="search-btn" type="primary" @click="handleConfig"> Config </a-button>
</a-col>
<a-col flex="380px">
<a-col flex="365px">
<span class="item-label">Cacl date</span>
<a-range-picker
:value="[moment(queryParams.startDate), moment(queryParams.endDate)]"
@change="onRangeDateChange"
/>
</a-col>
<a-col flex="265px">
<span class="item-label">Station</span>
<a-select
style="width: 180px"
v-model="queryParams.stationId"
placeholder="select..."
:filter-option="filterOption"
show-arrow
allowClear
:options="stationOptions"
@change="onStationChange"
>
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
</a-select>
</a-col>
<a-col flex="285px">
<span class="item-label">Source Type</span>
<a-select
style="width: 180px"
v-model="queryParams.sourceType"
placeholder="select..."
:filter-option="filterOption"
show-arrow
allowClear
:options="sourceOptions"
@change="onSourceChange"
>
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
</a-select>
</a-col>
</a-row>
</div>
<div class="analysis-main">
@ -23,6 +53,7 @@
:loading="loading"
:pagination="false"
:canSelect="false"
:scroll="{ y: 655 }"
>
</TableList>
<a-pagination
@ -89,6 +120,11 @@ import moment from 'moment'
import TableList from '../../components/tableList.vue'
import { getAction, postAction, httpAction, deleteAction } from '@/api/manage'
const columns = [
{
title: 'STATION',
align: 'center',
dataIndex: 'stationCode',
},
{
title: 'NUCLIDE',
align: 'center',
@ -125,6 +161,8 @@ export default {
dataSource: [],
loading: false,
queryParams: {
stationId: undefined,
sourceType: undefined,
startDate: dateFormat(new Date(), 'yyyy-MM-dd'),
endDate: dateFormat(new Date(), 'yyyy-MM-dd'),
},
@ -148,6 +186,17 @@ export default {
index: '',
},
currId: '',
stationOptions: [],
sourceOptions: [
{
label: 'ARMDARR',
value: '1',
},
{
label: 'ARMDRRR',
value: '2',
},
],
}
},
created() {
@ -155,8 +204,33 @@ export default {
},
mounted() {
this.getNuclideAvgList()
this.getStationList()
},
methods: {
onSourceChange(val) {
console.log(val)
},
getStationList() {
getAction('/webStatistics/findStationList', { menuName: '' }).then((res) => {
if (res.success) {
if (res.result.length > 0) {
this.stationOptions = res.result.map((item) => {
return {
label: item.stationCode,
value: `${item.stationId}`,
}
})
} else {
this.stationOptions = []
}
} else {
this.$message.warning('This operation fails. Contact your system administrator')
}
})
},
filterOption(input, option) {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
// n
getBeforeDate(n) {
var n = n
@ -183,8 +257,7 @@ export default {
getNuclideAvgList() {
this.loading = true
let params = {
startDate: this.queryParams.startDate,
endDate: this.queryParams.endDate,
...this.queryParams,
pageNo: this.ipagination.current,
pageSize: this.ipagination.pageSize,
}
@ -198,6 +271,14 @@ export default {
}
})
},
onStationChange(val) {
this.queryParams.stationId = val
this.getNuclideAvgList()
},
onSourceChange(val) {
this.queryParams.sourceType = val
this.getNuclideAvgList()
},
onRangeDateChange(date, dateString) {
this.queryParams.startDate = dateString[0]
this.queryParams.endDate = dateString[1]

View File

@ -1,9 +1,9 @@
<template>
<div class="search-bar">
<a-row type="flex">
<a-col flex="190px">
<!-- <a-col flex="190px">
<a-input placeholder="search..." />
</a-col>
</a-col> -->
<a-col flex="310px" v-if="type == 'alarmCenter'">
<a-form-model-item label="Type">
<a-select

View File

@ -11,7 +11,9 @@
:customRow="customRow"
:rowClassName="() => (canSelect ? 'custom-table-row' : '')"
@change="handleTableChange"
:scroll="scroll"
>
<!-- :scroll="{ y: 186 }" -->
<!-- 处理 scopedSlots -->
<template v-for="slotName of scopedSlotsKeys" :slot="slotName" slot-scope="text, record, index">
<slot :name="slotName" :text="text" :record="record" :index="index"></slot>
@ -57,6 +59,7 @@ export default {
type: Boolean,
default: false,
},
scroll: { type: Object },
},
data() {
return {

View File

@ -10,13 +10,15 @@
:loading="loading"
:pagination="false"
:canSelect="false"
:scroll="{ y: 655 }"
>
<template slot="info" slot-scope="{ record }">
<div class="info-alarm">{{ record.alarmValue }}{{ JSON.parse(record.operator).units }}</div>
<div>
{{ JSON.parse(record.operator).name }} {{ JSON.parse(record.operator).operator }}
{{ JSON.parse(record.operator).threshold }}{{ JSON.parse(record.operator).units }}
</div>
<a-popover>
<template slot="content">
{{ JSON.parse(record.alarmInfo) }}{{ JSON.parse(record.operator).units }}
</template>
{{ JSON.parse(record.alarmInfo) }}{{ JSON.parse(record.operator).units }}
</a-popover>
</template>
</TableList>
<a-pagination
@ -60,6 +62,7 @@ const columns = [
{
title: 'ALARM INFO',
align: 'left',
ellipsis: true,
dataIndex: 'alarmInfo',
scopedSlots: {
customRender: 'info',
@ -162,7 +165,7 @@ export default {
<style lang="less" scoped>
.server-main {
width: 100%;
// width: 100%;
height: calc(100% - 50px);
overflow: hidden;
padding-top: 15px;
@ -177,7 +180,7 @@ export default {
}
.info-alarm {
font-family: ArialMT;
font-size: 18px;
color: #f62424;
font-size: 16px;
// color: #f62424;
}
</style>

View File

@ -1,118 +1,129 @@
<template>
<div class="monitor-search">
<a-row type="flex" :gutter="10">
<a-col flex="335px">
<span class="item-label">Database name</span>
<a-select style="width:180px"
v-model="value.hostId"
placeholder="select..."
:filter-option="filterOption"
show-arrow
allowClear
:options="DbOptions"
@change="onDbChange"
>
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
</a-select>
</a-col>
<a-col flex="265px">
<span class="item-label">Time</span>
<a-select style="width:180px"
v-model="timer"
placeholder="select..."
show-arrow
allowClear
:options="timerOptions"
@change="onTimeChange"
>
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
</a-select>
</a-col>
<a-col flex="265px">
<a-range-picker
:show-time="true"
:value="[moment(value.start), moment(value.end)]"
@change="onRangeDateChange"
/>
</a-col>
</a-row>
<div class="monitor-search-btns">
<a-button class="monitor-search-btns-ant" @click="handleRefresh">
<img class="icon-add" src="@/assets/images/global/reset-pwd.png" alt="" />
<span style="margin-left: 10px;">
Refresh
</span>
</a-button>
</div>
<a-row type="flex" :gutter="10">
<a-col flex="335px">
<span class="item-label">Database name</span>
<a-select
style="width: 180px"
v-model="value.hostId"
placeholder="select..."
:filter-option="filterOption"
show-arrow
allowClear
:options="DbOptions"
@change="onDbChange"
>
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
</a-select>
</a-col>
<a-col flex="265px">
<span class="item-label">Time</span>
<a-select
style="width: 180px"
v-model="timer"
placeholder="select..."
show-arrow
allowClear
:options="timerOptions"
@change="onTimeChange"
>
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
</a-select>
</a-col>
<a-col flex="265px">
<a-range-picker
:show-time="true"
:value="[moment(value.start), moment(value.end)]"
@change="onRangeDateChange"
/>
</a-col>
</a-row>
<div class="monitor-search-btns">
<a-button class="monitor-search-btns-ant" @click="handleRefresh">
<img class="icon-add" src="@/assets/images/global/reset-pwd.png" alt="" />
<span style="margin-left: 10px"> Refresh </span>
</a-button>
</div>
</div>
</template>
<script>
import moment from 'moment';
import dateFormat from '@/components/jeecg/JEasyCron/format-date'
import { getAction, postAction, httpAction, deleteAction } from '@/api/manage'
import moment from 'moment'
import { getAction } from '@/api/manage'
export default {
props: {
value: {
type: Object,
required: true
}
required: true,
},
},
data() {
return {
timer: 1,
DbOptions: [],
timerOptions: [
{label: "1Hours",value: 1},
{label: "2Hours",value: 2},
{label: "3Hours",value: 3},
{label: "user-defined",value: 0},
]
{ label: '1Hours', value: 1 },
{ label: '2Hours', value: 2 },
{ label: '3Hours', value: 3 },
{ label: 'user-defined', value: 0 },
],
}
},
created() {
this.getBeforeHours(1)
},
mounted () {
this.getDbList();
mounted() {
this.getDbList()
},
watch: {
$route: {
handler: function (val, oldVal) {
if (val.query && val.query.id) {
this.getDbList()
}
},
deep: true,
immediate: true,
},
},
methods: {
getBeforeHours(num) {
let currentTime = moment()
let oneHourAgo = moment().subtract(num, 'hours');
let oneHourAgo = moment().subtract(num, 'hours')
this.value.start = oneHourAgo.format('YYYY-MM-DD HH:mm:ss')
this.value.end = currentTime.format('YYYY-MM-DD HH:mm:ss')
},
moment,
filterOption(input, option) {
return (
option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
);
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
getDbList() {
getAction("/sysDatabase/sourceList").then(res => {
getAction('/sysDatabase/sourceList').then((res) => {
if (res.success) {
const sourceId = this.$route.query.id
// urlsourceId
if(sourceId) {
const find = res.result.find(item => item.sourceId == sourceId)
if(find) {
if (sourceId) {
const find = res.result.find((item) => item.sourceId == sourceId)
if (find && find.hostId) {
this.value.hostId = find.hostId
} else {
this.value.hostId = `my${find.sourceId}`
}
}
if(!this.value.hostId) {
if (!this.value.hostId) {
this.value.hostId = res.result[0].hostId
}
this.DbOptions = res.result.map(item => {
this.DbOptions = res.result.map((item, index) => {
let str = `my${item.sourceId}`
return {
label: item.sourceName,
value: item.hostId
value: item.hostId || str,
}
})
this.$emit('change')
} else {
this.$message.warning("This operation fails. Contact your system administrator")
this.$message.warning('This operation fails. Contact your system administrator')
}
})
},
@ -133,13 +144,13 @@ export default {
handleRefresh() {
this.$emit('refresh')
}
},
},
}
</script>
<style lang="less" scoped>
.monitor-search{
.monitor-search {
height: 50px;
border-top: 1px solid rgba(13, 235, 201, 0.3);
border-bottom: 1px solid rgba(13, 235, 201, 0.3);
@ -148,13 +159,13 @@ export default {
justify-content: space-between;
padding: 0 10px;
background: rgba(12, 235, 201, 0.05);
.ant-row-flex{
.ant-row-flex {
flex-flow: nowrap;
}
/deep/ .ant-calendar-range-picker-separator{
/deep/ .ant-calendar-range-picker-separator {
color: white;
}
.item-label{
.item-label {
display: inline-block;
font-size: 16px;
font-family: ArialMT;
@ -163,8 +174,8 @@ export default {
height: 32px;
margin-right: 10px;
}
&-btns{
&-ant{
&-btns {
&-ant {
background: #1397a3;
border: none;
}

View File

@ -2,21 +2,23 @@
<div style="height: 100%">
<ConditionBox :value="queryParams" @change="getData" @refresh="getData"></ConditionBox>
<div class="monitor-content">
<a-row :gutter="10" style="height: 100%">
<a-col :span="12" style="height: 33.3333%" v-for="(el, i) in chartData" :key="i">
<div class="monitor-content-item">
<AreaChart
:title="el.title"
:layout="`area${i}`"
:color="el.color"
:dataSource="el.list"
:newUnits="el.newUnits"
:units="el.units"
>
</AreaChart>
</div>
</a-col>
</a-row>
<a-spin :spinning="spinning">
<a-row :gutter="10" style="height: 100%">
<a-col :span="12" style="height: 33.3333%" v-for="(el, i) in chartData" :key="i">
<div class="monitor-content-item">
<AreaChart
:title="el.title"
:layout="`area${i}`"
:color="el.color"
:dataSource="el.list"
:newUnits="el.newUnits"
:units="el.units"
>
</AreaChart>
</div>
</a-col>
</a-row>
</a-spin>
<!-- <div style="height: auto; margin-top: 15px; padding-right: 10px">
<BoxTitle title="Connect List"></BoxTitle>
<a-row :gutter="20" style="height: auto; margin-top: 15px">
@ -60,6 +62,7 @@ export default {
},
data() {
return {
spinning: false,
queryParams: {
hostId: '',
start: dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss'),
@ -360,32 +363,39 @@ export default {
methods: {
//
async getData() {
const hide = this.$message.loading('loading...', 0)
try {
const { success, result, message } = await getAction('/systemMonitor/dbDetail', this.queryParams)
if (success) {
this.chartData.forEach((chartItem, index) => {
const item = result[index]
if (item.units === 'B' || item.units === 'Kb') {
item.newUnits = this.unitConversion(item.min, item.units)
item.list.forEach((val) => {
let number = val.value
if (item.units === 'Kb') {
number = val.value * 1024
}
val.value = Number(this.dataConversion(number, item.newUnits))
})
}
Object.assign(chartItem, item)
})
} else {
this.$message.error(message)
if (!this.queryParams.hostId.includes('my')) {
this.spinning = true
try {
const { success, result, message } = await getAction('/systemMonitor/dbDetail', this.queryParams)
if (success) {
this.chartData.forEach((chartItem, index) => {
const item = result[index]
if (item.units === 'B' || item.units === 'Kb') {
item.newUnits = this.unitConversion(item.min, item.units)
item.list.forEach((val) => {
let number = val.value
if (item.units === 'Kb') {
number = val.value * 1024
}
val.value = Number(this.dataConversion(number, item.newUnits))
})
}
Object.assign(chartItem, item)
})
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
this.spinning = false
} finally {
// hide()
this.spinning = false
}
} catch (error) {
console.error(error)
} finally {
hide()
} else {
this.$message.error('No monitoring information')
}
// const hide = this.$message.loading('loading...', 0)
},
//
generateChart() {
@ -455,6 +465,14 @@ export default {
margin-top: 10px;
overflow-y: auto;
overflow-x: hidden;
/deep/.ant-spin-nested-loading {
width: 100%;
height: 100%;
}
/deep/.ant-spin-container {
width: 100%;
height: 100%;
}
&-item {
width: 100%;
height: 100%;

View File

@ -193,11 +193,11 @@ const columns = [
ellipsis: true,
width: 300,
},
{
title: 'SLOW QUERY',
align: 'center',
dataIndex: 'slowQuery',
},
// {
// title: 'SLOW QUERY',
// align: 'center',
// dataIndex: 'slowQuery',
// },
{
title: 'ALARMS',
align: 'center',
@ -207,25 +207,25 @@ const columns = [
},
},
{
title: 'CPU UTILIZATION',
title: 'DB MEMORY',
align: 'center',
dataIndex: 'cpuUutilzation',
dataIndex: 'dbMemory',
scopedSlots: {
customRender: 'cpu',
},
},
{
title: 'MEMORY USAGE',
title: 'LOG REMAINING SIZE',
align: 'center',
dataIndex: 'memoryUsage',
dataIndex: 'logRemainingSize',
scopedSlots: {
customRender: 'memory',
},
},
{
title: 'DISK USAGE',
title: 'DB SIZE',
align: 'center',
dataIndex: 'diskUsage',
dataIndex: 'dbSize',
scopedSlots: {
customRender: 'disk',
},

View File

@ -10,13 +10,15 @@
:loading="loading"
:pagination="false"
:canSelect="false"
:scroll="{ y: 655 }"
>
<template slot="info" slot-scope="{ record }">
<div class="info-alarm">{{ record.alarmValue }}{{ JSON.parse(record.operator).units }}</div>
<div>
{{ JSON.parse(record.operator).name }} {{ JSON.parse(record.operator).operator }}
{{ JSON.parse(record.operator).threshold }}{{ JSON.parse(record.operator).units }}
</div>
<a-popover>
<template slot="content">
{{ JSON.parse(record.alarmInfo) }}{{ JSON.parse(record.operator).units }}
</template>
{{ JSON.parse(record.alarmInfo) }}{{ JSON.parse(record.operator).units }}
</a-popover>
</template>
</TableList>
<a-pagination
@ -60,6 +62,7 @@ const columns = [
{
title: 'ALARM INFO',
align: 'left',
ellipsis: true,
dataIndex: 'alarmInfo',
scopedSlots: {
customRender: 'info',
@ -162,7 +165,7 @@ export default {
<style lang="less" scoped>
.server-main {
width: 100%;
// width: 100%;
height: calc(100% - 50px);
overflow: hidden;
padding-top: 15px;

View File

@ -98,7 +98,7 @@
<div class="email-top-content-li-right">
<div class="email-top-content-li-right-title">Used Capacity</div>
<div class="email-top-content-li-right-val" style="color: #ade6ee; font-size: 26px; margin-top: 36px">
{{ emailTotal.usage || 0 }}/<span style="font-size: 40px; vertical-align: middle"></span>
{{ emailSpace.usage || 0 }}/<span style="font-size: 40px; vertical-align: middle"></span>
</div>
</div>
<div class="email-top-content-li-rect" style="background: #8351d4"></div>
@ -111,7 +111,7 @@
<img src="@/assets/images/abnormalAlarm/email-split.png" alt="" />
</div>
<div class="email-top-content-li-right">
<div class="email-top-content-li-right-title">An Unread Mail</div>
<div class="email-top-content-li-right-title">Unread Mail</div>
<div class="email-top-content-li-right-val" style="color: #ade6ee; font-size: 26px; margin-top: 36px">
{{ emailSpace.unreadMsg || 0 }}
</div>
@ -239,7 +239,19 @@ export default {
mounted() {
this.getEmailList()
},
// activated() {
// this.getEmailList()
// },
watch: {
$route: {
handler: function (val, oldVal) {
if (val.query && val.query.emailId) {
this.getEmailList()
}
},
deep: true,
immediate: true,
},
emailId(newValue, oldValue) {
this.currId = newValue
this.getEmailStatus()
@ -271,18 +283,18 @@ export default {
},
onEmailChange(val) {
this.spinning = true
this.guageStore.clear()
if (this.guageStore) this.guageStore.clear()
this.emailId = val
},
onDateChange(val) {
this.spinning = true
this.areaMailLine.clear()
if (this.areaMailLine) this.areaMailLine.clear()
this.startDate = this.getBeforeDate(val - 1)
this.getEmailStatistics()
},
onRangeDateChange(date, dateString) {
this.spinning = true
this.areaMailLine.clear()
if (this.areaMailLine) this.areaMailLine.clear()
this.startDate = dateString[0]
this.endDate = dateString[1]
this.getEmailStatistics()
@ -315,7 +327,7 @@ export default {
s = s.substring(0, s.length - 1)
res.result.usage = s
this.emailSpace = res.result
this.drawGuageStore()
// this.drawGuageStore()
} else {
this.$message.warning('This operation fails. Contact your system administrator')
}

View File

@ -10,13 +10,15 @@
:loading="loading"
:pagination="false"
:canSelect="false"
:scroll="{ y: 655 }"
>
<template slot="info" slot-scope="{ record }">
<div class="info-alarm">{{ record.alarmValue }}{{ JSON.parse(record.operator).units }}</div>
<div>
{{ JSON.parse(record.operator).name }} {{ JSON.parse(record.operator).operator }}
{{ JSON.parse(record.operator).threshold }}{{ JSON.parse(record.operator).units }}
</div>
<a-popover>
<template slot="content">
{{ JSON.parse(record.alarmInfo) }}{{ JSON.parse(record.operator).units }}
</template>
{{ JSON.parse(record.alarmInfo) }}{{ JSON.parse(record.operator).units }}
</a-popover>
</template>
</TableList>
<a-pagination
@ -60,6 +62,7 @@ const columns = [
{
title: 'ALARM INFO',
align: 'left',
ellipsis: true,
dataIndex: 'alarmInfo',
scopedSlots: {
customRender: 'info',
@ -162,7 +165,7 @@ export default {
<style lang="less" scoped>
.server-main {
width: 100%;
// width: 100%;
height: calc(100% - 50px);
overflow: hidden;
padding-top: 15px;

View File

@ -49,112 +49,114 @@
</div>
</div>
<div class="cpu-content">
<a-row :gutter="[20, 15]" style="height: 100%">
<a-col :span="12" style="height: calc(50% + 10px)">
<div class="cpu-content-item">
<BoxTitle title="CPU utilizatior">
<template slot="right">
<ul>
<li><span>Avg:</span>{{ cpuUtilization.avg + cpuUtilization.units }}</li>
<li><span>Min:</span>{{ cpuUtilization.min + cpuUtilization.units }}</li>
<li><span>Max:</span>{{ cpuUtilization.max + cpuUtilization.units }}</li>
</ul>
</template>
<template slot="other">
<img
src="@/assets/images/abnormalAlarm/big.png"
@click="handelZoom('CPU utilizatior', option1)"
alt=""
/>
</template>
</BoxTitle>
<div class="cpu-content-item-chart" id="chart1"></div>
</div>
</a-col>
<a-col :span="12" style="height: calc(50% + 10px)">
<div class="cpu-content-item">
<BoxTitle title="Percentage of free system space">
<template slot="right">
<ul>
<li><span>Avg:</span>{{ cpuIdleRate.avg + cpuIdleRate.units }}</li>
<li><span>Min:</span>{{ cpuIdleRate.min + cpuIdleRate.units }}</li>
<li><span>Max:</span>{{ cpuIdleRate.max + cpuIdleRate.units }}</li>
</ul>
</template>
<template slot="other">
<img
src="@/assets/images/abnormalAlarm/big.png"
@click="handelZoom('Percentage of free system space', option2)"
alt=""
/>
</template>
</BoxTitle>
<div class="cpu-content-item-chart" id="chart2"></div>
</div>
</a-col>
<a-col :span="12" style="height: calc(50% + 10px)">
<div class="cpu-content-item">
<BoxTitle title="Interrupt and episodic switching">
<template slot="other">
<img
src="@/assets/images/abnormalAlarm/big.png"
@click="handelZoom('Interrupt and episodic switching', option3)"
alt=""
/>
</template>
</BoxTitle>
<div class="cpu-content-item-info">
<a-row style="height: 30px" type="flex">
<a-col flex="170px">Processor interrupt(s)</a-col>
<a-col flex="100px"
>Avg:<span>{{ multiLine.cpuInterrupt.avg + multiLine.cpuInterrupt.units }}</span></a-col
>
<a-col flex="100px"
>Min:<span>{{ multiLine.cpuInterrupt.min + multiLine.cpuInterrupt.units }}</span></a-col
>
<a-col flex="100px"
>Max:<span>{{ multiLine.cpuInterrupt.max + multiLine.cpuInterrupt.units }}</span></a-col
>
<a-col
><div style="background: #00a8ff" class="li-icon"></div>
<i>Processor interrupt</i></a-col
>
</a-row>
<a-row style="height: 30px" type="flex">
<a-col flex="170px">Situational switching(s)</a-col>
<a-col flex="100px"
>Avg:<span>{{ multiLine.cpuSwitch.avg + multiLine.cpuSwitch.units }}</span></a-col
>
<a-col flex="100px"
>Min:<span>{{ multiLine.cpuSwitch.min + multiLine.cpuSwitch.units }}</span></a-col
>
<a-col flex="100px"
>Max:<span>{{ multiLine.cpuSwitch.max + multiLine.cpuSwitch.units }}</span></a-col
>
<a-col
><div style="background: #73b54b" class="li-icon"></div>
<i>Situational switching(s)</i></a-col
>
</a-row>
<a-spin :spinning="spinning">
<a-row :gutter="[20, 15]" style="height: 100%">
<a-col :span="12" style="height: calc(50% + 10px)">
<div class="cpu-content-item">
<BoxTitle title="CPU utilizatior">
<template slot="right">
<ul>
<li><span>Avg:</span>{{ cpuUtilization.avg + cpuUtilization.units }}</li>
<li><span>Min:</span>{{ cpuUtilization.min + cpuUtilization.units }}</li>
<li><span>Max:</span>{{ cpuUtilization.max + cpuUtilization.units }}</li>
</ul>
</template>
<template slot="other">
<img
src="@/assets/images/abnormalAlarm/big.png"
@click="handelZoom('CPU utilizatior', option1)"
alt=""
/>
</template>
</BoxTitle>
<div class="cpu-content-item-chart" id="chart1"></div>
</div>
<div class="cpu-content-item-chart3" id="chart3"></div>
</div>
</a-col>
<a-col :span="12" style="height: calc(50% + 10px)">
<div class="cpu-content-item">
<BoxTitle title="CPU usage of diferent cores">
<template slot="other">
<img
src="@/assets/images/abnormalAlarm/big.png"
@click="handelZoom('CPU usage of diferent cores', option4)"
alt=""
/>
</template>
</BoxTitle>
<div class="cpu-content-item-chart" id="chart4"></div>
</div>
</a-col>
</a-row>
</a-col>
<a-col :span="12" style="height: calc(50% + 10px)">
<div class="cpu-content-item">
<BoxTitle title="Percentage of free system space">
<template slot="right">
<ul>
<li><span>Avg:</span>{{ cpuIdleRate.avg + cpuIdleRate.units }}</li>
<li><span>Min:</span>{{ cpuIdleRate.min + cpuIdleRate.units }}</li>
<li><span>Max:</span>{{ cpuIdleRate.max + cpuIdleRate.units }}</li>
</ul>
</template>
<template slot="other">
<img
src="@/assets/images/abnormalAlarm/big.png"
@click="handelZoom('Percentage of free system space', option2)"
alt=""
/>
</template>
</BoxTitle>
<div class="cpu-content-item-chart" id="chart2"></div>
</div>
</a-col>
<a-col :span="12" style="height: calc(50% + 10px)">
<div class="cpu-content-item">
<BoxTitle title="Interrupt and episodic switching">
<template slot="other">
<img
src="@/assets/images/abnormalAlarm/big.png"
@click="handelZoom('Interrupt and episodic switching', option3)"
alt=""
/>
</template>
</BoxTitle>
<div class="cpu-content-item-info">
<a-row style="height: 30px" type="flex">
<a-col flex="170px">Processor interrupt(s)</a-col>
<a-col flex="100px"
>Avg:<span>{{ multiLine.cpuInterrupt.avg + multiLine.cpuInterrupt.units }}</span></a-col
>
<a-col flex="100px"
>Min:<span>{{ multiLine.cpuInterrupt.min + multiLine.cpuInterrupt.units }}</span></a-col
>
<a-col flex="100px"
>Max:<span>{{ multiLine.cpuInterrupt.max + multiLine.cpuInterrupt.units }}</span></a-col
>
<a-col
><div style="background: #00a8ff" class="li-icon"></div>
<i>Processor interrupt</i></a-col
>
</a-row>
<a-row style="height: 30px" type="flex">
<a-col flex="170px">Situational switching(s)</a-col>
<a-col flex="100px"
>Avg:<span>{{ multiLine.cpuSwitch.avg + multiLine.cpuSwitch.units }}</span></a-col
>
<a-col flex="100px"
>Min:<span>{{ multiLine.cpuSwitch.min + multiLine.cpuSwitch.units }}</span></a-col
>
<a-col flex="100px"
>Max:<span>{{ multiLine.cpuSwitch.max + multiLine.cpuSwitch.units }}</span></a-col
>
<a-col
><div style="background: #73b54b" class="li-icon"></div>
<i>Situational switching(s)</i></a-col
>
</a-row>
</div>
<div class="cpu-content-item-chart3" id="chart3"></div>
</div>
</a-col>
<a-col :span="12" style="height: calc(50% + 10px)">
<div class="cpu-content-item">
<BoxTitle title="CPU usage of diferent cores">
<template slot="other">
<img
src="@/assets/images/abnormalAlarm/big.png"
@click="handelZoom('CPU usage of diferent cores', option4)"
alt=""
/>
</template>
</BoxTitle>
<div class="cpu-content-item-chart" id="chart4"></div>
</div>
</a-col>
</a-row>
</a-spin>
</div>
<a-modal :title="modalTitle" :width="1200" v-model="visible" :maskClosable="false" @cancel="onCancel">
<div class="modal-content" id="common_cpu"></div>
@ -176,7 +178,7 @@ import * as echarts from 'echarts'
import dateFormat from '@/components/jeecg/JEasyCron/format-date'
import BoxTitle from '../../components/boxTitle.vue'
import CreateRules from './createRules.vue'
import { getAction, postAction, httpAction, deleteAction } from '@/api/manage'
import { getAction, postAction } from '@/api/manage'
export default {
components: {
BoxTitle,
@ -184,6 +186,7 @@ export default {
},
data() {
return {
spinning: false,
currId: '',
visible_rule: false,
currLabel: '',
@ -234,6 +237,17 @@ export default {
mounted() {
this.getServerList()
},
watch: {
$route: {
handler: function (val, oldVal) {
if (val.query && val.query.serverId) {
this.getServerList()
}
},
deep: true,
immediate: true,
},
},
methods: {
handleRefresh() {
if (!this.userDefined) {
@ -251,58 +265,63 @@ export default {
start: this.queryParams.startDate,
end: this.queryParams.endDate,
}
getAction('/systemMonitor/queryHostDetails', params).then((res) => {
const data = res.result
//CPU utilizatior
this.cpuUtilization = data.find((item) => item.name === 'cpuUtilization')
this.cpuUtilization_xData = this.cpuUtilization.list.map((item) => {
return dateFormat(new Date(item.date * 1000), 'hh:mm')
})
this.cpuUtilization_data = this.cpuUtilization.list.map((item) => {
return Number(item.value.toFixed(2))
})
//Percentage of free system space
this.cpuIdleRate = data.find((item) => item.name === 'cpuIdleRate')
this.cpuIdleRate_xData = this.cpuIdleRate.list.map((item) => {
return dateFormat(new Date(item.date * 1000), 'hh:mm')
})
this.cpuIdleRate_data = this.cpuIdleRate.list.map((item) => {
return Number(item.value.toFixed(2))
})
// Interrupt and episodic switching
;(this.multiLine.cpuInterrupt = data.find((item) => item.name === 'cpuInterrupt')),
(this.multiLine.cpuSwitch = data.find((item) => item.name === 'cpuSwitch')),
(this.multiLine_xData = this.multiLine.cpuInterrupt.list.map((item) => {
this.spinning = true
getAction('/systemMonitor/queryHostDetails', params)
.then((res) => {
const data = res.result
//CPU utilizatior
this.cpuUtilization = data.find((item) => item.name === 'cpuUtilization')
this.cpuUtilization_xData = this.cpuUtilization.list.map((item) => {
return dateFormat(new Date(item.date * 1000), 'hh:mm')
}))
this.cpuInterrupt_data = this.multiLine.cpuInterrupt.list.map((item) => {
return Number(item.value.toFixed(2))
})
this.cpuSwitch_data = this.multiLine.cpuSwitch.list.map((item) => {
return Number(item.value.toFixed(2))
})
//CPU使
let totalCpu = []
data.map((item) => {
if (item.name.search('cpuUtilization_') != -1) {
totalCpu.push(item)
}
})
this.cpuDiff_xData = totalCpu[0].list.map((item) => {
return dateFormat(new Date(item.date * 1000), 'hh:mm')
})
this.cpuDiff_data = totalCpu.map((item) => {
return {
name: item.name,
data: item.list.map((el) => Number(el.value.toFixed(2))),
}
})
})
this.cpuUtilization_data = this.cpuUtilization.list.map((item) => {
return Number(item.value.toFixed(2))
})
//Percentage of free system space
this.cpuIdleRate = data.find((item) => item.name === 'cpuIdleRate')
this.cpuIdleRate_xData = this.cpuIdleRate.list.map((item) => {
return dateFormat(new Date(item.date * 1000), 'hh:mm')
})
this.cpuIdleRate_data = this.cpuIdleRate.list.map((item) => {
return Number(item.value.toFixed(2))
})
// Interrupt and episodic switching
;(this.multiLine.cpuInterrupt = data.find((item) => item.name === 'cpuInterrupt')),
(this.multiLine.cpuSwitch = data.find((item) => item.name === 'cpuSwitch')),
(this.multiLine_xData = this.multiLine.cpuInterrupt.list.map((item) => {
return dateFormat(new Date(item.date * 1000), 'hh:mm')
}))
this.cpuInterrupt_data = this.multiLine.cpuInterrupt.list.map((item) => {
return Number(item.value.toFixed(2))
})
this.cpuSwitch_data = this.multiLine.cpuSwitch.list.map((item) => {
return Number(item.value.toFixed(2))
})
//CPU使
let totalCpu = []
data.map((item) => {
if (item.name.search('cpuUtilization_') != -1) {
totalCpu.push(item)
}
})
this.cpuDiff_xData = totalCpu[0].list.map((item) => {
return dateFormat(new Date(item.date * 1000), 'hh:mm')
})
this.cpuDiff_data = totalCpu.map((item) => {
return {
name: item.name,
data: item.list.map((el) => Number(el.value.toFixed(2))),
}
})
this.drawChart1()
this.drawChart2()
this.drawChart3()
this.drawChart4()
})
this.drawChart1()
this.drawChart2()
this.drawChart3()
this.drawChart4()
})
.finally(() => {
this.spinning = false
})
},
getBeforeHours(num) {
let currentTime = moment()
@ -828,6 +847,14 @@ export default {
height: calc(100% - 60px);
margin-top: 10px;
overflow: hidden;
/deep/.ant-spin-nested-loading {
width: 100%;
height: 100%;
}
/deep/.ant-spin-container {
width: 100%;
height: 100%;
}
&-item {
width: 100%;
height: 100%;

View File

@ -292,7 +292,7 @@ export default {
if (res.success) {
this.itemOptions = res.result.map((item) => {
return {
label: item.name,
label: item.units ? `${item.name}(${item.units})` : item.name,
value: item.itemId,
units: item.units,
valueType: item.valueType,

View File

@ -1,364 +1,361 @@
<template>
<div style="height: 100%">
<div class="content-top">
<div style="width: calc(100% - 562px)">
<BoxTitle title="Basic lnformation"></BoxTitle>
<div class="basic-info">
<div
class="basic-info-list"
v-infinite-scroll="handleInfiniteOnLoad"
:infinite-scroll-disabled="busy"
:infinite-scroll-distance="5"
>
<a-list :dataSource="dataSource">
<a-list-item
:class="{ 'ant-list-item-active': index === currIndex }"
slot="renderItem"
slot-scope="item, index"
@click="handleBasicItem(index, item)"
>
<div>{{ item.sourceName }}</div>
</a-list-item>
</a-list>
<a-spin :spinning="spinning">
<div class="content-top">
<div style="width: calc(100% - 562px)">
<BoxTitle title="Basic lnformation"></BoxTitle>
<div class="basic-info">
<div
class="basic-info-list"
v-infinite-scroll="handleInfiniteOnLoad"
:infinite-scroll-disabled="busy"
:infinite-scroll-distance="5"
>
<a-list :dataSource="dataSource">
<a-list-item
:class="{ 'ant-list-item-active': index === currIndex }"
slot="renderItem"
slot-scope="item, index"
@click="handleBasicItem(index, item)"
>
<div>{{ item.sourceName }}</div>
</a-list-item>
</a-list>
<div v-if="loading && !busy" class="demo-loading-container">
<a-spin />
<div v-if="loading && !busy" class="demo-loading-container">
<a-spin />
</div>
</div>
</div>
<div class="basic-info-detail">
<a-row :gutter="10" style="height: 40px">
<a-col :span="6" style="height: 100%">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/running.png" alt="" />
</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">running state</div>
<div class="basic-info-detail">
<a-row :gutter="10" style="height: 40px">
<a-col :span="6" style="height: 100%">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/running.png" alt="" />
</div>
<div class="basic-info-detail-col-msg-num state">
{{ `${detailInfo.runningState ? 'NORMAL' : 'ERROR'}` }}
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">running state</div>
</div>
<div class="basic-info-detail-col-msg-num state">
{{ `${detailInfo.runningState ? 'NORMAL' : 'ERROR'}` }}
</div>
</div>
</div>
</div>
</a-col>
<a-col :span="5" style="height: 100%">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/alarm.png" alt="" />
</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">Alarm SMS</div>
</a-col>
<a-col :span="5" style="height: 100%">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/alarm.png" alt="" />
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.alarmSms }}</div>
</div>
</div>
</a-col>
<a-col :span="6" style="height: 100%; padding-left: 12px">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/email.png" alt="" />
</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">Alarm email</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">Alarm SMS</div>
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.alarmSms }}</div>
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.alarmEmail }}</div>
</div>
</div>
</a-col>
<a-col :span="7" style="height: 100%">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/warning.png" alt="" />
</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">Number of alarms</div>
</a-col>
<a-col :span="6" style="height: 100%; padding-left: 12px">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/email.png" alt="" />
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.alarms }}</div>
</div>
</div>
</a-col>
</a-row>
<a-row :gutter="10" style="height: 40px; margin-top: 10px">
<a-col :span="6" style="height: 100%">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/times.png" alt="" />
</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">Run time</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">Alarm email</div>
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.alarmEmail }}</div>
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.runTime }}</div>
</div>
</div>
</a-col>
<a-col :span="5" style="height: 100%">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/ram.png" alt="" />
</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">RAM Size</div>
</a-col>
<a-col :span="7" style="height: 100%">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/warning.png" alt="" />
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.ramSize }}</div>
</div>
</div>
</a-col>
<a-col :span="6" style="height: 100%; padding-left: 12px">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/cpu.png" alt="" />
</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">CPU Cores</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">Number of alarms</div>
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.alarms }}</div>
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.cpuCores }}</div>
</div>
</div>
</a-col>
<a-col :span="7" style="height: 100%">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/partition.png" alt="" />
</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">Total Disk Partition</div>
</a-col>
</a-row>
<a-row :gutter="10" style="height: 40px; margin-top: 10px">
<a-col :span="6" style="height: 100%">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/times.png" alt="" />
</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">Run time</div>
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.runTime }}</div>
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.totalDiskPar }}</div>
</div>
</div>
</a-col>
</a-row>
<div class="basic-info-detail-content">
<a-row style="height: 100%">
<a-col :span="12">
<a-row style="height: 26px">
<a-col :span="12" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="12" class="basic-info-detail-content-key">Host Name:</a-col>
<a-col :span="12" class="basic-info-detail-content-val">{{ detailInfo.hostName }}</a-col>
</a-row>
</a-col>
<a-col :span="12" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="12" class="basic-info-detail-content-key">Bios Version:</a-col>
<a-col :span="12" class="basic-info-detail-content-val">FX705GM.307</a-col>
<!-- <a-col :span="12" class="basic-info-detail-content-key">OS Version:</a-col>
</a-col>
<a-col :span="5" style="height: 100%">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/ram.png" alt="" />
</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">RAM Size</div>
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.ramSize }}</div>
</div>
</div>
</a-col>
<a-col :span="6" style="height: 100%; padding-left: 12px">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/cpu.png" alt="" />
</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">CPU Cores</div>
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.cpuCores }}</div>
</div>
</div>
</a-col>
<a-col :span="7" style="height: 100%">
<div class="basic-info-detail-col">
<div class="basic-info-detail-col-img">
<img src="~@/assets/images/abnormalAlarm/partition.png" alt="" />
</div>
<div class="basic-info-detail-col-msg">
<div class="basic-info-detail-col-msg-title">
<div class="circle"></div>
<div class="title">Total Disk Partition</div>
</div>
<div class="basic-info-detail-col-msg-num">{{ detailInfo.totalDiskPar }}</div>
</div>
</div>
</a-col>
</a-row>
<div class="basic-info-detail-content">
<a-row style="height: 100%">
<a-col :span="12">
<a-row style="height: 26px">
<a-col :span="12" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="12" class="basic-info-detail-content-key">Host Name:</a-col>
<a-col :span="12" class="basic-info-detail-content-val">{{ detailInfo.hostName }}</a-col>
</a-row>
</a-col>
<a-col :span="12" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="12" class="basic-info-detail-content-key">Bios Version:</a-col>
<a-col :span="12" class="basic-info-detail-content-val">FX705GM.307</a-col>
<!-- <a-col :span="12" class="basic-info-detail-content-key">OS Version:</a-col>
<a-col :span="12" class="basic-info-detail-content-val">{{ detailInfo.osVersion }}</a-col> -->
</a-row>
</a-col>
</a-row>
<a-row style="height: 26px">
<a-col :span="12" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="12" class="basic-info-detail-content-key">IP Address:</a-col>
<a-col :span="12" class="basic-info-detail-content-val">{{ detailInfo.ip }}</a-col>
</a-row>
</a-col>
<a-col :span="12" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="12" class="basic-info-detail-content-key">Kernel version:</a-col>
<a-col :span="12" class="basic-info-detail-content-val">2000</a-col>
</a-row>
</a-col>
</a-row>
<a-row style="height: 26px">
<a-col :span="4" style="height: 26px" class="basic-info-detail-content-key">OS Name:</a-col>
<a-col :span="20" style="height: 26px" class="basic-info-detail-content-val">
{{ detailInfo.osName }}
</a-col>
<!-- <a-col :span="12" style="height: 26px">
</a-row>
</a-col>
</a-row>
<a-row style="height: 26px">
<a-col :span="12" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="12" class="basic-info-detail-content-key">IP Address:</a-col>
<a-col :span="12" class="basic-info-detail-content-val">{{ detailInfo.ip }}</a-col>
</a-row>
</a-col>
<a-col :span="12" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="12" class="basic-info-detail-content-key">Kernel version:</a-col>
<a-col :span="12" class="basic-info-detail-content-val">2000</a-col>
</a-row>
</a-col>
</a-row>
<a-row style="height: 26px">
<a-col :span="4" style="height: 26px" class="basic-info-detail-content-key">OS Name:</a-col>
<a-col :span="20" style="height: 26px" class="basic-info-detail-content-val">
{{ detailInfo.osName }}
</a-col>
<!-- <a-col :span="12" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="12" class="basic-info-detail-content-key">OS Name:</a-col>
<a-col :span="12" class="basic-info-detail-content-val">{{ detailInfo.osName }}</a-col>
</a-row>
</a-col> -->
<!-- <a-col :span="12" style="height: 26px">
<!-- <a-col :span="12" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="12" class="basic-info-detail-content-key">Bios Version:</a-col>
<a-col :span="12" class="basic-info-detail-content-val">FX705GM.307</a-col>
</a-row>
</a-col> -->
</a-row>
<a-row style="height: 26px">
<a-col :span="4" style="height: 26px" class="basic-info-detail-content-key">CPU:</a-col>
<a-col :span="20" style="height: 26px" class="basic-info-detail-content-val">
{{ detailInfo.cpuType }}
</a-col>
</a-row>
<a-row style="height: 26px">
<a-col :span="6" style="height: 26px" class="basic-info-detail-content-key">Manufacturer:</a-col>
<a-col :span="18" style="height: 26px" class="basic-info-detail-content-val"
>ASUSTeK COMPUTER INC.</a-col
>
</a-row>
<a-row style="height: 26px">
<a-col :span="8" style="height: 26px" class="basic-info-detail-content-key"
>Server Agent Path:</a-col
>
<a-col :span="16" style="height: 26px" class="basic-info-detail-content-val"
>C:\Agent\Default\Desktop</a-col
>
</a-row>
</a-col>
<a-col :span="12">
<a-row style="height: 26px">
<a-col :span="11" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="18" class="basic-info-detail-content-key">Network Lnterface:</a-col>
<a-col :span="6" class="basic-info-detail-content-val">{{ detailInfo.network }}</a-col>
</a-row>
</a-col>
<a-col :span="13" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="15" class="basic-info-detail-content-key">Location:</a-col>
<a-col :span="9" class="basic-info-detail-content-val">{{ detailInfo.location }}</a-col>
</a-row>
</a-col>
</a-row>
<a-row style="height: 26px">
<a-col :span="11" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="18" class="basic-info-detail-content-key">Time Zone:</a-col>
<a-col :span="6" class="basic-info-detail-content-val">{{ detailInfo.zone }}</a-col>
</a-row>
</a-col>
<a-col :span="13" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="15" class="basic-info-detail-content-key">Server Agent User:</a-col>
<a-col :span="9" class="basic-info-detail-content-val">LocalSystem</a-col>
</a-row>
</a-col>
</a-row>
<a-row style="height: 26px">
<a-col :span="7" style="height: 26px" class="basic-info-detail-content-key">OS Version:</a-col>
<a-col :span="17" style="height: 26px" class="basic-info-detail-content-val"
>2023-03-01 14:00:01</a-col
>
</a-row>
<a-row style="height: 26px">
<a-col :span="7" style="height: 26px" class="basic-info-detail-content-key">Start Time:</a-col>
<a-col :span="17" style="height: 26px" class="basic-info-detail-content-val">
{{ detailInfo.osVersion }}
</a-col>
</a-row>
<a-row style="height: 26px">
<a-col :span="7" style="height: 26px" class="basic-info-detail-content-key">Model Number:</a-col>
<a-col :span="17" style="height: 26px" class="basic-info-detail-content-val"
>TUF GamingFX705GM_FX86SM</a-col
>
</a-row>
<a-row style="height: 26px">
<a-col :span="7" style="height: 26px" class="basic-info-detail-content-key">Bios Supplier:</a-col>
<a-col :span="17" style="height: 26px" class="basic-info-detail-content-val"
>American Megatrends lnc.</a-col
>
</a-row>
</a-col>
</a-row>
</a-row>
<a-row style="height: 26px">
<a-col :span="4" style="height: 26px" class="basic-info-detail-content-key">CPU:</a-col>
<a-col :span="20" style="height: 26px" class="basic-info-detail-content-val">
{{ detailInfo.cpuType }}
</a-col>
</a-row>
<a-row style="height: 26px">
<a-col :span="6" style="height: 26px" class="basic-info-detail-content-key">Manufacturer:</a-col>
<a-col :span="18" style="height: 26px" class="basic-info-detail-content-val"
>ASUSTeK COMPUTER INC.</a-col
>
</a-row>
<a-row style="height: 26px">
<a-col :span="8" style="height: 26px" class="basic-info-detail-content-key"
>Server Agent Path:</a-col
>
<a-col :span="16" style="height: 26px" class="basic-info-detail-content-val"
>C:\Agent\Default\Desktop</a-col
>
</a-row>
</a-col>
<a-col :span="12">
<a-row style="height: 26px">
<a-col :span="11" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="18" class="basic-info-detail-content-key">Network Lnterface:</a-col>
<a-col :span="6" class="basic-info-detail-content-val">{{ detailInfo.network }}</a-col>
</a-row>
</a-col>
<a-col :span="13" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="15" class="basic-info-detail-content-key">Location:</a-col>
<a-col :span="9" class="basic-info-detail-content-val">{{ detailInfo.location }}</a-col>
</a-row>
</a-col>
</a-row>
<a-row style="height: 26px">
<a-col :span="11" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="18" class="basic-info-detail-content-key">Time Zone:</a-col>
<a-col :span="6" class="basic-info-detail-content-val">{{ detailInfo.zone }}</a-col>
</a-row>
</a-col>
<a-col :span="13" style="height: 26px">
<a-row style="height: 100%">
<a-col :span="15" class="basic-info-detail-content-key">Server Agent User:</a-col>
<a-col :span="9" class="basic-info-detail-content-val">LocalSystem</a-col>
</a-row>
</a-col>
</a-row>
<a-row style="height: 26px">
<a-col :span="7" style="height: 26px" class="basic-info-detail-content-key">OS Version:</a-col>
<a-col :span="17" style="height: 26px" class="basic-info-detail-content-val"
>2023-03-01 14:00:01</a-col
>
</a-row>
<a-row style="height: 26px">
<a-col :span="7" style="height: 26px" class="basic-info-detail-content-key">Start Time:</a-col>
<a-col :span="17" style="height: 26px" class="basic-info-detail-content-val">
{{ detailInfo.osVersion }}
</a-col>
</a-row>
<a-row style="height: 26px">
<a-col :span="7" style="height: 26px" class="basic-info-detail-content-key">Model Number:</a-col>
<a-col :span="17" style="height: 26px" class="basic-info-detail-content-val"
>TUF GamingFX705GM_FX86SM</a-col
>
</a-row>
<a-row style="height: 26px">
<a-col :span="7" style="height: 26px" class="basic-info-detail-content-key">Bios Supplier:</a-col>
<a-col :span="17" style="height: 26px" class="basic-info-detail-content-val"
>American Megatrends lnc.</a-col
>
</a-row>
</a-col>
</a-row>
</div>
</div>
</div>
</div>
<div class="alarm-info" style="width: 542px">
<BoxTitle title="Alarm information"></BoxTitle>
<div
class="alarm-info-list"
style="margin-bottom: 15px"
v-infinite-scroll="handleInfiniteAlarmInfo"
:infinite-scroll-disabled="busy_alarm_info"
:infinite-scroll-distance="10"
>
<a-list :dataSource="dataSource_alarm_info">
<a-list-item slot="renderItem" slot-scope="item">
<img class="alarm-info-list-img" src="@/assets/images/abnormalAlarm/icon-r.png" alt="" />
<div class="alarm-info-list-info" :title="item.alarmInfo">{{ item.alarmInfo }}</div>
<div class="alarm-info-list-date">{{ item.alarmStartDate }}</div>
<!-- <a slot="actions" class="alarm-info-list-actions">Detail</a> -->
</a-list-item>
</a-list>
<div v-if="loading_alarm_info && !busy" class="demo-loading-container">
<a-spin />
</div>
</div>
</div>
</div>
<div class="alarm-info" style="width: 542px">
<BoxTitle title="Alarm information"></BoxTitle>
<div
class="alarm-info-list"
v-infinite-scroll="handleInfiniteAlarmInfo"
:infinite-scroll-disabled="busy_alarm_info"
:infinite-scroll-distance="10"
>
<a-list :dataSource="dataSource_alarm_info">
<a-list-item slot="renderItem" slot-scope="item">
<img class="alarm-info-list-img" src="@/assets/images/abnormalAlarm/icon-r.png" alt="" />
<div class="alarm-info-list-info" :title="item.alarmInfo">{{ item.alarmInfo }}</div>
<div class="alarm-info-list-date">{{ item.alarmStartDate }}</div>
<!-- <a slot="actions" class="alarm-info-list-actions">Detail</a> -->
</a-list-item>
</a-list>
<div v-if="loading_alarm_info && !busy" class="demo-loading-container">
<a-spin />
<div class="content-center">
<BoxTitle title="Event Timelinen">
<template slot="right">
<ul class="legend-list">
<li v-for="(item, index) in types" :key="index">
<div :style="`background:${item.color}`" class="li-icon"></div>
{{ item.name }}
</li>
</ul>
</template>
</BoxTitle>
<div class="line-bg"></div>
<div class="time-line" id="timeLine"></div>
</div>
<div class="content-bottom">
<div class="content-bottom-left">
<div class="content-bottom-left-top">
<a-row :gutter="20">
<a-col class="gutter-row" :span="8">
<BoxTitle title="CPU"></BoxTitle>
<div class="gauge-content" id="cpu"></div>
</a-col>
<a-col class="gutter-row" :span="8">
<BoxTitle title="MEMORY"></BoxTitle>
<div class="gauge-content" id="memory"></div>
</a-col>
<a-col class="gutter-row" :span="8">
<BoxTitle title="RESPONSE"></BoxTitle>
<div class="gauge-content" id="responseSuccessRate"></div>
</a-col>
</a-row>
</div>
<div class="content-bottom-left-bottom">
<BoxTitle title="CPU utilization">
<template slot="right">
<div class="right-title">
<div class="right-title-item">
average value:<i>{{ cpuData.avg }}%</i>
</div>
<div class="right-title-item">
minimum value:<i>{{ cpuData.min }}%</i>
</div>
<div class="right-title-item">
Maximum value:<i>{{ cpuData.max }}%</i>
</div>
</div>
</template>
</BoxTitle>
<div class="area-cpu" id="areaCpu"></div>
</div>
</div>
</div>
</div>
<!-- <div class="Timeline">
<p>事件时间线</p>
<div>
<div id="timeL" style="width: 100%; height: 140px"></div>
</div>
</div> -->
<div class="content-center">
<BoxTitle title="Event Timelinen">
<template slot="right">
<ul class="legend-list">
<li v-for="(item, index) in types" :key="index">
<div :style="`background:${item.color}`" class="li-icon"></div>
{{ item.name }}
</li>
</ul>
</template>
</BoxTitle>
<div class="line-bg"></div>
<div class="time-line" id="timeLine"></div>
</div>
<div class="content-bottom">
<div class="content-bottom-left">
<div class="content-bottom-left-top">
<a-row :gutter="20">
<a-col class="gutter-row" :span="8">
<BoxTitle title="CPU"></BoxTitle>
<div class="gauge-content" id="cpu"></div>
</a-col>
<a-col class="gutter-row" :span="8">
<BoxTitle title="MEMORY"></BoxTitle>
<div class="gauge-content" id="memory"></div>
</a-col>
<a-col class="gutter-row" :span="8">
<BoxTitle title="RESPONSE"></BoxTitle>
<div class="gauge-content" id="responseSuccessRate"></div>
</a-col>
</a-row>
</div>
<div class="content-bottom-left-bottom">
<BoxTitle title="CPU utilization">
<template slot="right">
<div class="right-title">
<div class="right-title-item">
average value:<i>{{ cpuData.avg }}%</i>
</div>
<div class="right-title-item">
minimum value:<i>{{ cpuData.min }}%</i>
</div>
<div class="right-title-item">
Maximum value:<i>{{ cpuData.max }}%</i>
</div>
</div>
</template>
</BoxTitle>
<div class="area-cpu" id="areaCpu"></div>
<div style="width: 542px">
<BoxTitle title="DISK"></BoxTitle>
<div class="bar-disk" id="disk"></div>
</div>
</div>
<div style="width: 542px">
<BoxTitle title="DISK"></BoxTitle>
<div class="bar-disk" id="disk"></div>
</div>
</div>
</a-spin>
</div>
</template>
@ -417,6 +414,7 @@ export default {
},
data() {
return {
spinning: false,
types,
dataSource: [],
loading: false,
@ -454,162 +452,64 @@ export default {
},
}
},
mounted() {
this.getSysServer((res) => {
this.loading = false
if (res.success) {
this.ipagination.total = res.result.total
this.dataSource = res.result.records
if (this.$route.query.serverId) {
this.serverId = this.$route.query.serverId
this.currIndex = this.dataSource.findIndex((item) => item.sourceId === this.serverId)
this.currHostId = this.dataSource.find((item) => item.sourceId === this.serverId).hostId
this.currSourceId = this.dataSource.find((item) => item.sourceId === this.serverId).sourceId
this.currItemId = this.dataSource.find((item) => item.sourceId === this.serverId).cpuUsedItemId
} else {
this.currHostId = this.dataSource[0].hostId
this.currSourceId = this.dataSource[0].sourceId
this.currItemId = this.dataSource[0].cpuUsedItemId
this.currIndex = 0
watch: {
$route: {
handler: function (val, oldVal) {
if (val.query && val.query.serverId) {
this.getData()
}
this.getBasiclnfo(this.currHostId)
this.getCpuUtilizationData()
this.getTimeLineData()
// this.EchartsTimeline()
this.getDetailsAlarmInfo((res) => {
this.loading_alarm_info = false
if (res.success) {
this.ipagination_alarm_info.total = res.result.total
this.dataSource_alarm_info = res.result.records
} else {
this.$message.warning('This operation fails. Contact your system administrator')
}
})
} else {
this.$message.warning('This operation fails. Contact your system administrator')
}
})
// this.$nextTick(() => {
// setTimeout(() => {
// this.drawGuageLoads()
// }, 0)
// })
},
deep: true,
immediate: true,
},
},
mounted() {
this.getData()
},
// activated() {},
methods: {
// Echarts (线)
// EchartsTimeline() {
// const params = {
// itemId: '37550',
// itemType: 0,
// start: '2023-09-21 00:00:00',
// end: '2023-09-21 18:54:00',
// }
// getAction('/systemMonitor/queryItemHistoryData', params).then((res) => {
// let data = res.result
// const percentage = 100 / data.length
// let indexArr = [[0, 0]]
// for (let i = 1; i < data.length; i++) {
// const num = i + 1
// if (i === data.length - 1) {
// indexArr[0][1] = data.length
// }
// if (data[i - 1].value != data[i].value) {
// indexArr[0][1] = i
// indexArr.unshift([i, num])
// }
// }
// let objArr = [],
// echartData = []
// indexArr.map((item) => {
// objArr.push(data.slice(item[0], item[1]))
// })
// const statusConversion = (val) => {
// if (val == 1) {
// return ''
// } else if (val == 2) {
// return ''
// } else {
// return '线'
// }
// }
// objArr.map((item, index) => {
// let obj = null
// if (index === 0) {
// const arr = objArr[index + 1]
// let timeInterval
// if (arr) {
// timeInterval = [item[0].date, arr[arr.length - 1].date]
// } else {
// timeInterval = [item[0].date, item[item.length - 1].date]
// }
// obj = {
// type: 'Cpu',
// value: statusConversion(item[0].value),
// valueInterval: [0, item.length * percentage],
// timeInterval: timeInterval, //
// }
// } else if (index === objArr.length - 1) {
// const arr = echartData[echartData.length - 1]
// obj = {
// type: 'Cpu',
// value: statusConversion(item[0].value),
// valueInterval: [arr.valueInterval[1], 100],
// timeInterval: [arr.timeInterval[1], item[0].date], //
// }
// } else {
// const arr = echartData[echartData.length - 1],
// arr1 = objArr[index + 1],
// num = arr.valueInterval[1],
// length = item.length * percentage
// obj = {
// type: 'Cpu',
// value: statusConversion(item[0].value),
// valueInterval: [num, length + num],
// timeInterval: [arr.timeInterval[1], arr1[arr1.length - 1].date], //
// }
// }
// echartData.push(obj)
// })
// if (this.barPlot) {
// this.barPlot.changeData(echartData)
// return
// }
// const timeDateHours = (val) => {
// return moment(val).format('HH:mm')
// }
// this.barPlot = new Bar('timeL', {
// data: echartData.reverse(),
// xField: 'valueInterval',
// yField: 'type',
// isRange: true,
// seriesField: 'value',
// padding: 20,
// yAxis: {
// label: null,
// },
// xAxis: {
// label: {
// formatter: (params) => {
// const percentage = params / 100,
// index = parseInt((data.length - 1) * percentage)
// return timeDateHours(data[index].date)
// },
// },
// },
// legend: {
// position: "top-left'",
// },
// tooltip: false,
// })
// this.barPlot.render()
// })
// },
getData() {
this.getSysServer((res) => {
this.loading = false
if (res.success) {
this.ipagination.total = res.result.total
this.dataSource = res.result.records
if (this.$route.query.serverId) {
this.serverId = this.$route.query.serverId
this.currIndex = this.dataSource.findIndex((item) => item.sourceId === this.serverId)
this.currHostId = this.dataSource.find((item) => item.sourceId === this.serverId).hostId
this.currSourceId = this.dataSource.find((item) => item.sourceId === this.serverId).sourceId
this.currItemId = this.dataSource.find((item) => item.sourceId === this.serverId).cpuUsedItemId
} else {
this.currHostId = this.dataSource[0].hostId
this.currSourceId = this.dataSource[0].sourceId
this.currItemId = this.dataSource[0].cpuUsedItemId
this.currIndex = 0
}
this.getBasiclnfo(this.currHostId)
this.getCpuUtilizationData()
this.getTimeLineData()
// this.EchartsTimeline()
this.getDetailsAlarmInfo((res) => {
this.loading_alarm_info = false
if (res.success) {
this.ipagination_alarm_info.total = res.result.total
this.dataSource_alarm_info = res.result.records
} else {
this.$message.warning('This operation fails. Contact your system administrator')
}
})
} else {
this.$message.warning('This operation fails. Contact your system administrator')
}
})
},
moment,
// Basic lnformation
getBasiclnfo(sourceId) {
let params = { hostId: sourceId }
getAction('/sysServer/detailsBasicInfo', params).then((res) => {
this.spinning = false
if (res.success) {
this.detailInfo = res.result
this.drawGuageCpu()
@ -630,6 +530,7 @@ export default {
end: dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss'),
}
getAction('/systemMonitor/queryItemHistoryData', params).then((res) => {
this.spinning = false
const arr = res.result.map((x) => x.value)
this.cpuData.max = Math.max(...arr).toFixed(2)
this.cpuData.min = Math.min(...arr).toFixed(2)
@ -654,6 +555,7 @@ export default {
end: `${dateFormat(new Date(), 'yyyy-MM-dd')} 23:59:59`,
}
getAction('/systemMonitor/queryItemHistoryData', params).then((res) => {
this.spinning = false
let data = res.result
startTime = data[0].clock * 1000
let indexArr = [[0, 0]]
@ -727,6 +629,7 @@ export default {
}
},
handleBasicItem(i, item) {
this.spinning = true
this.currIndex = i
this.currItemId = item.cpuUsedItemId
this.currSourceId = item.sourceId
@ -1700,4 +1603,12 @@ export default {
width: 100%;
text-align: center;
}
/deep/.ant-spin-nested-loading {
width: 100%;
height: 100%;
}
/deep/.ant-spin-container {
width: 100%;
height: 100%;
}
</style>

View File

@ -1,6 +1,6 @@
<template>
<div style="height: 100%;">
<a-card :bordered="false" style="height:100%;margin-left: 20px;">
<div style="height: 100%">
<a-card :bordered="false" style="height: 100%; margin-left: 20px">
<a-tabs default-active-key="detais" @change="handleTabChange">
<a-tab-pane key="detais" tab="DETAILS">
<Details></Details>
@ -14,22 +14,22 @@
<a-tab-pane key="cpu" tab="CPU">
<Cpu></Cpu>
</a-tab-pane>
<a-tab-pane key="memory" tab="MEMORY">
<!-- <a-tab-pane key="memory" tab="MEMORY">
MEMORY
</a-tab-pane>
<a-tab-pane key="disk" tab="DISK">
DISK
</a-tab-pane>
</a-tab-pane> -->
</a-tabs>
</a-card>
</div>
</template>
<script>
import Details from './details.vue';
import ServiceProcess from './serviceProcess.vue';
import Monitor from './monitor.vue';
import Cpu from './cpu.vue';
import Details from './details.vue'
import ServiceProcess from './serviceProcess.vue'
import Monitor from './monitor.vue'
import Cpu from './cpu.vue'
export default {
components: {
Details,
@ -39,13 +39,12 @@ export default {
},
methods: {
handleTabChange(key) {
console.log(key);
console.log(key)
},
},
}
</script>
<style lang="less" scoped>
@import "~@/assets/less/TabMenu.less";
@import '~@/assets/less/TabMenu.less';
</style>

View File

@ -49,22 +49,24 @@
</div>
</div>
<div class="monitor-content">
<a-row :gutter="[20, 15]" style="height: 100%">
<a-col v-for="(item, index) in chartDatas" :key="item.title" :span="8" style="height: 34%">
<div class="monitor-content-item">
<LineChart
:title="item.title"
:layout="'line' + index"
:xData="item.xData"
:dataSource="item.data"
:newUnits="item.newUnits"
:units="item.units"
@zoom="handelZoom"
>
</LineChart>
</div>
</a-col>
</a-row>
<a-spin :spinning="spinning">
<a-row :gutter="[20, 15]" style="height: 100%">
<a-col v-for="(item, index) in chartDatas" :key="item.title" :span="8" style="height: 34%">
<div class="monitor-content-item">
<LineChart
:title="item.title"
:layout="'line' + index"
:xData="item.xData"
:dataSource="item.data"
:newUnits="item.newUnits"
:units="item.units"
@zoom="handelZoom"
>
</LineChart>
</div>
</a-col>
</a-row>
</a-spin>
</div>
<a-modal :title="modalTitle" :width="1200" v-model="visible" :maskClosable="false" @cancel="onCancel">
<div class="modal-content" id="common"></div>
@ -85,7 +87,7 @@ import moment from 'moment'
import * as echarts from 'echarts'
import dateFormat from '@/components/jeecg/JEasyCron/format-date'
import BoxTitle from '../../components/boxTitle.vue'
import { getAction, postAction, httpAction, deleteAction } from '@/api/manage'
import { getAction, postAction } from '@/api/manage'
import LineChart from './lineChart.vue'
import CreateRules from './createRules.vue'
export default {
@ -94,19 +96,19 @@ export default {
LineChart,
CreateRules,
},
computed:{
unitConversion(){
return function(number,units){
if( units === 'Kb') {
number = number *1024
computed: {
unitConversion() {
return function (number, units) {
if (units === 'Kb') {
number = number * 1024
}
if (number < 1024 ) return "B"
if (number < 1024) return 'B'
number = number / 1024
if (number < 1024) return "KB"
if (number < 1024) return 'KB'
number = number / 1024
if (number < 1024) return "MB"
if (number < 1024) return 'MB'
number = number / 1024
console.log('TB',number)
console.log('TB', number)
if (number < 1024) return 'GB'
number = number / 1024
if (number < 1024) return 'TB'
@ -116,23 +118,24 @@ export default {
if (number < 1024) return 'EB'
}
},
dataConversion(){
return function(number,units){
dataConversion() {
return function (number, units) {
const obj = {
KB: 1024,
MB: Math.pow(1024,2),
GB: Math.pow(1024,3),
TB: Math.pow(1024,4),
PB: Math.pow(1024,5),
EB: Math.pow(1024,6),
MB: Math.pow(1024, 2),
GB: Math.pow(1024, 3),
TB: Math.pow(1024, 4),
PB: Math.pow(1024, 5),
EB: Math.pow(1024, 6),
}
// console.log(obj[units],number / obj[units])
return (number / obj[units]).toFixed(2)
}
}
},
},
data() {
return {
spinning: false,
currId: '',
visible_rule: false,
currLabel: '',
@ -163,6 +166,17 @@ export default {
mounted() {
this.getServerList()
},
watch: {
$route: {
handler: function (val, oldVal) {
if (val.query && val.query.serverId) {
this.getServerList()
}
},
deep: true,
immediate: true,
},
},
methods: {
handleRefresh() {
if (!this.userDefined) {
@ -176,10 +190,11 @@ export default {
sourceType: 'Server',
sourceId: this.currId,
}
this.spinning = true
getAction('/alarmRule/getItems', params).then((res) => {
if (res.success) {
this.MonitorItem = res.result
this.chartDatas = this.MonitorItem.map(f=>({
this.chartDatas = this.MonitorItem.map((f) => ({
title: f.name,
value: f.itemId,
type: f.valueType,
@ -207,7 +222,8 @@ export default {
}
try {
const res = await this.getMonitorItemData(params)
console.log("getMonitorItemData>",res);
this.spinning = false
console.log('getMonitorItemData>', res)
item.xData = res.xData
item.data = [
{
@ -219,6 +235,7 @@ export default {
item.newUnits = res.newUnits
} catch (error) {
console.error(error)
this.spinning = false
}
})
},
@ -234,21 +251,21 @@ export default {
return dateFormat(new Date(item.date * 1000), 'hh:mm')
})
let item = res.result;
if(item.units === 'B' || item.units === 'Kb'){
item.newUnits = this.unitConversion(item.min,item.units)
newUnits = item.newUnits
item.list.map(val =>{
let item = res.result
if (item.units === 'B' || item.units === 'Kb') {
item.newUnits = this.unitConversion(item.min, item.units)
newUnits = item.newUnits
item.list.map((val) => {
let number = val.value
if(item.units ==="Kb"){
number = val.value *1024
if (item.units === 'Kb') {
number = val.value * 1024
}
val.value = Number(this.dataConversion(number,item.newUnits))
data.push({
value: Number(val.value),
Date: moment(val.date * 1000).format('hh:mm')
})
val.value = Number(this.dataConversion(number, item.newUnits))
data.push({
value: Number(val.value),
Date: moment(val.date * 1000).format('hh:mm'),
})
})
console.log(item)
} else {
data = res.result.list.map((item_1) => {
@ -260,7 +277,7 @@ export default {
xData,
data,
units,
newUnits
newUnits,
}
}
},
@ -402,6 +419,14 @@ export default {
height: calc(100% - 60px);
margin-top: 10px;
overflow: hidden;
/deep/.ant-spin-nested-loading {
width: 100%;
height: 100%;
}
/deep/.ant-spin-container {
width: 100%;
height: 100%;
}
&-item {
width: 100%;
height: 100%;

View File

@ -57,63 +57,47 @@
</div>
</div>
<div class="service-content">
<div class="service-content-ranked">
<BoxTitle title="Top-ranked processes in the last hour">
<template slot="right">
<ul class="legend-list">
<li v-for="(item, index) in ranked.legend" :key="index">
<div :style="`background:${ranked.color[index]}`" class="li-icon"></div>
{{ item }}
</li>
</ul>
</template>
</BoxTitle>
<div class="service-content-ranked-box" id="ranked"></div>
</div>
<div class="service-content-center">
<a-row :gutter="20">
<a-col :span="12">
<BoxTitle title="Process CPU usage(%)">
<!-- <template slot="right">
<ul class="legend-list">
<li v-for="(item, index) in processCpu.legend" :key="index">
<div :style="`background:${processCpu.color[index]}`" class="li-icon"></div>
{{ item }}
</li>
</ul>
</template> -->
</BoxTitle>
<div class="service-content-center-item" id="processCpu"></div>
</a-col>
<a-col :span="12">
<BoxTitle title="Process memory usage(%)">
<!-- <template slot="right">
<ul class="legend-list">
<li v-for="(item, index) in processMenbry.legend" :key="index">
<div :style="`background:${processMenbry.color[index]}`" class="li-icon"></div>
{{ item }}
</li>
</ul>
</template> -->
</BoxTitle>
<div class="service-content-center-item" id="menbry"></div>
</a-col>
</a-row>
</div>
<div class="service-content-table">
<BoxTitle title="Service"></BoxTitle>
<div style="padding-top: 10px">
<TableList
size="middle"
rowKey="id"
:columns="columns"
:list="dataSource"
:loading="loading"
:pagination="false"
:canSelect="false"
>
</TableList>
<!-- <a-pagination
<a-spin :spinning="spinning">
<div class="service-content-ranked">
<BoxTitle title="Top-ranked processes in the last hour">
<template slot="right">
<ul class="legend-list">
<li v-for="(item, index) in ranked.legend" :key="index">
<div :style="`background:${ranked.color[index]}`" class="li-icon"></div>
{{ item }}
</li>
</ul>
</template>
</BoxTitle>
<div class="service-content-ranked-box" id="ranked"></div>
</div>
<div class="service-content-center">
<a-row :gutter="20">
<a-col :span="12">
<BoxTitle title="Process CPU usage(%)" />
<div class="service-content-center-item" id="processCpu"></div>
</a-col>
<a-col :span="12">
<BoxTitle title="Process memory usage(%)" />
<div class="service-content-center-item" id="menbry"></div>
</a-col>
</a-row>
</div>
<div class="service-content-table">
<BoxTitle title="Service" />
<div style="padding-top: 10px">
<TableList
size="middle"
rowKey="id"
:columns="columns"
:list="dataSource"
:loading="loading"
:pagination="false"
:canSelect="false"
:scroll="{ y: 186 }"
>
</TableList>
<!-- <a-pagination
size="small"
v-model="ipagination.current"
:pageSize="ipagination.pageSize"
@ -129,8 +113,9 @@
@change="handlePageChange"
@showSizeChange="handleSizeChange"
/> -->
</div>
</div>
</div>
</a-spin>
</div>
</div>
</template>
@ -140,7 +125,7 @@ import moment from 'moment'
import BoxTitle from '../../components/boxTitle.vue'
import TableList from '../../components/tableList.vue'
import dateFormat from '@/components/jeecg/JEasyCron/format-date'
import { getAction, postAction, httpAction, deleteAction } from '@/api/manage'
import { getAction } from '@/api/manage'
import * as echarts from 'echarts'
// const columns = [
// {
@ -193,27 +178,33 @@ import * as echarts from 'echarts'
// },
// ]
const columns = [{
title: 'Name',
dataIndex: 'name',
width: '20%'
}, {
title: 'Min(%)',
dataIndex: 'min',
width: '20%'
}, {
title: 'Max(%)',
dataIndex: 'max',
width: '20%'
}, {
title: 'Avg(%)',
dataIndex: 'avg',
width: '20%'
}, {
title: 'Now(%)',
dataIndex: 'now',
width: '20%'
}]
const columns = [
{
title: 'Name',
dataIndex: 'name',
width: '20%',
},
{
title: 'Min(%)',
dataIndex: 'min',
width: '20%',
},
{
title: 'Max(%)',
dataIndex: 'max',
width: '20%',
},
{
title: 'Avg(%)',
dataIndex: 'avg',
width: '20%',
},
{
title: 'Now(%)',
dataIndex: 'now',
width: '20%',
},
]
export default {
components: {
BoxTitle,
@ -221,6 +212,7 @@ export default {
},
data() {
return {
spinning: false,
type: 'cpu',
queryParams: {
server: undefined,
@ -294,6 +286,17 @@ export default {
setTimeout(() => {}, 0)
})
},
watch: {
$route: {
handler: function (val, oldVal) {
if (val.query && val.query.serverId) {
this.getServerList()
}
},
deep: true,
immediate: true,
},
},
methods: {
handleRefresh() {
if (!this.userDefined) {
@ -312,71 +315,75 @@ export default {
start: this.queryParams.startDate,
end: this.queryParams.endDate,
}
const hide = this.$message.loading('loading...', 0)
getAction('/systemMonitor/queryHostDetails', params).then((res) => {
this.list = res.result
this.listData = {
list: this.num === 0 ? this.list.cpu : this.list.memory,
type: this.num === 0 ? 'CPU' : '内存',
}
this.setTableData()
let cpu_xData = res.result.cpu[0].list.map((item) => {
return dateFormat(new Date(item.date * 1000), 'hh:mm')
})
let cpu_Data = res.result.cpu.map((item) => {
return {
name: item.name,
data: item.list.map((el) => Number((el.value * 100).toFixed(2))),
// const hide = this.$message.loading('loading...', 0)
this.spinning = true
getAction('/systemMonitor/queryHostDetails', params)
.then((res) => {
this.list = res.result
this.listData = {
list: this.num === 0 ? this.list.cpu : this.list.memory,
type: this.num === 0 ? 'CPU' : '内存',
}
})
let cpu_legend = res.result.cpu.map((item) => {
return item.name
})
let memory_xData = res.result.memory[0].list.map((item) => {
return dateFormat(new Date(item.date * 1000), 'hh:mm')
})
let memory_Data = res.result.memory.map((item) => {
return {
name: item.name,
data: item.list.map((el) => Number((el.value * 100).toFixed(2))),
}
})
let memory_legend = res.result.memory.map((item) => {
return item.name
})
this.rankData = {
type: this.type === 'cpu' ? 'CPU' : 'Memory',
cpu_xData,
cpu_Data,
memory_xData,
memory_Data,
}
this.ranked.legend = this.type === 'cpu' ? cpu_legend : memory_legend
this.processCpu.xData = cpu_xData
// this.processCpu.data = res.result.cpu.map((item) => {
// return {
// name: item.name,
// data: item.list.map((el) => el.value),
// }
// })
this.processCpu.data = cpu_Data
this.processMenbry.xData = memory_xData
// this.processMenbry.data = res.result.memory.map((item) => {
// return {
// name: item.name,
// data: item.list.map((el) => el.value),
// }
// })
this.processMenbry.data = memory_Data
this.drawRanked()
this.drawProcesCpu()
this.drawProcesMenbry()
}).finally(() => {
hide()
})
this.setTableData()
let cpu_xData = res.result.cpu[0].list.map((item) => {
return dateFormat(new Date(item.date * 1000), 'hh:mm')
})
let cpu_Data = res.result.cpu.map((item) => {
return {
name: item.name,
data: item.list.map((el) => Number((el.value * 100).toFixed(2))),
}
})
let cpu_legend = res.result.cpu.map((item) => {
return item.name
})
let memory_xData = res.result.memory[0].list.map((item) => {
return dateFormat(new Date(item.date * 1000), 'hh:mm')
})
let memory_Data = res.result.memory.map((item) => {
return {
name: item.name,
data: item.list.map((el) => Number((el.value * 100).toFixed(2))),
}
})
let memory_legend = res.result.memory.map((item) => {
return item.name
})
this.rankData = {
type: this.type === 'cpu' ? 'CPU' : 'Memory',
cpu_xData,
cpu_Data,
memory_xData,
memory_Data,
}
this.ranked.legend = this.type === 'cpu' ? cpu_legend : memory_legend
this.processCpu.xData = cpu_xData
// this.processCpu.data = res.result.cpu.map((item) => {
// return {
// name: item.name,
// data: item.list.map((el) => el.value),
// }
// })
this.processCpu.data = cpu_Data
this.processMenbry.xData = memory_xData
// this.processMenbry.data = res.result.memory.map((item) => {
// return {
// name: item.name,
// data: item.list.map((el) => el.value),
// }
// })
this.processMenbry.data = memory_Data
this.drawRanked()
this.drawProcesCpu()
this.drawProcesMenbry()
})
.finally(() => {
// hide()
this.spinning = false
})
},
getBeforeHours(num) {
let currentTime = moment()

View File

@ -156,9 +156,9 @@ const columns = [
},
},
{
title: 'DISK USAGE',
title: 'MEMORY FREE',
align: 'center',
dataIndex: 'diskUsage',
dataIndex: 'memoryFree',
scopedSlots: {
customRender: 'disk',
},

View File

@ -17,7 +17,7 @@
</template>
<!-- 标题结束 -->
<!-- 内容 -->
<a-spin :spinning="isGettingTreeData" style="margin-top: 80px; width: 100%; text-align: center;"> </a-spin>
<a-spin :spinning="isGettingTreeData" style="margin-top: 80px; width: 100%; text-align: center"> </a-spin>
<tree-with-line
v-if="treeData.length"
:treeData="treeData"
@ -30,6 +30,21 @@
</a-card>
<!-- 日志列表 -->
<div class="log-list">
<div class="search-bar">
<a-row type="flex">
<a-col flex="290px">
<a-form-model-item label="Name">
<a-input v-model="nameStr" placeholder="Please Input..." />
</a-form-model-item>
</a-col>
<a-col flex="108px">
<a-button class="search-btn" type="primary" @click="onSearch">
<img src="@/assets/images/global/search.png" alt="" />
Search
</a-button>
</a-col>
</a-row>
</div>
<custom-table
size="middle"
rowKey="id"
@ -39,7 +54,7 @@
:loading="isGettingTreeData || loading"
:can-select="false"
@change="handleTableChange"
:scroll="{ y: 'calc(100vh - 175px)' }"
:scroll="{ y: 'calc(100vh - 275px)' }"
>
<template slot="operate" slot-scope="{ record }">
<a-space :size="20">
@ -53,13 +68,30 @@
</a-space>
</template>
</custom-table>
<a-pagination
size="small"
v-model="ipagination.current"
:pageSize="ipagination.pageSize"
:page-size-options="ipagination.pageSizeOptions"
show-size-changer
show-quick-jumper
:total="ipagination.total"
:show-total="
(total, range) =>
`Total ${total} items Page ${ipagination.current} / ${Math.ceil(total / ipagination.pageSize)}`
"
show-less-items
@change="handlePageChange"
@showSizeChange="handleSizeChange"
/>
</div>
<!-- 日志列表结束 -->
<custom-modal title="Log" :width="950" v-model="visible" :footer="null">
<a-spin class="log-detail" :spinning="isGettingDetail">
<div v-for="(logItem, index) in logInfo" :key="index">
<pre style="font-family: 仿宋">{{ logInfo }}</pre>
<!-- <div style="font-family: 宋体" v-for="(logItem, index) in logInfo" :key="index">
{{ logItem }}
</div>
</div> -->
</a-spin>
</custom-modal>
</div>
@ -74,42 +106,43 @@ const columns = [
title: 'NAME',
align: 'center',
width: 320,
dataIndex: 'fileName'
dataIndex: 'fileName',
},
{
title: 'DATE',
align: 'center',
width: 200,
dataIndex: 'fileDate'
dataIndex: 'fileDate',
},
{
title: 'SIZE',
align: 'center',
width: 220,
dataIndex: 'fileSize'
dataIndex: 'fileSize',
},
{
title: 'OPERATE',
align: 'center',
width: 200,
scopedSlots: {
customRender: 'operate'
}
}
customRender: 'operate',
},
},
]
export default {
name: 'LogManage',
mixins: [JeecgListMixin],
components: {
TreeWithLine
TreeWithLine,
},
data() {
this.columns = columns
return {
nameStr: '',
disableMixinCreated: true,
url: {
list: '/logManage/findFiles'
list: '/logManage/findFiles',
},
isGettingTreeData: false, //
treeData: [],
@ -119,13 +152,38 @@ export default {
visible: false,
isGettingDetail: false,
logInfo: []
logInfo: [],
ipagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
const { current, pageSize } = this.ipagination
return `Total ${total} items Page ${current} / ${Math.ceil(total / pageSize)}`
},
showQuickJumper: true,
showSizeChanger: true,
total: 0,
},
}
},
created() {
this.getTreeData()
},
methods: {
onSearch() {
this.loadData()
},
handlePageChange(page, pageSize) {
this.ipagination.current = page
this.ipagination.pageSize = pageSize
this.loadData()
},
handleSizeChange(current, size) {
this.ipagination.current = current
this.ipagination.pageSize = size
this.loadData()
},
async getTreeData() {
try {
this.isGettingTreeData = true
@ -148,11 +206,11 @@ export default {
*/
buildTreeData(treeJson) {
const tree = []
treeJson.forEach(item => {
treeJson.forEach((item) => {
const treeNode = {
title: item.name,
key: item.path,
children: []
children: [],
}
if (item.children && item.children.length) {
treeNode.children.push(...this.buildTreeData(item.children))
@ -163,6 +221,8 @@ export default {
},
onSelect() {
this.queryParam.path = this.selectedKeys[0]
this.ipagination.current = 1
this.ipagination.pageSize = 10
this.loadData()
},
@ -178,10 +238,14 @@ export default {
this.onClearSelected()
var params = this.getQueryParams() //
params.name = this.nameStr
params.pageNo = this.ipagination.current
params.pageSize = this.ipagination.pageSize
this.loading = true
getAction(this.url.list, params)
.then(res => {
this.dataSource = res
.then(({ result: { records, total } }) => {
this.dataSource = records
this.ipagination.total = total
})
.finally(() => {
this.loading = false
@ -200,7 +264,8 @@ export default {
try {
this.isGettingDetail = true
const res = await postAction('/logManage/downloadFile', formData)
this.logInfo = res.split('\r\n')
// this.logInfo = res.split('\r\n')
this.logInfo = res
} catch (error) {
console.error(error)
} finally {
@ -216,8 +281,8 @@ export default {
formData.append('fileName', fileName)
formData.append('localPath', filePath)
downloadFile('/logManage/downloadFile', fileName, formData, 'post')
}
}
},
},
}
</script>
<style lang="less" scoped>
@ -300,6 +365,10 @@ export default {
}
}
}
&-list {
position: relative;
overflow: hidden;
}
}
.log-detail {
@ -312,4 +381,59 @@ export default {
}
}
}
.search-bar {
height: 50px;
border-top: 1px solid rgba(13, 235, 201, 0.3);
border-bottom: 1px solid rgba(13, 235, 201, 0.3);
margin-bottom: 15px;
padding: 8px 10px;
background: rgba(12, 235, 201, 0.05);
}
.ant-input {
width: 266px;
}
::v-deep {
.ant-form-item {
display: flex;
margin-bottom: 0;
.ant-form-item-label,
.ant-form-item-control {
line-height: 32px;
height: 32px;
}
.ant-form-item-label {
flex-shrink: 0;
margin-right: 10px;
label {
font-size: 16px;
font-family: ArialMT;
color: #ade6ee;
&::after {
display: none;
}
}
}
.ant-calendar-range-picker-separator {
color: white;
}
.ant-form-item-control-wrapper {
width: 100%;
// overflow: hidden;
}
}
}
.search-btn {
margin-bottom: 10px;
img {
width: 16px;
height: 17px;
margin-right: 9px;
}
}
.ant-pagination {
position: absolute;
left: 50%;
bottom: 0;
transform: translateX(-50%);
}
</style>

View File

@ -6,28 +6,28 @@
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="6" :sm="8">
<a-form-item label="消息标题">
<a-input placeholder="请输入消息标题" v-model="queryParam.esTitle"></a-input>
<a-form-item label="Message header">
<a-input placeholder="Please enter the message title" v-model="queryParam.esTitle"></a-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="发送内容">
<a-input placeholder="请输入发送内容" v-model="queryParam.esContent"></a-input>
<a-form-item label="Send content">
<a-input placeholder="Please enter the content to send" v-model="queryParam.esContent"></a-input>
</a-form-item>
</a-col>
<template v-if="toggleSearchStatus">
<a-col :md="6" :sm="8">
<a-form-item label="接收人">
<a-input placeholder="请输入接收人" v-model="queryParam.esReceiver"></a-input>
<a-form-item label="receiver">
<a-input placeholder="Please enter the recipient" v-model="queryParam.esReceiver"></a-input>
</a-form-item>
</a-col>
</template>
<a-col :md="6" :sm="8">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
<a-button type="primary" @click="searchQuery" icon="search">Search</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">Reset</a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
{{ toggleSearchStatus ? 'Pack up' : 'unfold' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
@ -39,20 +39,20 @@
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" v-show="show" type="primary" icon="plus">新增</a-button>
<a-button type="primary" v-show="show" icon="download" @click="handleExportXls('消息')">导出</a-button>
<a-button @click="handleAdd" v-show="show" type="primary" icon="plus">ADD</a-button>
<a-button type="primary" v-show="show" icon="download" @click="handleExportXls('消息')">Export</a-button>
<a-upload v-show="show" name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl"
@change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
<a-button type="primary" icon="import">Import</a-button>
</a-upload>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
<a-icon type="delete"/>
删除
Delete
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作
<a-button style="margin-left: 8px"> Batch operation
<a-icon type="down"/>
</a-button>
</a-dropdown>
@ -61,9 +61,9 @@
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{
selectedRowKeys.length }}</a>
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
<i class="anticon anticon-info-circle ant-alert-icon"></i> Selected <a style="font-weight: 600">{{
selectedRowKeys.length }}</a>item
<a style="margin-left: 24px" @click="onClearSelected">Clear</a>
</div>
<a-table
@ -84,17 +84,17 @@
</span>
<span slot="action" slot-scope="text, record">
<a href="javascript:;" @click="handleDetail(record)">详情</a>
<a href="javascript:;" @click="handleDetail(record)">Details</a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">更多<a-icon type="down"/></a>
<a class="ant-dropdown-link">More<a-icon type="down"/></a>
<a-menu slot="overlay">
<a-menu-item v-show="show">
<a @click="handleEdit(record)">编辑</a>
<a @click="handleEdit(record)">Edit</a>
</a-menu-item>
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
<a-popconfirm title="Are you sure to delete it?" @confirm="() => handleDelete(record.id)">
<a>Delete</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
@ -124,7 +124,7 @@
},
data() {
return {
description: '消息管理页面',
description: 'Message management page',
//
show: false,
//
@ -140,43 +140,43 @@
}
},
{
title: '消息标题',
title: 'Message header',
align: "center",
dataIndex: 'esTitle'
},
{
title: '发送内容',
title: 'Send content',
align: "center",
dataIndex: 'esContent',
scopedSlots: {customRender: 'esContent'},
},
{
title: '接收人',
title: 'receiver',
align: "center",
dataIndex: 'esReceiver'
},
{
title: '发送次数',
title: 'Transmission times',
align: "center",
dataIndex: 'esSendNum'
},
{
title: '发送状态',
title: 'Send state',
align: 'center',
dataIndex: 'esSendStatus_dictText'
},
{
title: '发送时间',
title: 'Send time',
align: "center",
dataIndex: 'esSendTime'
},
{
title: '发送方式',
title: 'Send mode',
align: 'center',
dataIndex: 'esType_dictText'
},
{
title: '操作',
title: 'Operation',
dataIndex: 'action',
align: "center",
scopedSlots: {customRender: 'action'},

View File

@ -7,33 +7,33 @@
<a-row :gutter="24">
<a-col :md="6" :sm="8">
<a-form-item label="模板CODE">
<a-input placeholder="请输入模板CODE" v-model="queryParam.templateCode"></a-input>
<a-form-item label="TEMPLATE CODE">
<a-input placeholder="Please enter the template CODE" v-model="queryParam.templateCode"></a-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="模板内容">
<a-input placeholder="请输入模板内容" v-model="queryParam.templateContent"></a-input>
<a-form-item label="TEMPLATE Content">
<a-input placeholder="Please enter the template content" v-model="queryParam.templateContent"></a-input>
</a-form-item>
</a-col>
<template v-if="toggleSearchStatus">
<a-col :md="6" :sm="8">
<a-form-item label="模板标题">
<a-input placeholder="请输入模板标题" v-model="queryParam.templateName"></a-input>
<a-form-item label="TEMPLATE Title">
<a-input placeholder="Please enter the template title" v-model="queryParam.templateName"></a-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="8">
<a-form-item label="模板类型">
<j-dict-select-tag placeholder="请选择模板类型" v-model="queryParam.templateType" dictCode="msgType"></j-dict-select-tag>
<a-form-item label="TEMPLATE Type">
<j-dict-select-tag placeholder="Please check the template type" v-model="queryParam.templateType" dictCode="msgType"></j-dict-select-tag>
</a-form-item>
</a-col>
</template>
<a-col :md="6" :sm="8">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
<a-button type="primary" @click="searchQuery" icon="search">Search</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">Reset</a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
{{ toggleSearchStatus ? 'Pack up' : 'unfold' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
@ -45,11 +45,11 @@
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('消息模板')">导出</a-button>
<a-button @click="handleAdd" type="primary" icon="plus">ADD</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('消息模版')">Export</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl"
@change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
<a-button type="primary" icon="import">Import</a-button>
</a-upload>
<!-- <a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
@ -67,9 +67,9 @@
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{
selectedRowKeys.length }}</a>
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
<i class="anticon anticon-info-circle ant-alert-icon"></i> Selected <a style="font-weight: 600">{{
selectedRowKeys.length }}</a>item
<a style="margin-left: 24px" @click="onClearSelected">Clear</a>
</div>
<a-table
@ -91,26 +91,26 @@
<span slot="action" slot-scope="text, record">
<a @click="handleMyEdit(record)">编辑</a>
<a @click="handleMyEdit(record)">Edit</a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">更多 <a-icon type="down"/></a>
<a class="ant-dropdown-link">More <a-icon type="down"/></a>
<a-menu slot="overlay">
<a-menu-item>
<a @click="handleUse(record)">应用</a>
<a @click="handleUse(record)">Use</a>
</a-menu-item>
<a-menu-item>
<a @click="handleNotUse(record)">停用</a>
<a @click="handleNotUse(record)">NotUse</a>
</a-menu-item>
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record)">
<a>删除</a>
<a-popconfirm title="Are you sure to delete it?" @confirm="() => handleDelete(record)">
<a>Delete</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item>
<a @click="handleTest(record)">发送测试</a>
<a @click="handleTest(record)">Send test</a>
</a-menu-item>
</a-menu>
</a-dropdown>
@ -148,7 +148,7 @@
},
data() {
return {
description: '消息模板管理页面',
description: 'Message template Management page',
//
columns: [
{
@ -162,48 +162,48 @@
}
},
{
title: '模板CODE',
title: 'templateCode',
align: "center",
dataIndex: 'templateCode'
},
{
title: '模板标题',
title: 'templateTitle',
align: "center",
dataIndex: 'templateName'
},
{
title: '模板内容',
title: 'templateContent',
align: "center",
dataIndex: 'templateContent',
scopedSlots: {customRender: 'templateContent'},
},
{
title: '模板类型',
title: 'templateType',
align: "center",
dataIndex: 'templateType',
customRender: function (text) {
if(text=='1') {
return "文本";
return "TEXT";
}
if(text=='2') {
return "富文本";
return "Rich text";
}
}
},
{
title: '是否应用',
title: 'useStatus',
align: "center",
dataIndex: 'useStatus',
customRender: function (text) {
if(text=='1') {
return "";
return "YES";
}else{
return ''
return 'NO'
}
}
},
{
title: '操作',
title: 'action',
dataIndex: 'action',
align: "center",
scopedSlots: {customRender: 'action'},
@ -226,7 +226,7 @@
methods: {
handleTest(record){
this.$refs.testModal.open(record);
this.$refs.testModal.title = "发送测试";
this.$refs.testModal.title = "Send test";
},
//update-begin-author:taoyan date:2022-7-8 for:
updateUseStatus(record, useStatus){
@ -251,7 +251,7 @@
},
handleMyEdit(record){
if(record.useStatus == '1'){
this.$message.warning('此模板已被应用,禁止编辑!');
this.$message.warning('This template has been applied and editing is prohibited!');
}else{
this.handleEdit(record);
}
@ -260,11 +260,11 @@
handleDelete: function (record) {
if(!this.url.delete){
this.$message.error("请设置url.delete属性!")
this.$message.error("Please set the url.delete property!")
return
}
if(record.useStatus=='1'){
this.$message.error("该模板已被应用禁止删除!")
this.$message.error("The template is prohibited from being deleted by the application!")
return
}
let id = record.id;

View File

@ -15,70 +15,70 @@
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="消息标题">
<a-input placeholder="请输入消息标题" v-decorator="['esTitle', {}]"/>
label="Message header">
<a-input placeholder="Please enter the message title" v-decorator="['esTitle', {}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="发送内容">
<a-input placeholder="请输入发送内容" v-decorator="['esContent', {}]"/>
label="Send content">
<a-input placeholder="Please enter the content to send" v-decorator="['esContent', {}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="发送所需参数">
<a-input placeholder="请输入发送所需参数Json格式" v-decorator="['esParam', {}]"/>
label="Send required parameters">
<a-input placeholder="Please enter the required parameters in Json format" v-decorator="['esParam', {}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="接收人">
<a-input placeholder="请输入接收人" v-decorator="['esReceiver', {}]"/>
label="receiver">
<a-input placeholder="Please enter the recipient" v-decorator="['esReceiver', {}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="发送方式">
<j-dict-select-tag :triggerChange="true" dictCode="msgType" v-decorator="[ 'esType', {}]" placeholder="请选择发送方式">
label="Sending mode">
<j-dict-select-tag :triggerChange="true" dictCode="msgType" v-decorator="[ 'esType', {}]" placeholder="Please select a sending method">
</j-dict-select-tag>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="发送时间">
label="Sending time">
<a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' v-decorator="[ 'esSendTime', {}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="发送状态">
<j-dict-select-tag :triggerChange="true" dictCode="msgSendStatus" v-decorator="[ 'esSendStatus', {}]" placeholder="请选择发送状态">
label="Sending state">
<j-dict-select-tag :triggerChange="true" dictCode="msgSendStatus" v-decorator="[ 'esSendStatus', {}]" placeholder="Please select Send status">
</j-dict-select-tag>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="发送次数">
label="Transmission times">
<a-input-number v-decorator="[ 'esSendNum', {}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="发送失败原因">
label="Cause of sending failure">
<a-input v-decorator="['esResult', {}]"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="备注">
label="remark">
<a-input v-decorator="['remark', {}]"/>
</a-form-item>
</a-form>
</a-spin>
<div v-show="!disableSubmit">
<a-button style="margin-right: .8rem" @confirm="handleCancel">取消</a-button>
<a-button @click="handleOk" type="primary" :loading="confirmLoading">提交</a-button>
<a-button style="margin-right: .8rem" @confirm="handleCancel">Cancel</a-button>
<a-button @click="handleOk" type="primary" :loading="confirmLoading">Submit</a-button>
</div>
</a-drawer>
</template>
@ -92,7 +92,7 @@
name: "SysMessageModal",
data() {
return {
title: "操作",
title: "Operation",
visible: false,
model: {},
labelCol: {

View File

@ -6,70 +6,67 @@
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
cancelText="Cancel">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-row :gutter="{ xs: 8, sm: 16, md: 24, lg: 32 }">
<a-col :span="12">
<a-row class="form-row" :gutter="24" >
<a-col :span="24">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板CODE"
style="margin-right: -35px"
label="Template Code"
>
<a-input
:disabled="disable"
placeholder="请输入模板编码"
placeholder="Please enter the template code"
v-decorator="['templateCode', validatorRules.templateCode ]"
/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-col :span="24">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板类型">
<j-dict-select-tag @change="handleChangeTemplateType" :triggerChange="true" dictCode="msgType" v-decorator="['templateType', validatorRules.templateType ]" placeholder="请选择模板类型">
label="Template type">
<j-dict-select-tag @change="handleChangeTemplateType" :triggerChange="true" dictCode="msgType" v-decorator="['templateType', validatorRules.templateType ]" placeholder="Please select a template type">
</j-dict-select-tag>
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="24" >
<a-col :span="24" pull="2">
<a-col :span="24">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板标题"
style="margin-left: -15px">
label="Template title">
<a-input
placeholder="请输入模板标题"
placeholder="Please enter the template title"
v-decorator="['templateName', validatorRules.templateName]"
style="width: 122%"
style="width: 100%"
/>
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="24" >
<a-col :span="24" pull="2">
<a-col :span="24">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="是否应用"
label="useStatus"
style="margin-left: -15px">
<j-switch v-decorator="['useStatus', validatorRules.useStatus]" :options="['1', '0']"></j-switch>
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="24">
<a-col :span="24" pull="4">
<a-col :span="24">
<a-form-item
v-show="!useEditor"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板内容"
style="margin-left: 4px;width: 126%">
<a-textarea placeholder="请输入模板内容" v-decorator="['templateContent', validatorRules.templateContent ]" :autosize="{ minRows: 8, maxRows: 8 }"/>
label="Template content">
<a-textarea placeholder="Please enter the template content" v-decorator="['templateContent', validatorRules.templateContent ]" :autosize="{ minRows: 8, maxRows: 8 }"/>
</a-form-item>
</a-col>
</a-row>
@ -79,7 +76,7 @@
v-show="useEditor"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板内容"
label="Template content"
style="margin-left: 4px;width: 126%">
<j-editor v-model="templateEditorContent"></j-editor>
</a-form-item>
@ -106,7 +103,7 @@
},
data() {
return {
title: "操作",
title: "Operation",
visible: false,
disable: true,
model: {},
@ -121,11 +118,11 @@
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules: {
templateCode: {rules: [{required: true, message: '请输入模板CODE!' },{validator: this.validateTemplateCode}]},
templateName: {rules: [{required: true, message: '请输入模板标题!'}]},
templateCode: {rules: [{required: true, message: 'Please enter the template Code!' },{validator: this.validateTemplateCode}]},
templateName: {rules: [{required: true, message: 'Please enter the template title!'}]},
templateContent: {rules: []},
useStatus:{rules: []},
templateType: {rules: [{required: true, message: '请输入模板类型!'}]},
templateType: {rules: [{required: true, message: 'Please enter the template type!'}]},
},
url: {
add: "/sys/message/sysMessageTemplate/add",

View File

@ -6,43 +6,43 @@
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
cancelText="Cancel">
<a-spin :spinning="confirmLoading">
<a-form>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板标题">
label="Template title">
<a-input disabled v-model="templateName"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="模板内容">
label="Template content">
<a-textarea disabled v-model="templateContent" :autosize="{ minRows: 5, maxRows: 8 }"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="测试数据">
<a-textarea placeholder="请输入json格式测试数据" v-model="testData" :autosize="{ minRows: 5, maxRows: 8 }"/>
label="Test data">
<a-textarea placeholder="Please enter the test data in json format" v-model="testData" :autosize="{ minRows: 5, maxRows: 8 }"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="消息类型">
label="Message type">
<j-dict-select-tag
v-model="msgType"
type="radio"
placeholder="请选择消息类型"
placeholder="Please select a message type"
dictCode="messageType"/>
</a-form-item>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="消息接收方">
<j-select-user-by-dep placeholder="请选择消息接收方" v-model="receiver"></j-select-user-by-dep>
label="Message receiver">
<j-select-user-by-dep placeholder="Please select a message recipient" v-model="receiver"></j-select-user-by-dep>
</a-form-item>
</a-form>
</a-spin>
@ -60,7 +60,7 @@
},
data() {
return {
title: "操作",
title: "Operation",
visible: false,
model: {},
labelCol: {

View File

@ -7,17 +7,17 @@
Detailed-Information
<beta-gamma-detailed-infomation slot="content" :data="spectrumData" />
</pop-over-with-icon>
<pop-over-with-icon placement="bottomLeft">
QC Flags
<beta-gamma-qc-flags slot="content" :data="qcFlags" @click="handleQcFlagClick" />
</pop-over-with-icon>
<custom-select
v-model="spectraType"
:options="SampleType"
@change="changeChartByType"
style="width: 246px"
style="width: 154px"
class="sample-select"
></custom-select>
<pop-over-with-icon placement="right" v-model="qcFlagsVisible" :auto-adjust-overflow="false">
QC Flags
<beta-gamma-qc-flags slot="content" :data="qcFlags" @click="handleQcFlagClick" />
</pop-over-with-icon>
</div>
<!-- 二级交互栏结束 -->
@ -26,7 +26,7 @@
<!-- 左侧图表 -->
<div class="beta-gamma-spectrum-sample">
<beta-gamma-chart-container>
<template slot="title"> Beta-Gamma Spectrum: Sample </template>
<template slot="title"> Beta-Gamma Spectrum: {{ currSpectrum }} </template>
<beta-gamma-spectrum-chart
ref="betaGammaChartRef"
:histogramDataList="histogramDataList"
@ -121,6 +121,7 @@
</template>
<script>
import { addSampleData, getSampleData, sampleList, setSampleList, updateSampleData } from '@/utils/SampleStore'
import { getAction, postAction } from '../../api/manage'
import BetaGammaChartContainer from './components/BetaGammaChartContainer.vue'
import BetaGammaSpectrumChart from './components/BetaGammaSpectrumChart.vue'
@ -134,6 +135,7 @@ import PopOverWithIcon from './components/SubOperators/PopOverWithIcon.vue'
import Spectra from './components/SubOperators/Spectra.vue'
import CustomSelect from '@/components/CustomSelect/index.vue'
import axios from 'axios'
import { cloneDeep } from 'lodash'
const StatisticsType = {
'Collection Time': 'Colloc_Time',
@ -161,6 +163,8 @@ const SampleType = [
},
]
const sortList = ['Xe131m', 'Xe133', 'Xe133m', 'Xe135']
export default {
components: {
BetaGammaChartContainer,
@ -186,16 +190,19 @@ export default {
analyseCurrentSpectrum: {
type: Object,
},
sampleList: {
type: Array,
required: true,
},
},
data() {
this.SampleType = SampleType
this.sampleDetail = {}
return {
currSpectrum: '',
// analyseCurrentSpectrum: {},
qcFlags: {},
sampleDetail: {},
spectraVisible: false,
spectraType: 'sample',
@ -224,15 +231,24 @@ export default {
statisticModalVisible: false, // Qc Flags
statisticsType: StatisticsType['Collection Time'],
currSample: {},
copyXeData: null,
qcFlagsVisible: false,
}
},
created() {
this.$bus.$on('ReAnalyses', this.handleReAnalyse)
},
destroyed() {
mounted() {
this.qcFlagsTimer = setTimeout(() => {
this.qcFlagsVisible = true
}, 100)
},
beforeDestroy() {
this.cancelLastRequest()
this.$bus.$off('ReAnalyses', this.handleReAnalyse)
if (this.qcFlagsTimer) {
clearTimeout(this.qcFlagsTimer)
}
},
methods: {
//
@ -278,7 +294,7 @@ export default {
}
}
this.changeChartByType(this.spectraType)
this.changeChartByType(this.spectraType, result.XeData)
},
handleGetFlag(val, obj) {
@ -294,8 +310,8 @@ export default {
const { dbName, sampleId, inputFileName, analyst } = this.sample
try {
this.isLoading = true
this.cancelLastRequest()
this.isLoading = true
const cancelToken = this.createCancelToken()
const { success, result, message } = await getAction(
'/spectrumAnalysis/getDBSpectrumChart',
@ -307,11 +323,12 @@ export default {
cancelToken
)
if (success) {
this.isLoading = false
this.sampleDetail = result
this.changeChartByType('sample')
this.emitGetFiles(result)
this.$store.commit('ADD_SAMPLE_DATA', {
addSampleData({
inputFileName,
data: result,
from: 'db',
@ -321,8 +338,10 @@ export default {
}
} catch (error) {
console.error(error)
} finally {
this.isLoading = false
const isCancel = axios.isCancel(error)
if (!isCancel) {
this.isLoading = false
}
}
},
@ -343,8 +362,8 @@ export default {
qcFileName: this.sample.qcFileStatus ? this.sample.qcFileName : '',
}
try {
this.isLoading = true
this.cancelLastRequest()
this.isLoading = true
const cancelToken = this.createCancelToken()
const { success, result, message } = await getAction(
'/spectrumAnalysis/getFileSpectrumChart',
@ -355,23 +374,29 @@ export default {
this.sampleDetail = result
this.changeChartByType('sample')
this.$store.commit('ADD_SAMPLE_DATA', {
addSampleData({
inputFileName: this.sample.sampleFileName,
data: result,
from: 'file',
})
this.isLoading = false
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
const isCancel = axios.isCancel(error)
if (!isCancel) {
this.isLoading = false
}
}
},
cancelLastRequest() {
if (this._cancelToken && typeof this._cancelToken == 'function') {
this._cancelToken()
this._cancelToken = undefined
}
},
@ -382,10 +407,15 @@ export default {
return cancelToken
},
changeChartByType(val) {
changeChartByType(val, data) {
if (val === 'qc' && !this.sampleDetail.qc) {
this.$message.warning('No qc spectrum file!')
} else {
if (val == 'sample') this.currSpectrum = 'Sample'
if (val == 'gasBg') this.currSpectrum = 'Gas'
if (val == 'detBg') this.currSpectrum = 'Det'
if (val == 'qc') this.currSpectrum = 'QC'
const {
betaOriginalData,
betaProjectedData,
@ -428,11 +458,8 @@ export default {
console.log('this.resultDisplaythis.resultDisplay', this.resultDisplay)
this.resultDisplay = this.copyXeData
? this.copyXeData
: this.resultDisplay.length > 0
? this.resultDisplay
: XeData
this.resultDisplay = data ? data : XeData
this.sortResultDisplay()
this.$emit('sendInfo', this.resultDisplay, this.spectrumData.stationCode, savedAnalysisResult)
@ -527,49 +554,109 @@ export default {
// this.isReAnalyed_beta = true
// this.analyseCurrentSpectrum = res.result
this.$emit('sendXeData', res.result.XeData)
if (res.result.XeData && res.result.XeData.length > 0) {
res.result.XeData.forEach((item) => {
item.conc = parseFloat(item.conc.toPrecision(6))
item.concErr = parseFloat(item.concErr.toPrecision(6))
item.lc = parseFloat(item.lc.toPrecision(6))
item.mdc = parseFloat(item.mdc.toPrecision(6))
})
this.$emit('reAnalyCurr', true, res.result.XeData)
this.copyXeData = res.result.XeData
this.handleReAnalyse(res.result)
}
} else {
this.$message.warning(res.message)
}
})
},
getAnalyzeAllSpectrum() {
let params = {
dbNames: [this.sample.dbName],
sampleIds: [this.sample.sampleId ? this.sample.sampleId : ''],
sampleFileNames: [this.sample.inputFileName],
gasFileNames: [this.sample.gasFileName],
detFileNames: [this.sample.detFileName],
qcFileNames: [this.sample.qcFileName],
currentFileName: this.sample.inputFileName,
}
postAction('/spectrumAnalysis/analyseAllSpectrum', params).then((res) => {
if (res.success) {
// this.analyseCurrentSpectrum = res.result
this.$emit('sendXeData', res.result.XeData)
// if (res.result.XeData && res.result.XeData.length > 0) {
res.result.XeData.forEach((item) => {
item.conc = parseFloat(item.conc.toPrecision(6))
item.concErr = parseFloat(item.concErr.toPrecision(6))
item.lc = parseFloat(item.lc.toPrecision(6))
item.mdc = parseFloat(item.mdc.toPrecision(6))
})
this.$emit('reAnalyAll', true, res.result.XeData)
this.$emit('reAnalyCurr', res.result.savedAnalysisResult, res.result.XeData)
this.handleReAnalyse(res.result)
updateSampleData({
inputFileName: this.sample.inputFileName,
key: 'XeData',
data: res.result.XeData,
})
updateSampleData({
inputFileName: this.sample.inputFileName,
key: 'savedAnalysisResult',
data: res.result.savedAnalysisResult,
})
if (res.result.bProcessed) {
this.$message.success(res.result.message)
} else {
this.$message.warning(res.result.message)
}
// }
} else {
this.$message.warning(res.message)
}
})
},
//
async getAnalyzeAllSpectrum() {
const regExp = /^([A-Z]{1,}\d{1,})_/
const regMatched = this.sample.inputFileName.match(regExp)
const currStationName = regMatched[1]
const dbNames = [],
sampleIds = [],
sampleFileNames = [],
gasFileNames = [],
detFileNames = [],
qcFileNames = []
const matchedSampleList = this.sampleList.filter((item) => item.inputFileName.includes(currStationName))
matchedSampleList.forEach(
({ dbName, sampleId, inputFileName, sampleFileName, gasFileName, detFileName, qcFileName, qcFileStatus }) => {
dbNames.push(dbName || '')
sampleIds.push(sampleId || '')
sampleFileNames.push(sampleFileName || inputFileName || '')
gasFileNames.push(gasFileName || '')
detFileNames.push(detFileName || '')
qcFileNames.push(qcFileStatus ? qcFileName : '')
}
)
const params = {
dbNames,
sampleIds,
sampleFileNames,
gasFileNames,
detFileNames,
qcFileNames,
currentFileName: this.sample.inputFileName,
}
const { success, result, message } = await postAction('/spectrumAnalysis/analyseAllSpectrum', params)
if (success) {
//
Object.entries(result).forEach(([inputFileName, sampleInfo]) => {
const { XeData, savedAnalysisResult, bProcessed, message } = sampleInfo
XeData.forEach((item) => {
item.conc = parseFloat(item.conc.toPrecision(6))
item.concErr = parseFloat(item.concErr.toPrecision(6))
item.lc = parseFloat(item.lc.toPrecision(6))
item.mdc = parseFloat(item.mdc.toPrecision(6))
})
if (inputFileName == this.sample.inputFileName) {
this.$emit('sendXeData', XeData)
this.$emit('reAnalyAll', savedAnalysisResult, XeData)
this.handleReAnalyse(sampleInfo)
if (bProcessed) {
this.$message.success(message)
} else {
this.$message.warning(message)
}
}
updateSampleData({
inputFileName,
key: 'XeData',
data: XeData,
})
updateSampleData({
inputFileName,
key: 'savedAnalysisResult',
data: savedAnalysisResult,
})
})
} else {
this.$message.warning(message)
}
},
//
handleZoom(nuclideName) {
@ -617,13 +704,24 @@ export default {
this.$refs.lineChart4Ref.setRange(minX, maxX)
}
},
// result display
sortResultDisplay() {
this.resultDisplay.sort((a, b) => {
const index1 = sortList.indexOf(a.nuclideName)
const index2 = sortList.indexOf(b.nuclideName)
return index1 - index2
})
},
},
watch: {
sample: {
async handler(newVal, oldVal) {
this.resultDisplay = []
const sampleData = await this.$store.dispatch('GET_SAMPLE_DATA', newVal.inputFileName)
const sampleData = getSampleData(newVal.inputFileName)
if (sampleData) {
this.cancelLastRequest()
this.isLoading = false
const { data, from } = sampleData
this.sampleDetail = data
this.changeChartByType('sample')
@ -638,6 +736,7 @@ export default {
this.getSampleDetail_file()
}
}
await this.$nextTick()
this.$refs.betaGammaChartRef.handleUnzoom()
},
immediate: true,
@ -646,13 +745,8 @@ export default {
analyseCurrentSpectrum: {
handler(newVal, oldVal) {
// this.currResultDisplay = newVal.XeData
this.resultDisplay = newVal.XeData || []
this.$store.commit('UPDATE_SAMPLE_DATA', {
inputFileName: this.sample.inputFileName,
key: 'XeData',
data: newVal.XeData,
})
this.resultDisplay = cloneDeep(newVal.XeData) || []
this.sortResultDisplay()
},
// immediate: true,
deep: true,
@ -683,6 +777,32 @@ export default {
}
}
//
.spectrum-analysis-sub-operators {
flex-shrink: 0;
margin-bottom: 19px;
display: flex;
gap: 11px;
flex-wrap: nowrap;
overflow: auto;
height: 46px;
align-items: center;
.pop-over-with-icon {
height: 32px;
flex-shrink: 0;
&:nth-child(1) {
width: 224px;
}
&:nth-child(3) {
width: 125px;
}
}
}
//
.sample-select {
::v-deep {
.ant-select-selection {
@ -693,7 +813,7 @@ export default {
}
&-main {
height: calc(100% - 51px);
height: calc(100% - 65px);
display: flex;
gap: 30px;
overflow: auto hidden;

View File

@ -1,5 +1,5 @@
import { deleteAction } from '@/api/manage'
import store from '@/store'
import { removeSampleData } from '@/utils/SampleStore'
import Vue from 'vue'
/**
@ -16,7 +16,7 @@ export const clearSampleCache = sampleList => {
params = { sampleFileName: fileName }
}
deleteAction(url, params)
store.commit('REMOVE_SAMPLE_DATA', fileName)
removeSampleData(fileName)
Vue.ls.remove(`CALIBRATION_GAMMA_${fileName}`)
Vue.ls.remove(`CALIBRATION_BETA_${fileName}`)
})

View File

@ -57,11 +57,11 @@ const twoDOption = {
top: 15,
left: 55,
right: 10,
bottom: 45
bottom: 45,
},
tooltip: {
trigger: 'item',
formatter: params => {
formatter: (params) => {
const [b, g, c] = params.value
return `Beta: ${b}<br>Gamma: ${g}<br>Count: ${c}`
},
@ -69,69 +69,69 @@ const twoDOption = {
animation: false,
type: 'cross',
lineStyle: {
type: 'dashed'
}
}
type: 'dashed',
},
},
},
xAxis: {
name: 'Beta Channel',
nameTextStyle: {
color: '#5b9cba',
fontSize: 16
fontSize: 16,
},
nameLocation: 'center',
nameGap: 30,
axisLine: {
lineStyle: {
color: 'rgba(119, 181, 213, .3)'
}
color: 'rgba(119, 181, 213, .3)',
},
},
axisLabel: {
color: '#ade6ee',
fontSize: 12
fontSize: 12,
},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(119, 181, 213, .3)'
}
color: 'rgba(119, 181, 213, .3)',
},
},
axisTick: {
show: false
show: false,
},
min: 0,
max: 256,
interval: 64
interval: 64,
},
yAxis: {
name: 'Gamma Channel',
nameTextStyle: {
color: '#5b9cba',
fontSize: 16
fontSize: 16,
},
nameLocation: 'center',
nameGap: 35,
axisLine: {
lineStyle: {
color: 'rgba(119, 181, 213, .3)'
}
color: 'rgba(119, 181, 213, .3)',
},
},
axisLabel: {
color: '#ade6ee',
fontSize: 12
fontSize: 12,
},
splitLine: {
show: true,
lineStyle: {
color: 'rgba(119, 181, 213, .3)'
}
color: 'rgba(119, 181, 213, .3)',
},
},
axisTick: {
show: false
show: false,
},
min: 0,
max: 256,
interval: 64
interval: 64,
},
series: [
{
@ -139,12 +139,12 @@ const twoDOption = {
symbolSize: 4,
data: [],
itemStyle: {
color: '#fff'
}
}
color: '#fff',
},
},
],
brush: {},
animation: false
animation: false,
}
//3D Surface
@ -155,66 +155,66 @@ const threeDSurfaceOption = {
formatter: ({ value: [x, y, z] }) => {
// tooltip
return `Beta Channel:${x} Count:${z} Gamma Channel: ${y}`
}
},
},
visualMap: {
show: false,
min: 0,
max: 0,
inRange: {
color: ['#0DCF38', '#B5475E']
}
color: ['#0DCF38', '#B5475E'],
},
},
grid3D: {
axisLabel: {
color: '#ade6ee'
color: '#ade6ee',
},
axisPointer: {
show: false
show: false,
},
axisLine: {
lineStyle: {
color: 'rgba(119, 181, 213, .3)'
}
color: 'rgba(119, 181, 213, .3)',
},
},
splitLine: {
lineStyle: {
color: 'rgba(119, 181, 213, .3)'
}
}
color: 'rgba(119, 181, 213, .3)',
},
},
},
xAxis3D: {
name: 'Beta Channel',
nameTextStyle: {
color: '#5b9cba',
fontSize: 14
fontSize: 14,
},
min: 0,
max: 256,
interval: 64
interval: 64,
},
yAxis3D: {
name: 'Gamma Channel',
nameTextStyle: {
color: '#5b9cba',
fontSize: 14
fontSize: 14,
},
min: 0,
max: 256,
interval: 64
interval: 64,
},
zAxis3D: {
name: 'Count',
nameTextStyle: {
color: '#5b9cba',
fontSize: 14
fontSize: 14,
},
max: 0
max: 0,
},
series: {
type: 'surface',
data: []
}
data: [],
},
}
// 3D Scatter
@ -224,92 +224,92 @@ const threeDScatterOption = {
formatter: ({ value: [x, y, z] }) => {
// tooltip
return `Beta Channel:${x} Count:${z} Gamma Channel: ${y}`
}
},
},
visualMap: {
show: false,
min: 0,
max: 0,
inRange: {
color: ['#0DCF38', '#B5475E']
}
color: ['#0DCF38', '#B5475E'],
},
},
grid3D: {
axisLabel: {
color: '#ade6ee'
color: '#ade6ee',
},
axisPointer: {
show: false
show: false,
},
axisLine: {
lineStyle: {
color: 'rgba(119, 181, 213, .3)'
}
color: 'rgba(119, 181, 213, .3)',
},
},
splitLine: {
lineStyle: {
color: 'rgba(119, 181, 213, .3)'
}
}
color: 'rgba(119, 181, 213, .3)',
},
},
},
xAxis3D: {
name: 'Beta Channel',
nameTextStyle: {
color: '#5b9cba',
fontSize: 14
fontSize: 14,
},
min: 0,
max: 256,
interval: 64
interval: 64,
},
yAxis3D: {
name: 'Gamma Channel',
nameTextStyle: {
color: '#5b9cba',
fontSize: 14
fontSize: 14,
},
min: 0,
max: 256,
interval: 64
interval: 64,
},
zAxis3D: {
name: 'Count',
nameTextStyle: {
color: '#5b9cba',
fontSize: 14
fontSize: 14,
},
max: 0
max: 0,
},
series: {
type: 'scatter3D',
symbolSize: 5,
emphasis: {
label: {
show: false
}
show: false,
},
},
data: []
}
data: [],
},
}
export default {
props: {
histogramDataList: {
type: Array,
default: () => []
default: () => [],
},
histogramDataDList: {
type: Array,
default: () => []
default: () => [],
},
boundary: {
type: Array,
default: () => []
}
default: () => [],
},
},
components: {
CustomChart,
ColorPalette
ColorPalette,
},
data() {
this.buttons = buttons
@ -323,11 +323,10 @@ export default {
threeDScatterOption,
showROI: true,
opts: {
notMerge: false
}
notMerge: false,
},
}
},
mounted() {
this.opts.notMerge = true
this.$nextTick(() => {
@ -340,6 +339,7 @@ export default {
// Beta-Gamma Spectrum: Sample
handleChange(index) {
this.active = index
this.handleUnzoom()
// v-show(Unzoom)resize0, resize
if (this.active == 0) {
@ -388,8 +388,8 @@ export default {
key: 'brush',
brushOption: {
// brush brushType false
brushType: 'rect'
}
brushType: 'rect',
},
})
},
@ -404,12 +404,12 @@ export default {
//
chart.dispatchAction({
type: 'brush',
areas: []
areas: [],
})
//
chart.dispatchAction({
type: 'takeGlobalCursor'
type: 'takeGlobalCursor',
})
},
@ -421,8 +421,8 @@ export default {
const range = areas.range
const [[minX, maxX], [minY, maxY]] = range
const point1 = chart.convertFromPixel({ seriesIndex: 0 }, [minX, minY]).map(num => parseInt(num.toFixed()))
const point2 = chart.convertFromPixel({ seriesIndex: 0 }, [maxX, maxY]).map(num => parseInt(num.toFixed()))
const point1 = chart.convertFromPixel({ seriesIndex: 0 }, [minX, minY]).map((num) => parseInt(num.toFixed()))
const point2 = chart.convertFromPixel({ seriesIndex: 0 }, [maxX, maxY]).map((num) => parseInt(num.toFixed()))
const [x1, y2, x2, y1] = [...point1, ...point2] //
@ -444,7 +444,7 @@ export default {
buildScatterList() {
const {
xAxis: { min: minX, max: maxX },
yAxis: { min: minY, max: maxY }
yAxis: { min: minY, max: maxY },
} = this.twoDOption
this.twoDOption.series[0].data = this.histogramDataDList
@ -458,8 +458,8 @@ export default {
return {
value: [xAxis, yAxis],
itemStyle: {
color: `rgb(${r}, ${g}, ${b})`
}
color: `rgb(${r}, ${g}, ${b})`,
},
}
},
@ -498,16 +498,16 @@ export default {
[maxX, minY],
[maxX, maxY],
[minX, maxY],
[minX, minY]
[minX, minY],
]
rectList.push(this.drawOneRect(rect, color))
})
}
const lineSeries = rectList.map(rect => ({
const lineSeries = rectList.map((rect) => ({
type: 'line',
...rect,
zlevel: 11
zlevel: 11,
}))
this.opts.notMerge = true
@ -527,8 +527,8 @@ export default {
data: rect,
symbol: 'none',
itemStyle: {
color
}
color,
},
}
},
@ -549,7 +549,7 @@ export default {
const g = color1.g + (color2.g - color1.g) * percentage
const b = color1.b + (color2.b - color1.b) * percentage
return { r, g, b }
}
},
},
watch: {
// 2D
@ -558,22 +558,29 @@ export default {
this.active = 0
this.buildScatterList()
},
immediate: true
immediate: true,
},
// 3D
histogramDataDList: {
handler(newVal) {
const maxCount = Math.max(...newVal.map(item => item.c))
let maxCount = 0
const data = []
for (const item of newVal) {
const { b, g, c } = item //
if (c > maxCount) maxCount = c
data.push([b, g, c])
}
this.threeDSurfaceOption.zAxis3D.max = Math.ceil(maxCount * 1.2)
this.threeDSurfaceOption.series.data = newVal.map(item => [item.b, item.g, item.c]) // 3D surface
this.threeDSurfaceOption.series.data = data // 设置3D surface数据 // 第一次设置耗时较多
this.threeDSurfaceOption.visualMap.max = maxCount
this.threeDScatterOption.zAxis3D.max = Math.ceil(maxCount * 1.2)
this.threeDScatterOption.series.data = newVal.map(item => [item.b, item.g, item.c]) // 3D scatter
this.threeDScatterOption.series.data = data // 3D scatter
this.threeDScatterOption.visualMap.max = maxCount
},
immediate: true
immediate: true,
},
// 2D
@ -585,16 +592,16 @@ export default {
this.boundaryData = newVal
this.reDrawRect()
},
immediate: true
immediate: true,
},
currCount: {
handler() {
this.buildScatterList()
},
immediate: true
}
}
immediate: true,
},
},
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<custom-modal v-model="visible" :width="1280" title="Nuclide Review" :footer="null" @close="handleCancel">
<custom-modal v-model="visible" :width="1280" title="Nuclide Review" :footer="null">
<a-spin :spinning="isLoading">
<div class="nuclide-review-search">
<span @click="handleNuclideChange('prev')">&lt;</span>

View File

@ -1,182 +1,187 @@
<template>
<custom-modal v-model="visible" :width="1280" title="Interactive Analyse Tools" :footer="null" destroy-on-close>
<a-spin :spinning="isLoading">
<div class="interactive-analysis-tools">
<div class="interactive-analysis-tools-left">
<div class="chart">
<CustomChart
ref="chartRef"
:option="option"
:opts="opts"
@zr:mousedown="handleMouseDown"
@zr:mouseup="handleMouseUp"
@brushEnd="handleBrushEnd"
@zr:click="handleChartClick"
/>
<rect-list
ref="rectListRef"
:chartRef="$refs.chartRef"
:baseControls="baseCtrls_Copy"
:draggable="isModifying"
@move="handleMove"
@moveEnd="handleMoveEnd"
/>
</div>
<!-- 缩略图 -->
<div class="thumbnail">
<CustomChart :option="thumbnailOption" />
</div>
<!-- 缩略图结束 -->
<!-- 表格 -->
<div class="table">
<p class="title">
<span @click="handleChangeMarkLine('prev')">&lt; </span>
6 Peaks with Anthro.Nuclides
<span @click="handleChangeMarkLine('next')">&gt;</span>
</p>
<custom-table
ref="tableRef"
size="small"
:class="list.length ? 'has-data' : ''"
:list="list"
:columns="columns"
:scroll="{ y: 288 }"
:selectedRowKeys.sync="selectedKeys"
rowKey="index"
:canDeselect="false"
@rowClick="handleTableRowClick"
>
</custom-table>
<div class="operators">
<a-button type="primary" @click="nuclideReviewModalVisible = true">Nuclide Review Window</a-button>
<a-button type="primary" @click="handleAddPeakComment()">Add Peak Comment</a-button>
<a-button type="primary" @click="handleAddGeneralComment()">Add General Comment</a-button>
</div>
</div>
<!-- 表格结束 -->
<custom-modal
v-model="visible"
:width="1280"
class="interactive-analysis-tools-dialog"
:enableFullScreen="true"
title="Interactive Analyse Tools"
:footer="null"
destroy-on-close
@fullscreen="handleFullScreenChange"
>
<div class="interactive-analysis-tools">
<div class="interactive-analysis-tools-left">
<div class="chart">
<CustomChart
ref="chartRef"
:option="option"
:opts="opts"
@zr:mousedown="handleMouseDown"
@zr:mouseup="handleMouseUp"
@brushEnd="handleBrushEnd"
@zr:click="handleChartClick"
/>
<rect-list
ref="rectListRef"
:chartRef="$refs.chartRef"
:baseControls="baseCtrls_Copy"
:draggable="isModifying"
@move="handleMove"
@moveEnd="handleMoveEnd"
/>
</div>
<!-- 缩略图 -->
<div class="thumbnail">
<CustomChart ref="thumbnailRef" :option="thumbnailOption" />
</div>
<!-- 缩略图结束 -->
<!-- 右侧 -->
<div class="interactive-analysis-tools-right">
<title-over-border :title="btnGroupType == 1 ? 'Peak' : 'Baseline Control Points'">
<div class="peak-box">
<!-- 按钮组1 -->
<template v-if="btnGroupType == 1">
<div class="peak-box-item">
<a-button type="primary" @click="handleInsert">Insert</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" @click="handleDel">Delete</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" :class="{ 'is-fitting': isFitting }" @click="handleFit">Fit</a-button>
</div>
<div class="peak-box-item symbol" :key="4">
<a-button type="primary" @click="handleChangeMarkLine('prev')">&lt;</a-button>
<a-button type="primary" @click="handleChangeMarkLine('next')">&gt;</a-button>
</div>
<div class="peak-box-item base-line">
<a-button type="primary" @click="handleSwitchOperation">BaseLine</a-button>
</div>
</template>
<!-- 按钮组2 -->
<template v-if="btnGroupType == 2">
<div class="peak-box-item">
<a-button type="primary" @click="handleAddCP">(A)dd CP</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" @click="handleRemoveCP">(R)emove CP</a-button>
</div>
<div class="peak-box-item">
<a-button
type="primary"
key="modify-btn"
:class="{ 'is-modify': isModifying }"
@click="handleModifyCP"
>(M)odify CP</a-button
>
</div>
<div class="peak-box-item">
<a-button type="primary" @click="handleEditSlope">Edit (S)lope</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" :disabled="isOperationStackEmpty" @click="handleUndo">Undo</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" :loading="isReploting" @click="handleReplot">Replot</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" :loading="isAccepting" @click="handleAccept">Accept</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" @click="handleSwitchOperation">Cancel</a-button>
</div>
</template>
</div>
</title-over-border>
<div class="reset-btn-box">
<a-button type="primary" @click="handleResetChart">Reset Chart</a-button>
<!-- 表格 -->
<div class="table">
<p class="title">
<span @click="handleChangeMarkLine('prev')">&lt; </span>
6 Peaks with Anthro.Nuclides
<span @click="handleChangeMarkLine('next')">&gt;</span>
</p>
<custom-table
ref="tableRef"
size="small"
:class="list.length ? 'has-data' : ''"
:list="list"
:columns="columns"
:scroll="{ y: 288 }"
:selectedRowKeys.sync="selectedKeys"
rowKey="index"
:canDeselect="false"
@rowClick="handleTableRowClick"
>
</custom-table>
<div class="operators">
<a-button type="primary" @click="nuclideReviewModalVisible = true">Nuclide Review Window</a-button>
<a-button type="primary" @click="handleAddPeakComment()">Add Peak Comment</a-button>
<a-button type="primary" @click="handleAddGeneralComment()">Add General Comment</a-button>
</div>
<div class="identify-box">
<title-over-border title="Nuclide Identify">
<a-form-model class="tolerance">
<a-form-model-item label="Tolerance">
<a-input-number
v-model="model.tolerance"
:step="0.1"
:min="0"
@change="handleToleranceChange"
></a-input-number>
</a-form-model-item>
</a-form-model>
<div class="identify-item">
<div class="title">Possible Nuclide</div>
<a-spin :spinning="!!(selectedTableItem && selectedTableItem._loading)">
<div class="content">
<template v-if="selectedTableItem && selectedTableItem._possible">
<div
class="item"
:class="{ active: possible == model.possibleNuclide }"
v-for="(possible, index) in selectedTableItem._possible"
:key="index"
@click="model.possibleNuclide = possible"
>
{{ possible }}
</div>
</template>
</div>
</a-spin>
</div>
<!-- 表格结束 -->
<resize-observer @notify="handleResize" />
</div>
<!-- 右侧 -->
<div class="interactive-analysis-tools-right">
<title-over-border class="peak-box-container" :title="btnGroupType == 1 ? 'Peak' : 'Baseline Control Points'">
<div class="peak-box">
<!-- 按钮组1 -->
<template v-if="btnGroupType == 1">
<div class="peak-box-item">
<a-button type="primary" @click="handleInsert">Insert</a-button>
</div>
<div class="identify-item">
<div class="title">Nuclide Identified</div>
<div class="peak-box-item">
<a-button type="primary" @click="handleDel">Delete</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" :class="{ 'is-fitting': isFitting }" @click="handleFit">Fit</a-button>
</div>
<div class="peak-box-item symbol" :key="4">
<a-button type="primary" @click="handleChangeMarkLine('prev')">&lt;</a-button>
<a-button type="primary" @click="handleChangeMarkLine('next')">&gt;</a-button>
</div>
<div class="peak-box-item base-line">
<a-button type="primary" @click="handleSwitchOperation">BaseLine</a-button>
</div>
</template>
<!-- 按钮组2 -->
<template v-if="btnGroupType == 2">
<div class="peak-box-item">
<a-button type="primary" @click="handleAddCP">(A)dd CP</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" @click="handleRemoveCP">(R)emove CP</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" key="modify-btn" :class="{ 'is-modify': isModifying }" @click="handleModifyCP"
>(M)odify CP</a-button
>
</div>
<div class="peak-box-item">
<a-button type="primary" @click="handleEditSlope">Edit (S)lope</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" :disabled="isOperationStackEmpty" @click="handleUndo">Undo</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" :loading="isReploting" @click="handleReplot">Replot</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" :loading="isAccepting" @click="handleAccept">Accept</a-button>
</div>
<div class="peak-box-item">
<a-button type="primary" @click="handleSwitchOperation">Cancel</a-button>
</div>
</template>
</div>
</title-over-border>
<div class="reset-btn-box">
<a-button type="primary" @click="handleResetChart">Reset Chart</a-button>
</div>
<div class="identify-box">
<title-over-border title="Nuclide Identify">
<a-form-model class="tolerance">
<a-form-model-item label="Tolerance">
<a-input-number
v-model="model.tolerance"
:step="0.1"
:min="0"
@change="handleToleranceChange"
></a-input-number>
</a-form-model-item>
</a-form-model>
<div class="identify-item">
<div class="title">Possible Nuclide</div>
<a-spin :spinning="!!(selectedTableItem && selectedTableItem._loading)">
<div class="content">
<template v-if="selectedTableItem">
<template v-if="selectedTableItem && selectedTableItem._possible">
<div
class="item"
:class="{ active: identified == model.identifiedNuclide }"
v-for="(identified, index) in selectedTableItem.nuclides"
:class="{ active: possible == model.possibleNuclide }"
v-for="(possible, index) in selectedTableItem._possible"
:key="index"
@click="model.identifiedNuclide = identified"
@click="model.possibleNuclide = possible"
>
{{ identified }}
{{ possible }}
</div>
</template>
</div>
</a-spin>
</div>
<div class="identify-item">
<div class="title">Nuclide Identified</div>
<div class="content">
<template v-if="selectedTableItem">
<div
class="item"
:class="{ active: identified == model.identifiedNuclide }"
v-for="(identified, index) in selectedTableItem.nuclides"
:key="index"
@click="model.identifiedNuclide = identified"
>
{{ identified }}
</div>
</template>
</div>
<div class="identify-operators">
<span class="text">{{ model.possibleNuclide }}</span>
<a-button type="primary" :disabled="!model.possibleNuclide" @click="handleAddNuclide">Add</a-button>
<a-button type="primary" @click="handleDelNuclide">Del</a-button>
</div>
</title-over-border>
</div>
</div>
<div class="identify-operators">
<span class="text">{{ model.possibleNuclide }}</span>
<a-button type="primary" :disabled="!model.possibleNuclide" @click="handleAddNuclide">Add</a-button>
<a-button type="primary" @click="handleDelNuclide">Del</a-button>
</div>
</title-over-border>
</div>
<!-- 右侧结束 -->
</div>
</a-spin>
<!-- 右侧结束 -->
</div>
<!-- Peak Comment弹窗 开始 -->
<peak-comment-modal v-model="peakCommentModalVisible" :curRow="curRow" />
<!-- Peak Comment弹窗 结束 -->
@ -218,11 +223,12 @@ import { buildLineSeries, findSeriesByName, getXAxisAndYAxisByPosition, rangeNum
import SampleDataMixin from '@/views/spectrumAnalysis/SampleDataMixin'
import GeneralCommentModal from './components/GeneralCommentModal.vue'
import EditSlopeModal from './components/EditSlopeModal.vue'
import Response from './Response.json'
// import Response from './Response.json'
import { updateBaseLine } from '@/utils/WasmHelper'
import RectList from './components/RectList.vue'
import { isNullOrUndefined } from '@/utils/util'
import { findNearPeak, getLineData, transformPointListData } from '@/utils/sampleHelper'
import { getSampleData } from '@/utils/SampleStore'
//
const initialOption = {
@ -450,8 +456,8 @@ export default {
},
},
data() {
this.columns = columns
return {
columns,
searchParam: {
energy: '',
tolerance: '',
@ -459,9 +465,6 @@ export default {
option: cloneDeep(initialOption),
opts: { notMerge: false },
thumbnailOption: cloneDeep(thumbnailOption),
isLoading: false,
channelBaseCPChart: [],
channelBaseLineChart: [],
channelCountChart: [],
@ -512,7 +515,7 @@ export default {
}
},
methods: {
async getInfo() {
getInfo() {
this.option.series = []
this.thumbnailOption.series = []
this.list = []
@ -520,7 +523,7 @@ export default {
const { inputFileName } = this.sampleData
const currSampleDetailInfo = await this.$store.dispatch('GET_SAMPLE_DATA', inputFileName)
const currSampleDetailInfo = getSampleData(inputFileName)
const {
data: { allData, shadowChannelChart, shapeChannelData, peak, BaseCtrls, barChart },
} = currSampleDetailInfo
@ -581,8 +584,8 @@ export default {
this.handleResetChart()
},
async beforeModalOpen() {
await this.getInfo()
beforeModalOpen() {
this.getInfo()
this.reset()
},
@ -1560,14 +1563,16 @@ export default {
try {
this.$set(this.selectedTableItem, '_deleting', true)
const { inputFileName: fileName } = this.sampleData
const { success, message } = await postAction('/gamma/deleteNuclide', {
const { success, result, message } = await postAction('/gamma/deleteNuclide', {
curRow: this.curRow,
nuclideName: this.model.identifiedNuclide,
fileName,
list_identify: nuclides,
})
if (success) {
nuclides.splice(findIndex, 1)
const { identify, table } = result
this.selectedTableItem.nuclides = identify
this.list = table
} else {
this.$message.error(message)
}
@ -1703,6 +1708,15 @@ export default {
clearOperationStack() {
this.operationStack = []
},
handleResize() {
this.$refs.chartRef.resize()
this.$refs.thumbnailRef.resize()
},
handleFullScreenChange(isFullScreen) {
this.columns[7].width = isFullScreen ? 180 : 120
},
},
computed: {
curRow() {
@ -1721,11 +1735,12 @@ export default {
<style lang="less" scoped>
.interactive-analysis-tools {
display: flex;
margin-top: 5px;
padding-top: 5px;
gap: 20px;
&-left {
width: 75%;
margin-right: 20px;
flex: 1;
overflow: hidden;
.chart {
height: 331px;
@ -1785,6 +1800,9 @@ export default {
}
&-right {
width: 290px;
flex-shrink: 0;
.peak-box {
height: 326px;
@ -1836,6 +1854,8 @@ export default {
}
.identify-item {
margin-bottom: 10px;
.title {
background-color: #497e9d;
height: 30px;
@ -1847,7 +1867,7 @@ export default {
.content {
height: 80px;
background-color: #275466;
margin: 10px 0;
margin-top: 10px;
padding: 5px;
overflow: auto;
@ -1897,3 +1917,78 @@ export default {
color: #f00;
}
</style>
<style lang="less">
.interactive-analysis-tools-dialog.fullscreen {
.interactive-analysis-tools {
height: calc(100vh - 90px);
&-left {
display: flex;
flex-direction: column;
.chart {
flex: 1;
}
.thumbnail {
height: 60px;
}
.table {
height: 397px;
.custom-table {
height: calc(100% - 82px);
.ant-spin-nested-loading,
.ant-spin-container,
.ant-table,
.ant-table-content,
.ant-table-scroll {
height: 100%;
}
.ant-table-body {
height: calc(100% - 25px) !important;
max-height: calc(100% - 25px) !important;
}
}
}
}
&-right {
display: flex;
flex-direction: column;
.identify-box {
flex: 1;
padding-top: 5px;
overflow: hidden;
.title-over-border {
height: 100%;
&-content {
display: flex;
flex-direction: column;
.identify-item {
flex: 1;
overflow: auto;
.ant-spin-nested-loading,
.content {
height: calc(100% - 40px);
.ant-spin-container,
.content {
height: 100%;
}
}
}
}
}
}
}
}
}
</style>

View File

@ -1,7 +1,7 @@
<template>
<custom-modal v-model="visible" :width="1200" :title="type == 1 || type == 3 ? 'ARR' : 'RRR'">
<a-spin :spinning="isLoading">
<a-textarea style="font-family: " v-model="content" :readonly="type == 1 || type == 2"></a-textarea>
<a-textarea style="font-family: 仿宋" v-model="content" :readonly="type == 1 || type == 2"></a-textarea>
</a-spin>
<div slot="custom-footer" style="text-align: center">
<a-space :size="20">

View File

@ -1,7 +1,7 @@
<template>
<custom-modal v-model="visible" :width="1000" title="Auto Process Log Viewer">
<a-spin :spinning="isLoading">
<pre style="font-family: ">
<pre style="font-family: 仿宋">
{{ content }}
</pre>
</a-spin>

View File

@ -1,7 +1,7 @@
<template>
<custom-modal v-model="visible" title="BetaGamma Analyser Log" :width="1200">
<a-spin :spinning="isLoading">
<a-textarea v-model="content" style="font-family: "></a-textarea>
<a-textarea v-model="content" style="font-family: 仿宋"></a-textarea>
</a-spin>
<div slot="custom-footer">
<a-button type="primary" @click="handleClick">Save As</a-button>

View File

@ -128,9 +128,24 @@
<span>C to E : </span>
<span>
E =
<a-input-number size="small" v-model="newCalibrationFuncModel.paramA" @change="newCalibrationFuncModelChange"/> +
<a-input-number size="small" v-model="newCalibrationFuncModel.paramB" @change="newCalibrationFuncModelChange"/> *C +
<a-input-number size="small" v-model="newCalibrationFuncModel.paramC" @change="newCalibrationFuncModelChange" /> *C <sup>2</sup>
<a-input-number
size="small"
v-model="newCalibrationFuncModel.paramA"
@change="newCalibrationFuncModelChange"
/>
+
<a-input-number
size="small"
v-model="newCalibrationFuncModel.paramB"
@change="newCalibrationFuncModelChange"
/>
*C +
<a-input-number
size="small"
v-model="newCalibrationFuncModel.paramC"
@change="newCalibrationFuncModelChange"
/>
*C <sup>2</sup>
</span>
</p>
<div class="func">
@ -546,15 +561,15 @@ const newCalibrationFuncModel = {
export default {
mixins: [SampleDataMixin],
components: { CustomChart, TitleOverBorder },
props: {
props: {
isFirstFitting: {
type: Boolean,
required: false,
},
isBetaReset:{
isBetaReset: {
type: Boolean,
required: false,
}
},
},
data() {
this.columns = columns
@ -614,12 +629,16 @@ export default {
this.$bus.$on('betaRefresh', this.getData)
this.getData()
},
beforeDestroy() {
this.$bus.$off('betaRefresh', this.handleReset)
this.$bus.$off('betaRefresh', this.getData)
},
watch: {
isFirstFitting: {
handler() {
// this.getData()
},
immediate: true
immediate: true,
},
},
methods: {
@ -636,11 +655,20 @@ export default {
sampleId,
qcFileName,
sampleFileName: inputFileName,
fittingBtn: this.isFirstFitting
fittingBtn: this.isFirstFitting,
})
if (res.success) {
const { CToE, EToC, betaEnergy, gammaEnergy, gammaGatedBetaSpectrum, histogramData, oldScatterSeries } =
res.result
const {
CToE,
EToC,
betaEnergy,
gammaEnergy,
gammaGatedBetaSpectrum,
histogramData,
oldScatterSeries,
newCToE,
newEToC,
} = res.result
this.c2e = CToE
this.e2c = EToC
@ -669,9 +697,19 @@ export default {
// reanalyzefittingReanalyze 20231101xiao
// todo fitting
if(this.getCache("CALIBRATION_BETA_"+this.newSampleData.inputFileName)) {
this.setFirringResult(this.getCache("CALIBRATION_BETA_"+this.newSampleData.inputFileName))
return false;
if (this.getCache('CALIBRATION_BETA_' + this.newSampleData.inputFileName)) {
this.setFirringResult(this.getCache('CALIBRATION_BETA_' + this.newSampleData.inputFileName))
return false
}
/**
* 对人工交互的返回数据单独处理
*/
if (this.sampleData.dbName == 'man') {
const result = res.result
result.EToC = newEToC || []
result.CToE = newCToE
this.setFirringResult(res.result)
}
} else {
this.$message.error(res.message)
@ -723,7 +761,7 @@ export default {
chartHeight: this.gammaEnergy.length,
channelWidth: this.gammaChannelWidth,
qcFileName,
sampleFileName
sampleFileName,
},
cancelToken
)
@ -797,7 +835,7 @@ export default {
}
this.tooltipVisible = true
this.channelAndEnergyModel.channel = xAxis
if(!isNullOrUndefined(this.currEnergy)) {
if (!isNullOrUndefined(this.currEnergy)) {
this.channelAndEnergyModel.energy = add(661.657, -this.currEnergy)
}
}
@ -816,12 +854,12 @@ export default {
channel,
energy,
})
// add chart线 20231028Xiao
if(this.figureChartOption.series[1].data) {
if (this.figureChartOption.series[1].data) {
this.figureChartOption.series[1].data = []
}
this.figureChartOption.series[1].markPoint.data.push({ xAxis: channel, yAxis: energy })
const { min, max } = this.getFigureChartMaxAndMin()
@ -850,10 +888,10 @@ export default {
// table 20231028Xiao
this.list = []
// chart线 20231028Xiao
if(this.figureChartOption.series[1].data) {
if (this.figureChartOption.series[1].data) {
this.figureChartOption.series[1].data = []
}
if(this.figureChartOption.series[1].markPoint.data) {
if (this.figureChartOption.series[1].markPoint.data) {
this.figureChartOption.series[1].markPoint.data = []
}
},
@ -894,19 +932,22 @@ export default {
// Reset Button
async handleReset() {
this.$emit('isFitting', false)
this.removeCache("CALIBRATION_BETA_"+this.newSampleData.inputFileName) // fitting 20231101:xiao
this.removeCache('CALIBRATION_BETA_' + this.newSampleData.inputFileName) // fitting 20231101:xiao
this.newCalibrationFuncModel = cloneDeep(newCalibrationFuncModel)
this.list = []
this.newE2C = []
// reset 20231211xiao
const res = await postAction('/spectrumAnalysis/resetButton?tabName=beta&sampleFileName='+this.newSampleData.inputFileName, {})
const res = await postAction(
'/spectrumAnalysis/resetButton?tabName=beta&sampleFileName=' + this.newSampleData.inputFileName,
{}
)
this.figureChartOption = this.oldChartOption
this.figureChartOption = cloneDeep(this.oldChartOption)
// this.isFirstFitting = true
this.isInverse = false
},
@ -918,13 +959,14 @@ export default {
}
try {
const { success, result, message } = await postAction('/spectrumAnalysis/fitting', {
...this.list.length <= 0 ? this.newCalibrationFuncModel : [], // list C to E 20231101xiao
...(this.list.length <= 0 ? this.newCalibrationFuncModel : []), // list C to E 20231101xiao
sampleFileName: this.newSampleData.inputFileName,
tabName: "beta",
tabName: 'beta',
// 20231028Xiao
tempPoints: this.list.length > 0
? this.list.map((item) => ({ x: item.channel, y: item.energy }))
: this.oldScatterSeries,
tempPoints:
this.list.length > 0
? this.list.map((item) => ({ x: item.channel, y: item.energy }))
: this.oldScatterSeries,
// tempPoints: this.isFirstFitting
// ? this.oldScatterSeries
// : this.list.map((item) => ({ x: item.channel, y: item.energy })),
@ -934,10 +976,9 @@ export default {
this.betaIsFitting = true
this.$emit('isFitting', true) // reAnalyzeisFirstFittingtrue 20231101xiao
this.setCache("CALIBRATION_BETA_"+this.newSampleData.inputFileName, result) // ReAnalyze 20231101xiao
this.setCache('CALIBRATION_BETA_' + this.newSampleData.inputFileName, result) // ReAnalyze 20231101xiao
this.setFirringResult(result)
} else {
this.$message.error(message)
}
@ -947,7 +988,7 @@ export default {
},
// fittingReAnalyze 20231101xiao
setFirringResult(result){
setFirringResult(result) {
const { EToC, newLineSeries, newScatterSeriesData, tableWidgets, CToE } = result
this.newE2C = EToC
this.newLineSeries = newLineSeries
@ -964,21 +1005,23 @@ export default {
paramC: Number(paramC).toPrecision(6),
}
}
if (newLineSeries) {
const energyValues = newLineSeries.map((item) => item.y)
const energyValues = newLineSeries.map((item) => item.y)
const { max: prevMax, min: prevMin } = this.oldChartOption.yAxis
const { max: prevMax, min: prevMin } = this.oldChartOption.yAxis
const energyMax = Math.max(Math.max(...energyValues), prevMax)
const energyMin = Math.min(Math.min(...energyValues), prevMin)
const energyMax = Math.max(Math.max(...energyValues), prevMax)
const energyMin = Math.min(Math.min(...energyValues), prevMin)
const { min, max, interval } = splitAxis(energyMax, energyMin, 4)
const { min, max, interval } = splitAxis(energyMax, energyMin, 4)
this.figureChartOption.yAxis.max = max
this.figureChartOption.yAxis.min = min
this.figureChartOption.yAxis.interval = interval
this.figureChartOption.yAxis.max = max
this.figureChartOption.yAxis.min = min
this.figureChartOption.yAxis.interval = interval
this.figureChartOption.series[1].data = newLineSeries.map(({ x, y }) => [x, y])
}
this.figureChartOption.series[1].data = newLineSeries.map(({ x, y }) => [x, y])
if (newScatterSeriesData) {
this.figureChartOption.series[1].markPoint.data = newScatterSeriesData.map(({ x, y }) => {
return {
@ -1032,15 +1075,15 @@ export default {
}
return 0
},
getCache(name){
getCache(name) {
return this.$ls.get(name)
},
setCache(name, data){
setCache(name, data) {
this.$ls.set(name, data)
},
removeCache(name){
removeCache(name) {
this.$ls.remove(name) // fitting 20231101:xiao
}
},
},
computed: {
rectHeight() {

View File

@ -95,9 +95,24 @@
<span>C to E : </span>
<span>
E =
<a-input-number size="small" v-model="newCalibrationFuncModel.paramA" @change="newCalibrationFuncModelChange()"/> +
<a-input-number size="small" v-model="newCalibrationFuncModel.paramB" @change="newCalibrationFuncModelChange()"/> *C +
<a-input-number size="small" v-model="newCalibrationFuncModel.paramC" @change="newCalibrationFuncModelChange()"/> *C <sup>2</sup>
<a-input-number
size="small"
v-model="newCalibrationFuncModel.paramA"
@change="newCalibrationFuncModelChange()"
/>
+
<a-input-number
size="small"
v-model="newCalibrationFuncModel.paramB"
@change="newCalibrationFuncModelChange()"
/>
*C +
<a-input-number
size="small"
v-model="newCalibrationFuncModel.paramC"
@change="newCalibrationFuncModelChange()"
/>
*C <sup>2</sup>
</span>
</p>
<div class="func">
@ -494,11 +509,11 @@ export default {
sampleId,
qcFileName,
sampleFileName: inputFileName,
fittingBtn: this.isFirstFitting
fittingBtn: this.isFirstFitting,
})
if (res.success) {
const { CToE, EToC, gammaEnergy, gammaSpectrum, max, min, oldScatterSeries } = res.result
const { CToE, EToC, gammaEnergy, gammaSpectrum, max, min, oldScatterSeries, newCToE, newEToC } = res.result
this.c2e = CToE
this.e2c = EToC
@ -530,9 +545,19 @@ export default {
// reanalyzefittingReanalyze 20231101xiao
// todo fitting
if(this.getCache("CALIBRATION_GAMMA_"+this.newSampleData.inputFileName)) {
this.setFirringResult(this.getCache("CALIBRATION_GAMMA_"+this.newSampleData.inputFileName))
return false;
if (this.getCache('CALIBRATION_GAMMA_' + this.newSampleData.inputFileName)) {
this.setFirringResult(this.getCache('CALIBRATION_GAMMA_' + this.newSampleData.inputFileName))
return false
}
/**
* 对人工交互的返回数据单独处理
*/
if (this.sampleData.dbName == 'man') {
const result = res.result
result.EToC = newEToC || []
result.CToE = newCToE
this.setFirringResult(result)
}
} else {
this.$message.error(res.message)
@ -588,7 +613,7 @@ export default {
})
// add chart线 20231028Xiao
if(this.figureChartOption.series[1].data) {
if (this.figureChartOption.series[1].data) {
this.figureChartOption.series[1].data = []
}
@ -615,14 +640,14 @@ export default {
this.isInverse = true
},
//
newCalibrationFuncModelChange(val,a) {
newCalibrationFuncModelChange(val, a) {
// table 20231028Xiao
this.list = []
// chart线 20231028Xiao
if(this.figureChartOption.series[1].data) {
if (this.figureChartOption.series[1].data) {
this.figureChartOption.series[1].data = []
}
if(this.figureChartOption.series[1].markPoint.data) {
if (this.figureChartOption.series[1].markPoint.data) {
this.figureChartOption.series[1].markPoint.data = []
}
},
@ -655,13 +680,16 @@ export default {
// Reset Button
async handleReset() {
this.$ls.remove("CALIBRATION_GAMMA_"+this.newSampleData.inputFileName) // fitting 20231101:xiao
this.$ls.remove('CALIBRATION_GAMMA_' + this.newSampleData.inputFileName) // fitting 20231101:xiao
this.newCalibrationFuncModel = cloneDeep(newCalibrationFuncModel)
this.list = []
this.newE2C = []
// reset 20231211xiao
const res = await postAction('/spectrumAnalysis/resetButton?tabName=gamma&sampleFileName='+ this.newSampleData.inputFileName, { })
const res = await postAction(
'/spectrumAnalysis/resetButton?tabName=gamma&sampleFileName=' + this.newSampleData.inputFileName,
{}
)
this.$emit('isFitting', false)
@ -680,32 +708,32 @@ export default {
}
try {
const { success, result, message } = await postAction('/spectrumAnalysis/fitting', {
...this.list.length <= 0 ? this.newCalibrationFuncModel : [], // list C to E 20231101xiao
...(this.list.length <= 0 ? this.newCalibrationFuncModel : []), // list C to E 20231101xiao
sampleFileName: this.newSampleData.inputFileName,
tabName: "gamma",
tabName: 'gamma',
// 20231028Xiao
tempPoints: this.list.length > 0
? this.list.map((item) => ({ x: item.channel, y: item.energy }))
: this.oldScatterSeries,
// tempPoints: this.isFirstFitting
// ? this.oldScatterSeries
// : this.list.map((item) => ({ x: item.channel, y: item.energy })),
tempPoints:
this.list.length > 0
? this.list.map((item) => ({ x: item.channel, y: item.energy }))
: this.oldScatterSeries,
// tempPoints: this.isFirstFitting
// ? this.oldScatterSeries
// : this.list.map((item) => ({ x: item.channel, y: item.energy })),
count: this.isFirstFitting || !this.isInverse ? undefined : this.count,
fittingBtn : this.isFirstFitting
fittingBtn: this.isFirstFitting,
})
if (success) {
this.gammaIsFitting = true
this.$emit('isFitting', true) // reAnalyzeisFirstFittingtrue 20231101xiao
this.setCache("CALIBRATION_GAMMA_"+this.newSampleData.inputFileName, result) // ReAnalyze 20231101xiao
this.setCache('CALIBRATION_GAMMA_' + this.newSampleData.inputFileName, result) // ReAnalyze 20231101xiao
this.setFirringResult(result)
// Beta
this.$bus.$emit('betaRefresh', {})
console.log("betaRefresh>>>");
console.log('betaRefresh>>>')
} else {
this.$message.error(message)
}
@ -715,7 +743,7 @@ export default {
},
// fittingReAnalyze 20231101xiao
setFirringResult(result){
setFirringResult(result) {
const { EToC, newLineSeries, newScatterSeriesData, tableWidgets, CToE } = result
this.newE2C = EToC
this.newLineSeries = newLineSeries
@ -732,20 +760,24 @@ export default {
paramC: Number(paramC).toPrecision(6),
}
}
const energyValues = newLineSeries.map((item) => item.y)
const { max: prevMax, min: prevMin } = this.oldChartOption.yAxis
if (newLineSeries) {
const energyValues = newLineSeries.map((item) => item.y)
const energyMax = Math.max(Math.max(...energyValues), prevMax)
const energyMin = Math.min(Math.min(...energyValues), prevMin)
const { max: prevMax, min: prevMin } = this.oldChartOption.yAxis
const { min, max, interval } = splitAxis(energyMax, energyMin, 4)
const energyMax = Math.max(Math.max(...energyValues), prevMax)
const energyMin = Math.min(Math.min(...energyValues), prevMin)
this.figureChartOption.yAxis.max = max
this.figureChartOption.yAxis.min = min
this.figureChartOption.yAxis.interval = interval
const { min, max, interval } = splitAxis(energyMax, energyMin, 4)
this.figureChartOption.yAxis.max = max
this.figureChartOption.yAxis.min = min
this.figureChartOption.yAxis.interval = interval
this.figureChartOption.series[1].data = newLineSeries.map(({ x, y }) => [x, y])
}
this.figureChartOption.series[1].data = newLineSeries.map(({ x, y }) => [x, y])
if (newScatterSeriesData) {
this.figureChartOption.series[1].markPoint.data = newScatterSeriesData.map(({ x, y }) => ({
xAxis: x,
@ -797,15 +829,15 @@ export default {
}
return 0
},
getCache(name){
getCache(name) {
return this.$ls.get(name)
},
setCache(name, data){
setCache(name, data) {
this.$ls.set(name, data)
},
removeCache(name){
removeCache(name) {
this.$ls.remove(name) // fitting 20231101:xiao
}
},
},
}
</script>

View File

@ -50,6 +50,7 @@ import { postAction } from '@/api/manage'
import BetaDetectorCalibration from './components/BetaDetectorCalibration.vue'
import GammaDetectorCalibration from './components/GammaDetectorCalibration.vue'
import TitleOverBorder from '@/views/spectrumAnalysis/components/TitleOverBorder.vue'
import { removeSampleData } from '@/utils/SampleStore'
export default {
components: { BetaDetectorCalibration, GammaDetectorCalibration, TitleOverBorder },
mixins: [ModalMixin, SampleDataMixin],
@ -153,11 +154,15 @@ export default {
item.mdc = parseFloat(item.mdc.toPrecision(6))
})
this.$emit('sendXeData', res.result.XeData)
this.$emit('reAnalyCurr', true, res.result.XeData)
this.$message.success('Analyse Success!')
this.$emit('reAnalyCurr', res.result.savedAnalysisResult, res.result.XeData)
this.isReanlyze = true
this.handleExit()
this.$bus.$emit('ReAnalyses', res.result)
if (res.result.bProcessed) {
this.$message.success(res.result.message)
} else {
this.$message.warning(res.result.message)
}
if (this.newCalibrationIsAppliedTo == 'AllSpectrum') {
let sameStation = matchedSampleList.filter(
@ -175,8 +180,7 @@ export default {
//
clearSameStationCache(sampleList) {
sampleList.forEach(({ inputFileName }) => {
console.log('inputFileName>>' + inputFileName)
this.$store.commit('REMOVE_SAMPLE_DATA', inputFileName)
removeSampleData(inputFileName)
})
},
// Calibration 20231115xiao

View File

@ -1,7 +1,7 @@
<template>
<custom-modal v-model="visible" :width="1000" title="View Sample Infomation">
<a-spin :spinning="isLoading">
<a-textarea v-model="content" style="font-family: "></a-textarea>
<a-textarea v-model="content" style="font-family: 仿宋"></a-textarea>
</a-spin>
<div slot="custom-footer">

View File

@ -3,16 +3,16 @@
<a-spin :spinning="isLoading">
<a-tabs :animated="false" @change="handleTabChange">
<a-tab-pane tab="Sample Spectrum" :key="1">
<a-textarea v-model="content.sample" style="font-family: "></a-textarea>
<a-textarea v-model="content.sample" style="font-family: 仿宋"></a-textarea>
</a-tab-pane>
<a-tab-pane tab="GasBg Spectrum" :key="2">
<a-textarea v-model="content.gasBg" style="font-family: "></a-textarea>
<a-textarea v-model="content.gasBg" style="font-family: 仿宋"></a-textarea>
</a-tab-pane>
<a-tab-pane tab="DetBg Spectrum" :key="3">
<a-textarea v-model="content.detBg" style="font-family: "></a-textarea>
<a-textarea v-model="content.detBg" style="font-family: 仿宋"></a-textarea>
</a-tab-pane>
<a-tab-pane tab="QC Spectrum" :key="4">
<a-textarea v-model="content.qc" style="font-family: "></a-textarea>
<a-textarea v-model="content.qc" style="font-family: 仿宋"></a-textarea>
</a-tab-pane>
</a-tabs>
</a-spin>

View File

@ -7,24 +7,28 @@
:dataSource="list"
:list-style="{
width: '200px',
height: '400px'
height: '400px',
}"
:target-keys="targetKeys"
:render="item => item.title"
:render="(item) => item.title"
:showSearch="true"
:showSelectAll="false"
@change="handleChange"
></a-transfer>
<div class="config-user-library-btns">
<div>
<!--<div class="config-user-library-btns">
<div>
<a-button type="primary" @click="handleDefault">Default</a-button>
<a-button type="primary">Load</a-button>
</div>
</div>
<div>
<a-button type="primary" :loading="isSaving" @click="handleSave">Save</a-button>
<a-button type="primary">Apply</a-button>
</div>
<a-button type="primary" :loading="isSaving" @click="handleSave">Save</a-button>
</div>-->
<div style="margin-top: 20px; display: flex; justify-content: end">
<a-button type="primary" :loading="isSaving" @click="handleSave">Save</a-button>
</div>
</div>
</a-spin>
@ -43,7 +47,7 @@ export default {
return {
list: [],
targetKeys: [],
isSaving: false
isSaving: false,
}
},
methods: {
@ -58,17 +62,17 @@ export default {
const { sampleId, inputFileName: fileName } = this.sampleData
const { success, result, message } = await getAction('/gamma/configUserLibrary', {
sampleId,
fileName
fileName,
})
if (success) {
this.isLoading = false
const { AllNuclides, UserNuclides } = result
this.list = AllNuclides.map(item => ({
this.list = AllNuclides.map((item) => ({
key: item,
title: item
title: item,
}))
this.targetKeys = UserNuclides.map(item => item)
this.targetKeys = UserNuclides.map((item) => item)
this.initialTargetKeys = cloneDeep(this.targetKeys)
} else {
@ -95,7 +99,7 @@ export default {
const { inputFileName: fileName } = this.sampleData
const { success, result, message } = await postAction('/gamma/saveUserLibrary', {
fileName,
userLibraryName: this.targetKeys
userLibraryName: this.targetKeys,
})
if (success) {
this.$message.success('Save Success')
@ -107,8 +111,8 @@ export default {
} finally {
this.isSaving = false
}
}
}
},
},
}
</script>

View File

@ -1,7 +1,7 @@
<template>
<custom-modal v-model="visible" :width="1000" title="Data Processing Log">
<a-spin :spinning="isLoading">
<pre class="data-processing-log" style="font-family: ">{{ text }}</pre>
<pre class="data-processing-log" style="font-family: 仿宋">{{ text }}</pre>
</a-spin>
<div slot="custom-footer" style="text-align: center">
<a-space :size="20">

View File

@ -23,7 +23,7 @@
<!-- 底部操作栏 -->
<template slot="custom-footer">
<a-space>
<a-radio-group v-model="queryParam.dbName">
<a-radio-group v-model="queryParam.dbName" @change="handleSourceChange">
<a-radio value="auto">From Auto DB</a-radio>
<a-radio value="man">From Interactive DB</a-radio>
</a-radio-group>
@ -162,6 +162,10 @@ export default {
},
methods: {
loadData(arg) {
// 1
if (arg === 1) {
this.ipagination.current = 1
}
const params = this.getQueryParams() //
const { startDate, endDate, menuTypes } = params
if (!menuTypes) {
@ -179,11 +183,6 @@ export default {
return
}
// 1
if (arg === 1) {
this.ipagination.current = 1
}
params.AllUsers = this.allUsersValue
params.CollectStopB = this.collectStopValue
params.AcqStartB = this.acqStartValue
@ -220,6 +219,11 @@ export default {
})
},
//
handleSourceChange() {
this.searchQuery()
},
show() {
this.visible = true
},

View File

@ -202,7 +202,7 @@
</template>
<script>
import { getAction, postAction } from '../../../../api/manage'
import { getAction, postActionWithTimeOut } from '../../../../api/manage'
import { FilePicker } from '@/utils/FilePicker'
import { readFile, zipFile } from '@/utils/file'
import { isSample, PHDParser, PHD_DATA_TYPE } from '@/utils/phdHelper'
@ -622,7 +622,7 @@ export default {
async uploadZipFile(file) {
const formData = new FormData()
formData.append('file', file)
const res = await postAction('/spectrumFile/upload', formData)
const res = await postActionWithTimeOut('/spectrumFile/upload', formData, 0)
return res
},

View File

@ -1,9 +1,14 @@
<template>
<custom-modal v-model="visible" :width="800" title="Spectrum" :footer="null">
<a-spin :spinning="isLoading">
<pre>
{{ content }}
</pre>
<a-tabs :animated="false">
<a-tab-pane tab="phd" key="1">
<pre key="1">{{ spectrum }}</pre>
</a-tab-pane>
<a-tab-pane tab="phd:raw" key="2">
<pre key="2">{{ phdSpectrum }}</pre>
</a-tab-pane>
</a-tabs>
</a-spin>
</custom-modal>
</template>
@ -16,8 +21,9 @@ export default {
mixins: [ModalMixin, SampleDataMixin],
data() {
return {
content: '',
isLoading: true
spectrum: '',
phdSpectrum: '',
isLoading: true,
}
},
methods: {
@ -27,10 +33,12 @@ export default {
const { sampleId, inputFileName: fileName } = this.sampleData
const { success, result, message } = await getAction('/gamma/Spectrum', {
sampleId,
fileName
fileName,
})
if (success) {
this.content = result
const { Spectrum, phdSpectrum } = result
this.spectrum = Spectrum
this.phdSpectrum = (phdSpectrum || []).join('\r\n')
} else {
this.$message.error(message)
}
@ -43,8 +51,8 @@ export default {
beforeModalOpen() {
this.getContent()
}
}
},
},
}
</script>

View File

@ -57,20 +57,23 @@ export default {
<style lang="less" scoped>
.qc-flags {
display: flex;
max-width: calc(100vw - 685px);
overflow: auto;
&-item {
background-color: #46738e;
display: flex;
align-items: center;
width: 150px;
height: 30px;
cursor: pointer;
padding: 0 10px;
flex-shrink: 0;
&:not(:last-child) {
margin-right: 2px;
}
span {
margin-left: 20px;
margin-right: 5px;
width: 14px;
height: 14px;

View File

@ -1,14 +1,21 @@
<template>
<a-popover :placement="placement" overlayClassName="popover-with-icon" v-model="innerVisible">
<a-popover
v-bind="$attrs"
:placement="placement"
overlayClassName="popover-with-icon"
:visible="innerVisible"
:getPopupContainer="(ele) => ele"
@click="handleClick"
>
<div class="pop-over-with-icon">
<span class="text">
<slot />
</span>
<img src="@/assets/images/global/select-down.png" alt="" />
</div>
<template slot="content">
<div slot="content" @click.stop>
<slot name="content" />
</template>
</div>
</a-popover>
</template>
<script>
@ -16,27 +23,32 @@ export default {
props: {
placement: {
type: String,
default: 'bottom'
default: 'bottom',
},
value: {
type: Boolean
}
type: Boolean,
},
},
data() {
return {
innerVisible: false
innerVisible: false,
}
},
methods: {
handleClick() {
this.innerVisible = !this.innerVisible
},
},
watch: {
value: {
handler(val) {
this.innerVisible = val
},
immediate: true
immediate: true,
},
innerVisible(val) {
this.$emit('input', val)
}
}
},
},
}
</script>

View File

@ -15,31 +15,34 @@ export default {
props: {
data: {
type: Array,
default: () => []
}
default: () => [],
},
},
created() {
this.items = items
}
},
}
</script>
<style lang="less" scoped>
.qc-flags {
display: flex;
max-width: calc(100vw - 1120px);
overflow: auto;
&-item {
background-color: #46738e;
display: flex;
align-items: center;
width: 150px;
height: 30px;
padding: 0 10px;
flex-shrink: 0;
&:not(:last-child) {
margin-right: 2px;
}
span {
margin-left: 20px;
margin-right: 5px;
width: 14px;
height: 14px;
@ -58,7 +61,7 @@ export default {
}
&.BLUE {
background: radial-gradient(circle, #00E57D 0, #00E57D 100%);
background: radial-gradient(circle, #00e57d 0, #00e57d 100%);
}
&.YELLOW {

View File

@ -7,10 +7,6 @@
Detailed-Information
<detailed-infomation slot="content" :data="detailedInfomation" />
</pop-over-with-icon>
<pop-over-with-icon placement="bottomLeft">
QC Flags
<qc-flags slot="content" :data="qcFlags" />
</pop-over-with-icon>
<pop-over-with-icon>
Graph Assistance
<graph-assistance
@ -20,24 +16,20 @@
@reset="handleResetChart"
/>
</pop-over-with-icon>
<a-popover
overlayClassName="popover-with-icon"
:visible="nuclideLibraryVisible"
@click="handleChangeNuclideVisible"
placement="bottom"
>
<div class="pop-over-with-icon">
<span class="text"> Nuclide Library </span>
<img src="@/assets/images/global/select-down.png" alt="" />
</div>
<pop-over-with-icon v-model="subOperatorsState.nuclideLibraryVisible">
Nuclide Library
<a-spin slot="content" :spinning="isLoadingNuclide">
<nuclide-library :list="nuclideLibraryList" @dblclick="handleNuclideDblClick" />
</a-spin>
</a-popover>
</pop-over-with-icon>
<div class="peak-info">
<button-with-switch-icon @change="handlePeakInfoChange" @click="handleTogglePeak"></button-with-switch-icon>
</div>
<pop-over-with-icon placement="right" v-model="subOperatorsState.qcFlagsVisible" :auto-adjust-overflow="false">
QC Flags
<qc-flags slot="content" :data="qcFlags" />
</pop-over-with-icon>
</div>
<!-- 二级交互栏结束 -->
<!-- 主体部分 -->
@ -119,7 +111,7 @@ import GraphAssistance from './components/SubOperators/GraphAssistance/GraphAssi
import NuclideLibrary from './components/SubOperators/NuclideLibrary.vue'
import ButtonWithSwitchIcon from './components/SubOperators/ButtonWithSwitchIcon.vue'
import { getAction, postAction } from '@/api/manage'
import Response from './response.json'
// import Response from './response.json'
import {
buildLineSeries,
findSeriesByName,
@ -144,6 +136,7 @@ import { readFile, zipFile } from '@/utils/file'
import { findNearPeak } from '@/utils/sampleHelper'
import { add, subtract } from 'xe-utils/methods'
import { PHDParser, isSample, getSampleTypeIdentify } from '@/utils/phdHelper'
import { addSampleData, getSampleData } from '@/utils/SampleStore'
export default {
props: {
@ -171,6 +164,36 @@ export default {
StripModal,
},
data() {
this.channelData = {
peakGroup: [],
spectrumLine: null,
baseLine: null,
lcLine: null,
scacLine: null,
all: null,
baseLineCP: [],
compareLine: null,
stripSumOrCutLine: null,
stripReferenceLine: null,
}
this.energyData = {
peakGroup: [],
spectrumLine: null,
baseLine: null,
lcLine: null,
scacLine: null,
all: null,
baseLineCP: [],
compareLine: null,
stripSumOrCutLine: null,
stripReferenceLine: null,
}
this.peakList = [] // Peak
this.baseCtrls = {} // BaseCtrls
return {
abc: false,
isLoading: false,
@ -184,36 +207,12 @@ export default {
detailedInfomation: [],
qcFlags: [],
graphAssistance: cloneDeep(graphAssistance),
nuclideLibraryVisible: false,
channelData: {
peakGroup: [],
spectrumLine: null,
baseLine: null,
lcLine: null,
scacLine: null,
all: null,
baseLineCP: [],
compareLine: null,
stripSumOrCutLine: null,
stripReferenceLine: null,
//
subOperatorsState: {
nuclideLibraryVisible: false,
qcFlagsVisible: false,
},
energyData: {
peakGroup: [],
spectrumLine: null,
baseLine: null,
lcLine: null,
scacLine: null,
all: null,
baseLineCP: [],
compareLine: null,
stripSumOrCutLine: null,
stripReferenceLine: null,
},
peakList: [], // Peak
baseCtrls: {}, // BaseCtrls
nuclideLibraryList: [], // channel
peakInfomationTooltip: {
@ -255,7 +254,7 @@ export default {
window.addEventListener('keydown', this.handleKeyboardEvent)
window.addEventListener('click', this.closePeakInfomationTooltip)
},
destroyed() {
beforeDestroy() {
this.cancelLastRequest()
this.$bus.$off('gammaRefresh', this.handleRefresh)
@ -263,13 +262,30 @@ export default {
window.removeEventListener('keydown', this.handleKeyboardEvent)
window.removeEventListener('click', this.closePeakInfomationTooltip)
if (this.qcFlagsTimer) {
window.clearTimeout(this.qcFlagsTimer)
}
this.closeWebSocket()
if (this.websocketTimer) {
window.clearTimeout(this.websocketTimer)
}
this.websock = null
},
deactivated() {
this.nuclideLibraryVisible = false
// Object.keys(this.subOperatorsState).forEach(k => {
// this.subOperatorsState[k] = false
// })
},
mounted() {
this.option.brush = { toolbox: [] }
this.initWebSocket()
this.qcFlagsTimer = setTimeout(() => {
this.subOperatorsState.qcFlagsVisible = true
}, 100)
},
methods: {
//
@ -457,10 +473,10 @@ export default {
let token = Vue.ls.get(ACCESS_TOKEN)
this.websock = new WebSocket(url, [token])
//update-end-author:taoyan date:2022-4-22 for: v2.4.6 websocket #3278
this.websock.onopen = this.websocketOnopen
this.websock.onerror = this.websocketOnerror
this.websock.onmessage = this.websocketOnmessage
this.websock.onclose = this.websocketOnclose
this.websock.addEventListener('open', this.websocketOnopen)
this.websock.addEventListener('error', this.websocketOnerror)
this.websock.addEventListener('message', this.websocketOnmessage)
this.websock.addEventListener('close', this.websocketOnclose)
},
websocketOnopen: function () {
// console.log('WebSocket1231')
@ -486,19 +502,32 @@ export default {
if (that.lockReconnect) return
that.lockReconnect = true
//
setTimeout(function () {
this.websocketTimer = setTimeout(function () {
console.info('尝试重连...')
that.initWebSocket()
that.lockReconnect = false
}, 20000)
},
// websocket
closeWebSocket() {
if (this.websock) {
this.websock.removeEventListener('open', this.websocketOnopen)
this.websock.removeEventListener('error', this.websocketOnerror)
this.websock.removeEventListener('message', this.websocketOnmessage)
this.websock.removeEventListener('close', this.websocketOnclose)
this.websock.close()
this.websock = null
}
},
//
async getSampleDetail() {
const { dbName, sampleId, analyst } = this.sample
try {
this.isLoading = true
// const { success, result, message } = Response
this.cancelLastRequest()
this.isLoading = true
const cancelToken = this.createCancelToken()
const { success, result, message } = await getAction(
@ -510,7 +539,6 @@ export default {
},
cancelToken
)
console.log('%c [ result ]-243', 'font-size:13px; background:pink; color:#bf2c9f;', result)
if (success) {
this.dataProcess(result, 'db')
} else {
@ -519,17 +547,19 @@ export default {
}
} catch (error) {
console.error(error)
this.isLoading = false
const isCancel = axios.isCancel(error)
if (!isCancel) {
this.isLoading = false
}
}
},
async getSampleDetail_file() {
const { inputFileName: fileName } = this.sample
try {
this.isLoading = true
// const { success, result, message } = Response
this.cancelLastRequest()
this.isLoading = true
const cancelToken = this.createCancelToken()
const { success, result, message } = await getAction(
@ -539,7 +569,6 @@ export default {
},
cancelToken
)
console.log('%c [ result ]-243', 'font-size:13px; background:pink; color:#bf2c9f;', result)
if (success) {
this.dataProcess(result, 'file')
} else {
@ -548,13 +577,17 @@ export default {
}
} catch (error) {
console.error(error)
this.isLoading = false
const isCancel = axios.isCancel(error)
if (!isCancel) {
this.isLoading = false
}
}
},
cancelLastRequest() {
if (this._cancelToken && typeof this._cancelToken == 'function') {
this._cancelToken()
this._cancelToken = undefined
}
},
@ -568,7 +601,7 @@ export default {
dataProcess(result, flag) {
const { inputFileName } = this.sample
this.$store.commit('ADD_SAMPLE_DATA', {
addSampleData({
inputFileName,
data: result,
from: flag,
@ -900,7 +933,7 @@ export default {
changeSeriesType() {},
handleChangeNuclideVisible() {
this.nuclideLibraryVisible = !this.nuclideLibraryVisible
this.subOperatorsState.nuclideLibraryVisible = !this.subOperatorsState.nuclideLibraryVisible
},
// seriesName线
@ -1024,7 +1057,7 @@ export default {
sampleId,
channel,
fileName,
energy
energy,
})
if (success) {
const { possible } = result
@ -1042,7 +1075,7 @@ export default {
// Nuclide Library
handleNuclideDblClick(nuclide) {
this.nuclideLibraryVisible = false
this.subOperatorsState.nuclideLibraryVisible = false
this.nuclideReview.nuclide = nuclide
this.nuclideReview.visible = true
},
@ -1802,6 +1835,7 @@ export default {
return success
} else {
this.isLoading = false
this.reprocessingModalVisible = false
if (showMessage) {
const arr = message.split('\n')
this.$warning({
@ -2045,12 +2079,14 @@ export default {
immediate: true,
},
sample: {
async handler(newVal, oldVal) {
handler(newVal, oldVal) {
console.log('newValnewVal', newVal)
this.graphAssistance.axisType = 'Channel'
this.handleResetState()
const sampleData = await this.$store.dispatch('GET_SAMPLE_DATA', newVal.inputFileName)
const sampleData = getSampleData(newVal.inputFileName)
if (sampleData) {
this.cancelLastRequest()
this.isLoading = false
this.dataProcess(sampleData.data, sampleData.from)
} else {
if (newVal.sampleId) {
@ -2102,8 +2138,45 @@ export default {
}
}
//
.spectrum-analysis-sub-operators {
flex-shrink: 0;
margin-bottom: 19px;
display: flex;
gap: 11px;
flex-wrap: nowrap;
overflow: auto;
height: 46px;
align-items: center;
flex-shrink: 0;
.pop-over-with-icon {
height: 32px;
&:nth-child(1) {
width: 216px;
}
&:nth-child(2) {
width: 182px;
}
&:nth-child(3) {
width: 170px;
}
&:nth-child(5) {
width: 156px;
}
}
.peak-info {
width: 226px;
height: 32px;
flex-shrink: 0;
}
}
//
&-main {
height: calc(100% - 51px);
height: calc(100% - 65px);
display: flex;
overflow: auto hidden;
position: relative;
@ -2141,5 +2214,6 @@ export default {
pointer-events: none;
background-color: #55a9fe;
border-color: #55a9fe;
user-select: none;
}
</style>

View File

@ -63,6 +63,7 @@
:sampleInfo="sampleInfo"
:sample="sampleData"
:analyseCurrentSpectrum="analyseCurrentSpectrumData"
:sampleList="sampleList"
/>
<!-- Beta-Gamma 分析 -->
<div v-else class="empty">Please Select a Sample</div>
@ -281,6 +282,7 @@ import BGLogViewer from './components/Modals/BetaGammaModals/BGLogViewer.vue'
import { saveAs } from 'file-saver'
import CompareFromDbModal from './components/Modals/CompareFromDBModal.vue'
import { clearSampleData, getSampleData, updateSampleDataAnaly } from '@/utils/SampleStore'
//
const ANALYZE_TYPE = {
@ -465,9 +467,9 @@ export default {
window.addEventListener('beforeunload', this.handleCleanAll)
},
destroyed() {
beforeDestroy() {
this.$bus.$off('reanalyse', this.handleReanalyse)
this.$store.commit('CLEAR_SAMPLE_DATA')
clearSampleData()
this.handleCleanAll()
window.removeEventListener('beforeunload', this.handleCleanAll)
},
@ -475,11 +477,13 @@ export default {
methods: {
getReAnalyCurr(flag, val) {
this.isReAnalyed_beta = flag
this.params_toDB.savedAnalysisResult = true
this.params_toDB.savedAnalysisResult = flag
this.resultDisplayFlag = val
},
getReAnalyAll(val) {
getReAnalyAll(flag, val) {
this.isReAnalyed_beta = flag
this.resultDisplayFlag = val
this.params_toDB.savedAnalysisResult = flag
},
handleReAnalyed(val) {
this.isReAnalyed_gamma = val
@ -501,6 +505,7 @@ export default {
}
this.resultDisplayFlag = arg
this.params_toDB.stationName = val
this.params_toDB.savedAnalysisResult = flag
this.isReAnalyed_beta = this.isReAnalyed_beta ? this.isReAnalyed_beta : flag
},
getCheckFlag(val) {
@ -509,10 +514,10 @@ export default {
this.params_toDB.checkDet = val.checkDet
},
getXeData(val) {
if (val && val.length) {
this.$set(this.analyseCurrentSpectrumData, 'XeData', val)
this.resultDisplayFlag = val
}
// if (val && val.length) {
this.$set(this.analyseCurrentSpectrumData, 'XeData', val)
this.resultDisplayFlag = val
// }
},
// formDB sampleData
getFiles(val) {
@ -602,16 +607,16 @@ export default {
//
async loadSelectedSample(sample) {
console.log('%c [ sample ]-381', 'font-size:13px; background:pink; color:red;', sample)
// Bbeta-gamma P Ggamma
if (sample.sampleType == 'B') {
this.analysisType = ANALYZE_TYPE.BETA_GAMMA
const sampleData = getSampleData(sample.inputFileName)
this.params_toDB.savedAnalysisResult = sampleData ? sampleData.data.savedAnalysisResult : false
} else {
this.analysisType = ANALYZE_TYPE.GAMMA
}
this.sampleData = this.newSampleData = sample
this.currSampleDet = this.allSampleDet[sample.inputFileName]
this.params_toDB.savedAnalysisResult = sample.sampleId ? true : false
this.params_toDB.comment = ''
},
@ -842,7 +847,6 @@ export default {
* @param { 'all' | 'current' } type
*/
handleSavePHDToFile(type) {
console.log('%c [ savePHDToFile ]-162', 'font-size:13px; background:pink; color:#bf2c9f;', type)
if (this.isGamma) {
if (type == 'current') {
let params = {
@ -902,7 +906,7 @@ export default {
try {
const { success, result, message } = await postAction(`/gamma/Reprocessing?fileName=${fileNames[0]}`)
if (success) {
this.$store.commit('UPDATE_SAMPLE_DATA_ANALY', {
updateSampleDataAnaly({
inputFileName: fileNames[0],
data: result,
})
@ -1372,11 +1376,13 @@ export default {
children: [
{
type: 'a-menu-item',
show: this.isGamma,
title: 'Nuclide Library',
handler: () => (this.nuclideLibraryModalVisible = true),
},
{
type: 'a-menu-item',
show: this.isGamma,
title: 'Config User Library',
handler: () => (this.configUserLibModalVisible = true),
},
@ -1709,49 +1715,10 @@ export default {
}
//
::v-deep {
//
.spectrum-analysis-sub-operators {
flex-shrink: 0;
margin-bottom: 19px;
display: flex;
flex-wrap: nowrap;
overflow: auto;
.pop-over-with-icon {
height: 32px;
&:not(:last-child) {
margin-right: 11px;
}
&:nth-child(1) {
width: 256px;
}
&:nth-child(2) {
width: 186px;
}
&:nth-child(3) {
width: 246px;
}
&:nth-child(4) {
width: 246px;
}
}
.peak-info {
width: 306px;
height: 32px;
display: inline-block;
}
}
//
}
//
&-main {
margin-top: 15px;
height: calc(100% - 45px);
padding-top: 5px;
height: calc(100% - 15px);
overflow: hidden;
}
//
@ -1797,6 +1764,8 @@ export default {
<style lang="less">
.spectrum-analysis-operators-dropdown-overlay {
background-color: #03353f;
z-index: 999;
.ant-menu {
background: transparent;
padding: 0;

View File

@ -4,7 +4,7 @@
{{ item.stationName || item.stationCode }}
</h4>
<div class="data-list-item-container">
<div class="data-list-item-content">
<div class="data-list-item-content" :class="[item.scheduling ? 'active' : '']">
<div class="data-list-item-children">
<div class="data-list-item-child">
<label>Station Type:</label>
@ -42,9 +42,9 @@
export default {
props: {
item: {
type: Object
}
}
type: Object,
},
},
}
</script>
@ -85,6 +85,10 @@ export default {
flex-direction: column;
justify-content: space-between;
&.active {
background-image: url(~@/assets/images/station-operation/data-item-bg-active.png);
}
.data-list-item-children {
display: flex;
justify-content: space-between;

View File

@ -11,6 +11,14 @@ import Map from 'ol/Map'
import XYZ from 'ol/source/XYZ'
import View from 'ol/View'
import { fromLonLat } from 'ol/proj'
import Stroke from 'ol/style/Stroke'
import { MarkerIcon, MarkerType } from './markerEnum'
import Icon from 'ol/style/Icon'
import VectorSource from 'ol/source/Vector'
import VectorLayer from 'ol/layer/Vector'
import { LineString, Point } from 'ol/geom'
import { Feature } from 'ol'
import Style from 'ol/style/Style'
const mapSourceUrl = process.env.VUE_APP_MAP_BASE_URL
export default {
@ -57,20 +65,29 @@ export default {
}),
})
const layers = [this.tileLayer]
this.animationSource = new VectorSource({
features: [],
})
const view = new View({
this.animationLayer = new VectorLayer({
source: this.animationSource,
})
const layers = [this.tileLayer, this.animationLayer]
this.view = new View({
projection: 'EPSG:3857', // 使
center: fromLonLat([longitude, latitude]),
zoom: this.zoom,
maxZoom: this.maxZoom,
minZoom: this.minZoom,
extent: [-20037508.34 - 3500000, -20037508.34, 20037508.34 + 3500000, 20037508.34],
})
this.map = new Map({
target: this.$refs.mapContainerRef,
layers,
view,
view: this.view,
controls: [],
})
},
@ -119,6 +136,110 @@ export default {
})
)
},
// 线
animateByRoute(coordinates) {
if (!coordinates) {
return
}
if (!coordinates.length) {
this.stopRouteAnimation()
this.removeAnimationFeatures()
return
}
this.startRouteAnimation(
coordinates,
{
stroke: new Stroke({
color: '#17f85c',
lineDash: [6],
width: 2,
}),
},
{
image: new Icon({
src: MarkerIcon[MarkerType.Car],
anchor: [0.65, 0.5],
}),
},
[100, 430, 100, 450]
)
},
/**
* 沿轨迹运动
* @param {Array<any>} route 轨迹路线
* @param {Object} marker 运动的物体
*/
startRouteAnimation(route, lineStyleOptions, markerStyleOptions, padding = []) {
//
this.stopRouteAnimation()
//
this.removeAnimationFeatures()
const lineString = new LineString(route.map((item) => fromLonLat(item)))
const extent = lineString.getExtent()
this.view.fit(extent, {
padding,
duration: 1000,
})
// 线
const routeFeature = new Feature({
geometry: lineString,
})
// 线
routeFeature.setStyle(new Style(lineStyleOptions))
this.animationSource.addFeature(routeFeature)
// 线
const markerFeature = new Feature({
geometry: new Point(lineString.getFirstCoordinate()),
})
//
markerFeature.setStyle(new Style(markerStyleOptions))
this.animationSource.addFeature(markerFeature)
let lastTime = Date.now(),
distance = 0
this.postRenderCallback = (event) => {
const speed = 60
const time = event.frameState.time
const elapsedTime = time - lastTime
distance = (distance + (speed * elapsedTime) / 1e6) % 2
lastTime = time
if (distance >= 1) {
this.stopRouteAnimation()
return
}
const currentCoordinate = lineString.getCoordinateAt(distance > 1 ? 2 - distance : distance)
markerFeature.setGeometry(new Point(currentCoordinate))
// tell OpenLayers to continue the postrender animation
this.map.render()
}
this.animationLayer.on('postrender', this.postRenderCallback)
},
//
removeAnimationFeatures() {
this.animationSource.clear()
},
//
stopRouteAnimation() {
if (this.postRenderCallback) {
this.animationLayer.un('postrender', this.postRenderCallback)
this.postRenderCallback = null
}
},
},
}
</script>

View File

@ -26,30 +26,30 @@ export default {
props: {
list: {
type: Array,
required: true
required: true,
},
currList: {
type: Array,
required: true
required: true,
},
orgList: {
type: Array,
required: true
required: true,
},
markerType: {
type: Number,
default: 1
default: 1,
},
radius: {
type: Number
}
type: Number,
},
},
data() {
return {
currStationInfo: {},
isGettingInfo: false,
columns: {},
popupTitle: ''
popupTitle: '',
}
},
mounted() {
@ -59,7 +59,7 @@ export default {
this.changeCircleRadius()
})
this.getStationInfo = debounce(stationInfo => {
this.getStationInfo = debounce((stationInfo) => {
//
if (this.isHover) {
this._getStationInfo(stationInfo)
@ -69,13 +69,14 @@ export default {
methods: {
initCircles() {
const circleRadius = this.getRadius() * 2
console.log('this.list', this.list)
this.list
.filter(
stationInfo =>
(stationInfo) =>
stationInfo.stationType !== MarkerType.NuclearFacility && stationInfo.stationType !== MarkerType.NRL
)
.forEach(stationInfo => {
.forEach((stationInfo) => {
this.map.addOverlay(this.getCircle(stationInfo, circleRadius))
})
},
@ -92,17 +93,17 @@ export default {
element: circleDiv,
id: `circle_${stationType}_${stationId}`,
positioning: 'center-center',
className: 'circle-overlay'
className: 'circle-overlay',
})
},
//
changeCircleRadius() {
const overlays = this.map.getOverlays().getArray()
const circleOverlays = overlays.filter(item => item.id.indexOf('circle') == 0) // id
const circleOverlays = overlays.filter((item) => item.id.indexOf('circle') == 0) // id
const circleRadius = this.getRadius() * 2
circleOverlays.forEach(circle => {
circleOverlays.forEach((circle) => {
const circleEle = circle.getElement()
circleEle.style.width = circleRadius + 'px'
circleEle.style.height = circleRadius + 'px'
@ -111,10 +112,7 @@ export default {
//
getRadius() {
const metersPerUnit = this.map
.getView()
.getProjection()
.getMetersPerUnit()
const metersPerUnit = this.map.getView().getProjection().getMetersPerUnit()
const distance = (this.radius * 1000) / metersPerUnit
const resolution = this.map.getView().getResolution()
@ -123,7 +121,7 @@ export default {
// marker
initMarkers() {
this.list.forEach(stationInfo => {
this.list.forEach((stationInfo) => {
this.map.addOverlay(this.getMarker(stationInfo))
})
},
@ -153,18 +151,19 @@ export default {
position: fromLonLat([lon, lat]),
element: img,
id: `marker_${stationInfo.stationType}_${stationInfo.stationId}`,
positioning: 'center-center'
positioning: 'center-center',
})
},
//
initRipples() {
this.currList
.filter((stationInfo) => stationInfo.status !== 'Unoperating')
// .filter(
// stationInfo =>
// stationInfo.stationType !== MarkerType.NuclearFacility && stationInfo.stationType !== MarkerType.NRL
// )
.forEach(stationInfo => {
.forEach((stationInfo) => {
this.map.addOverlay(this.getRipple(stationInfo))
})
},
@ -172,15 +171,15 @@ export default {
getRipple({ lon, lat, stationId, stationType, quality }) {
const rippleDiv = document.createElement('div')
rippleDiv.className = 'custom-ripple'
if (quality == "excellent") {
if (quality == 'excellent') {
rippleDiv.innerHTML = ` <div class="inner-ripple-excellent-1"></div>
<div class="inner-ripple-excellent-2"></div>
`
} else if (quality == "good") {
} else if (quality == 'good') {
rippleDiv.innerHTML = ` <div class="inner-ripple-good-1"></div>
<div class="inner-ripple-good-2"></div>
`
} else if(quality == "bad"){
} else if (quality == 'bad') {
rippleDiv.innerHTML = ` <div class="inner-ripple-bad-1"></div>
<div class="inner-ripple-bad-2"></div>
`
@ -191,7 +190,7 @@ export default {
element: rippleDiv,
id: `ripple_${stationType}_${stationId}`,
positioning: 'center-center',
className: 'ripple-overlay'
className: 'ripple-overlay',
})
},
@ -200,7 +199,7 @@ export default {
this.popupOverlay = new Overlay({
element: this.$refs.mapPopupRef,
positioning: 'top-center',
id: POPUP_OVERLAY_ID
id: POPUP_OVERLAY_ID,
})
this.map.addOverlay(this.popupOverlay)
},
@ -218,17 +217,18 @@ export default {
//
async _getStationInfo(stationInfo) {
try {
const { success, result, message } = await getAction('/jeecg-station-operation/stationOperation/findInfo', {
const { success, result, message } = await getAction('/stationOperation/findInfo', {
stationId: stationInfo.stationId,
type: stationInfo.stationType
type: stationInfo.stationType,
})
if (success) {
result.lon = decimalToDms(result.lon || result.longitude)
result.lat = decimalToDms(result.lat || result.latitude, false)
let params = this.currList.find(item => {
return item.stationId === result.stationId
}) || {}
let params =
this.currList.find((item) => {
return item.stationId === result.stationId
}) || {}
this.currStationInfo = { ...result, ...params }
} else {
this.$message.error(message)
@ -243,7 +243,7 @@ export default {
//
closeMapPopup() {
this.popupOverlay.setPosition(null)
}
},
},
watch: {
list() {
@ -257,19 +257,22 @@ export default {
},
currList: {
handler(newVal, oldVal) {
this.orgList.forEach(item => {
var layer = this.map.getOverlays().getArray().find(layer=> {
return layer.id === `ripple_${item.stationType}_${item.stationId}`;
});
this.orgList.forEach((item) => {
var layer = this.map
.getOverlays()
.getArray()
.find((layer) => {
return layer.id === `ripple_${item.stationType}_${item.stationId}`
})
if (layer) {
this.map.removeOverlay(layer);
this.map.removeOverlay(layer)
}
})
this.initRipples()
},
deep:true
}
}
deep: true,
},
},
}
</script>
<style lang="less" scoped>
@ -362,7 +365,12 @@ export default {
width: 100%;
height: 100%;
border-radius: 50%;
background-image: radial-gradient(circle, transparent 10%, rgba(187, 138, 18, 0.2) 30%, rgba(187, 138, 18, 0.5) 60%);
background-image: radial-gradient(
circle,
transparent 10%,
rgba(187, 138, 18, 0.2) 30%,
rgba(187, 138, 18, 0.5) 60%
);
animation: rippleEffect @duration linear 0s infinite;
}
@ -373,7 +381,12 @@ export default {
height: 100%;
border-radius: 50%;
transform: scale(0);
background-image: radial-gradient(circle, transparent 10%, rgba(187, 138, 18, 0.2) 30%, rgba(187, 138, 18, 0.5) 60%);
background-image: radial-gradient(
circle,
transparent 10%,
rgba(187, 138, 18, 0.2) 30%,
rgba(187, 138, 18, 0.5) 60%
);
animation: rippleEffect @duration linear @delay infinite;
}
.inner-ripple-bad-1 {

View File

@ -32,6 +32,14 @@
/>
<img v-else src="@/assets/images/station-operation/filter-station.png" @click="onPaneChange(2)" />
</div>
<div title="Route">
<img
v-if="active == 3 && showPane"
src="@/assets/images/station-operation/icon-route-active.png"
@click="showPane = !showPane"
/>
<img v-else src="@/assets/images/station-operation/icon-route.png" @click="onPaneChange(3)" />
</div>
</div>
<div class="map-pane-operators-zoom">
@ -149,6 +157,39 @@
</div>
</div>
<!-- 站点筛选结束 -->
<!-- 路径 -->
<div class="route" v-show="active == 3">
<div class="map-pane-content-header">Route</div>
<div class="map-pane-content-main">
<div class="route-form-item">
<div class="label">Station</div>
<custom-select v-model="routeParams.stationCode" :options="stationSelectOptions"></custom-select>
</div>
<div class="route-form-item">
<div class="label">Start Date</div>
<custom-date-picker
format="YYYY-MM-DD"
valueFormat="YYYY-MM-DD"
v-model="routeParams.startDate"
></custom-date-picker>
</div>
<div class="route-form-item">
<div class="label">End Date</div>
<custom-date-picker
format="YYYY-MM-DD"
valueFormat="YYYY-MM-DD"
v-model="routeParams.endDate"
></custom-date-picker>
</div>
<div class="route-form-item">
<a-button class="btn" type="primary" :loading="isSearchingRoute" @click="handleRouteSearch"
>Search</a-button
>
</div>
</div>
</div>
<!-- 路径结束 -->
</div>
<!-- 主体部分结束 -->
@ -189,7 +230,7 @@
<div class="content">
<a-form-model class="attribute-form" layout="vertical">
<a-form-model-item label="Cache time">
<a-input-number type="number" v-model="dataRecieveStatusModel.cacheTime" :min="0"></a-input-number>
<a-input-number type="number" v-model="dataRecieveStatusModel.cacheTime" :min="1"></a-input-number>
<span>day</span>
</a-form-model-item>
<a-form-model-item label="Scale interval">
@ -268,16 +309,13 @@
import CustomModal from '@/components/CustomModal/index.vue'
import CustomTree from '@/components/CustomTree/index.vue'
import RealTimeDataChart from './RealTimeDataChart.vue'
import { getAction, postAction } from '../../../api/manage'
import { deleteAction, getAction, postAction } from '../../../api/manage'
import { MarkerType, FilterIcon } from './markerEnum'
import { Vector as VectorLayer } from 'ol/layer'
import VectorSource from 'ol/source/Vector'
import { Circle } from 'ol/geom'
import { fromLonLat } from 'ol/proj'
import Feature from 'ol/Feature'
import { Fill, Stroke, Style } from 'ol/style'
import { cloneDeep } from 'lodash'
import dayjs from 'dayjs'
// Filter
const filterList = [
@ -397,10 +435,13 @@ export default {
type: Number,
default: 500,
},
treeData: {
type: Array,
},
originalDataList: {
type: Array,
default: () => [],
},
},
components: {
CustomModal,
@ -449,14 +490,20 @@ export default {
stationInfo: undefined,
mapSource: 'online',
routeParams: {
stationCode: undefined,
startDate: dayjs().subtract(7, 'd').format('YYYY-MM-DD'),
endDate: dayjs().format('YYYY-MM-DD'),
},
isSearchingRoute: false,
}
},
created() {
this.initParentMapProps()
document.addEventListener('fullscreenchange', this.onFullScreenChange)
this.stationList = []
this.getDataRecieveSettings()
},
destroyed() {
document.removeEventListener('fullscreenchange', this.onFullScreenChange)
@ -498,18 +545,33 @@ export default {
//
onPaneChange(active) {
this.showPane = true
this.prevPane = this.active //
this.active = active
const source = this.circleLayer.getSource()
source.clear() //
switch (active) {
case 1: //
// 使
if (active == 3) {
if (this.lastRoute) {
this.$emit('drawRoute', this.lastRoute)
}
this.$emit('changeMarker', [])
} else {
//
if (this.prevPane == 3) {
this.$emit('drawRoute', [])
}
if (active == 1) {
this.emitDrawCircle(2)
this.emitStationChange()
break
case 2: //
}
if (active == 2) {
this.emitDrawCircle(1)
this.emitFilter()
break
}
}
},
@ -579,7 +641,7 @@ export default {
success,
result: { GIS: markerList, table },
message,
} = await postAction('/jeecg-station-operation/stationOperation/getHitEquList', {
} = await postAction('/stationOperation/getHitEquList', {
radius: this.radius,
stationIds,
})
@ -695,17 +757,15 @@ export default {
try {
const stationIds = this.dataStatusCheckedKeys.filter((key) => -1 == key.toString().indexOf('root_'))
this.isSavingDataRecieveSettings = true
const { success, message } = await postAction(
'/jeecg-station-operation/sysUserFocusStation/saveUserFocusByUserId',
{
stationIds,
...this.dataRecieveStatusModel,
}
)
const { success, message } = await postAction('/sysUserFocusStation/saveUserFocusByUserId', {
stationIds,
...this.dataRecieveStatusModel,
})
if (success) {
this.$message.success('Save Success')
await this.getDataRecieveSettings()
this.startGetDataReceiveStatusList()
this.$emit('focusStationChange')
} else {
this.$message.error(message)
}
@ -738,14 +798,20 @@ export default {
//
async getDataRecieveSettings() {
try {
const { success, result, message } = await getAction(
'/jeecg-station-operation/sysUserFocusStation/findUserFocusByUserId',
{
userId: this.$store.getters.userInfo.id,
}
)
const { success, result, message } = await getAction('/sysUserFocusStation/findUserFocusByUserId', {
userId: this.$store.getters.userInfo.id,
})
if (success) {
const { cacheTime, scaleInterval, timelineLength, updateIntervalTime, sysUserFocusStations } = result
this.initialDataRecieveSettings = result
this.dataRecieveStatusModel = {
cacheTime,
scaleInterval,
timelineLength,
updateIntervalTime,
}
this.dataStatusCheckedKeys = sysUserFocusStations.map((item) => parseInt(item.stationId))
} else {
this.$message.error(message)
}
@ -774,13 +840,11 @@ export default {
this.spinLoading = true
try {
this.isGettingStatusList = true
const { success, result, message } = await getAction(
'/jeecg-station-operation/stationOperation/getDataReceivingStatus',
{
userId: this.$store.getters.userInfo.id,
oneStationId: (this.stationInfo && this.stationInfo.stationId) || '',
}
)
const { success, result, message } = await getAction('/stationOperation/getDataReceivingStatus', {
userId: this.$store.getters.userInfo.id,
oneStationId: (this.stationInfo && this.stationInfo.stationId) || '',
cacheTime: this.initialDataRecieveSettings.cacheTime,
})
this.maskVisi = false
this.spinLoading = false
if (success) {
@ -813,29 +877,80 @@ export default {
}
},
//
async clearDataRecieveSetting() {
const { success, message } = await deleteAction('/sysUserFocusStation/deleteUserCache', {
userId: this.$store.getters.userInfo.id,
})
if (!success) {
throw new Error(message)
}
},
handleResize() {
this.$refs.realtimeChartRef.resize()
},
//
async handleRouteSearch() {
if (!this.routeParams.stationCode) {
this.$message.warn('Station Code Cannot Be Null')
return
}
this.isSearchingRoute = true
try {
const { success, result, message } = await getAction('/stationOperation/getSelfStationGPS', {
...this.routeParams,
})
if (success) {
if (!result.length) {
this.$message.warn('No Route Found')
return
}
this.lastRoute = result.map(({ lon, lat }) => [lon, lat])
this.$emit('drawRoute', this.lastRoute)
} else {
this.$message.error(message)
}
} catch (e) {
console.error(e)
} finally {
this.isSearchingRoute = false
}
},
},
watch: {
dataStatusModalVisible(val) {
async dataStatusModalVisible(val) {
if (val) {
this.dataStatusCheckedKeys = this.initialDataRecieveSettings.sysUserFocusStations.map((item) =>
parseInt(item.stationId)
)
this.dataRecieveStatusModel = {
cacheTime: this.initialDataRecieveSettings.cacheTime,
scaleInterval: this.initialDataRecieveSettings.scaleInterval,
timelineLength: this.initialDataRecieveSettings.timelineLength,
updateIntervalTime: this.initialDataRecieveSettings.updateIntervalTime,
try {
this.spinLoading = true
await this.clearDataRecieveSetting()
await this.getDataRecieveSettings()
this.startGetDataReceiveStatusList()
} catch (error) {
this.$message.error(error)
this.spinLoading = false
}
this.startGetDataReceiveStatusList()
} else {
clearInterval(this.timer)
}
},
},
computed: {
stationSelectOptions() {
return this.originalDataList
.filter(({ stationType }) => stationType == 'Car')
.map(({ stationName: label }) => ({
label,
value: label,
}))
},
},
}
</script>
<style lang="less" scoped>
@ -864,6 +979,8 @@ export default {
img {
cursor: pointer;
width: 30px;
height: 30px;
}
&-main-operator {
margin-top: 5px;
@ -1053,17 +1170,12 @@ export default {
}
.ant-table-thead > tr th {
padding-top: 2px !important;
padding-bottom: 2px !important;
padding-top: 2px 6px !important;
}
.ant-table-tbody .ant-table-row td {
padding: 6px !important;
}
.ant-table-placeholder {
background-color: transparent;
}
}
}
}
@ -1131,6 +1243,27 @@ export default {
}
}
}
//
.route {
pointer-events: all;
&-form-item {
.label {
margin-bottom: 10px;
}
&:not(:first-child) {
margin-top: 15px;
}
}
.btn {
width: 100%;
margin-top: 50px;
height: 40px;
}
}
}
}
//

View File

@ -29,8 +29,10 @@
import CustomChart from '@/components/CustomChart/index.vue'
import * as echarts from 'echarts'
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import { cloneDeep } from 'lodash'
dayjs.extend(utc)
const typeList = ['MET', 'SOH', 'QC', 'PHD'] //
//
@ -71,7 +73,16 @@ const legendList = [
const initialOption = {
tooltip: {
formatter: (params) => {
return `${params.marker}${params.name}: ${(params.value[3] / 1000 / 60).toFixed()}min`
// return `
// <div>${params.marker}${params.name}</div>
// <div>START${dayjs(new Date(params.value[4])).format('YYYY-MM-DD HH:mm:ss')}</div>
// <div style="white-space: pre"> END${dayjs(new Date(params.value[2])).format('YYYY-MM-DD HH:mm:ss')}</div>
// `
return `
<div>${params.marker}${params.name}</div>
<div>START${dayjs(params.value[4]).format('YYYY-MM-DD HH:mm:ss')}</div>
<div style="white-space: pre"> END${dayjs(params.value[2]).format('YYYY-MM-DD HH:mm:ss')}</div>
`
},
},
grid: [],
@ -179,7 +190,7 @@ export default {
let now = dayjs(new Date())
now = now.add(1, 'hour').set('minute', 0).set('second', 0).set('millisecond', 0)
const max = now.valueOf()
const max = dayjs(dayjs.utc(now.valueOf()).format('YYYY-MM-DD HH:mm:ss')).valueOf()
const min = max - this.scaleSettings.cacheTime * 24 * 60 * 60 * 1000
const option = cloneDeep(initialOption)
const { grid, xAxis, yAxis, series, dataZoom } = option
@ -199,8 +210,9 @@ export default {
axisLabel: {
show: true,
formatter: (val) => {
let dateTime = new Date(val)
return dayjs(dateTime).format('HH:mm\nMM/DD')
// let dateTime = new Date(val)
// return dayjs.utc(dateTime).format('HH:mm\nMM/DD')
return dayjs(val).format('HH:mm\nMM/DD')
},
color: '#ade6ee',
},
@ -245,6 +257,7 @@ export default {
item.dataList.forEach((item) => {
this.convertStatus(item)
let originalTime = new Date(item.beginTime * 1000).getTime()
let startTime = new Date(item.beginTime * 1000).getTime()
if (item.type == 'PHD') {
startTime = item.endTime * 1000 - 60 * 1000 * 30
@ -257,7 +270,7 @@ export default {
if (find.isShow) {
data.push({
name: item.status,
value: [index, startTime, endTime, duration],
value: [index, startTime, endTime, duration, originalTime],
itemStyle: {
normal: {
color: find.color,

View File

@ -152,10 +152,13 @@
<MapPane
ref="mapPane"
:treeData="treeData"
:originalDataList="originalDataList"
@changeMarker="onChangeMarker"
@filterMarker="onFilterMarker"
@drawCircle="onDrawCircle"
@mapSourceChange="handleMapSourceChange"
@focusStationChange="getFollowedStationList"
@drawRoute="handleDrawRoute"
/>
</Map>
</div>
@ -180,19 +183,6 @@ export default {
ScrollContainer,
DataListItem,
},
watch: {
$route: {
handler: function (val, oldVal) {
console.log('fasdfasde12312', val)
console.log('8765432', oldVal)
if (val.name === 'station-operation') {
this.getDataProvisionEfficiency(this.markerList_clone)
}
},
deep: true,
// immediate: true,
},
},
deactivated() {
//
console.log('切换出发了3')
@ -200,6 +190,11 @@ export default {
clearInterval(this.timer)
this.timer = null
},
activated() {
this.getFollowedStationList()
this.getStationList()
this.getStationTree()
},
data() {
return {
activeKey: '1',
@ -236,13 +231,11 @@ export default {
updataFilterType: [],
updataFilterDataQuality: [],
httpNum: 0,
originalDataList: [],
}
},
created() {
this.getStationList()
this.getFollowedStationList()
this.getStationTypeList()
this.getStationTree()
},
beforeDestroy() {
clearInterval(this.timer)
@ -253,7 +246,7 @@ export default {
async getStationList() {
try {
this.isGettingDataList = true
const res = await getAction('/jeecg-station-operation/stationOperation/findList')
const res = await getAction('/stationOperation/findList')
res.forEach((item) => {
const { stationId, stationName, stationType } = item
item._stationId = `${stationId}${stationName}${stationType}`
@ -264,7 +257,7 @@ export default {
this.markerList = cloneDeep(res).filter((stationInfo) => stationInfo.stationType !== MarkerType.NuclearFacility) //
this.markerList_clone = cloneDeep(res)
this.getDataProvisionEfficiency(this.markerList_clone, 'one')
this.getDataProvisionEfficiency(this.markerList_clone)
// this.timer = setInterval(() => {
// setTimeout(() => {
// this.getDataProvisionEfficiency(this.markerList_clone)
@ -281,17 +274,18 @@ export default {
},
//
async getDataProvisionEfficiency(arr, str) {
async getDataProvisionEfficiency(arr) {
this.httpNum++
if (str && this.$route.path == '/station-operation') {
if (!this.loaded && this.$route.path == '/station-operation') {
this.$message.loading({ content: 'Loading station data, please wait...', key, duration: 0 })
}
getAction('/stationOperation/getDataProvisionEfficiency')
.then((res) => {
if (res.success) {
this.$message.destroy()
if (str && this.$route.path == '/station-operation') {
if (!this.loaded && this.$route.path == '/station-operation') {
this.$message.success({ content: 'Loaded!', key, duration: 2 })
this.loaded = true
}
res.result.forEach((item) => {
if (Object.prototype.toString.call(item) == '[object Object]') {
@ -364,7 +358,7 @@ export default {
async getFollowedStationList() {
try {
this.isGettingFollowedDataList = true
const res = await getAction('/jeecg-station-operation/sysUserFocusStation/findList')
const res = await getAction('/sysUserFocusStation/findList')
this.followedDataList = res
const scrollContainer2Ref = this.$refs.scrollContainer2Ref
@ -383,7 +377,7 @@ export default {
//
async getStationTypeList() {
try {
const res = await getAction('/jeecg-station-operation/stationOperation/findStationType')
const res = await getAction('/stationOperation/findStationType')
this.stationTypeList = res.filter((item) => item).map((item) => ({ label: item, value: item }))
} catch (error) {
console.error(error)
@ -521,12 +515,6 @@ export default {
*/
onFilterMarker({ filterType, filterDataQuality }) {
this.updataFilterType = filterType
console.log(
'%c [ filterType, filterDataQuality ]-343',
'font-size:13px; background:pink; color:#bf2c9f;',
filterType,
filterDataQuality
)
this.updataFilterDataQuality = []
filterDataQuality.forEach((item) => {
if (item === 'Excellent data quality') {
@ -548,8 +536,14 @@ export default {
//
onMarkerClick(stationInfo) {
const { stationType } = stationInfo
if (stationType !== 'NRL' && stationType !== 'Nuclear Facility') {
const { stationType, stationName } = stationInfo
const find = this.orgStationList.find((item) => item.stationCode == stationName)
if (!find) {
return
}
const status = find.status
if (stationType !== 'NRL' && stationType !== 'Nuclear Facility' && status !== 'Unoperating') {
this.$refs.mapPane.handleOpenAnalyzeModal(stationInfo)
}
},
@ -574,6 +568,11 @@ export default {
getDictSelectTagContainer() {
return document.body
},
//
handleDrawRoute(routes) {
this.$refs.mapRef.animateByRoute(routes)
},
},
}
</script>

View File

@ -1,8 +1,8 @@
<template>
<a-card :bordered="false" style="height: 100%;">
<a-card :bordered="false" style="height: 100%">
<a-layout id="components-layout-demo-custom-trigger" style="height: 100%">
<a-layout-sider theme="light" v-model="collapsed" :trigger="null" collapsible width="350px">
<div style="height:100%">
<div style="height: 100%">
<!-- :defaultSelectedKeys="defaultSelectedKeys" -->
<!-- :defaultOpenKeys="defaultOpenKeys" -->
<a-menu
@ -30,9 +30,9 @@
</a-layout-sider>
<a-layout style="background-color: aliceblue">
<keep-alive>
<router-view v-if="keepAlive" />
<router-view />
</keep-alive>
<router-view v-if="!keepAlive" />
<!-- <router-view v-if="!keepAlive" /> -->
</a-layout>
</a-layout>
</a-card>
@ -74,11 +74,11 @@ const SubMenu = {
export default {
name: 'menuTree',
components: { 'sub-menu': SubMenu },
computed: {
keepAlive() {
return this.$route.meta.keepAlive
},
},
// computed: {
// keepAlive() {
// return this.$route.meta.keepAlive
// },
// },
data() {
const collapsed = false
return {
@ -104,30 +104,29 @@ export default {
this.menus = f.children
}
})
console.log("路由信息",this.menus);
// this.initDefaultKeys(this.menus[0])
// openKeys
const openKeys = window.sessionStorage.getItem('openKeys')
const selectedKeys = window.sessionStorage.getItem('currMenu_web')
if (selectedKeys) {
this.currSlecteKey=[]
this.currSlecteKey = []
// this.defaultSelectedKeys.push(selectedKeys)
this.currSlecteKey.push(selectedKeys)
} else {
this.currSlecteKey=[]
this.currSlecteKey = []
this.initDefaultKeys(this.menus[0])
this.menus.forEach(item => {
if (item.name!=="istatistics-data") {
// this.defaultOpenKeys.push(item.path)
this.openKeys.push(item.path)
}
this.menus.forEach((item) => {
if (item.name !== 'istatistics-data') {
// this.defaultOpenKeys.push(item.path)
this.openKeys.push(item.path)
}
})
window.sessionStorage.setItem('openKeys', JSON.stringify(this.openKeys))
}
// if (openKeys) {
// //
// this.defaultOpenKeys = JSON.parse(openKeys)
// }
// }
if (openKeys) {
//
this.openKeys = JSON.parse(openKeys)
@ -151,25 +150,25 @@ export default {
// this.defaultOpenKeys.push(data.path)
this.openKeys.push(data.path)
// if (data.children) {
if (data.name!=="istatistics-StateOfHealth-alerts") {
data.children.some((f) => {
if (f.name!=="istatistics-met") {
if (f.children) {
//
// this.defaultOpenKeys.push(f.path)
this.openKeys.push(f.path)
this.initDefaultKeys(f.children[0])
} else {
//
// this.defaultSelectedKeys.push(f.path)
this.currSlecteKey.push(f.path)
return true
}
if (data.name !== 'istatistics-StateOfHealth-alerts') {
data.children.some((f) => {
if (f.name !== 'istatistics-met') {
if (f.children) {
//
// this.defaultOpenKeys.push(f.path)
this.openKeys.push(f.path)
this.initDefaultKeys(f.children[0])
} else {
//
// this.defaultSelectedKeys.push(f.path)
this.currSlecteKey.push(f.path)
return true
}
})
}
}
})
}
// } else {
// this.defaultOpenKeys.push(data.path)
// this.defaultOpenKeys.push(data.path)
// }
},
onOpenChange(openKeys) {
@ -193,7 +192,7 @@ export default {
background: none;
}
}
::v-deep .ant-card-body{
::v-deep .ant-card-body {
height: 100%;
}
.ant-menu {

View File

@ -28,6 +28,10 @@
{{ index + 1 }}
</template>
</custom-table>
<!-- 日志列表结束 -->
<custom-modal title="List Of File Deletion Failures" :width="950" v-model="visibleInfo" :footer="null">
<a-table :columns="columnsModal" :data-source="dataInfo" :pagination="false"> </a-table>
</custom-modal>
</div>
</template>
@ -163,11 +167,24 @@ const columns = [
dataIndex: 'status',
},
]
const columnsModal = [
{
title: 'Index',
dataIndex: 'rowCount',
align: 'center',
},
{
title: 'Information',
dataIndex: 'info',
align: 'left',
},
]
export default {
mixins: [JeecgListMixin],
data() {
this.columns = columns
this.columnsModal = columnsModal
return {
queryParam: {
collectStart: this.getBeforeDate(6),
@ -183,6 +200,8 @@ export default {
},
stationList: [],
detectorList: [],
visibleInfo: false,
dataInfo: [],
}
},
created() {
@ -264,7 +283,7 @@ export default {
cancelText: 'Cancel',
onOk: async () => {
try {
const { success, message } = await deleteAction('/gardsSampleData/deleteById', {
const { success, message, result } = await deleteAction('/gardsSampleData/deleteById', {
sampleId: this.selectedRowKeys[0],
...this.delParams,
})
@ -273,6 +292,13 @@ export default {
that.loadData()
} else {
this.$message.error(message)
this.visibleInfo = true
this.dataInfo = result.map((item, index) => {
return {
rowCount: `${index + 1}`,
info: item,
}
})
}
} catch (error) {
console.error(error)

View File

@ -1,6 +1,20 @@
<template>
<div style="height: 100%">
<div class="header">
<div>
<span class="item-label">Nuclide Type</span>
<a-select
style="width: 180px; display: inline-block"
v-model="type"
:options="typeOptions"
show-arrow
allowClear
placeholder="select..."
@change="onTypeChange"
>
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
</a-select>
</div>
<a-button type="primary" @click="handleAdd">
<img src="@/assets/images/global/add.png" alt="" />
Edit
@ -29,8 +43,22 @@
</custom-table>
</div>
<!-- 列表结束 -->
<a-modal title="Edit" :width="845" v-model="visible" :maskClosable="false" @ok="handleOk" destroy-on-close>
<a-modal title="Edit" :width="845" v-model="visible" :maskClosable="false" @ok="handleOk">
<a-spin :spinning="spinning">
<div style="padding-left: 52px; margin-bottom: 20px">
<span class="item-label">Nuclide Type</span>
<a-select
style="width: 180px; display: inline-block"
v-model="currType"
:options="typeOptions"
show-arrow
allowClear
placeholder="select..."
@change="onCurrTypeChange"
>
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
</a-select>
</div>
<div class="group-assign">
<a-transfer
:dataSource="dataList"
@ -86,6 +114,11 @@ const columns = [
align: 'left',
dataIndex: 'nuclideName',
},
{
title: 'NUCLIDE TYPE',
align: 'left',
dataIndex: 'nuclideType',
},
{
title: 'CREATE TIME',
align: 'left',
@ -113,6 +146,22 @@ export default {
total: 0,
},
loading: false,
typeOptions: [
{
label: 'P',
value: 'P',
},
{
label: 'G',
value: 'G',
},
{
label: 'B',
value: 'B',
},
],
type: undefined,
currType: 'P',
targetKeys: [],
visible: false,
dataList: [],
@ -129,6 +178,7 @@ export default {
pageNo: this.ipagination.current,
pageSize: this.ipagination.pageSize,
useType: 2,
nuclideType: this.type || '',
}
getAction(this.url.list, params).then((res) => {
this.loading = false
@ -145,6 +195,16 @@ export default {
this.ipagination.pageSize = pagination.pageSize
this.getRulesList()
},
onTypeChange(val) {
this.type = val
this.ipagination.current = 1
this.ipagination.pageSize = 10
this.getRulesList()
},
onCurrTypeChange(val) {
this.currType = val
this.getNuclideList()
},
handleAdd() {
this.visible = true
this.spinning = true
@ -171,7 +231,7 @@ export default {
})
},
getNuclideList() {
getAction('/sys/defaultNuclide/allName', { useType: 2 }).then((res) => {
getAction('/sys/defaultNuclide/allName', { useType: 2, nuclideType: this.currType }).then((res) => {
if (res.success) {
if (res.result.length > 0) {
this.targetKeys = res.result.map((item) => item)
@ -192,6 +252,7 @@ export default {
handleOk() {
let params = {
nuclideNames: this.targetKeys,
nuclideType: this.currType,
useType: 2,
}
getAction('/sys/defaultNuclide/add', params).then((res) => {
@ -218,10 +279,20 @@ export default {
border-bottom: 1px solid rgba(12, 235, 201, 0.3);
display: flex;
align-items: center;
justify-content: space-between;
background-color: rgba(12, 235, 201, 0.05);
padding: 0 10px;
margin-bottom: 18px;
}
.item-label {
display: inline-block;
font-size: 16px;
font-family: ArialMT;
color: #ade6ee;
line-height: 32px;
height: 32px;
margin-right: 10px;
}
.operators {
width: 100%;
justify-content: center;

View File

@ -43,7 +43,7 @@
</custom-table>
</div>
<!-- 列表结束 -->
<a-modal title="Edit" :width="845" v-model="visible" :maskClosable="false" @ok="handleOk" destroy-on-close>
<a-modal title="Edit" :width="845" v-model="visible" :maskClosable="false" @ok="handleOk">
<a-spin :spinning="spinning">
<div style="padding-left: 52px; margin-bottom: 20px">
<span class="item-label">Nuclide Type</span>
@ -155,6 +155,10 @@ export default {
label: 'G',
value: 'G',
},
{
label: 'B',
value: 'B',
},
],
type: undefined,
currType: 'P',
@ -193,6 +197,8 @@ export default {
},
onTypeChange(val) {
this.type = val
this.ipagination.current = 1
this.ipagination.pageSize = 10
this.getAuroPeocessList()
},
onCurrTypeChange(val) {

View File

@ -1,114 +1,116 @@
<template>
<div class="scheduling">
<!-- 左侧日程列表 -->
<a-card class="scheduling-list">
<!-- 标题 -->
<template slot="title">
<div class="card-title">Scheduling</div>
<div class="line"></div>
</template>
<!-- 标题结束 -->
<!-- 内容 -->
<div class="scheduling-list-content">
<div class="scheduling-list-item" v-for="item of schedulingInfo" :key="item.id">
<h4 class="title">
<span>
{{ item.username }}
</span>
<a-popconfirm title="Do You Want To Delete This Item?" placement="bottom" @confirm="onDel(item)">
<a class="del"></a>
</a-popconfirm>
</h4>
<div class="scheduling-list-item-container" @dragover.prevent @drop="onDrop(item)">
<!-- 左侧边框 -->
<div class="left-border">
<div class="left-top-border">
<div class="left-top-corner"></div>
<a-spin :spinning="spinningMain">
<!-- 左侧日程列表 -->
<a-card class="scheduling-list">
<!-- 标题 -->
<template slot="title">
<div class="card-title">Scheduling</div>
<div class="line"></div>
</template>
<!-- 标题结束 -->
<!-- 内容 -->
<div class="scheduling-list-content" ref="listContainer">
<div class="scheduling-list-item" v-for="item of schedulingInfo" :key="item.id">
<h4 class="title">
<span>
{{ item.username }}
</span>
<a-popconfirm title="Do You Want To Delete This Item?" placement="bottom" @confirm="onDel(item)">
<a class="del"></a>
</a-popconfirm>
</h4>
<div class="scheduling-list-item-container" @dragover.prevent @drop="onDrop(item)">
<!-- 左侧边框 -->
<div class="left-border">
<div class="left-top-border">
<div class="left-top-corner"></div>
</div>
<div class="left-bottom-border"></div>
</div>
<div class="left-bottom-border"></div>
<!-- 左侧边框结束 -->
<div class="scheduling-list-item-content">
<template v-for="(station, index) in item.stationList">
<span
:key="station.stationId"
class="draggable"
draggable
@dragstart="onDragStart(station, item.userId)"
>
{{ station.stationName + (index == item.stationList.length - 1 ? '' : '、') }}
</span>
</template>
</div>
<!-- 右侧边框 -->
<div class="right-border">
<div class="right-top-border"></div>
<div class="right-bottom-border"></div>
</div>
<!-- 右侧边框结束 -->
</div>
<!-- 左侧边框结束 -->
<div class="scheduling-list-item-content">
<template v-for="(station, index) in item.stationList">
<span
:key="station.stationId"
class="draggable"
draggable
@dragstart="onDragStart(station, item.userId)"
>
{{ station.stationName + (index == item.stationList.length - 1 ? '' : '、') }}
</span>
</template>
</div>
<!-- 右侧边框 -->
<div class="right-border">
<div class="right-top-border"></div>
<div class="right-bottom-border"></div>
</div>
<!-- 右侧边框结束 -->
</div>
<custom-empty v-if="!schedulingInfo || !schedulingInfo.length" style="margin-top: 40px"></custom-empty>
</div>
<custom-empty v-if="!schedulingInfo || !schedulingInfo.length" style="margin-top: 40px"></custom-empty>
</div>
<!-- 内容结束 -->
</a-card>
<div class="scheduling-calendar">
<!-- 日历 -->
<a-calendar v-model="currentDate" @select="onSelectDate">
<template slot="headerRender">
<!-- 搜索栏 -->
<div class="search-form">
<a-row>
<a-col :span="6">
<a-form-model class="search-form-form">
<a-form-model-item label="Month" style="marign-bottom: 0">
<custom-month-picker v-model="currentMonth" :allow-clear="false"></custom-month-picker>
</a-form-model-item>
</a-form-model>
</a-col>
<a-space class="btn-group">
<a-button @click="onAdd" type="primary">
<img src="@/assets/images/global/add.png" alt="" />
Add
</a-button>
<a-button @click="onEdit" type="primary">
<img src="@/assets/images/global/edit.png" alt="" />
Edit
</a-button>
<a-button type="primary" @click="onDownloadTpl">
<img src="@/assets/images/global/export.png" alt="" />
Download Template
</a-button>
<a-upload :custom-request="onImport" accept=".xlsx, .xls" :show-upload-list="false">
<a-button type="primary">
<img src="@/assets/images/global/import.png" alt="" />
Import
<!-- 内容结束 -->
</a-card>
<div class="scheduling-calendar">
<!-- 日历 -->
<a-calendar v-model="currentDate" @select="onSelectDate">
<template slot="headerRender">
<!-- 搜索栏 -->
<div class="search-form">
<a-row>
<a-col :span="6">
<a-form-model class="search-form-form">
<a-form-model-item label="Month" style="marign-bottom: 0">
<custom-month-picker v-model="currentMonth" :allow-clear="false"></custom-month-picker>
</a-form-model-item>
</a-form-model>
</a-col>
<a-space class="btn-group">
<a-button @click="onAdd" type="primary">
<img src="@/assets/images/global/add.png" alt="" />
Add
</a-button>
</a-upload>
<a-button type="primary" @click="onExport">
<img src="@/assets/images/global/export.png" alt="" />
Export
</a-button>
</a-space>
</a-row>
</div>
<!-- 搜索栏结束 -->
</template>
<!-- 日历内部内容 -->
<template slot="dateCellRender" slot-scope="value">
<div
class="scheduling-calendar-content"
v-if="scheduleList[value.format(dateFormat)] && scheduleList[value.format(dateFormat)].length"
>
<div class="item" v-for="item in scheduleList[value.format(dateFormat)]" :key="item.id">
{{ `${item.username}(${item.stationList.length})` }}
<a-button @click="onEdit" type="primary">
<img src="@/assets/images/global/edit.png" alt="" />
Edit
</a-button>
<a-button type="primary" @click="onDownloadTpl">
<img src="@/assets/images/global/export.png" alt="" />
Download Template
</a-button>
<a-upload :custom-request="onImport" accept=".xlsx, .xls" :show-upload-list="false">
<a-button :loading="isImport" type="primary">
<img src="@/assets/images/global/import.png" alt="" />
Import
</a-button>
</a-upload>
<a-button type="primary" @click="onExport">
<img src="@/assets/images/global/export.png" alt="" />
Export
</a-button>
</a-space>
</a-row>
</div>
</div>
</template>
<!-- 日历内部内容 -->
</a-calendar>
<!-- 日历结束 -->
</div>
<!-- 搜索栏结束 -->
</template>
<!-- 日历内部内容 -->
<template slot="dateCellRender" slot-scope="value">
<div
class="scheduling-calendar-content"
v-if="scheduleList[value.format(dateFormat)] && scheduleList[value.format(dateFormat)].length"
>
<div class="item" v-for="item in scheduleList[value.format(dateFormat)]" :key="item.id">
{{ `${item.username}(${item.stationList.length})` }}
</div>
</div>
</template>
<!-- 日历内部内容 -->
</a-calendar>
<!-- 日历结束 -->
</div>
</a-spin>
<!-- 增加/编辑排班弹窗 -->
<custom-modal :title="isAdd ? 'Add' : 'Edit'" :width="845" v-model="visible" :okHandler="submit" destroy-on-close>
@ -193,6 +195,13 @@
</a-spin>
</custom-modal>
<!-- 增加/编辑排班弹窗结束 -->
<custom-modal title="Failure record" v-model="visibleRes" :footer="null">
<a-table size="middle" :columns="columns" :dataSource="dataSource" :pagination="false" :scroll="{ y: 600 }">
<template slot="index" slot-scope="{ index }">
{{ index + 1 }}
</template>
</a-table>
</custom-modal>
</div>
</template>
<script>
@ -217,6 +226,8 @@ export default {
data() {
this.dateFormat = dateFormat
return {
isImport: false,
spinningMain: false,
currentMonth: moment(), //
currentDate: moment(), //
@ -246,6 +257,41 @@ export default {
dragItem: null,
fromUserId: '',
stationName: '',
visibleRes: false,
columns: [
{
title: 'NO',
align: 'left',
scopedSlots: {
customRender: 'index',
},
customHeaderCell: () => {
return {
style: {
'padding-left': '60px !important',
},
}
},
customCell: () => {
return {
style: {
'padding-left': '60px !important',
},
}
},
},
{
title: 'LINE',
align: 'left',
dataIndex: 'line',
},
{
title: 'RESULT',
align: 'left',
dataIndex: 'result',
},
],
dataSource: [],
}
},
created() {
@ -255,6 +301,7 @@ export default {
methods: {
//
async getList() {
this.spinningMain = true
try {
this.isGettingList = true
const { result } = await getAction(`/sysTask/findList?yearMonth=${this.currentMonth.format('YYYY-MM')}`)
@ -262,8 +309,10 @@ export default {
this.schedulingInfo = this.scheduleList[this.currentDate.format(dateFormat)]
} catch (error) {
console.error(error)
this.spinningMain = false
} finally {
this.isGettingList = false
this.spinningMain = false
}
},
@ -313,6 +362,9 @@ export default {
return
}
this.schedulingInfo = this.scheduleList[date.format(dateFormat)]
this.$nextTick(() => {
this.$refs.listContainer.scrollTop = 0
})
},
//
@ -407,14 +459,19 @@ export default {
},
async onImport({ file }) {
this.isImport = true
try {
const formData = new FormData()
formData.append('file', file)
const { success, failure } = await postAction('/sysTask/importExcel', formData)
const { success, failure, detailList } = await postAction('/sysTask/importExcel', formData)
this.$message.success(`${success} Success, ${failure} Fail`)
this.dataSource = detailList
this.visibleRes = true
this.isImport = false
this.getList()
} catch (error) {
console.error(error)
this.isImport = false
}
},
@ -645,7 +702,14 @@ export default {
.scheduling {
height: 100%;
overflow: hidden;
display: flex;
//display: flex;
::v-deep.ant-spin-nested-loading {
height: 100%;
.ant-spin-container {
height: 100%;
display: flex;
}
}
&-list {
flex-shrink: 0;
width: 350px;
@ -681,13 +745,15 @@ export default {
}
}
&-body {
height: calc(100% - 66px);
overflow: auto;
height: calc(100% - 52px);
// overflow: auto;
}
}
}
&-content {
height: 100%;
padding: 0 12px;
overflow: auto;
}
&-item {
margin-top: 15px;

View File

@ -6,27 +6,32 @@
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel"
okText="保存并安排任务"
cancelText="关闭">
okText="Save And Schedule Tasks"
cancelText="Close"
>
<a-spin :spinning="confirmLoading">
<a-form-model ref="form" :model="model" :rules="validatorRules">
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="任务类名" prop="jobClassName" hasFeedback >
<a-input placeholder="请输入任务类名" v-model="model.jobClassName" />
<a-form-model-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="Task Class Name"
prop="jobClassName"
hasFeedback
>
<a-input placeholder="Please enter a task class name" v-model="model.jobClassName" />
</a-form-model-item>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="Cron表达式" prop="cronExpression">
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="Cron Expression" prop="cronExpression">
<!-- <j-cron v-model="model.cronExpression"/>-->
<j-easy-cron v-model="model.cronExpression" />
</a-form-model-item>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="参数" prop="parameter" >
<a-textarea placeholder="请输入参数" :rows="5" v-model="model.parameter" />
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="Arguments" prop="parameter">
<a-textarea placeholder="Please enter parameters" :rows="5" v-model="model.parameter" />
</a-form-model-item>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="描述" prop="description">
<a-textarea placeholder="请输入描述" :rows="3" v-model="model.description" />
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="Description" prop="description">
<a-textarea placeholder="Please enter a description" :rows="3" v-model="model.description" />
</a-form-model-item>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="状态" prop="status">
<j-dict-select-tag type="radioButton" v-model="model.status" dictCode="quartz_status"/>
<a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="Status" prop="status">
<j-dict-select-tag type="radioButton" v-model="model.status" dictCode="quartz_status" />
</a-form-model-item>
</a-form-model>
</a-spin>
@ -34,108 +39,103 @@
</template>
<script>
import { httpAction } from '@/api/manage'
// import JCron from "@/components/jeecg/JCron";
import cronValidator from "@/components/jeecg/JEasyCron/validator";
import { httpAction } from '@/api/manage'
// import JCron from "@/components/jeecg/JCron";
import cronValidator from '@/components/jeecg/JEasyCron/validator'
export default {
name: "QuartzJobModal",
components: {
// JCron,
},
data () {
return {
title:"操作",
buttonStyle: 'solid',
visible: false,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
cron: {
label: '',
value: ''
},
confirmLoading: false,
validatorRules: {
cronExpression: [
{required: true, message: '请输入cron表达式!'},
{validator: cronValidator,}
],
jobClassName: [{required: true, message: '请输入任务类名!'}]
},
url: {
add: "/sys/quartzJob/add",
edit: "/sys/quartzJob/edit",
},
}
},
created () {
},
methods: {
add() {
//
this.edit({
cronExpression: '* * * * * ? *',
status: 0,
})
export default {
name: 'QuartzJobModal',
components: {
// JCron,
},
data() {
return {
title: '操作',
buttonStyle: 'solid',
visible: false,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
edit (record) {
this.visible = true;
this.$nextTick(() => {
this.$refs.form.resetFields()
this.model = Object.assign({}, record)
})
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
close () {
this.$emit('close');
this.visible = false;
cron: {
label: '',
value: '',
},
handleOk () {
const that = this;
//
this.$refs.form.validate((ok, err) => {
if (ok) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
if(!this.model.id){
httpurl+=this.url.add;
method = 'post';
}else{
httpurl+=this.url.edit;
method = 'put';
}
console.log('提交参数',this.model)
httpAction(httpurl,this.model,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
that.close();
}else{
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
})
}
})
confirmLoading: false,
validatorRules: {
cronExpression: [{ required: true, message: '请输入cron表达式!' }, { validator: cronValidator }],
jobClassName: [{ required: true, message: '请输入任务类名!' }],
},
handleCancel () {
this.close()
url: {
add: '/sys/quartzJob/add',
edit: '/sys/quartzJob/edit',
},
}
}
},
created() {},
methods: {
add() {
//
this.edit({
cronExpression: '* * * * * ? *',
status: 0,
})
},
edit(record) {
this.visible = true
this.$nextTick(() => {
this.$refs.form.resetFields()
this.model = Object.assign({}, record)
})
},
close() {
this.$emit('close')
this.visible = false
},
handleOk() {
const that = this
//
this.$refs.form.validate((ok, err) => {
if (ok) {
that.confirmLoading = true
let httpurl = ''
let method = ''
if (!this.model.id) {
httpurl += this.url.add
method = 'post'
} else {
httpurl += this.url.edit
method = 'put'
}
console.log('提交参数', this.model)
httpAction(httpurl, this.model, method)
.then((res) => {
if (res.success) {
that.$message.success(res.message)
that.$emit('ok')
that.close()
} else {
that.$message.warning(res.message)
}
})
.finally(() => {
that.confirmLoading = false
})
}
})
},
handleCancel() {
this.close()
},
},
}
</script>
<style scoped>
</style>

View File

@ -79,7 +79,23 @@
<a-textarea v-model="model.description" :rows="3"></a-textarea>
</a-form-model-item>
<a-form-model-item label="Status" prop="status">
<j-dict-select-tag v-model="model.status" dictCode="STATION_STATUS"></j-dict-select-tag>
<j-dict-select-tag
v-model="model.status"
dictCode="STATION_STATUS"
@change="handleStatus"
></j-dict-select-tag>
</a-form-model-item>
<a-form-model-item label="Category" prop="category">
<a-select
v-model="model.category"
:options="categoryOptions"
show-arrow
allowClear
placeholder="select..."
@change="onCategoryChange"
>
<img slot="suffixIcon" src="@/assets/images/global/select-down.png" alt="" />
</a-select>
</a-form-model-item>
</a-form-model>
</custom-modal>
@ -99,76 +115,76 @@ const columns = [
align: 'left',
width: 100,
scopedSlots: {
customRender: 'index'
customRender: 'index',
},
customHeaderCell: () => {
return {
style: {
'padding-left': '60px !important'
}
'padding-left': '60px !important',
},
}
},
customCell: () => {
return {
style: {
'padding-left': '60px !important'
}
'padding-left': '60px !important',
},
}
}
},
},
{
title: 'STATION ID',
align: 'left',
dataIndex: 'stationId',
width: 100
width: 100,
},
{
title: 'STATION CODE',
align: 'left',
width: 100,
dataIndex: 'stationCode'
dataIndex: 'stationCode',
},
{
title: 'COUNTRY CODE',
align: 'left',
width: 100,
dataIndex: 'countryCode'
dataIndex: 'countryCode',
},
{
title: 'TYPE',
align: 'left',
width: 100,
dataIndex: 'type'
dataIndex: 'type',
},
{
title: 'LON',
align: 'left',
width: 100,
dataIndex: 'lon'
dataIndex: 'lon',
},
{
title: 'LAT',
align: 'left',
width: 100,
dataIndex: 'lat'
dataIndex: 'lat',
},
{
title: 'ELEVATION',
width: 100,
dataIndex: 'elevation'
dataIndex: 'elevation',
},
{
title: 'DESCRIPTION',
width: 100,
dataIndex: 'description',
ellipsis: true
ellipsis: true,
},
{
title: 'STATUS',
align: 'left',
width: 100,
dataIndex: 'status'
}
dataIndex: 'status',
},
]
export default {
@ -188,38 +204,66 @@ export default {
}
const validateCountryCode = (_, value, callback) => {
if (value && value.length > 2) {
if (!value) {
callback(new Error('Please Enter Country Code'))
} else if (value.length > 2) {
callback(new Error('Country Code Limit 2 Char'))
} else {
callback()
}
}
return {
categoryOptions: [],
queryParam: {},
rules: {
stationId: [{ required: true, message: 'Please Enter Station Id' }],
stationCode: [{ required: true, validator: validateStationCode }],
countryCode: [{ validator: validateCountryCode }]
countryCode: [{ required: true, validator: validateCountryCode }],
status: [{ required: true, message: 'Please Select Status', trigger: 'change' }],
category: [{ required: true, message: 'Please Select Category', trigger: 'change' }],
},
url: {
list: '/gardsStations/findPage',
delete: '/gardsStations/deleteById',
add: '/gardsStations/create',
edit: '/gardsStations/update'
edit: '/gardsStations/update',
},
countryCodeList: [],
typeList: []
typeList: [],
}
},
created() {
this.getTypeList()
this.getCountryCodeList()
},
mounted() {
this.$set(this.model, 'status', 'Operating')
},
methods: {
async getCategoryItem() {
try {
const res = await getAction('/sys/dict/getItems', { dictCode: 'Station Category' })
console.log(res)
this.categoryOptions = res.map((item) => {
return {
label: item.text,
value: item.value,
}
})
} catch (error) {
console.error(error)
}
},
onCategoryChange(val) {
console.log(val)
},
handleStatus(val) {
this.model.status = val
},
async getTypeList() {
try {
const res = await getAction('/gardsStations/findType')
this.typeList = res.filter(item => item).map(item => ({ label: item, value: item }))
this.typeList = res.filter((item) => item).map((item) => ({ label: item, value: item }))
} catch (error) {
console.error(error)
}
@ -228,7 +272,7 @@ export default {
async getCountryCodeList() {
try {
const res = await getAction('/gardsStations/findCountryCode')
this.countryCodeList = res.filter(item => item).map(item => ({ label: item, value: item }))
this.countryCodeList = res.filter((item) => item).map((item) => ({ label: item, value: item }))
} catch (error) {
console.error(error)
}
@ -239,15 +283,20 @@ export default {
},
onAdd() {
this.getCategoryItem()
this.isAdd = true
this.model = {}
// this.model = {}
this.visible = true
},
onEdit() {
this.getCategoryItem()
if (this.selectedRowKeys && this.selectedRowKeys.length) {
this.isAdd = false
this.visible = true
const find = this.dataSource.find(item => item.stationId === this.selectedRowKeys[0])
const find = this.dataSource.find((item) => item.stationId === this.selectedRowKeys[0])
if (find) {
find.category = find.category.toString()
}
this.model = cloneDeep(find)
} else {
this.$message.warn('Please Select An Item To Edit')
@ -261,12 +310,12 @@ export default {
cancelText: 'Cancel',
onOk: () => {
this.handleDelete(this.selectedRowKeys[0], 'stationId')
}
},
})
} else {
this.$message.warn('Please Select An Item To Delete')
}
}
},
},
computed: {
formItems() {
@ -281,12 +330,12 @@ export default {
showSearch: true,
filterOption: this.filterOption,
style: {
width: '261px'
}
width: '261px',
},
},
style: {
width: 'auto'
}
width: 'auto',
},
},
{
label: 'Type',
@ -298,12 +347,12 @@ export default {
showSearch: true,
filterOption: this.filterOption,
style: {
width: '261px'
}
width: '261px',
},
},
style: {
width: 'auto'
}
width: 'auto',
},
},
{
label: 'Status',
@ -315,16 +364,16 @@ export default {
return document.body
},
style: {
width: '261px'
}
width: '261px',
},
},
style: {
width: 'auto'
}
}
width: 'auto',
},
},
]
}
}
},
},
}
</script>