调整代码
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 6.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.6 KiB |
BIN
public/favicon3.ico
Normal file
BIN
public/favicon3.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
@@ -1,310 +1,310 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="w100">
|
<div class="w100">
|
||||||
<!-- el-select 的远程下拉只在有搜索词时,才会加载数据(显示出 option 列表) -->
|
<!-- el-select 的远程下拉只在有搜索词时,才会加载数据(显示出 option 列表) -->
|
||||||
<!-- 使用 el-popover 在无数据/无搜索词时,显示一个无数据的提醒 -->
|
<!-- 使用 el-popover 在无数据/无搜索词时,显示一个无数据的提醒 -->
|
||||||
<el-popover
|
<el-popover
|
||||||
width="100%"
|
width="100%"
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
popper-class="remote-select-popper"
|
popper-class="remote-select-popper"
|
||||||
:visible="state.focusStatus && !state.loading && !state.keyword && !state.options.length"
|
:visible="state.focusStatus && !state.loading && !state.keyword && !state.options.length"
|
||||||
:teleported="false"
|
:teleported="false"
|
||||||
:content="$t('utils.No data')"
|
:content="$t('utils.No data')"
|
||||||
>
|
>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-select
|
<el-select
|
||||||
ref="selectRef"
|
ref="selectRef"
|
||||||
class="w100"
|
class="w100"
|
||||||
@focus="onFocus"
|
@focus="onFocus"
|
||||||
@blur="onBlur"
|
@blur="onBlur"
|
||||||
:loading="state.loading || state.accidentBlur"
|
:loading="state.loading || state.accidentBlur"
|
||||||
:filterable="true"
|
:filterable="true"
|
||||||
:remote="true"
|
:remote="true"
|
||||||
clearable
|
clearable
|
||||||
remote-show-suffix
|
remote-show-suffix
|
||||||
:remote-method="onLogKeyword"
|
:remote-method="onLogKeyword"
|
||||||
v-model="state.value"
|
v-model="state.value"
|
||||||
@change="onChangeSelect"
|
@change="onChangeSelect"
|
||||||
:multiple="multiple"
|
:multiple="multiple"
|
||||||
:key="state.selectKey"
|
:key="state.selectKey"
|
||||||
@clear="onClear"
|
@clear="onClear"
|
||||||
@visible-change="onVisibleChange"
|
@visible-change="onVisibleChange"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
class="remote-select-option"
|
class="remote-select-option"
|
||||||
v-for="item in state.options"
|
v-for="item in state.options"
|
||||||
:label="item[field]"
|
:label="item[field]"
|
||||||
:value="item[state.primaryKey].toString()"
|
:value="item[state.primaryKey].toString()"
|
||||||
:key="item[state.primaryKey]"
|
:key="item[state.primaryKey]"
|
||||||
>
|
>
|
||||||
<el-tooltip placement="right" effect="light" v-if="!isEmpty(tooltipParams)">
|
<el-tooltip placement="right" effect="light" v-if="!isEmpty(tooltipParams)">
|
||||||
<template #content>
|
<template #content>
|
||||||
<p v-for="(tooltipParam, key) in tooltipParams" :key="key">{{ key }}: {{ item[tooltipParam] }}</p>
|
<p v-for="(tooltipParam, key) in tooltipParams" :key="key">{{ key }}: {{ item[tooltipParam] }}</p>
|
||||||
</template>
|
</template>
|
||||||
<div>{{ item[field] }}</div>
|
<div>{{ item[field] }}</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-option>
|
</el-option>
|
||||||
<el-pagination
|
<el-pagination
|
||||||
v-if="state.total"
|
v-if="state.total"
|
||||||
:currentPage="state.currentPage"
|
:currentPage="state.currentPage"
|
||||||
:page-size="state.pageSize"
|
:page-size="state.pageSize"
|
||||||
class="select-pagination"
|
class="select-pagination"
|
||||||
layout="->, prev, next"
|
layout="->, prev, next"
|
||||||
:total="state.total"
|
:total="state.total"
|
||||||
@current-change="onSelectCurrentPageChange"
|
@current-change="onSelectCurrentPageChange"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, watch, onMounted, onUnmounted, ref, nextTick, getCurrentInstance, toRaw } from 'vue'
|
import { reactive, watch, onMounted, onUnmounted, ref, nextTick, getCurrentInstance, toRaw } from 'vue'
|
||||||
import { getSelectData } from '@/api/common'
|
// import { getSelectData } from '@/api/common'
|
||||||
import { uuid } from '@/utils/random'
|
import { uuid } from '@/utils/random'
|
||||||
import type { ElSelect } from 'element-plus'
|
import type { ElSelect } from 'element-plus'
|
||||||
import { isEmpty } from 'lodash-es'
|
import { isEmpty } from 'lodash-es'
|
||||||
import { getArrayKey } from '@/utils/common'
|
// import { getArrayKey } from '@/utils/common'
|
||||||
|
|
||||||
const selectRef = ref<InstanceType<typeof ElSelect> | undefined>()
|
const selectRef = ref<InstanceType<typeof ElSelect> | undefined>()
|
||||||
type ElSelectProps = Partial<InstanceType<typeof ElSelect>['$props']>
|
type ElSelectProps = Partial<InstanceType<typeof ElSelect>['$props']>
|
||||||
type valType = string | number | string[] | number[]
|
type valType = string | number | string[] | number[]
|
||||||
|
|
||||||
interface Props extends /* @vue-ignore */ ElSelectProps {
|
interface Props extends /* @vue-ignore */ ElSelectProps {
|
||||||
pk?: string
|
pk?: string
|
||||||
field?: string
|
field?: string
|
||||||
params?: anyObj
|
params?: anyObj
|
||||||
multiple?: boolean
|
multiple?: boolean
|
||||||
remoteUrl: string
|
remoteUrl: string
|
||||||
modelValue: valType
|
modelValue: valType
|
||||||
labelFormatter?: (optionData: anyObj, optionKey: string) => string
|
labelFormatter?: (optionData: anyObj, optionKey: string) => string
|
||||||
tooltipParams?: anyObj
|
tooltipParams?: anyObj
|
||||||
}
|
}
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
pk: 'id',
|
pk: 'id',
|
||||||
field: 'name',
|
field: 'name',
|
||||||
params: () => {
|
params: () => {
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
remoteUrl: '',
|
remoteUrl: '',
|
||||||
modelValue: '',
|
modelValue: '',
|
||||||
multiple: false,
|
multiple: false,
|
||||||
tooltipParams: () => {
|
tooltipParams: () => {
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const state: {
|
const state: {
|
||||||
// 主表字段名(不带表别名)
|
// 主表字段名(不带表别名)
|
||||||
primaryKey: string
|
primaryKey: string
|
||||||
options: anyObj[]
|
options: anyObj[]
|
||||||
loading: boolean
|
loading: boolean
|
||||||
total: number
|
total: number
|
||||||
currentPage: number
|
currentPage: number
|
||||||
pageSize: number
|
pageSize: number
|
||||||
params: anyObj
|
params: anyObj
|
||||||
keyword: string
|
keyword: string
|
||||||
value: valType
|
value: valType
|
||||||
selectKey: string
|
selectKey: string
|
||||||
initializeData: boolean
|
initializeData: boolean
|
||||||
accidentBlur: boolean
|
accidentBlur: boolean
|
||||||
focusStatus: boolean
|
focusStatus: boolean
|
||||||
} = reactive({
|
} = reactive({
|
||||||
primaryKey: props.pk,
|
primaryKey: props.pk,
|
||||||
options: [],
|
options: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
total: 0,
|
total: 0,
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
params: props.params,
|
params: props.params,
|
||||||
keyword: '',
|
keyword: '',
|
||||||
value: props.modelValue ? props.modelValue : '',
|
value: props.modelValue ? props.modelValue : '',
|
||||||
selectKey: uuid(),
|
selectKey: uuid(),
|
||||||
initializeData: false,
|
initializeData: false,
|
||||||
accidentBlur: false,
|
accidentBlur: false,
|
||||||
focusStatus: false,
|
focusStatus: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
let io: null | IntersectionObserver = null
|
let io: null | IntersectionObserver = null
|
||||||
const instance = getCurrentInstance()
|
const instance = getCurrentInstance()
|
||||||
|
|
||||||
const emits = defineEmits<{
|
const emits = defineEmits<{
|
||||||
(e: 'update:modelValue', value: valType): void
|
(e: 'update:modelValue', value: valType): void
|
||||||
(e: 'row', value: any): void
|
(e: 'row', value: any): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const onChangeSelect = (val: valType) => {
|
const onChangeSelect = (val: valType) => {
|
||||||
emits('update:modelValue', val)
|
emits('update:modelValue', val)
|
||||||
if (typeof instance?.vnode.props?.onRow == 'function') {
|
if (typeof instance?.vnode.props?.onRow == 'function') {
|
||||||
let pkArr = props.pk.split('.')
|
let pkArr = props.pk.split('.')
|
||||||
let pk = pkArr[pkArr.length - 1]
|
let pk = pkArr[pkArr.length - 1]
|
||||||
if (typeof val == 'number' || typeof val == 'string') {
|
if (typeof val == 'number' || typeof val == 'string') {
|
||||||
const dataKey = getArrayKey(state.options, pk, val.toString())
|
// const dataKey = getArrayKey(state.options, pk, val.toString())
|
||||||
emits('row', dataKey ? toRaw(state.options[dataKey]) : {})
|
// emits('row', dataKey ? toRaw(state.options[dataKey]) : {})
|
||||||
} else {
|
} else {
|
||||||
const valueArr = []
|
// const valueArr = []
|
||||||
for (const key in val) {
|
// for (const key in val) {
|
||||||
let dataKey = getArrayKey(state.options, pk, val[key].toString())
|
// let dataKey = getArrayKey(state.options, pk, val[key].toString())
|
||||||
if (dataKey) valueArr.push(toRaw(state.options[dataKey]))
|
// if (dataKey) valueArr.push(toRaw(state.options[dataKey]))
|
||||||
}
|
// }
|
||||||
emits('row', valueArr)
|
// emits('row', valueArr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onVisibleChange = (val: boolean) => {
|
const onVisibleChange = (val: boolean) => {
|
||||||
// 保持面板状态和焦点状态一致
|
// 保持面板状态和焦点状态一致
|
||||||
if (!val) {
|
if (!val) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
selectRef.value?.blur()
|
selectRef.value?.blur()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onFocus = () => {
|
const onFocus = () => {
|
||||||
state.focusStatus = true
|
state.focusStatus = true
|
||||||
if (selectRef.value?.query != state.keyword) {
|
if (selectRef.value?.query != state.keyword) {
|
||||||
state.keyword = ''
|
state.keyword = ''
|
||||||
state.initializeData = false
|
state.initializeData = false
|
||||||
// el-select 自动清理搜索词会产生意外的脱焦
|
// el-select 自动清理搜索词会产生意外的脱焦
|
||||||
state.accidentBlur = true
|
state.accidentBlur = true
|
||||||
}
|
}
|
||||||
if (!state.initializeData) {
|
if (!state.initializeData) {
|
||||||
getData()
|
getData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onBlur = () => {
|
const onBlur = () => {
|
||||||
state.focusStatus = false
|
state.focusStatus = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const onClear = () => {
|
const onClear = () => {
|
||||||
state.keyword = ''
|
state.keyword = ''
|
||||||
state.initializeData = false
|
state.initializeData = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const onLogKeyword = (q: string) => {
|
const onLogKeyword = (q: string) => {
|
||||||
if (state.keyword != q) {
|
if (state.keyword != q) {
|
||||||
state.keyword = q
|
state.keyword = q
|
||||||
getData()
|
getData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getData = (initValue: valType = '') => {
|
const getData = (initValue: valType = '') => {
|
||||||
state.loading = true
|
state.loading = true
|
||||||
state.params.page = state.currentPage
|
state.params.page = state.currentPage
|
||||||
state.params.initKey = props.pk
|
state.params.initKey = props.pk
|
||||||
state.params.initValue = initValue
|
state.params.initValue = initValue
|
||||||
getSelectData(props.remoteUrl, state.keyword, state.params)
|
// getSelectData(props.remoteUrl, state.keyword, state.params)
|
||||||
.then((res) => {
|
// .then((res) => {
|
||||||
let initializeData = true
|
// let initializeData = true
|
||||||
let opts = res.data.options ? res.data.options : res.data.list
|
// let opts = res.data.options ? res.data.options : res.data.list
|
||||||
if (typeof props.labelFormatter == 'function') {
|
// if (typeof props.labelFormatter == 'function') {
|
||||||
for (const key in opts) {
|
// for (const key in opts) {
|
||||||
opts[key][props.field] = props.labelFormatter(opts[key], key)
|
// opts[key][props.field] = props.labelFormatter(opts[key], key)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
state.options = opts
|
// state.options = opts
|
||||||
state.total = res.data.total ?? 0
|
// state.total = res.data.total ?? 0
|
||||||
if (initValue) {
|
// if (initValue) {
|
||||||
// 重新渲染组件,确保在赋值前,opts已加载到-兼容 modelValue 更新
|
// // 重新渲染组件,确保在赋值前,opts已加载到-兼容 modelValue 更新
|
||||||
state.selectKey = uuid()
|
// state.selectKey = uuid()
|
||||||
initializeData = false
|
// initializeData = false
|
||||||
}
|
// }
|
||||||
state.loading = false
|
// state.loading = false
|
||||||
state.initializeData = initializeData
|
// state.initializeData = initializeData
|
||||||
if (state.accidentBlur) {
|
// if (state.accidentBlur) {
|
||||||
nextTick(() => {
|
// nextTick(() => {
|
||||||
const inputEl = selectRef.value?.$el.querySelector('.el-select__tags .el-select__input')
|
// const inputEl = selectRef.value?.$el.querySelector('.el-select__tags .el-select__input')
|
||||||
inputEl && inputEl.focus()
|
// inputEl && inputEl.focus()
|
||||||
state.accidentBlur = false
|
// state.accidentBlur = false
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
.catch(() => {
|
// .catch(() => {
|
||||||
state.loading = false
|
// state.loading = false
|
||||||
})
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSelectCurrentPageChange = (val: number) => {
|
const onSelectCurrentPageChange = (val: number) => {
|
||||||
state.currentPage = val
|
state.currentPage = val
|
||||||
getData()
|
getData()
|
||||||
}
|
}
|
||||||
|
|
||||||
const initDefaultValue = () => {
|
const initDefaultValue = () => {
|
||||||
if (state.value) {
|
if (state.value) {
|
||||||
// number[]转string[]确保默认值能够选中
|
// number[]转string[]确保默认值能够选中
|
||||||
if (typeof state.value === 'object') {
|
if (typeof state.value === 'object') {
|
||||||
for (const key in state.value as string[]) {
|
for (const key in state.value as string[]) {
|
||||||
state.value[key] = state.value[key].toString()
|
state.value[key] = state.value[key].toString()
|
||||||
}
|
}
|
||||||
} else if (typeof state.value === 'number') {
|
} else if (typeof state.value === 'number') {
|
||||||
state.value = state.value.toString()
|
state.value = state.value.toString()
|
||||||
}
|
}
|
||||||
getData(state.value)
|
getData(state.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.pk.indexOf('.') > 0) {
|
if (props.pk.indexOf('.') > 0) {
|
||||||
let pk = props.pk.split('.')
|
let pk = props.pk.split('.')
|
||||||
state.primaryKey = pk[1] ? pk[1] : pk[0]
|
state.primaryKey = pk[1] ? pk[1] : pk[0]
|
||||||
}
|
}
|
||||||
initDefaultValue()
|
initDefaultValue()
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (window?.IntersectionObserver) {
|
if (window?.IntersectionObserver) {
|
||||||
io = new IntersectionObserver((entries) => {
|
io = new IntersectionObserver((entries) => {
|
||||||
for (const key in entries) {
|
for (const key in entries) {
|
||||||
if (!entries[key].isIntersecting) selectRef.value?.blur()
|
if (!entries[key].isIntersecting) selectRef.value?.blur()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (selectRef.value?.$el instanceof Element) {
|
if (selectRef.value?.$el instanceof Element) {
|
||||||
io.observe(selectRef.value.$el)
|
io.observe(selectRef.value.$el)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 500)
|
}, 500)
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
io?.disconnect()
|
io?.disconnect()
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
if (String(state.value) != String(newVal)) {
|
if (String(state.value) != String(newVal)) {
|
||||||
state.value = newVal ? newVal : ''
|
state.value = newVal ? newVal : ''
|
||||||
initDefaultValue()
|
initDefaultValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const getSelectRef = () => {
|
const getSelectRef = () => {
|
||||||
return selectRef.value
|
return selectRef.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const focus = () => {
|
const focus = () => {
|
||||||
selectRef.value?.focus()
|
selectRef.value?.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
const blur = () => {
|
const blur = () => {
|
||||||
selectRef.value?.blur()
|
selectRef.value?.blur()
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
blur,
|
blur,
|
||||||
focus,
|
focus,
|
||||||
getSelectRef,
|
getSelectRef,
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
:deep(.remote-select-popper) {
|
:deep(.remote-select-popper) {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.remote-select-option {
|
.remote-select-option {
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,190 +1,190 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="view2">
|
<div v-if="view2">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<span style="font-size: 14px; line-height: 30px">值类型选择:</span>
|
<span style="font-size: 14px; line-height: 30px">值类型选择:</span>
|
||||||
<el-select
|
<el-select
|
||||||
style="min-width: 200px; width: 200px"
|
style="min-width: 200px; width: 200px"
|
||||||
@change="changeView"
|
@change="changeView"
|
||||||
v-model="value"
|
v-model="value"
|
||||||
placeholder="请选择值类型"
|
placeholder="请选择值类型"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in options"
|
v-for="item in options"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<!-- <el-button v-if="view2 && senior" class="ml10" type="primary"
|
<!-- <el-button v-if="view2 && senior" class="ml10" type="primary"
|
||||||
@click="AdvancedAnalytics">高级分析</el-button> -->
|
@click="AdvancedAnalytics">高级分析</el-button> -->
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-button
|
<el-button
|
||||||
@click="backbxlb"
|
@click="backbxlb"
|
||||||
class="el-icon-refresh-right"
|
class="el-icon-refresh-right"
|
||||||
icon="el-icon-CloseBold"
|
icon="el-icon-Back"
|
||||||
style="float: right"
|
style="float: right"
|
||||||
>
|
>
|
||||||
返回
|
返回
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div v-loading="loading" style="height: calc(100vh - 190px)">
|
<div v-loading="loading" style="height: calc(100vh - 190px)">
|
||||||
<el-tabs v-if="view4" class="default-main" v-model="bxactiveName" @tab-click="bxhandleClick">
|
<el-tabs v-if="view4" class="default-main" v-model="bxactiveName" @tab-click="bxhandleClick">
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
label="瞬时波形"
|
label="瞬时波形"
|
||||||
name="ssbx"
|
name="ssbx"
|
||||||
class="boxbx pt10 pb10"
|
class="boxbx pt10 pb10"
|
||||||
:style="'height:' + bxecharts + ';overflow-y: scroll;'"
|
:style="'height:' + bxecharts + ';overflow-y: scroll;'"
|
||||||
>
|
>
|
||||||
<shushiboxi
|
<shushiboxi
|
||||||
ref="shushiboxiRef"
|
ref="shushiboxiRef"
|
||||||
v-if="bxactiveName == 'ssbx' && showBoxi"
|
v-if="bxactiveName == 'ssbx' && showBoxi"
|
||||||
:value="value"
|
:value="value"
|
||||||
:parentHeight="parentHeight"
|
:parentHeight="parentHeight"
|
||||||
:boxoList="boxoList"
|
:boxoList="boxoList"
|
||||||
:wp="wp"
|
:wp="wp"
|
||||||
></shushiboxi>
|
></shushiboxi>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
label="RMS波形"
|
label="RMS波形"
|
||||||
class="boxbx pt10 pb10"
|
class="boxbx pt10 pb10"
|
||||||
name="rmsbx"
|
name="rmsbx"
|
||||||
:style="'height:' + bxecharts + ';overflow-y: scroll;'"
|
:style="'height:' + bxecharts + ';overflow-y: scroll;'"
|
||||||
>
|
>
|
||||||
<rmsboxi
|
<rmsboxi
|
||||||
ref="rmsboxiRef"
|
ref="rmsboxiRef"
|
||||||
v-if="bxactiveName == 'rmsbx' && showBoxi"
|
v-if="bxactiveName == 'rmsbx' && showBoxi"
|
||||||
:value="value"
|
:value="value"
|
||||||
:parentHeight="parentHeight"
|
:parentHeight="parentHeight"
|
||||||
:boxoList="boxoList"
|
:boxoList="boxoList"
|
||||||
:wp="wp"
|
:wp="wp"
|
||||||
></rmsboxi>
|
></rmsboxi>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
<el-empty v-else description="暂无数据" style="height: calc(100vh - 190px)" />
|
<el-empty v-else description="暂无数据" style="height: calc(100vh - 190px)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="view3" class="pd10">
|
<div v-if="view3" class="pd10">
|
||||||
<span style="font-weight: 500; font-size: 22px">高级分析</span>
|
<span style="font-weight: 500; font-size: 22px">高级分析</span>
|
||||||
<el-button icon="el-icon-Back" @click="gaoBack" style="float: right">返回</el-button>
|
<el-button icon="el-icon-Back" @click="gaoBack" style="float: right">返回</el-button>
|
||||||
<analytics :flag="true" :GJList="GJList" :boxoList="boxoList"></analytics>
|
<analytics :flag="true" :GJList="GJList" :boxoList="boxoList"></analytics>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import shushiboxi from '@/components/echarts/shushiboxi.vue'
|
import shushiboxi from '@/components/echarts/shushiboxi.vue'
|
||||||
import rmsboxi from '@/components/echarts/rmsboxi.vue'
|
import rmsboxi from '@/components/echarts/rmsboxi.vue'
|
||||||
import analytics from '@/components/echarts/analytics.vue'
|
import analytics from '@/components/echarts/analytics.vue'
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue'
|
||||||
import { analysis } from '@/api/advance-boot/analyse'
|
import { analysis } from '@/api/advance-boot/analyse'
|
||||||
import { mainHeight } from '@/utils/layout'
|
import { mainHeight } from '@/utils/layout'
|
||||||
import { getMonitorEventAnalyseWave, downloadWaveFile } from '@/api/event-boot/transient'
|
import { getMonitorEventAnalyseWave, downloadWaveFile } from '@/api/event-boot/transient'
|
||||||
const emit = defineEmits(['backbxlb'])
|
const emit = defineEmits(['backbxlb'])
|
||||||
interface Props {
|
interface Props {
|
||||||
// boxoList: any
|
// boxoList: any
|
||||||
// wp: any,
|
// wp: any,
|
||||||
senior?: boolean
|
senior?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
senior: false
|
senior: false
|
||||||
})
|
})
|
||||||
const parentHeight = ref(0)
|
const parentHeight = ref(0)
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const bxactiveName = ref('ssbx')
|
const bxactiveName = ref('ssbx')
|
||||||
const rmsboxiRef = ref()
|
const rmsboxiRef = ref()
|
||||||
const value = ref(1)
|
const value = ref(1)
|
||||||
const options = ref([
|
const options = ref([
|
||||||
{
|
{
|
||||||
value: 1,
|
value: 1,
|
||||||
label: '一次值'
|
label: '一次值'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 2,
|
value: 2,
|
||||||
label: '二次值'
|
label: '二次值'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const shushiboxiRef = ref()
|
const shushiboxiRef = ref()
|
||||||
const bxecharts = ref(mainHeight(95).height as any)
|
const bxecharts = ref(mainHeight(95).height as any)
|
||||||
const view2 = ref(true)
|
const view2 = ref(true)
|
||||||
const boxoList = ref(null)
|
const boxoList = ref(null)
|
||||||
const wp = ref(null)
|
const wp = ref(null)
|
||||||
const showBoxi = ref(true)
|
const showBoxi = ref(true)
|
||||||
const view3 = ref(false)
|
const view3 = ref(false)
|
||||||
const view4 = ref(false)
|
const view4 = ref(false)
|
||||||
const GJList = ref([])
|
const GJList = ref([])
|
||||||
|
|
||||||
const open = async (row: any) => {
|
const open = async (row: any) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
await getMonitorEventAnalyseWave({ id: row.eventId, systemType: 0 })
|
await getMonitorEventAnalyseWave({ id: row.eventId, systemType: 0 })
|
||||||
.then(res => {
|
.then(res => {
|
||||||
row.loading = false
|
row.loading = false
|
||||||
if (res != undefined) {
|
if (res != undefined) {
|
||||||
boxoList.value = row
|
boxoList.value = row
|
||||||
wp.value = res.data
|
wp.value = res.data
|
||||||
loading.value = false
|
loading.value = false
|
||||||
view4.value = true
|
view4.value = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const bxhandleClick = (tab: any) => {
|
const bxhandleClick = (tab: any) => {
|
||||||
if (shushiboxiRef.value) shushiboxiRef.value.backbxlb()
|
if (shushiboxiRef.value) shushiboxiRef.value.backbxlb()
|
||||||
if (rmsboxiRef.value) rmsboxiRef.value.backbxlb()
|
if (rmsboxiRef.value) rmsboxiRef.value.backbxlb()
|
||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
if (tab.name == 'ssbx') {
|
if (tab.name == 'ssbx') {
|
||||||
bxactiveName.value = 'ssbx'
|
bxactiveName.value = 'ssbx'
|
||||||
} else if (tab.name == 'rmsbx') {
|
} else if (tab.name == 'rmsbx') {
|
||||||
bxactiveName.value = 'rmsbx'
|
bxactiveName.value = 'rmsbx'
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}, 0)
|
}, 0)
|
||||||
// console.log(tab, event);
|
// console.log(tab, event);
|
||||||
}
|
}
|
||||||
const backbxlb = () => {
|
const backbxlb = () => {
|
||||||
boxoList.value = null
|
boxoList.value = null
|
||||||
wp.value = null
|
wp.value = null
|
||||||
if (shushiboxiRef.value) shushiboxiRef.value.backbxlb()
|
if (shushiboxiRef.value) shushiboxiRef.value.backbxlb()
|
||||||
if (rmsboxiRef.value) rmsboxiRef.value.backbxlb()
|
if (rmsboxiRef.value) rmsboxiRef.value.backbxlb()
|
||||||
|
|
||||||
emit('backbxlb')
|
emit('backbxlb')
|
||||||
}
|
}
|
||||||
const setHeight = (h: any, vh: any) => {
|
const setHeight = (h: any, vh: any) => {
|
||||||
if (h != false) {
|
if (h != false) {
|
||||||
parentHeight.value = h
|
parentHeight.value = h
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
bxecharts.value = mainHeight(vh).height
|
bxecharts.value = mainHeight(vh).height
|
||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
// 高级分析
|
// 高级分析
|
||||||
const AdvancedAnalytics = () => {
|
const AdvancedAnalytics = () => {
|
||||||
analysis({
|
analysis({
|
||||||
eventIndex: boxoList.value.eventId
|
eventIndex: boxoList.value.eventId
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
GJList.value = res.data
|
GJList.value = res.data
|
||||||
view3.value = true
|
view3.value = true
|
||||||
view2.value = false
|
view2.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const changeView = () => {
|
const changeView = () => {
|
||||||
if (shushiboxiRef.value) shushiboxiRef.value.backbxlb()
|
if (shushiboxiRef.value) shushiboxiRef.value.backbxlb()
|
||||||
if (rmsboxiRef.value) rmsboxiRef.value.backbxlb()
|
if (rmsboxiRef.value) rmsboxiRef.value.backbxlb()
|
||||||
showBoxi.value = false
|
showBoxi.value = false
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
showBoxi.value = true
|
showBoxi.value = true
|
||||||
}, 0)
|
}, 0)
|
||||||
}
|
}
|
||||||
const gaoBack = () => {
|
const gaoBack = () => {
|
||||||
view2.value = true
|
view2.value = true
|
||||||
view3.value = false
|
view3.value = false
|
||||||
}
|
}
|
||||||
defineExpose({ open, setHeight })
|
defineExpose({ open, setHeight })
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@@ -1,43 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :style="{ height:props.height?props.height: tableStore.table.height }">
|
<div :style="{ height: typeof props.height === 'string' ? props.height : tableStore.table.height }">
|
||||||
<vxe-table
|
<vxe-table ref="tableRef" height="auto" :key="key" :data="tableStore.table.data"
|
||||||
ref="tableRef"
|
v-loading="tableStore.table.loading" v-bind="Object.assign({}, defaultAttribute, $attrs)"
|
||||||
height="auto"
|
@checkbox-all="selectChangeEvent" @checkbox-change="selectChangeEvent" :showOverflow="showOverflow"
|
||||||
:key="key"
|
@sort-change="handleSortChange">
|
||||||
:data="tableStore.table.data"
|
|
||||||
v-loading="tableStore.table.loading"
|
|
||||||
v-bind="Object.assign({}, defaultAttribute, $attrs)"
|
|
||||||
@checkbox-all="selectChangeEvent"
|
|
||||||
@checkbox-change="selectChangeEvent"
|
|
||||||
:showOverflow="showOverflow"
|
|
||||||
@sort-change="handleSortChange"
|
|
||||||
>
|
|
||||||
<!-- Column 组件内部是 el-table-column -->
|
<!-- Column 组件内部是 el-table-column -->
|
||||||
<template v-if="isGroup">
|
<template v-if="isGroup">
|
||||||
<GroupColumn :column="tableStore.table.column" />
|
<GroupColumn :column="tableStore.table.column" />
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<Column
|
<Column :attr="item" :key="key + '-column'" v-for="(item, key) in tableStore.table.column"
|
||||||
:attr="item"
|
:tree-node="item.treeNode">
|
||||||
:key="key + '-column'"
|
|
||||||
v-for="(item, key) in tableStore.table.column"
|
|
||||||
:tree-node="item.treeNode"
|
|
||||||
>
|
|
||||||
<!-- tableStore 预设的列 render 方案 -->
|
<!-- tableStore 预设的列 render 方案 -->
|
||||||
<template v-if="item.render" #default="scope">
|
<template v-if="item.render" #default="scope">
|
||||||
<FieldRender
|
<FieldRender :field="item" :row="scope.row" :column="scope.column" :index="scope.rowIndex" :key="key +
|
||||||
:field="item"
|
'-' +
|
||||||
:row="scope.row"
|
item.render +
|
||||||
:column="scope.column"
|
'-' +
|
||||||
:index="scope.rowIndex"
|
(item.field ? '-' + item.field + '-' + scope.row[item.field] : '')
|
||||||
:key="
|
" />
|
||||||
key +
|
|
||||||
'-' +
|
|
||||||
item.render +
|
|
||||||
'-' +
|
|
||||||
(item.field ? '-' + item.field + '-' + scope.row[item.field] : '')
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</Column>
|
</Column>
|
||||||
</template>
|
</template>
|
||||||
@@ -46,16 +27,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="tableStore.showPage" class="table-pagination">
|
<div v-if="tableStore.showPage" class="table-pagination">
|
||||||
<el-pagination
|
<el-pagination :currentPage="tableStore.table.params!.pageNum" :page-size="tableStore.table.params!.pageSize"
|
||||||
:currentPage="tableStore.table.params!.pageNum"
|
:page-sizes="pageSizes" background
|
||||||
:page-size="tableStore.table.params!.pageSize"
|
|
||||||
:page-sizes="pageSizes"
|
|
||||||
background
|
|
||||||
:layout="config.layout.shrink ? 'prev, next, jumper' : 'sizes,total, ->, prev, pager, next, jumper'"
|
:layout="config.layout.shrink ? 'prev, next, jumper' : 'sizes,total, ->, prev, pager, next, jumper'"
|
||||||
:total="tableStore.table.total"
|
:total="tableStore.table.total" @size-change="onTableSizeChange"
|
||||||
@size-change="onTableSizeChange"
|
@current-change="onTableCurrentChange"></el-pagination>
|
||||||
@current-change="onTableCurrentChange"
|
|
||||||
></el-pagination>
|
|
||||||
</div>
|
</div>
|
||||||
<slot name="footer"></slot>
|
<slot name="footer"></slot>
|
||||||
</template>
|
</template>
|
||||||
@@ -80,13 +56,13 @@ const key = ref(0)
|
|||||||
interface Props extends /* @vue-ignore */ Partial<InstanceType<typeof ElTable>> {
|
interface Props extends /* @vue-ignore */ Partial<InstanceType<typeof ElTable>> {
|
||||||
isGroup?: boolean
|
isGroup?: boolean
|
||||||
showOverflow?: boolean
|
showOverflow?: boolean
|
||||||
height?: string | boolean
|
height?: string | number
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
isGroup: false,
|
isGroup: false,
|
||||||
showOverflow: true,
|
showOverflow: true,
|
||||||
height: false
|
height: undefined
|
||||||
})
|
})
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
tableStore.table.ref = tableRef.value as VxeTableInstance
|
tableStore.table.ref = tableRef.value as VxeTableInstance
|
||||||
|
|||||||
@@ -1,197 +1,197 @@
|
|||||||
<template>
|
<template>
|
||||||
|
|
||||||
<Tree ref="treRef" :data="tree" style="height: 100%" :width="'100%'" :expanded="expanded" />
|
<Tree ref="treRef" :data="tree" style="height: 100%" :width="'100%'" :expanded="expanded" />
|
||||||
</template>
|
</template>
|
||||||
<!-- <div class="mb10">
|
<!-- <div class="mb10">
|
||||||
<el-button type="primary" icon="el-icon-Download" size="small" @click="exportExcelTemplate" :loading="loading">模版下载</el-button>
|
<el-button type="primary" icon="el-icon-Download" size="small" @click="exportExcelTemplate" :loading="loading">模版下载</el-button>
|
||||||
<el-button type="primary" icon="el-icon-Upload" size="small">导入</el-button>
|
<el-button type="primary" icon="el-icon-Upload" size="small">导入</el-button>
|
||||||
<el-button type="primary" icon="el-icon-Download" size="small" @click="ledgerEverywhere" :loading="loading1">导出</el-button>
|
<el-button type="primary" icon="el-icon-Download" size="small" @click="ledgerEverywhere" :loading="loading1">导出</el-button>
|
||||||
</div> -->
|
</div> -->
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, nextTick } from 'vue'
|
import { ref, nextTick } from 'vue'
|
||||||
import Tree from './index.vue'
|
import Tree from './index.vue'
|
||||||
|
|
||||||
import { getTerminalTree,downTerminalTemplate,exportTerminalBase } from '@/api/device-boot/Business'
|
import { getTerminalTree,downTerminalTemplate,exportTerminalBase } from '@/api/device-boot/Business'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
const VITE_FLAG = import.meta.env.VITE_NAME == 'jibei'
|
const VITE_FLAG = import.meta.env.VITE_NAME == 'jibei'
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'govern/deviceTree'
|
name: 'govern/deviceTree'
|
||||||
})
|
})
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const loading1 = ref(false)
|
const loading1 = ref(false)
|
||||||
const emit = defineEmits(['init'])
|
const emit = defineEmits(['init'])
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
const expanded: any = ref([])
|
const expanded: any = ref([])
|
||||||
const tree = ref()
|
const tree = ref()
|
||||||
const treRef = ref()
|
const treRef = ref()
|
||||||
const info = (id: any) => {
|
const info = (id: any) => {
|
||||||
expanded.value = [id]
|
expanded.value = [id]
|
||||||
getTerminalTree().then(res => {
|
getTerminalTree().then(res => {
|
||||||
// let arr: any[] = []
|
// let arr: any[] = []
|
||||||
if (VITE_FLAG) {
|
if (VITE_FLAG) {
|
||||||
res.data.forEach((item: any) => {
|
res.data.forEach((item: any) => {
|
||||||
item.icon = 'el-icon-Menu'
|
item.icon = 'el-icon-Menu'
|
||||||
item.plevel = item.level
|
item.plevel = item.level
|
||||||
item.level = 0
|
item.level = 0
|
||||||
item.children.forEach((item2: any) => {
|
item.children.forEach((item2: any) => {
|
||||||
item2.icon = 'el-icon-HomeFilled'
|
item2.icon = 'el-icon-HomeFilled'
|
||||||
|
|
||||||
item2.plevel = item2.level
|
item2.plevel = item2.level
|
||||||
item2.level = 100
|
item2.level = 100
|
||||||
expanded.value.push(item2.id)
|
expanded.value.push(item2.id)
|
||||||
item2.children.forEach((item3: any) => {
|
item2.children.forEach((item3: any) => {
|
||||||
item3.icon = 'el-icon-CollectionTag'
|
item3.icon = 'el-icon-CollectionTag'
|
||||||
item3.plevel = item3.level
|
item3.plevel = item3.level
|
||||||
item3.level = 200
|
item3.level = 200
|
||||||
item3.children.forEach((item4: any) => {
|
item3.children.forEach((item4: any) => {
|
||||||
item4.icon = 'el-icon-Flag'
|
item4.icon = 'el-icon-Flag'
|
||||||
item4.plevel = item4.level
|
item4.plevel = item4.level
|
||||||
item4.level = 300
|
item4.level = 300
|
||||||
// arr.push(item4)
|
// arr.push(item4)
|
||||||
item4.children.forEach((item5: any) => {
|
item4.children.forEach((item5: any) => {
|
||||||
item5.icon = 'el-icon-OfficeBuilding'
|
item5.icon = 'el-icon-OfficeBuilding'
|
||||||
item5.plevel = item5.level
|
item5.plevel = item5.level
|
||||||
item5.level = 300
|
item5.level = 300
|
||||||
// item5.id = item4.id
|
// item5.id = item4.id
|
||||||
item5.children.forEach((item6: any) => {
|
item5.children.forEach((item6: any) => {
|
||||||
item6.icon = 'el-icon-HelpFilled'
|
item6.icon = 'el-icon-HelpFilled'
|
||||||
item6.plevel = 4
|
item6.plevel = 4
|
||||||
if (item6.name == '电网侧' && item6.children.length == 0) {
|
if (item6.name == '电网侧' && item6.children.length == 0) {
|
||||||
item6.level = 400
|
item6.level = 400
|
||||||
} else {
|
} else {
|
||||||
item6.level = 400
|
item6.level = 400
|
||||||
}
|
}
|
||||||
item6.children.forEach((item7: any) => {
|
item6.children.forEach((item7: any) => {
|
||||||
item7.icon = 'el-icon-Film'
|
item7.icon = 'el-icon-Film'
|
||||||
item7.plevel = item7.level
|
item7.plevel = item7.level
|
||||||
item7.level = 400
|
item7.level = 400
|
||||||
item7.children.forEach((item8: any) => {
|
item7.children.forEach((item8: any) => {
|
||||||
item8.icon = 'el-icon-Collection'
|
item8.icon = 'el-icon-Collection'
|
||||||
item8.plevel = item8.level
|
item8.plevel = item8.level
|
||||||
item8.level = 500
|
item8.level = 500
|
||||||
item8.children.forEach((item9: any) => {
|
item8.children.forEach((item9: any) => {
|
||||||
item9.icon = 'el-icon-Share'
|
item9.icon = 'el-icon-Share'
|
||||||
item9.plevel = item9.level
|
item9.plevel = item9.level
|
||||||
item9.level = 600
|
item9.level = 600
|
||||||
item9.children.forEach((item10: any) => {
|
item9.children.forEach((item10: any) => {
|
||||||
item10.icon = 'el-icon-Location'
|
item10.icon = 'el-icon-Location'
|
||||||
item10.plevel = item10.level
|
item10.plevel = item10.level
|
||||||
item10.level = 700
|
item10.level = 700
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
res.data.forEach((item: any) => {
|
res.data.forEach((item: any) => {
|
||||||
item.icon = 'el-icon-Menu'
|
item.icon = 'el-icon-Menu'
|
||||||
item.plevel = item.level
|
item.plevel = item.level
|
||||||
item.level = (item.level + 1) * 100
|
item.level = (item.level + 1) * 100
|
||||||
item.children.forEach((item2: any) => {
|
item.children.forEach((item2: any) => {
|
||||||
item2.icon = 'el-icon-HomeFilled'
|
item2.icon = 'el-icon-HomeFilled'
|
||||||
item2.plevel = item2.level
|
item2.plevel = item2.level
|
||||||
item2.level = (item2.level + 1) * 100
|
item2.level = (item2.level + 1) * 100
|
||||||
expanded.value.push(item2.id)
|
expanded.value.push(item2.id)
|
||||||
item2.children.forEach((item3: any) => {
|
item2.children.forEach((item3: any) => {
|
||||||
item3.icon = 'el-icon-CollectionTag'
|
item3.icon = 'el-icon-CollectionTag'
|
||||||
item3.plevel = item3.level
|
item3.plevel = item3.level
|
||||||
item3.level = (item3.level + 1) * 100
|
item3.level = (item3.level + 1) * 100
|
||||||
item3.children.forEach((item4: any) => {
|
item3.children.forEach((item4: any) => {
|
||||||
item4.icon = 'el-icon-Flag'
|
item4.icon = 'el-icon-Flag'
|
||||||
item4.plevel = item4.level
|
item4.plevel = item4.level
|
||||||
item4.level = (item4.level + 1) * 100
|
item4.level = (item4.level + 1) * 100
|
||||||
item4.children.forEach((item5: any) => {
|
item4.children.forEach((item5: any) => {
|
||||||
item5.icon = 'el-icon-OfficeBuilding'
|
item5.icon = 'el-icon-OfficeBuilding'
|
||||||
item5.plevel = item5.level
|
item5.plevel = item5.level
|
||||||
item5.level = (item5.level == 7 ? 4 : item5.level + 1) * 100
|
item5.level = (item5.level == 7 ? 4 : item5.level + 1) * 100
|
||||||
item5.children.forEach((item6: any) => {
|
item5.children.forEach((item6: any) => {
|
||||||
item6.icon = 'el-icon-Film'
|
item6.icon = 'el-icon-Film'
|
||||||
item6.plevel = item6.level
|
item6.plevel = item6.level
|
||||||
item6.level = (item6.level + 1) * 100
|
item6.level = (item6.level + 1) * 100
|
||||||
item6.children.forEach((item7: any) => {
|
item6.children.forEach((item7: any) => {
|
||||||
item7.icon = 'el-icon-Share'
|
item7.icon = 'el-icon-Share'
|
||||||
item7.plevel = item7.level
|
item7.plevel = item7.level
|
||||||
item7.level = (item7.level + 1) * 100
|
item7.level = (item7.level + 1) * 100
|
||||||
item7.children.forEach((item8: any) => {
|
item7.children.forEach((item8: any) => {
|
||||||
item8.icon = 'el-icon-Location'
|
item8.icon = 'el-icon-Location'
|
||||||
item8.plevel = item8.level
|
item8.plevel = item8.level
|
||||||
item8.level = (item8.level + 1) * 100
|
item8.level = (item8.level + 1) * 100
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.value = res.data
|
tree.value = res.data
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
treRef.value.setCurrentKey(id)
|
treRef.value.setCurrentKey(id)
|
||||||
// if (arr.length) {
|
// if (arr.length) {
|
||||||
// treRef.value.treeRef.setCurrentKey(arr[0].id)
|
// treRef.value.treeRef.setCurrentKey(arr[0].id)
|
||||||
// // 注册父组件事件
|
// // 注册父组件事件
|
||||||
// emit('init', {
|
// emit('init', {
|
||||||
// level: 2,
|
// level: 2,
|
||||||
// ...arr[0]
|
// ...arr[0]
|
||||||
// })
|
// })
|
||||||
// } else {
|
// } else {
|
||||||
// emit('init')
|
// emit('init')
|
||||||
// }
|
// }
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 下载模版
|
// 下载模版
|
||||||
const exportExcelTemplate = async() => {
|
const exportExcelTemplate = async() => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
downTerminalTemplate().then((res: any) => {
|
downTerminalTemplate().then((res: any) => {
|
||||||
let blob = new Blob([res], {
|
let blob = new Blob([res], {
|
||||||
type: 'application/vnd.ms-excel'
|
type: 'application/vnd.ms-excel'
|
||||||
})
|
})
|
||||||
const url = window.URL.createObjectURL(blob)
|
const url = window.URL.createObjectURL(blob)
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
link.href = url
|
link.href = url
|
||||||
link.download = '终端台账模版'
|
link.download = '终端台账模版'
|
||||||
document.body.appendChild(link)
|
document.body.appendChild(link)
|
||||||
link.click()
|
link.click()
|
||||||
link.remove()
|
link.remove()
|
||||||
})
|
})
|
||||||
await setTimeout(() => {
|
await setTimeout(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}, 0)
|
}, 0)
|
||||||
}
|
}
|
||||||
// 导出台账
|
// 导出台账
|
||||||
const ledgerEverywhere = async() => {
|
const ledgerEverywhere = async() => {
|
||||||
loading1.value = true
|
loading1.value = true
|
||||||
exportTerminalBase().then((res: any) => {
|
exportTerminalBase().then((res: any) => {
|
||||||
let blob = new Blob([res], {
|
let blob = new Blob([res], {
|
||||||
type: 'application/vnd.ms-excel'
|
type: 'application/vnd.ms-excel'
|
||||||
})
|
})
|
||||||
const url = window.URL.createObjectURL(blob)
|
const url = window.URL.createObjectURL(blob)
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
link.href = url
|
link.href = url
|
||||||
link.download = '终端台账'
|
link.download = '终端台账'
|
||||||
document.body.appendChild(link)
|
document.body.appendChild(link)
|
||||||
link.click()
|
link.click()
|
||||||
link.remove()
|
link.remove()
|
||||||
})
|
})
|
||||||
await setTimeout(() => {
|
await setTimeout(() => {
|
||||||
loading1.value = false
|
loading1.value = false
|
||||||
}, 0)
|
}, 0)
|
||||||
}
|
}
|
||||||
info('')
|
info('')
|
||||||
|
|
||||||
defineExpose({ info })
|
defineExpose({ info })
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.el-tree {
|
.el-tree {
|
||||||
background: #efeff0;
|
background: #efeff0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-container class="layout-container">
|
<el-container class="layout-container">
|
||||||
<Aside />
|
<Aside />
|
||||||
<el-container class="content-wrapper">
|
<el-container class="content-wrapper">
|
||||||
<Header />
|
<Header />
|
||||||
<Nav />
|
<Nav />
|
||||||
<Main />
|
<Main />
|
||||||
</el-container>
|
</el-container>
|
||||||
</el-container>
|
</el-container>
|
||||||
<CloseFullScreen v-if="navTabs.state.tabFullScreen" />
|
<CloseFullScreen v-if="navTabs.state.tabFullScreen" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Aside from '@/layouts/admin/components/aside.vue'
|
import Aside from '@/layouts/admin/components/aside.vue'
|
||||||
import Header from '@/layouts/admin/components/header.vue'
|
import Header from '@/layouts/admin/components/header.vue'
|
||||||
import Main from '@/layouts/admin/router-view/main.vue'
|
import Main from '@/layouts/admin/router-view/main.vue'
|
||||||
import CloseFullScreen from '@/layouts/admin/components/closeFullScreen.vue'
|
import CloseFullScreen from '@/layouts/admin/components/closeFullScreen.vue'
|
||||||
import { useNavTabs } from '@/stores/navTabs'
|
import { useNavTabs } from '@/stores/navTabs'
|
||||||
import Nav from '@/layouts/admin/components/nav.vue'
|
import Nav from '@/layouts/admin/components/nav.vue'
|
||||||
const navTabs = useNavTabs()
|
const navTabs = useNavTabs()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.layout-container {
|
.layout-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.content-wrapper {
|
.content-wrapper {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,71 +1,70 @@
|
|||||||
import { useCache, CACHE_KEY } from '@/hooks/web/useCache'
|
import { useCache, CACHE_KEY } from '@/hooks/web/useCache'
|
||||||
import { TokenType } from '@/api/login/types'
|
import { decrypt, encrypt } from '@/utils/jsencrypt'
|
||||||
import { decrypt, encrypt } from '@/utils/jsencrypt'
|
|
||||||
|
const { wsCache } = useCache()
|
||||||
const { wsCache } = useCache()
|
|
||||||
|
const AccessTokenKey = 'ACCESS_TOKEN'
|
||||||
const AccessTokenKey = 'ACCESS_TOKEN'
|
const RefreshTokenKey = 'REFRESH_TOKEN'
|
||||||
const RefreshTokenKey = 'REFRESH_TOKEN'
|
|
||||||
|
// 获取token
|
||||||
// 获取token
|
export const getAccessToken = () => {
|
||||||
export const getAccessToken = () => {
|
// 此处与TokenKey相同,此写法解决初始化时Cookies中不存在TokenKey报错
|
||||||
// 此处与TokenKey相同,此写法解决初始化时Cookies中不存在TokenKey报错
|
return wsCache.get(AccessTokenKey) ? wsCache.get(AccessTokenKey) : wsCache.get('ACCESS_TOKEN')
|
||||||
return wsCache.get(AccessTokenKey) ? wsCache.get(AccessTokenKey) : wsCache.get('ACCESS_TOKEN')
|
}
|
||||||
}
|
|
||||||
|
// 刷新token
|
||||||
// 刷新token
|
export const getRefreshToken = () => {
|
||||||
export const getRefreshToken = () => {
|
return wsCache.get(RefreshTokenKey)
|
||||||
return wsCache.get(RefreshTokenKey)
|
}
|
||||||
}
|
|
||||||
|
// 设置token
|
||||||
// 设置token
|
export const setToken = (token: any) => {
|
||||||
export const setToken = (token: TokenType) => {
|
wsCache.set(RefreshTokenKey, token.refreshToken)
|
||||||
wsCache.set(RefreshTokenKey, token.refreshToken)
|
wsCache.set(AccessTokenKey, token.accessToken)
|
||||||
wsCache.set(AccessTokenKey, token.accessToken)
|
}
|
||||||
}
|
|
||||||
|
// 删除token
|
||||||
// 删除token
|
export const removeToken = () => {
|
||||||
export const removeToken = () => {
|
wsCache.delete(AccessTokenKey)
|
||||||
wsCache.delete(AccessTokenKey)
|
wsCache.delete(RefreshTokenKey)
|
||||||
wsCache.delete(RefreshTokenKey)
|
}
|
||||||
}
|
|
||||||
|
/** 格式化token(jwt格式) */
|
||||||
/** 格式化token(jwt格式) */
|
export const formatToken = (token: string): string => {
|
||||||
export const formatToken = (token: string): string => {
|
return 'Bearer ' + token
|
||||||
return 'Bearer ' + token
|
}
|
||||||
}
|
// ========== 账号相关 ==========
|
||||||
// ========== 账号相关 ==========
|
|
||||||
|
export type LoginFormType = {
|
||||||
export type LoginFormType = {
|
tenantName: string
|
||||||
tenantName: string
|
username: string
|
||||||
username: string
|
password: string
|
||||||
password: string
|
rememberMe: boolean
|
||||||
rememberMe: boolean
|
}
|
||||||
}
|
|
||||||
|
export const getLoginForm = () => {
|
||||||
export const getLoginForm = () => {
|
const loginForm: LoginFormType = wsCache.get(CACHE_KEY.LoginForm)
|
||||||
const loginForm: LoginFormType = wsCache.get(CACHE_KEY.LoginForm)
|
if (loginForm) {
|
||||||
if (loginForm) {
|
loginForm.password = decrypt(loginForm.password) as string
|
||||||
loginForm.password = decrypt(loginForm.password) as string
|
}
|
||||||
}
|
return loginForm
|
||||||
return loginForm
|
}
|
||||||
}
|
|
||||||
|
export const setLoginForm = (loginForm: LoginFormType) => {
|
||||||
export const setLoginForm = (loginForm: LoginFormType) => {
|
loginForm.password = encrypt(loginForm.password) as string
|
||||||
loginForm.password = encrypt(loginForm.password) as string
|
wsCache.set(CACHE_KEY.LoginForm, loginForm, { exp: 30 * 24 * 60 * 60 })
|
||||||
wsCache.set(CACHE_KEY.LoginForm, loginForm, { exp: 30 * 24 * 60 * 60 })
|
}
|
||||||
}
|
|
||||||
|
export const removeLoginForm = () => {
|
||||||
export const removeLoginForm = () => {
|
wsCache.delete(CACHE_KEY.LoginForm)
|
||||||
wsCache.delete(CACHE_KEY.LoginForm)
|
}
|
||||||
}
|
|
||||||
|
// ========== 租户相关 ==========
|
||||||
// ========== 租户相关 ==========
|
|
||||||
|
export const getTenantId = () => {
|
||||||
export const getTenantId = () => {
|
return wsCache.get(CACHE_KEY.TenantId)
|
||||||
return wsCache.get(CACHE_KEY.TenantId)
|
}
|
||||||
}
|
|
||||||
|
export const setTenantId = (username: string) => {
|
||||||
export const setTenantId = (username: string) => {
|
wsCache.set(CACHE_KEY.TenantId, username)
|
||||||
wsCache.set(CACHE_KEY.TenantId, username)
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,159 +1,302 @@
|
|||||||
const dataProcessing = (arr: any[]) => {
|
const dataProcessing = (arr: any[]) => {
|
||||||
return arr
|
return arr
|
||||||
.filter(item => typeof item === 'number' || (typeof item === 'string' && !isNaN(parseFloat(item))))
|
.filter(item => typeof item === 'number' || (typeof item === 'string' && !isNaN(parseFloat(item))))
|
||||||
.map(item => (typeof item === 'number' ? item : parseFloat(item)))
|
.map(item => (typeof item === 'number' ? item : parseFloat(item)))
|
||||||
}
|
}
|
||||||
const calculateValue = (o: number, value: number, num: number, isMin: boolean) => {
|
const calculateValue = (o: number, value: number, num: number, isMin: boolean) => {
|
||||||
if (value === 0) {
|
if (value === 0) {
|
||||||
return 0
|
return 0
|
||||||
} else if (value > 0 && Math.abs(value) < 1 && isMin == true) {
|
} else if (value > 0 && Math.abs(value) < 1 && isMin == true) {
|
||||||
return 0
|
return 0
|
||||||
} else if (value > -1 && value < 0 && isMin == false) {
|
} else if (value > -1 && value < 0 && isMin == false) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
let base
|
let base
|
||||||
if (Math.abs(o) >= 100) {
|
if (Math.abs(o) >= 100) {
|
||||||
base = 100
|
base = 100
|
||||||
} else if (Math.abs(o) >= 10) {
|
} else if (Math.abs(o) >= 10) {
|
||||||
base = 10
|
base = 10
|
||||||
} else if (Math.abs(o) >= 1) {
|
} else if (Math.abs(o) >= 1) {
|
||||||
base = 1
|
base = 1
|
||||||
} else {
|
} else {
|
||||||
base = 0.1
|
base = 0.1
|
||||||
}
|
}
|
||||||
let calculatedValue
|
let calculatedValue
|
||||||
if (isMin) {
|
if (isMin) {
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
calculatedValue = value + num * value
|
calculatedValue = value + num * value
|
||||||
} else {
|
} else {
|
||||||
calculatedValue = value - num * value
|
calculatedValue = value - num * value
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
calculatedValue = value - num * value
|
calculatedValue = value - num * value
|
||||||
} else {
|
} else {
|
||||||
calculatedValue = value + num * value
|
calculatedValue = value + num * value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (base === 0.1) {
|
if (base === 0.1) {
|
||||||
return parseFloat(calculatedValue.toFixed(1))
|
return parseFloat(calculatedValue.toFixed(1))
|
||||||
} else if (isMin) {
|
} else if (isMin) {
|
||||||
return Math.floor(calculatedValue / base) * base
|
return Math.floor(calculatedValue / base) * base
|
||||||
} else {
|
} else {
|
||||||
return Math.ceil(calculatedValue / base) * base
|
return Math.ceil(calculatedValue / base) * base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理y轴最大最小值
|
// 处理y轴最大最小值
|
||||||
export const yMethod = (arr: any) => {
|
export const yMethod = (arr: any) => {
|
||||||
let num = 0.1
|
let num = 0.1
|
||||||
let numList = dataProcessing(arr)
|
let numList = dataProcessing(arr)
|
||||||
let maxValue = 0
|
let maxValue = 0
|
||||||
let minValue = 0
|
let minValue = 0
|
||||||
let max = 0
|
let max = 0
|
||||||
let min = 0
|
let min = 0
|
||||||
maxValue = Math.max(...numList)
|
maxValue = Math.max(...numList)
|
||||||
minValue = Math.min(...numList)
|
minValue = Math.min(...numList)
|
||||||
const o = maxValue - minValue
|
const o = maxValue - minValue
|
||||||
if (Math.abs(o) >= 300) {
|
if (Math.abs(o) >= 300) {
|
||||||
num = 0.02
|
num = 0.02
|
||||||
}
|
}
|
||||||
|
|
||||||
min = calculateValue(o, minValue, num, true)
|
min = calculateValue(o, minValue, num, true)
|
||||||
max = calculateValue(o, maxValue, num, false)
|
max = calculateValue(o, maxValue, num, false)
|
||||||
// if (-100 >= minValue) {
|
// if (-100 >= minValue) {
|
||||||
// min = Math.floor((minValue + num * minValue) / 100) * 100
|
// min = Math.floor((minValue + num * minValue) / 100) * 100
|
||||||
// } else if (-10 >= minValue && minValue > -100) {
|
// } else if (-10 >= minValue && minValue > -100) {
|
||||||
// min = Math.floor((minValue + num * minValue) / 10) * 10
|
// min = Math.floor((minValue + num * minValue) / 10) * 10
|
||||||
// } else if (-1 >= minValue && minValue > -10) {
|
// } else if (-1 >= minValue && minValue > -10) {
|
||||||
// min = Math.floor(minValue + num * minValue)
|
// min = Math.floor(minValue + num * minValue)
|
||||||
// } else if (0 > minValue && minValue > -1) {
|
// } else if (0 > minValue && minValue > -1) {
|
||||||
// min = parseFloat((minValue + num * minValue).toFixed(1))
|
// min = parseFloat((minValue + num * minValue).toFixed(1))
|
||||||
// } else if (minValue == 0) {
|
// } else if (minValue == 0) {
|
||||||
// min = 0
|
// min = 0
|
||||||
// } else if (0 < minValue && minValue < 1) {
|
// } else if (0 < minValue && minValue < 1) {
|
||||||
// min = parseFloat((minValue - num * minValue).toFixed(1))
|
// min = parseFloat((minValue - num * minValue).toFixed(1))
|
||||||
// } else if (1 <= minValue && minValue < 10) {
|
// } else if (1 <= minValue && minValue < 10) {
|
||||||
// min = Math.floor(minValue - num * minValue)
|
// min = Math.floor(minValue - num * minValue)
|
||||||
// } else if (10 <= minValue && minValue < 100) {
|
// } else if (10 <= minValue && minValue < 100) {
|
||||||
// min = Math.floor((minValue - num * minValue) / 10) * 10
|
// min = Math.floor((minValue - num * minValue) / 10) * 10
|
||||||
// } else if (100 <= minValue) {
|
// } else if (100 <= minValue) {
|
||||||
// min = Math.floor((minValue - num * minValue) / 100) * 100
|
// min = Math.floor((minValue - num * minValue) / 100) * 100
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if (-100 >= maxValue) {
|
// if (-100 >= maxValue) {
|
||||||
// max = Math.ceil((maxValue - num * maxValue) / 100) * 100
|
// max = Math.ceil((maxValue - num * maxValue) / 100) * 100
|
||||||
// } else if (-10 >= maxValue && maxValue > -100) {
|
// } else if (-10 >= maxValue && maxValue > -100) {
|
||||||
// max = Math.ceil((maxValue - num * maxValue) / 10) * 10
|
// max = Math.ceil((maxValue - num * maxValue) / 10) * 10
|
||||||
// } else if (-1 >= maxValue && maxValue > -10) {
|
// } else if (-1 >= maxValue && maxValue > -10) {
|
||||||
// max = Math.ceil(maxValue - num * maxValue)
|
// max = Math.ceil(maxValue - num * maxValue)
|
||||||
// } else if (0 > maxValue && maxValue > -1) {
|
// } else if (0 > maxValue && maxValue > -1) {
|
||||||
// max = parseFloat((maxValue - num * maxValue).toFixed(1))
|
// max = parseFloat((maxValue - num * maxValue).toFixed(1))
|
||||||
// } else if (maxValue == 0) {
|
// } else if (maxValue == 0) {
|
||||||
// max = 0
|
// max = 0
|
||||||
// } else if (0 < maxValue && maxValue < 1) {
|
// } else if (0 < maxValue && maxValue < 1) {
|
||||||
// max = parseFloat((maxValue + num * maxValue).toFixed(1))
|
// max = parseFloat((maxValue + num * maxValue).toFixed(1))
|
||||||
// } else if (1 <= maxValue && maxValue < 10) {
|
// } else if (1 <= maxValue && maxValue < 10) {
|
||||||
// max = Math.ceil(maxValue + num * maxValue)
|
// max = Math.ceil(maxValue + num * maxValue)
|
||||||
// } else if (10 <= maxValue && maxValue < 100) {
|
// } else if (10 <= maxValue && maxValue < 100) {
|
||||||
// max = Math.ceil((maxValue + num * maxValue) / 10) * 10
|
// max = Math.ceil((maxValue + num * maxValue) / 10) * 10
|
||||||
// } else if (100 <= maxValue) {
|
// } else if (100 <= maxValue) {
|
||||||
// max = Math.ceil((maxValue + num * maxValue) / 100) * 100
|
// max = Math.ceil((maxValue + num * maxValue) / 100) * 100
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if (maxValue > 1000 || minValue < -1000) {
|
// if (maxValue > 1000 || minValue < -1000) {
|
||||||
// max = Math.ceil(maxValue / 100) * 100
|
// max = Math.ceil(maxValue / 100) * 100
|
||||||
// if (minValue == 0) {
|
// if (minValue == 0) {
|
||||||
// min = 0
|
// min = 0
|
||||||
// } else {
|
// } else {
|
||||||
// min = Math.floor(minValue / 100) * 100
|
// min = Math.floor(minValue / 100) * 100
|
||||||
// }
|
// }
|
||||||
// } else if (maxValue < 60 && minValue > 40) {
|
// } else if (maxValue < 60 && minValue > 40) {
|
||||||
// max = 60
|
// max = 60
|
||||||
// min = 40
|
// min = 40
|
||||||
// } else if (maxValue == minValue && maxValue < 10 && minValue > 0) {
|
// } else if (maxValue == minValue && maxValue < 10 && minValue > 0) {
|
||||||
// max = Math.ceil(maxValue / 10) * 10
|
// max = Math.ceil(maxValue / 10) * 10
|
||||||
// min = Math.floor(minValue / 10) * 10
|
// min = Math.floor(minValue / 10) * 10
|
||||||
// } else if (maxValue == minValue && maxValue != 0 && minValue != 0) {
|
// } else if (maxValue == minValue && maxValue != 0 && minValue != 0) {
|
||||||
// max = Math.ceil(maxValue / 10 + 1) * 10
|
// max = Math.ceil(maxValue / 10 + 1) * 10
|
||||||
// min = Math.floor(minValue / 10 - 1) * 10
|
// min = Math.floor(minValue / 10 - 1) * 10
|
||||||
// } else {
|
// } else {
|
||||||
// max = Math.ceil(maxValue / 10) * 10
|
// max = Math.ceil(maxValue / 10) * 10
|
||||||
// min = Math.floor(minValue / 10) * 10
|
// min = Math.floor(minValue / 10) * 10
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if (maxValue > 0 && maxValue < 1) {
|
// if (maxValue > 0 && maxValue < 1) {
|
||||||
// max = 1
|
// max = 1
|
||||||
// } else if (max == 0 && minValue > -1 && minValue < 0) {
|
// } else if (max == 0 && minValue > -1 && minValue < 0) {
|
||||||
// min = -1
|
// min = -1
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return [min, max]
|
return [min, max]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* title['A相','B相',]
|
* title['A相','B相',]
|
||||||
* data[[1,2],[3,4]]
|
* data[[1,2],[3,4]]
|
||||||
*/
|
*/
|
||||||
// 导出csv文件
|
// 导出csv文件
|
||||||
const convertToCSV = (title: object, data: any) => {
|
const convertToCSV = (title: object, data: any) => {
|
||||||
console.log('🚀 ~ convertToCSV ~ data:', data)
|
console.log('🚀 ~ convertToCSV ~ data:', data)
|
||||||
let csv = ''
|
let csv = ''
|
||||||
// 添加列头
|
// 添加列头
|
||||||
csv += ',' + title.join(',') + '\n'
|
csv += ',' + title.join(',') + '\n'
|
||||||
// 遍历数据并添加到CSV字符串中
|
// 遍历数据并添加到CSV字符串中
|
||||||
data?.map(item => {
|
data?.map(item => {
|
||||||
csv += item.join(',') + '\n'
|
csv += item.join(',') + '\n'
|
||||||
})
|
})
|
||||||
return csv
|
return csv
|
||||||
}
|
}
|
||||||
export const exportCSV = (title: object, data: any, filename: string) => {
|
export const exportCSV = (title: object, data: any, filename: string) => {
|
||||||
const csv = convertToCSV(title, data)
|
const csv = convertToCSV(title, data)
|
||||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
|
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
link.href = URL.createObjectURL(blob)
|
link.href = URL.createObjectURL(blob)
|
||||||
link.download = filename
|
link.download = filename
|
||||||
link.click()
|
link.click()
|
||||||
// 释放URL对象
|
// 释放URL对象
|
||||||
URL.revokeObjectURL(link.href)
|
URL.revokeObjectURL(link.href)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 补全时间序列数据中缺失的条目
|
||||||
|
* @param rawData 原始数据,格式为 [["时间字符串", "数值", "单位", "类型"], ...]
|
||||||
|
* @returns 补全后的数据,缺失条目数值为 null
|
||||||
|
*/
|
||||||
|
export const completeTimeSeries = (rawData: string[][]): (string | null)[][] => {
|
||||||
|
// 步骤1:校验原始数据并解析时间
|
||||||
|
if (rawData.length < 2) {
|
||||||
|
console.warn('数据量不足2条,无法计算时间间隔,直接返回原始数据')
|
||||||
|
return rawData.map(item => [...item])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析所有时间为Date对象,过滤无效时间并按时间排序
|
||||||
|
const validData = rawData
|
||||||
|
.map(item => {
|
||||||
|
// 确保至少有时间和数值字段
|
||||||
|
if (!item[0]) {
|
||||||
|
return { time: new Date(0), item, isValid: false }
|
||||||
|
}
|
||||||
|
const time = new Date(item[0])
|
||||||
|
return { time, item, isValid: !isNaN(time.getTime()) }
|
||||||
|
})
|
||||||
|
.filter(data => data.isValid)
|
||||||
|
.sort((a, b) => a.time.getTime() - b.time.getTime()) // 确保数据按时间排序
|
||||||
|
.map(data => data.item)
|
||||||
|
|
||||||
|
if (validData.length < 2) {
|
||||||
|
throw new Error('有效时间数据不足2条,无法继续处理')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 步骤2:计算时间间隔(分析前几条数据确定最可能的间隔)
|
||||||
|
const intervals: number[] = []
|
||||||
|
// 分析前10条数据来确定间隔,避免单一间隔出错
|
||||||
|
const analyzeCount = Math.min(10, validData.length - 1)
|
||||||
|
for (let i = 0; i < analyzeCount; i++) {
|
||||||
|
const currentTime = new Date(validData[i][0]!).getTime()
|
||||||
|
const nextTime = new Date(validData[i + 1][0]!).getTime()
|
||||||
|
const interval = nextTime - currentTime
|
||||||
|
if (interval > 0) {
|
||||||
|
intervals.push(interval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取最常见的间隔作为标准间隔
|
||||||
|
const timeInterval = getMostFrequentValue(intervals)
|
||||||
|
if (timeInterval <= 0) {
|
||||||
|
throw new Error('无法确定有效的时间间隔')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 步骤3:生成完整的时间序列范围(从第一条到最后一条)
|
||||||
|
const startTime = new Date(validData[0][0]!).getTime()
|
||||||
|
const endTime = new Date(validData[validData.length - 1][0]!).getTime()
|
||||||
|
const completeTimes: Date[] = []
|
||||||
|
|
||||||
|
// 生成从 startTime 到 endTime 的所有间隔时间点
|
||||||
|
for (let time = startTime; time <= endTime; time += timeInterval) {
|
||||||
|
completeTimes.push(new Date(time))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 步骤4:将原始数据转为时间映射表,使用精确的时间字符串匹配
|
||||||
|
const timeDataMap = new Map<string, (string | undefined)[]>()
|
||||||
|
validData.forEach(item => {
|
||||||
|
// 使用原始时间字符串作为键,避免格式转换导致的匹配问题
|
||||||
|
if (item[0]) {
|
||||||
|
timeDataMap.set(item[0], item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 提取模板数据(从第一条有效数据中提取单位和类型,处理可能的缺失)
|
||||||
|
const template = validData[0]
|
||||||
|
|
||||||
|
// 步骤5:对比补全数据,缺失条目数值为 null
|
||||||
|
const completedData = completeTimes.map(time => {
|
||||||
|
// 保持与原始数据相同的时间格式
|
||||||
|
const timeStr = formatTime(time)
|
||||||
|
const existingItem = timeDataMap.get(timeStr)
|
||||||
|
|
||||||
|
if (existingItem) {
|
||||||
|
// 存在该时间,返回原始数据
|
||||||
|
return [...existingItem]
|
||||||
|
} else {
|
||||||
|
// 缺失该时间,数值设为 null,其他字段沿用第一个有效数据的格式
|
||||||
|
// 处理可能缺失的单位和类型字段
|
||||||
|
const result: (string | null | undefined)[] = [timeStr, '/']
|
||||||
|
// 仅在原始数据有单位字段时才添加
|
||||||
|
if (template.length > 2) {
|
||||||
|
result.push(template[2])
|
||||||
|
}
|
||||||
|
// 仅在原始数据有类型字段时才添加
|
||||||
|
if (template.length > 3) {
|
||||||
|
result.push(template[3])
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return completedData
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化时间为 "YYYY-MM-DD HH:mm:ss" 格式
|
||||||
|
* @param date 日期对象
|
||||||
|
* @returns 格式化后的时间字符串
|
||||||
|
*/
|
||||||
|
function formatTime(date: Date): string {
|
||||||
|
const year = date.getFullYear()
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||||
|
const day = String(date.getDate()).padStart(2, '0')
|
||||||
|
const hours = String(date.getHours()).padStart(2, '0')
|
||||||
|
const minutes = String(date.getMinutes()).padStart(2, '0')
|
||||||
|
const seconds = String(date.getSeconds()).padStart(2, '0')
|
||||||
|
|
||||||
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数组中出现频率最高的值
|
||||||
|
* @param arr 数字数组
|
||||||
|
* @returns 出现频率最高的值
|
||||||
|
*/
|
||||||
|
function getMostFrequentValue(arr: number[]): number {
|
||||||
|
if (arr.length === 0) return 0
|
||||||
|
|
||||||
|
const frequencyMap = new Map<number, number>()
|
||||||
|
arr.forEach(num => {
|
||||||
|
frequencyMap.set(num, (frequencyMap.get(num) || 0) + 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
let maxFrequency = 0
|
||||||
|
let mostFrequent = arr[0]
|
||||||
|
|
||||||
|
frequencyMap.forEach((frequency, num) => {
|
||||||
|
if (frequency > maxFrequency) {
|
||||||
|
maxFrequency = frequency
|
||||||
|
mostFrequent = num
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return mostFrequent
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,295 +1,295 @@
|
|||||||
import router from '@/router/index'
|
import router from '@/router/index'
|
||||||
import { isNavigationFailure, NavigationFailureType } from 'vue-router'
|
import { isNavigationFailure, NavigationFailureType } from 'vue-router'
|
||||||
import type { RouteRecordRaw, RouteLocationRaw } from 'vue-router'
|
import type { RouteRecordRaw, RouteLocationRaw } from 'vue-router'
|
||||||
import { ElNotification } from 'element-plus'
|
import { ElNotification } from 'element-plus'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import { useNavTabs } from '@/stores/navTabs'
|
import { useNavTabs } from '@/stores/navTabs'
|
||||||
import { closeShade } from '@/utils/pageShade'
|
import { closeShade } from '@/utils/pageShade'
|
||||||
import { adminBaseRoute } from '@/router/static'
|
import { adminBaseRoute } from '@/router/static'
|
||||||
import { compact, isEmpty, reverse } from 'lodash-es'
|
import { compact, isEmpty, reverse } from 'lodash-es'
|
||||||
import { isAdminApp } from '@/utils/common'
|
import { isAdminApp } from '@/utils/common'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导航失败有错误消息的路由push
|
* 导航失败有错误消息的路由push
|
||||||
* @param to — 导航位置,同 router.push
|
* @param to — 导航位置,同 router.push
|
||||||
*/
|
*/
|
||||||
export const routePush = async (to: RouteLocationRaw) => {
|
export const routePush = async (to: RouteLocationRaw) => {
|
||||||
try {
|
try {
|
||||||
const failure = await router.push(to)
|
const failure = await router.push(to)
|
||||||
if (isNavigationFailure(failure, NavigationFailureType.aborted)) {
|
if (isNavigationFailure(failure, NavigationFailureType.aborted)) {
|
||||||
ElNotification({
|
ElNotification({
|
||||||
message: 'utils.Navigation failed, navigation guard intercepted!',
|
message: 'utils.Navigation failed, navigation guard intercepted!',
|
||||||
type: 'error'
|
type: 'error'
|
||||||
})
|
})
|
||||||
} else if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
|
} else if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
|
||||||
// ElNotification({
|
// ElNotification({
|
||||||
// message: '已在目标页',
|
// message: '已在目标页',
|
||||||
// type: 'warning'
|
// type: 'warning'
|
||||||
// })
|
// })
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElNotification({
|
ElNotification({
|
||||||
message: '导航失败,路由无效',
|
message: '导航失败,路由无效',
|
||||||
type: 'error'
|
type: 'error'
|
||||||
})
|
})
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取第一个菜单
|
* 获取第一个菜单
|
||||||
*/
|
*/
|
||||||
export const getFirstRoute = (routes: RouteRecordRaw[], menuType = 'tab'): false | RouteRecordRaw => {
|
export const getFirstRoute = (routes: RouteRecordRaw[], menuType = 'tab'): false | RouteRecordRaw => {
|
||||||
const routerPaths: string[] = []
|
const routerPaths: string[] = []
|
||||||
const routers = router.getRoutes()
|
const routers = router.getRoutes()
|
||||||
routers.forEach(item => {
|
routers.forEach(item => {
|
||||||
if (item.path) routerPaths.push(item.path)
|
if (item.path) routerPaths.push(item.path)
|
||||||
})
|
})
|
||||||
let find: boolean | RouteRecordRaw = false
|
let find: boolean | RouteRecordRaw = false
|
||||||
for (const key in routes) {
|
for (const key in routes) {
|
||||||
if (
|
if (
|
||||||
routes[key].meta?.type == 'menu' &&
|
routes[key].meta?.type == 'menu' &&
|
||||||
routes[key].meta?.menu_type == menuType &&
|
routes[key].meta?.menu_type == menuType &&
|
||||||
routerPaths.indexOf(routes[key].path) !== -1
|
routerPaths.indexOf(routes[key].path) !== -1
|
||||||
) {
|
) {
|
||||||
return routes[key]
|
return routes[key]
|
||||||
} else if (routes[key].children && routes[key].children?.length) {
|
} else if (routes[key].children && routes[key].children?.length) {
|
||||||
find = getFirstRoute(routes[key].children!)
|
find = getFirstRoute(routes[key].children!)
|
||||||
if (find) return find
|
if (find) return find
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return find
|
return find
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开侧边菜单
|
* 打开侧边菜单
|
||||||
* @param menu 菜单数据
|
* @param menu 菜单数据
|
||||||
*/
|
*/
|
||||||
export const onClickMenu = (menu: RouteRecordRaw) => {
|
export const onClickMenu = (menu: RouteRecordRaw) => {
|
||||||
switch (menu.meta?.menu_type) {
|
switch (menu.meta?.menu_type) {
|
||||||
case 'iframe':
|
case 'iframe':
|
||||||
case 'tab':
|
case 'tab':
|
||||||
routePush({ path: menu.path })
|
routePush({ path: menu.path })
|
||||||
break
|
break
|
||||||
case 'link':
|
case 'link':
|
||||||
window.open(menu.path, '_blank')
|
window.open(menu.path, '_blank')
|
||||||
break
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ElNotification({
|
ElNotification({
|
||||||
message: 'utils.Navigation failed, the menu type is unrecognized!',
|
message: 'utils.Navigation failed, the menu type is unrecognized!',
|
||||||
type: 'error'
|
type: 'error'
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
if (config.layout.shrink) {
|
if (config.layout.shrink) {
|
||||||
closeShade(() => {
|
closeShade(() => {
|
||||||
config.setLayout('menuCollapse', true)
|
config.setLayout('menuCollapse', true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理后台的路由
|
* 处理后台的路由
|
||||||
*/
|
*/
|
||||||
export const handleAdminRoute = (routes: any) => {
|
export const handleAdminRoute = (routes: any) => {
|
||||||
const viewsComponent = import.meta.glob('/src/views/**/*.vue')
|
const viewsComponent = import.meta.glob('/src/views/**/*.vue')
|
||||||
addRouteAll(viewsComponent, routes, adminBaseRoute.name as string)
|
addRouteAll(viewsComponent, routes, adminBaseRoute.name as string)
|
||||||
const menuAdminBaseRoute = (adminBaseRoute.path as string) + '/'
|
const menuAdminBaseRoute = (adminBaseRoute.path as string) + '/'
|
||||||
// 更新stores中的路由菜单数据
|
// 更新stores中的路由菜单数据
|
||||||
const navTabs = useNavTabs()
|
const navTabs = useNavTabs()
|
||||||
navTabs.setTabsViewRoutes(handleMenuRule(routes, menuAdminBaseRoute))
|
navTabs.setTabsViewRoutes(handleMenuRule(routes, menuAdminBaseRoute))
|
||||||
navTabs.fillAuthNode(handleAuthNode(routes, menuAdminBaseRoute))
|
navTabs.fillAuthNode(handleAuthNode(routes, menuAdminBaseRoute))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取菜单的paths
|
* 获取菜单的paths
|
||||||
*/
|
*/
|
||||||
export const getMenuPaths = (menus: RouteRecordRaw[]): string[] => {
|
export const getMenuPaths = (menus: RouteRecordRaw[]): string[] => {
|
||||||
let menuPaths: string[] = []
|
let menuPaths: string[] = []
|
||||||
menus.forEach(item => {
|
menus.forEach(item => {
|
||||||
menuPaths.push(item.path)
|
menuPaths.push(item.path)
|
||||||
if (item.children && item.children.length > 0) {
|
if (item.children && item.children.length > 0) {
|
||||||
menuPaths = menuPaths.concat(getMenuPaths(item.children))
|
menuPaths = menuPaths.concat(getMenuPaths(item.children))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return menuPaths
|
return menuPaths
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 后台的菜单处理
|
* 后台的菜单处理
|
||||||
*/
|
*/
|
||||||
const handleMenuRule = (routes: any, pathPrefix = '/', type = ['menu', 'menu_dir']) => {
|
const handleMenuRule = (routes: any, pathPrefix = '/', type = ['menu', 'menu_dir']) => {
|
||||||
const menuRule: RouteRecordRaw[] = []
|
const menuRule: RouteRecordRaw[] = []
|
||||||
for (const key in routes) {
|
for (const key in routes) {
|
||||||
if (routes[key].extend == 'add_rules_only') {
|
if (routes[key].extend == 'add_rules_only') {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (!type.includes(routes[key].type)) {
|
if (!type.includes(routes[key].type)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (routes[key].type == 'menu_dir' && routes[key].children && !routes[key].children.length) {
|
if (routes[key].type == 'menu_dir' && routes[key].children && !routes[key].children.length) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
['route', 'menu', 'nav_user_menu', 'nav'].includes(routes[key].type) &&
|
['route', 'menu', 'nav_user_menu', 'nav'].includes(routes[key].type) &&
|
||||||
((routes[key].menu_type == 'tab' && !routes[key].component) ||
|
((routes[key].menu_type == 'tab' && !routes[key].component) ||
|
||||||
(['link', 'iframe'].includes(routes[key].menu_type) && !routes[key].url))
|
(['link', 'iframe'].includes(routes[key].menu_type) && !routes[key].url))
|
||||||
) {
|
) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const currentPath = ['link', 'iframe'].includes(routes[key].menu_type)
|
const currentPath = ['link', 'iframe'].includes(routes[key].menu_type)
|
||||||
? routes[key].url
|
? routes[key].url
|
||||||
: pathPrefix + routes[key].path
|
: pathPrefix + routes[key].path
|
||||||
let children: RouteRecordRaw[] = []
|
let children: RouteRecordRaw[] = []
|
||||||
if (routes[key].children && routes[key].children.length > 0) {
|
if (routes[key].children && routes[key].children.length > 0) {
|
||||||
children = handleMenuRule(routes[key].children, pathPrefix, type)
|
children = handleMenuRule(routes[key].children, pathPrefix, type)
|
||||||
}
|
}
|
||||||
menuRule.push({
|
menuRule.push({
|
||||||
path: currentPath,
|
path: currentPath,
|
||||||
name: routes[key].name,
|
name: routes[key].name,
|
||||||
component: routes[key].component,
|
component: routes[key].component,
|
||||||
meta: {
|
meta: {
|
||||||
id: routes[key].id,
|
id: routes[key].id,
|
||||||
title: routes[key].title,
|
title: routes[key].title,
|
||||||
icon: routes[key].icon,
|
icon: routes[key].icon,
|
||||||
keepalive: routes[key].keepalive,
|
keepalive: routes[key].keepalive,
|
||||||
menu_type: routes[key].menu_type,
|
menu_type: routes[key].menu_type,
|
||||||
type: routes[key].type
|
type: routes[key].type
|
||||||
},
|
},
|
||||||
children: children
|
children: children
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return menuRule
|
return menuRule
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理权限节点
|
* 处理权限节点
|
||||||
* @param routes 路由数据
|
* @param routes 路由数据
|
||||||
* @param prefix 节点前缀
|
* @param prefix 节点前缀
|
||||||
* @returns 组装好的权限节点
|
* @returns 组装好的权限节点
|
||||||
*/
|
*/
|
||||||
const handleAuthNode = (routes: any, prefix = '/') => {
|
const handleAuthNode = (routes: any, prefix = '/') => {
|
||||||
const authNode: Map<string, string[]> = new Map([])
|
const authNode: Map<string, string[]> = new Map([])
|
||||||
assembleAuthNode(routes, authNode, prefix, prefix)
|
assembleAuthNode(routes, authNode, prefix, prefix)
|
||||||
return authNode
|
return authNode
|
||||||
}
|
}
|
||||||
const assembleAuthNode = (routes: any, authNode: Map<string, string[]>, prefix = '/', parent = '/') => {
|
const assembleAuthNode = (routes: any, authNode: Map<string, string[]>, prefix = '/', parent = '/') => {
|
||||||
const authNodeTemp = []
|
const authNodeTemp = []
|
||||||
for (const key in routes) {
|
for (const key in routes) {
|
||||||
if (routes[key].type == 'button') authNodeTemp.push(prefix + routes[key].name)
|
if (routes[key].type == 'button') authNodeTemp.push(prefix + routes[key].name)
|
||||||
if (routes[key].children && routes[key].children.length > 0) {
|
if (routes[key].children && routes[key].children.length > 0) {
|
||||||
assembleAuthNode(routes[key].children, authNode, prefix, prefix + routes[key].name)
|
assembleAuthNode(routes[key].children, authNode, prefix, prefix + routes[key].name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (authNodeTemp && authNodeTemp.length > 0) {
|
if (authNodeTemp && authNodeTemp.length > 0) {
|
||||||
authNode.set(parent, authNodeTemp)
|
authNode.set(parent, authNodeTemp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 动态添加路由-带子路由
|
* 动态添加路由-带子路由
|
||||||
* @param viewsComponent
|
* @param viewsComponent
|
||||||
* @param routes
|
* @param routes
|
||||||
* @param parentName
|
* @param parentName
|
||||||
* @param analyticRelation 根据 name 从已注册路由分析父级路由
|
* @param analyticRelation 根据 name 从已注册路由分析父级路由
|
||||||
*/
|
*/
|
||||||
export const addRouteAll = (
|
export const addRouteAll = (
|
||||||
viewsComponent: Record<string, any>,
|
viewsComponent: Record<string, any>,
|
||||||
routes: any,
|
routes: any,
|
||||||
parentName: string,
|
parentName: string,
|
||||||
analyticRelation = false
|
analyticRelation = false
|
||||||
) => {
|
) => {
|
||||||
for (const idx in routes) {
|
for (const idx in routes) {
|
||||||
if (routes[idx].extend == 'add_menu_only') {
|
if (routes[idx].extend == 'add_menu_only') {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
(routes[idx].menu_type == 'tab' && viewsComponent[routes[idx].component]) ||
|
(routes[idx].menu_type == 'tab' && viewsComponent[routes[idx].component]) ||
|
||||||
routes[idx].menu_type == 'iframe'
|
routes[idx].menu_type == 'iframe'
|
||||||
) {
|
) {
|
||||||
addRouteItem(viewsComponent, routes[idx], parentName, analyticRelation)
|
addRouteItem(viewsComponent, routes[idx], parentName, analyticRelation)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (routes[idx].children && routes[idx].children.length > 0) {
|
if (routes[idx].children && routes[idx].children.length > 0) {
|
||||||
addRouteAll(viewsComponent, routes[idx].children, parentName, analyticRelation)
|
addRouteAll(viewsComponent, routes[idx].children, parentName, analyticRelation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 动态添加路由
|
* 动态添加路由
|
||||||
* @param viewsComponent
|
* @param viewsComponent
|
||||||
* @param route
|
* @param route
|
||||||
* @param parentName
|
* @param parentName
|
||||||
* @param analyticRelation 根据 name 从已注册路由分析父级路由
|
* @param analyticRelation 根据 name 从已注册路由分析父级路由
|
||||||
*/
|
*/
|
||||||
export const addRouteItem = (
|
export const addRouteItem = (
|
||||||
viewsComponent: Record<string, any>,
|
viewsComponent: Record<string, any>,
|
||||||
route: any,
|
route: any,
|
||||||
parentName: string,
|
parentName: string,
|
||||||
analyticRelation: boolean
|
analyticRelation: boolean
|
||||||
) => {
|
) => {
|
||||||
let path = '',
|
let path = '',
|
||||||
component
|
component
|
||||||
if (route.menu_type == 'iframe') {
|
if (route.menu_type == 'iframe') {
|
||||||
path = (isAdminApp() ? adminBaseRoute.path : '') + '/iframe/' + encodeURIComponent(route.url)
|
path = (isAdminApp() ? adminBaseRoute.path : '') + '/iframe/' + encodeURIComponent(route.url)
|
||||||
component = () => import('@/layouts/common/router-view/iframe.vue')
|
component = () => import('@/layouts/common/router-view/iframe.vue')
|
||||||
} else {
|
} else {
|
||||||
path = parentName ? route.path : '/' + route.path
|
path = parentName ? route.path : '/' + route.path
|
||||||
component = viewsComponent[route.component]
|
component = viewsComponent[route.component]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (route.menu_type == 'tab' && analyticRelation) {
|
if (route.menu_type == 'tab' && analyticRelation) {
|
||||||
const parentNames = getParentNames(route.name)
|
const parentNames = getParentNames(route.name)
|
||||||
if (parentNames.length) {
|
if (parentNames.length) {
|
||||||
for (const key in parentNames) {
|
for (const key in parentNames) {
|
||||||
if (router.hasRoute(parentNames[key])) {
|
if (router.hasRoute(parentNames[key])) {
|
||||||
parentName = parentNames[key]
|
parentName = parentNames[key]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const routeBaseInfo: RouteRecordRaw = {
|
const routeBaseInfo: RouteRecordRaw = {
|
||||||
path: path,
|
path: path,
|
||||||
name: route.name,
|
name: route.name,
|
||||||
component: component,
|
component: component,
|
||||||
meta: {
|
meta: {
|
||||||
...route,
|
...route,
|
||||||
title: route.title,
|
title: route.title,
|
||||||
extend: route.extend,
|
extend: route.extend,
|
||||||
icon: route.icon,
|
icon: route.icon,
|
||||||
keepalive: route.keepalive,
|
keepalive: route.keepalive,
|
||||||
menu_type: route.menu_type,
|
menu_type: route.menu_type,
|
||||||
type: route.type,
|
type: route.type,
|
||||||
url: route.url,
|
url: route.url,
|
||||||
addtab: true
|
addtab: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (parentName) {
|
if (parentName) {
|
||||||
router.addRoute(parentName, routeBaseInfo)
|
router.addRoute(parentName, routeBaseInfo)
|
||||||
} else {
|
} else {
|
||||||
router.addRoute(routeBaseInfo)
|
router.addRoute(routeBaseInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据name字符串,获取父级name组合的数组
|
* 根据name字符串,获取父级name组合的数组
|
||||||
* @param name
|
* @param name
|
||||||
*/
|
*/
|
||||||
const getParentNames = (name: string) => {
|
const getParentNames = (name: string) => {
|
||||||
const names = compact(name.split('/'))
|
const names = compact(name.split('/'))
|
||||||
const tempNames = []
|
const tempNames = []
|
||||||
const parentNames = []
|
const parentNames = []
|
||||||
for (const key in names) {
|
for (const key in names) {
|
||||||
tempNames.push(names[key])
|
tempNames.push(names[key])
|
||||||
if (parseInt(key) != names.length - 1) {
|
if (parseInt(key) != names.length - 1) {
|
||||||
parentNames.push(tempNames.join('/'))
|
parentNames.push(tempNames.join('/'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return reverse(parentNames)
|
return reverse(parentNames)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const prop = defineProps({
|
|||||||
const dictData = useDictData()
|
const dictData = useDictData()
|
||||||
const fontdveoption = dictData.getBasicData('Dev_Ops')
|
const fontdveoption = dictData.getBasicData('Dev_Ops')
|
||||||
|
|
||||||
const tableStore = new TableStore({
|
const tableStore:any = new TableStore({
|
||||||
url: '/device-boot/pqsTerminalLogs/getList',
|
url: '/device-boot/pqsTerminalLogs/getList',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
column: [
|
column: [
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ const handleCurrentChange = (val: number) => {
|
|||||||
const exportEvent = () => {
|
const exportEvent = () => {
|
||||||
const allFilteredData = filteredData.value
|
const allFilteredData = filteredData.value
|
||||||
tableRef.value.exportData({
|
tableRef.value.exportData({
|
||||||
filename: '场战级评估-污染值报告',
|
filename: '场站级评估-污染值报告',
|
||||||
sheetName: 'Sheet1',
|
sheetName: 'Sheet1',
|
||||||
type: 'xlsx',
|
type: 'xlsx',
|
||||||
useStyle: true,
|
useStyle: true,
|
||||||
|
|||||||
@@ -652,7 +652,7 @@ const initRadioCharts = () => {
|
|||||||
echartsData1.value.options.series[i].center = ['50%', '50%']
|
echartsData1.value.options.series[i].center = ['50%', '50%']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const initEcharts = (color: string, key: number) => {
|
const initEcharts = (color: string, key: number, name: string) => {
|
||||||
return {
|
return {
|
||||||
options: {
|
options: {
|
||||||
tooltip: {},
|
tooltip: {},
|
||||||
@@ -731,7 +731,7 @@ const initEcharts = (color: string, key: number) => {
|
|||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
value: 0,
|
value: 0,
|
||||||
name: 'A相',
|
name: name,
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: color
|
color: color
|
||||||
}
|
}
|
||||||
@@ -744,14 +744,14 @@ const initEcharts = (color: string, key: number) => {
|
|||||||
}
|
}
|
||||||
//渲染echarts
|
//渲染echarts
|
||||||
const init = () => {
|
const init = () => {
|
||||||
const url = (localStorage.getItem('WebSocketUrl') || 'ws://192.168.1.68:10407/api/pushMessage/')
|
const url = localStorage.getItem('WebSocketUrl') || 'ws://192.168.1.68:10407/api/pushMessage/'
|
||||||
echartsDataV1.value = initEcharts('#DAA520', 0)
|
echartsDataV1.value = initEcharts('#DAA520', 0, 'A相')
|
||||||
echartsDataV2.value = initEcharts('#2E8B57', 0)
|
echartsDataV2.value = initEcharts('#2E8B57', 0, 'B相')
|
||||||
echartsDataV3.value = initEcharts('#A52a2a', 0)
|
echartsDataV3.value = initEcharts('#A52a2a', 0, 'C相')
|
||||||
|
|
||||||
echartsDataA1.value = initEcharts('#DAA520', 1)
|
echartsDataA1.value = initEcharts('#DAA520', 1, 'A相')
|
||||||
echartsDataA2.value = initEcharts('#2E8B57', 1)
|
echartsDataA2.value = initEcharts('#2E8B57', 1, 'B相')
|
||||||
echartsDataA3.value = initEcharts('#A52a2a', 1)
|
echartsDataA3.value = initEcharts('#A52a2a', 1, 'C相')
|
||||||
|
|
||||||
if (!dataSocket.socketServe) {
|
if (!dataSocket.socketServe) {
|
||||||
console.error('WebSocket 客户端实例不存在')
|
console.error('WebSocket 客户端实例不存在')
|
||||||
@@ -764,9 +764,7 @@ const url = (localStorage.getItem('WebSocketUrl') || 'ws://192.168.1.68:10407/ap
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
let pids = monitoringPoint.state.pid.split(',')
|
let pids = monitoringPoint.state.pid.split(',')
|
||||||
dataSocket.socketServe.connect(
|
dataSocket.socketServe.connect(`${url}${adminInfo.id},${monitoringPoint.state.lineId},${pids[pids.length - 2]}`)
|
||||||
`${url}${adminInfo.id},${monitoringPoint.state.lineId},${pids[pids.length - 2]}`
|
|
||||||
)
|
|
||||||
dataSocket.socketServe.registerCallBack('message', (res: any) => {
|
dataSocket.socketServe.registerCallBack('message', (res: any) => {
|
||||||
txtContent.value = res.value
|
txtContent.value = res.value
|
||||||
let data = JSON.parse(res.value)
|
let data = JSON.parse(res.value)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,170 +1,172 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main" :style="height">
|
<div class="default-main" :style="height">
|
||||||
<splitpanes style="height: 100%" class="default-theme" id="navigation-splitpanes">
|
<splitpanes style="height: 100%" class="default-theme" id="navigation-splitpanes">
|
||||||
<pane :size="size">
|
<pane :size="size">
|
||||||
<PointTree
|
<PointTree
|
||||||
v-if="showTree"
|
v-if="showTree"
|
||||||
:default-expand-all="false"
|
:default-expand-all="false"
|
||||||
@node-click="handleNodeClick"
|
@node-click="handleNodeClick"
|
||||||
@init="handleNodeClick"
|
@init="handleNodeClick"
|
||||||
></PointTree>
|
></PointTree>
|
||||||
</pane>
|
</pane>
|
||||||
<pane style="background: #fff" :style="height">
|
<pane style="background: #fff" :style="height">
|
||||||
<TableHeader ref="TableHeaderRef" datePicker @selectChange="selectChange">
|
<TableHeader ref="TableHeaderRef" datePicker @selectChange="selectChange">
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="模板策略">
|
<el-form-item label="模板策略">
|
||||||
<el-select v-model="Template" @change="changetype" placeholder="请选择模版" value-key="id">
|
<el-select v-model="Template" @change="changetype" placeholder="请选择模版" value-key="id">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in templatePolicy"
|
v-for="item in templatePolicy"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
:value="item"
|
:value="item"
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="报表类型">
|
<el-form-item label="报表类型">
|
||||||
<el-input readonly type="text" value="分析报表"></el-input>
|
<el-input readonly type="text" value="分析报表"></el-input>
|
||||||
<!-- <el-select-->
|
<!-- <el-select-->
|
||||||
<!-- :disabled="true"-->
|
<!-- :disabled="true"-->
|
||||||
<!-- v-model="reportForm"-->
|
<!-- v-model="reportForm"-->
|
||||||
<!-- :popper-append-to-body="false"-->
|
<!-- :popper-append-to-body="false"-->
|
||||||
<!-- placeholder="请选择报表类型"-->
|
<!-- placeholder="请选择报表类型"-->
|
||||||
<!-- >-->
|
<!-- >-->
|
||||||
<!-- <el-option-->
|
<!-- <el-option-->
|
||||||
<!-- v-for="item in reportFormList"-->
|
<!-- v-for="item in reportFormList"-->
|
||||||
<!-- :key="item.value"-->
|
<!-- :key="item.value"-->
|
||||||
<!-- :label="item.label"-->
|
<!-- :label="item.label"-->
|
||||||
<!-- :value="item.value"-->
|
<!-- :value="item.value"-->
|
||||||
<!-- ></el-option>-->
|
<!-- ></el-option>-->
|
||||||
<!-- </el-select>-->
|
<!-- </el-select>-->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
<template #operation>
|
<template #operation>
|
||||||
<el-button icon="el-icon-Download" type="primary" @click="exportEvent">导出excel</el-button>
|
<el-button icon="el-icon-Download" type="primary" @click="exportEvent">导出excel</el-button>
|
||||||
</template>
|
</template>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div id="luckysheet" :style="`height: calc(${tableStore.table.height} + 45px)`"></div>
|
<div id="luckysheet" :style="`height: calc(${tableStore.table.height} + 45px)`"></div>
|
||||||
</div>
|
</div>
|
||||||
</pane>
|
</pane>
|
||||||
</splitpanes>
|
</splitpanes>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref, provide } from 'vue'
|
import { onMounted, ref, provide } from 'vue'
|
||||||
import 'splitpanes/dist/splitpanes.css'
|
import 'splitpanes/dist/splitpanes.css'
|
||||||
import { Splitpanes, Pane } from 'splitpanes'
|
import { Splitpanes, Pane } from 'splitpanes'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import PointTree from '@/components/tree/pqs/pointTree.vue'
|
import PointTree from '@/components/tree/pqs/pointTree.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import { useDictData } from '@/stores/dictData'
|
import { useDictData } from '@/stores/dictData'
|
||||||
import { mainHeight } from '@/utils/layout'
|
import { mainHeight } from '@/utils/layout'
|
||||||
import { getTemplateByDept } from '@/api/harmonic-boot/luckyexcel'
|
import { getTemplateByDept } from '@/api/harmonic-boot/luckyexcel'
|
||||||
import { exportExcel } from '@/views/system/reportForms/export.js'
|
import { exportExcel } from '@/views/system/reportForms/export.js'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'harmonic-boot/xieboReport'
|
name: 'harmonic-boot/xieboReport'
|
||||||
})
|
})
|
||||||
const showTree = ref(false)
|
const showTree = ref(false)
|
||||||
const height = mainHeight(20)
|
const height = mainHeight(20)
|
||||||
const size = ref(0)
|
const size = ref(0)
|
||||||
const dictData = useDictData()
|
const dictData = useDictData()
|
||||||
const TableHeaderRef = ref()
|
const TableHeaderRef = ref()
|
||||||
const dotList: any = ref({})
|
const dotList: any = ref({})
|
||||||
const Template: any = ref({})
|
const Template: any = ref({})
|
||||||
const reportForm: any = ref('')
|
const reportForm: any = ref('')
|
||||||
|
|
||||||
const templatePolicy: any = ref([])
|
const templatePolicy: any = ref([])
|
||||||
const reportFormList: any = ref([
|
const reportFormList: any = ref([
|
||||||
{
|
{
|
||||||
value: '1',
|
value: '1',
|
||||||
label: '分析报表'
|
label: '分析报表'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: '2',
|
value: '2',
|
||||||
label: '统计报表'
|
label: '统计报表'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: '3',
|
value: '3',
|
||||||
label: '自定义报表'
|
label: '自定义报表'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const tableStore = new TableStore({
|
const tableStore = new TableStore({
|
||||||
url: '/harmonic-boot/customReport/getCustomReport',
|
url: '/harmonic-boot/customReport/getCustomReport',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.tempId = Template.value.id
|
tableStore.table.params.tempId = Template.value.id
|
||||||
tableStore.table.params.lineId = dotList.value.id
|
tableStore.table.params.lineId = dotList.value.id
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data.forEach((item: any) => {
|
tableStore.table.data.forEach((item: any) => {
|
||||||
item.data1 ? (item.data = JSON.parse(item.data1)) : ''
|
item.data1 ? (item.data = JSON.parse(item.data1)) : ''
|
||||||
item.celldata.forEach((k: any) => {
|
item.celldata.forEach((k: any) => {
|
||||||
item.data[k.r][k.c].v ? (item.data[k.r][k.c] = k.v) : ''
|
item.data[k.r][k.c].v ? (item.data[k.r][k.c] = k.v) : ''
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
console.log(tableStore.table.data)
|
console.log(tableStore.table.data)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
luckysheet.create({
|
luckysheet.create({
|
||||||
container: 'luckysheet',
|
container: 'luckysheet',
|
||||||
title: '', // 表 头名
|
title: '', // 表 头名
|
||||||
lang: 'zh', // 中文
|
lang: 'zh', // 中文
|
||||||
showtoolbar: false, // 是否显示工具栏
|
showtoolbar: false, // 是否显示工具栏
|
||||||
showinfobar: false, // 是否显示顶部信息栏
|
showinfobar: false, // 是否显示顶部信息栏
|
||||||
showsheetbar: true, // 是否显示底部sheet按钮
|
showsheetbar: true, // 是否显示底部sheet按钮
|
||||||
data: tableStore.table.data
|
allowEdit: false, // 禁止所有编辑操作(必填)
|
||||||
})
|
data: tableStore.table.data
|
||||||
}, 10)
|
})
|
||||||
}
|
}, 10)
|
||||||
})
|
}
|
||||||
provide('tableStore', tableStore)
|
})
|
||||||
|
provide('tableStore', tableStore)
|
||||||
onMounted(() => {
|
|
||||||
const dom = document.getElementById('navigation-splitpanes')
|
onMounted(() => {
|
||||||
if (dom) {
|
const dom = document.getElementById('navigation-splitpanes')
|
||||||
size.value = Math.round((180 / dom.offsetHeight) * 100)
|
if (dom) {
|
||||||
}
|
size.value = Math.round((180 / dom.offsetHeight) * 100)
|
||||||
})
|
}
|
||||||
getTemplateByDept({ id: dictData.state.area[0].id })
|
})
|
||||||
.then((res: any) => {
|
getTemplateByDept({ id: dictData.state.area[0].id })
|
||||||
templatePolicy.value = res.data
|
.then((res: any) => {
|
||||||
Template.value = res.data[0]
|
templatePolicy.value = res.data
|
||||||
reportForm.value = res.data[0]?.reportForm
|
Template.value = res.data[0]
|
||||||
showTree.value = true
|
reportForm.value = res.data[0]?.reportForm
|
||||||
})
|
showTree.value = true
|
||||||
.catch((err: any) => {
|
})
|
||||||
showTree.value = true
|
.catch((err: any) => {
|
||||||
})
|
showTree.value = true
|
||||||
const changetype = (val: any) => {
|
})
|
||||||
reportForm.value = val.reportForm
|
const changetype = (val: any) => {
|
||||||
}
|
reportForm.value = val.reportForm
|
||||||
const selectChange = () => {
|
}
|
||||||
console.log('🚀 ~ selectChange ~ tableStore.table.data.lnegth :', tableStore.table.data.length)
|
const selectChange = () => {
|
||||||
if (tableStore.table.data.length != 0) {
|
console.log('🚀 ~ selectChange ~ tableStore.table.data.lnegth :', tableStore.table.data.length)
|
||||||
setTimeout(() => {
|
if (tableStore.table.data.length != 0) {
|
||||||
luckysheet && luckysheet?.resize()
|
setTimeout(() => {
|
||||||
}, 10)
|
luckysheet && luckysheet?.resize()
|
||||||
}
|
}, 10)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
const handleNodeClick = (data: any, node: any) => {
|
|
||||||
if (data.level == 6) {
|
const handleNodeClick = (data: any, node: any) => {
|
||||||
dotList.value = data
|
if (data.level == 6) {
|
||||||
tableStore.index()
|
dotList.value = data
|
||||||
}
|
tableStore.index()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
const exportEvent = () => {
|
|
||||||
exportExcel(luckysheet.getAllSheets(), '统计报表下载')
|
const exportEvent = () => {
|
||||||
}
|
exportExcel(luckysheet.getAllSheets(), '统计报表下载')
|
||||||
</script>
|
}
|
||||||
<style lang="scss">
|
</script>
|
||||||
.splitpanes.default-theme .splitpanes__pane {
|
<style lang="scss">
|
||||||
background: #eaeef1;
|
.splitpanes.default-theme .splitpanes__pane {
|
||||||
}
|
background: #eaeef1;
|
||||||
|
}
|
||||||
.box {
|
|
||||||
padding: 10px;
|
.box {
|
||||||
}
|
padding: 10px;
|
||||||
</style>
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,338 +1,338 @@
|
|||||||
<template>
|
<template>
|
||||||
<div @keyup.enter="onSubmit(formRef)">
|
<div @keyup.enter="onSubmit(formRef)">
|
||||||
<div @contextmenu.stop="" id="bubble" class="bubble">
|
<div @contextmenu.stop="" id="bubble" class="bubble">
|
||||||
<canvas id="bubble-canvas" class="bubble-canvas"></canvas>
|
<canvas id="bubble-canvas" class="bubble-canvas"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<div class="login-image"></div>
|
<div class="login-image"></div>
|
||||||
<div class="login-container-form">
|
<div class="login-container-form">
|
||||||
<div class="title-container">
|
<div class="title-container">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<span style="font-size: 28px">{{ getThemeList.name || '电能质量监测系统' }}</span>
|
<span style="font-size: 28px">{{ getThemeList.name || '电能质量监测系统' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-form :rules="rules" ref="formRef" size="large" class="login-form" :model="form">
|
<el-form :rules="rules" ref="formRef" size="large" class="login-form" :model="form">
|
||||||
<el-form-item prop="username">
|
<el-form-item prop="username">
|
||||||
<el-input
|
<el-input
|
||||||
ref="usernameRef"
|
ref="usernameRef"
|
||||||
v-model="form.username"
|
v-model="form.username"
|
||||||
type="text"
|
type="text"
|
||||||
clearable
|
clearable
|
||||||
placeholder="用户名"
|
placeholder="用户名"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<!-- <span class="iconfont icon-yonghu" style="color: var(--el-color-primary)"></span> -->
|
<!-- <span class="iconfont icon-yonghu" style="color: var(--el-color-primary)"></span> -->
|
||||||
<Icon name="fa fa-user" style="color: var(--el-color-primary); font-size: 16px" />
|
<Icon name="fa fa-user" style="color: var(--el-color-primary); font-size: 16px" />
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="password">
|
<el-form-item prop="password">
|
||||||
<el-input
|
<el-input
|
||||||
ref="passwordRef"
|
ref="passwordRef"
|
||||||
v-model="form.password"
|
v-model="form.password"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="密码"
|
placeholder="密码"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<Icon name="local-password" style="color: var(--el-color-primary); font-size: 16px" />
|
<Icon name="local-password" style="color: var(--el-color-primary); font-size: 16px" />
|
||||||
<!-- <span class="iconfont icon-mima" style="color: var(--el-color-primary)"></span> -->
|
<!-- <span class="iconfont icon-mima" style="color: var(--el-color-primary)"></span> -->
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button
|
<el-button
|
||||||
:loading="state.submitLoading"
|
:loading="state.submitLoading"
|
||||||
class="submit-btn"
|
class="submit-btn"
|
||||||
round
|
round
|
||||||
type="info"
|
type="info"
|
||||||
@click="onSubmit(formRef)"
|
@click="onSubmit(formRef)"
|
||||||
>
|
>
|
||||||
登录
|
登录
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="copy-right">
|
<!-- <div class="copy-right">
|
||||||
<span>版权所有 @ 南京灿能电力自动化股份有限公司</span>
|
<span>版权所有 @ 南京灿能电力自动化股份有限公司</span>
|
||||||
<br />
|
<br />
|
||||||
<img style="width: 20px; height: 20px; position: absolute" src="@/assets/login/jhui.png" />
|
<img style="width: 20px; height: 20px; position: absolute" src="@/assets/login/jhui.png" />
|
||||||
|
|
||||||
<span> 苏公网安备 32011502011902号</span>
|
<span> 苏公网安备 32011502011902号</span>
|
||||||
</div> -->
|
</div> -->
|
||||||
<PopupUpdatePwd ref="popupUpdatePwdRef"></PopupUpdatePwd>
|
<PopupUpdatePwd ref="popupUpdatePwdRef"></PopupUpdatePwd>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onBeforeUnmount, reactive, ref, nextTick } from 'vue'
|
import { onMounted, onBeforeUnmount, reactive, ref, nextTick } from 'vue'
|
||||||
import * as pageBubble from '@/utils/pageBubble'
|
import * as pageBubble from '@/utils/pageBubble'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { gongkey, login,getSysConfig } from '@/api/user-boot/user'
|
import { gongkey, login,getSysConfig } from '@/api/user-boot/user'
|
||||||
import { useAdminInfo } from '@/stores/adminInfo'
|
import { useAdminInfo } from '@/stores/adminInfo'
|
||||||
import type { FormInstance, InputInstance, FormRules } from 'element-plus'
|
import type { FormInstance, InputInstance, FormRules } from 'element-plus'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { ADMIN_INFO } from '@/stores/constant/cacheKey'
|
import { ADMIN_INFO } from '@/stores/constant/cacheKey'
|
||||||
import { Local } from '@/utils/storage'
|
import { Local } from '@/utils/storage'
|
||||||
import { getTheme } from '@/api/systerm'
|
import { getTheme } from '@/api/systerm'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import PopupUpdatePwd from './popupUpdatePwd.vue'
|
import PopupUpdatePwd from './popupUpdatePwd.vue'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
let timer: number
|
let timer: number
|
||||||
const configStore = useConfig()
|
const configStore = useConfig()
|
||||||
const popupUpdatePwdRef = ref()
|
const popupUpdatePwdRef = ref()
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
const usernameRef = ref<InputInstance>()
|
const usernameRef = ref<InputInstance>()
|
||||||
const passwordRef = ref<InputInstance>()
|
const passwordRef = ref<InputInstance>()
|
||||||
const userInfo = useAdminInfo()
|
const userInfo = useAdminInfo()
|
||||||
Local.remove(ADMIN_INFO)
|
Local.remove(ADMIN_INFO)
|
||||||
userInfo.removeToken()
|
userInfo.removeToken()
|
||||||
const getThemeList: any = ref([])
|
const getThemeList: any = ref([])
|
||||||
interface RuleForm {
|
interface RuleForm {
|
||||||
username: string
|
username: string
|
||||||
password: string
|
password: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
showCaptcha: false,
|
showCaptcha: false,
|
||||||
submitLoading: false
|
submitLoading: false
|
||||||
})
|
})
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
username: '',
|
username: '',
|
||||||
password: ''
|
password: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
const rules = reactive<FormRules<RuleForm>>({
|
const rules = reactive<FormRules<RuleForm>>({
|
||||||
username: [{ required: true, trigger: 'blur', message: '请输入用户名' }],
|
username: [{ required: true, trigger: 'blur', message: '请输入用户名' }],
|
||||||
password: [{ required: true, trigger: 'blur', message: '请输入密码' }]
|
password: [{ required: true, trigger: 'blur', message: '请输入密码' }]
|
||||||
})
|
})
|
||||||
|
|
||||||
const focusInput = () => {
|
const focusInput = () => {
|
||||||
if (form.username === '') {
|
if (form.username === '') {
|
||||||
usernameRef.value!.focus()
|
usernameRef.value!.focus()
|
||||||
} else if (form.password === '') {
|
} else if (form.password === '') {
|
||||||
passwordRef.value!.focus()
|
passwordRef.value!.focus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
timer = window.setTimeout(() => {
|
timer = window.setTimeout(() => {
|
||||||
pageBubble.init()
|
pageBubble.init()
|
||||||
}, 0)
|
}, 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
clearTimeout(timer)
|
clearTimeout(timer)
|
||||||
pageBubble.removeListeners()
|
pageBubble.removeListeners()
|
||||||
})
|
})
|
||||||
getTheme().then(res => {
|
getTheme().then(res => {
|
||||||
document.title = res.data.name || '电能质量在线监测系统'
|
document.title = res.data.name || '电能质量在线监测系统'
|
||||||
|
|
||||||
let list: any = [
|
let list: any = [
|
||||||
'elementUiPrimary',
|
'elementUiPrimary',
|
||||||
'tableHeaderBackground',
|
'tableHeaderBackground',
|
||||||
'tableHeaderColor',
|
'tableHeaderColor',
|
||||||
'tableCurrent',
|
'tableCurrent',
|
||||||
'menuBackground',
|
'menuBackground',
|
||||||
'menuColor',
|
'menuColor',
|
||||||
'menuTopBarBackground',
|
'menuTopBarBackground',
|
||||||
'menuActiveBackground',
|
'menuActiveBackground',
|
||||||
'menuActiveColor',
|
'menuActiveColor',
|
||||||
'headerBarTabColor',
|
'headerBarTabColor',
|
||||||
'headerBarBackground'
|
'headerBarBackground'
|
||||||
]
|
]
|
||||||
getThemeList.value = res.data
|
getThemeList.value = res.data
|
||||||
window.localStorage.setItem('getTheme', JSON.stringify(res.data))
|
window.localStorage.setItem('getTheme', JSON.stringify(res.data))
|
||||||
for (let i = 0; i < list.length; i++) {
|
for (let i = 0; i < list.length; i++) {
|
||||||
configStore.setLayout(list[i], JSON.parse(res.data[list[i]]))
|
configStore.setLayout(list[i], JSON.parse(res.data[list[i]]))
|
||||||
}
|
}
|
||||||
configStore.setLayout('elementUiPrimary', JSON.parse(res.data['elementUiPrimary']))
|
configStore.setLayout('elementUiPrimary', JSON.parse(res.data['elementUiPrimary']))
|
||||||
})
|
})
|
||||||
const onSubmit = async (formEl: FormInstance | undefined) => {
|
const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
await formEl.validate((valid, fields) => {
|
await formEl.validate((valid, fields) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
state.submitLoading = true
|
state.submitLoading = true
|
||||||
login({
|
login({
|
||||||
username: form.username,
|
username: form.username,
|
||||||
password: form.password,
|
password: form.password,
|
||||||
grant_type: 'captcha',
|
grant_type: 'captcha',
|
||||||
imageCode: '',
|
imageCode: '',
|
||||||
verifyCode: 0
|
verifyCode: 0
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
userInfo.dataFill(res.data)
|
userInfo.dataFill(res.data)
|
||||||
state.submitLoading = false
|
state.submitLoading = false
|
||||||
getSysConfig().then(res => {
|
getSysConfig().then(res => {
|
||||||
window.localStorage.setItem('sysdata', JSON.stringify(res.data))
|
window.localStorage.setItem('sysdata', JSON.stringify(res.data))
|
||||||
})
|
})
|
||||||
router.push({
|
router.push({
|
||||||
path: '/'
|
path: '/'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
if (err.code === 'A0101' && err.message === '登录认证,密码失效,请重置') {
|
if (err.code === 'A0101' && err.message === '登录认证,密码失效,请重置') {
|
||||||
popupUpdatePwdRef.value.open(form.username)
|
popupUpdatePwdRef.value.open(form.username)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
state.submitLoading = false
|
state.submitLoading = false
|
||||||
}, 500)
|
}, 500)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.bubble {
|
.bubble {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: var(--el-color-primary) !important;
|
background-color: var(--el-color-primary) !important;
|
||||||
background-position: center 110px;
|
background-position: center 110px;
|
||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
background-image: url(https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg);
|
background-image: url(https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-image {
|
.login-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 20%;
|
left: 20%;
|
||||||
min-width: 45%;
|
min-width: 45%;
|
||||||
min-height: 80%;
|
min-height: 80%;
|
||||||
|
|
||||||
background: url('../../assets/login/login2.png') no-repeat center center;
|
background: url('../../assets/login/login2.png') no-repeat center center;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
transform: translate(-15%, -50%);
|
transform: translate(-15%, -50%);
|
||||||
// box-shadow: 0 0 0 #011b2bab;
|
// box-shadow: 0 0 0 #011b2bab;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-item-icon {
|
.form-item-icon {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-container-form {
|
.login-container-form {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 85%;
|
left: 85%;
|
||||||
width: 500px;
|
width: 500px;
|
||||||
height: auto;
|
height: auto;
|
||||||
border-radius: 30px;
|
border-radius: 30px;
|
||||||
transform: translate(-85%, -50%);
|
transform: translate(-85%, -50%);
|
||||||
box-shadow: 3px 3px 2px 2px #011b2bab;
|
box-shadow: 3px 3px 2px 2px #011b2bab;
|
||||||
|
|
||||||
.title-container {
|
.title-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 398px;
|
width: 398px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
padding: 20px 0 0;
|
padding: 20px 0 0;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
font-size: 33px;
|
font-size: 33px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: rgba(255, 255, 255, 0.85);
|
color: rgba(255, 255, 255, 0.85);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
& :v-deep .svg-icon {
|
& :v-deep .svg-icon {
|
||||||
// color: $;
|
// color: $;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
width: 46px;
|
width: 46px;
|
||||||
height: 46px;
|
height: 46px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-form {
|
.login-form {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 368px;
|
width: 368px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
//padding: 20px 0 0;
|
//padding: 20px 0 0;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&.el-input {
|
&.el-input {
|
||||||
input {
|
input {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
padding-right: 40px;
|
padding-right: 40px;
|
||||||
padding-left: 40px;
|
padding-left: 40px;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input__prefix,
|
.el-input__prefix,
|
||||||
.el-input__suffix {
|
.el-input__suffix {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
|
|
||||||
.svg-icon {
|
.svg-icon {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
vertical-align: -0.25em;
|
vertical-align: -0.25em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input__prefix {
|
.el-input__prefix {
|
||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input__suffix {
|
.el-input__suffix {
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.copy-right {
|
.copy-right {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: rgb(233, 229, 229);
|
color: rgb(233, 229, 229);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
:v-deep.el-form-item--large {
|
:v-deep.el-form-item--large {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.submit-btn {
|
.submit-btn {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
background: var(--el-color-primary-light-3);
|
background: var(--el-color-primary-light-3);
|
||||||
// background: #009688;
|
// background: #009688;
|
||||||
//background: #4d6ea1;
|
//background: #4d6ea1;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--el-color-primary-light-5);
|
background: var(--el-color-primary-light-5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 720px) {
|
@media screen and (max-width: 720px) {
|
||||||
.login {
|
.login {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.login-box {
|
.login-box {
|
||||||
width: 340px;
|
width: 340px;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-height: 800px) {
|
@media screen and (max-height: 800px) {
|
||||||
.login .login-box {
|
.login .login-box {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user