台账调整、用户调整

This commit is contained in:
GGJ
2025-03-24 18:26:50 +08:00
parent 1154b7e69c
commit d4c7a9b0ca
17 changed files with 3585 additions and 124 deletions

View File

@@ -110,3 +110,11 @@ export function selectDown() {
method: 'get' method: 'get'
}) })
} }
//获取用户大类小类
export function queryAllByType(params: any) {
return createAxios({
url: '/system-boot/dictTree/queryAllByType',
method: 'get',
params
})
}

View File

@@ -54,6 +54,54 @@
<div class="content unicode" style="display: block;"> <div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe6fb;</span>
<div class="name">异常</div>
<div class="code-name">&amp;#xe6fb;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe65e;</span>
<div class="name">igw-f-warning-data</div>
<div class="code-name">&amp;#xe65e;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe708;</span>
<div class="name">收入占比</div>
<div class="code-name">&amp;#xe708;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe62a;</span>
<div class="name">企业总数</div>
<div class="code-name">&amp;#xe62a;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe606;</span>
<div class="name">异常</div>
<div class="code-name">&amp;#xe606;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6b7;</span>
<div class="name">右箭头</div>
<div class="code-name">&amp;#xe6b7;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6f4;</span>
<div class="name">监控频率</div>
<div class="code-name">&amp;#xe6f4;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe615;</span>
<div class="name">返回</div>
<div class="code-name">&amp;#xe615;</div>
</li>
<li class="dib"> <li class="dib">
<span class="icon iconfont">&#xe635;</span> <span class="icon iconfont">&#xe635;</span>
<div class="name">密码</div> <div class="name">密码</div>
@@ -96,9 +144,9 @@
<pre><code class="language-css" <pre><code class="language-css"
>@font-face { >@font-face {
font-family: 'iconfont'; font-family: 'iconfont';
src: url('iconfont.woff2?t=1703485952035') format('woff2'), src: url('iconfont.woff2?t=1742784434631') format('woff2'),
url('iconfont.woff?t=1703485952035') format('woff'), url('iconfont.woff?t=1742784434631') format('woff'),
url('iconfont.ttf?t=1703485952035') format('truetype'); url('iconfont.ttf?t=1742784434631') format('truetype');
} }
</code></pre> </code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3> <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -124,6 +172,78 @@
<div class="content font-class"> <div class="content font-class">
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-yichang1"></span>
<div class="name">
异常
</div>
<div class="code-name">.icon-yichang1
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-igw-f-warning-data"></span>
<div class="name">
igw-f-warning-data
</div>
<div class="code-name">.icon-igw-f-warning-data
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-shouruzhanbi"></span>
<div class="name">
收入占比
</div>
<div class="code-name">.icon-shouruzhanbi
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-qiyezongshu"></span>
<div class="name">
企业总数
</div>
<div class="code-name">.icon-qiyezongshu
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-yichang"></span>
<div class="name">
异常
</div>
<div class="code-name">.icon-yichang
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-sanjiaoright"></span>
<div class="name">
右箭头
</div>
<div class="code-name">.icon-sanjiaoright
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-frequency"></span>
<div class="name">
监控频率
</div>
<div class="code-name">.icon-frequency
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-fanhui"></span>
<div class="name">
返回
</div>
<div class="code-name">.icon-fanhui
</div>
</li>
<li class="dib"> <li class="dib">
<span class="icon iconfont icon-mima"></span> <span class="icon iconfont icon-mima"></span>
<div class="name"> <div class="name">
@@ -187,6 +307,70 @@
<div class="content symbol"> <div class="content symbol">
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-yichang1"></use>
</svg>
<div class="name">异常</div>
<div class="code-name">#icon-yichang1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-igw-f-warning-data"></use>
</svg>
<div class="name">igw-f-warning-data</div>
<div class="code-name">#icon-igw-f-warning-data</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-shouruzhanbi"></use>
</svg>
<div class="name">收入占比</div>
<div class="code-name">#icon-shouruzhanbi</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-qiyezongshu"></use>
</svg>
<div class="name">企业总数</div>
<div class="code-name">#icon-qiyezongshu</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-yichang"></use>
</svg>
<div class="name">异常</div>
<div class="code-name">#icon-yichang</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-sanjiaoright"></use>
</svg>
<div class="name">右箭头</div>
<div class="code-name">#icon-sanjiaoright</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-frequency"></use>
</svg>
<div class="name">监控频率</div>
<div class="code-name">#icon-frequency</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-fanhui"></use>
</svg>
<div class="name">返回</div>
<div class="code-name">#icon-fanhui</div>
</li>
<li class="dib"> <li class="dib">
<svg class="icon svg-icon" aria-hidden="true"> <svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-mima"></use> <use xlink:href="#icon-mima"></use>

View File

@@ -1,8 +1,8 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 3482754 */ font-family: "iconfont"; /* Project id 3482754 */
src: url('iconfont.woff2?t=1703485952035') format('woff2'), src: url('iconfont.woff2?t=1742784434631') format('woff2'),
url('iconfont.woff?t=1703485952035') format('woff'), url('iconfont.woff?t=1742784434631') format('woff'),
url('iconfont.ttf?t=1703485952035') format('truetype'); url('iconfont.ttf?t=1742784434631') format('truetype');
} }
.iconfont { .iconfont {
@@ -13,6 +13,38 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-yichang1:before {
content: "\e6fb";
}
.icon-igw-f-warning-data:before {
content: "\e65e";
}
.icon-shouruzhanbi:before {
content: "\e708";
}
.icon-qiyezongshu:before {
content: "\e62a";
}
.icon-yichang:before {
content: "\e606";
}
.icon-sanjiaoright:before {
content: "\e6b7";
}
.icon-frequency:before {
content: "\e6f4";
}
.icon-fanhui:before {
content: "\e615";
}
.icon-mima:before { .icon-mima:before {
content: "\e635"; content: "\e635";
} }

File diff suppressed because one or more lines are too long

View File

@@ -5,6 +5,62 @@
"css_prefix_text": "icon-", "css_prefix_text": "icon-",
"description": "", "description": "",
"glyphs": [ "glyphs": [
{
"icon_id": "3238029",
"name": "异常",
"font_class": "yichang1",
"unicode": "e6fb",
"unicode_decimal": 59131
},
{
"icon_id": "27610878",
"name": "igw-f-warning-data",
"font_class": "igw-f-warning-data",
"unicode": "e65e",
"unicode_decimal": 58974
},
{
"icon_id": "3118154",
"name": "收入占比",
"font_class": "shouruzhanbi",
"unicode": "e708",
"unicode_decimal": 59144
},
{
"icon_id": "12494439",
"name": "企业总数",
"font_class": "qiyezongshu",
"unicode": "e62a",
"unicode_decimal": 58922
},
{
"icon_id": "7978112",
"name": "异常",
"font_class": "yichang",
"unicode": "e606",
"unicode_decimal": 58886
},
{
"icon_id": "781638",
"name": "右箭头",
"font_class": "sanjiaoright",
"unicode": "e6b7",
"unicode_decimal": 59063
},
{
"icon_id": "2075693",
"name": "监控频率",
"font_class": "frequency",
"unicode": "e6f4",
"unicode_decimal": 59124
},
{
"icon_id": "1725613",
"name": "返回",
"font_class": "fanhui",
"unicode": "e615",
"unicode_decimal": 58901
},
{ {
"icon_id": "8765228", "icon_id": "8765228",
"name": "密码", "name": "密码",

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
<svg t="1742540927351" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9114" width="32" height="32"><path d="M960 112v270h-50V162H114v220H64V112h896z m-50 750H114V642H64v270h896V642h-50v220z m-489-68.6l139.7-240.7L641.4 654 746 423.9l51.7 109.5h92.8v-50h-61.2L745.1 305 629.7 559l-75.4-94.7L434 671.5 290.4 230.6 184.8 483.5h-51.4v50h84.7l66.4-159.2L421 793.4z" p-id="9115"></path></svg>

After

Width:  |  Height:  |  Size: 432 B

View File

@@ -72,30 +72,30 @@ const info = (id: any) => {
} else { } else {
res.data.forEach((item: any) => { res.data.forEach((item: any) => {
item.icon = 'el-icon-Menu' item.icon = 'el-icon-Menu'
item.level = 0 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.level = 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.level = 200 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.level = 300 item4.level = (item4.level + 1) * 100
// arr.push(item4)
item4.children.forEach((item5: any) => { item4.children.forEach((item5: any) => {
item5.icon = 'el-icon-OfficeBuilding' item5.icon = 'el-icon-OfficeBuilding'
item5.level = 400 item5.plevel = item5.level
item5.level = (item5.level == 7 ? 4 : item5.level) * 100
item5.children.forEach((item6: any) => { item5.children.forEach((item6: any) => {
item6.icon = 'el-icon-Film' item6.icon = 'el-icon-Film'
item6.level = 500 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.level = 600 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.level = 700 item8.level = (item8.level + 1) * 100
}) })
}) })
}) })

View File

@@ -0,0 +1,179 @@
<template>
<el-dialog draggable width="1300px" class="cn-operate-dialog" v-model="dialogVisible" :title="title">
<div style="display: flex">
<el-tabs v-model="activeName" type="border-card" class="mr10" style="width: 450px">
<el-tab-pane label="异常监测点详情" name="first">
<div :style="height">
<vxe-table height="auto" :data="TableData" v-bind="defaultAttribute">
<vxe-column type="seq" title="序号" width="60px"></vxe-column>
<vxe-column field="time" title="日期">
<template #default="{ row }">
<span class="time">{{ row.time }}</span>
</template>
</vxe-column>
<vxe-column field="name" title="监测点名称" width="120px"></vxe-column>
<vxe-column field="fz" title="异常时间(分钟)" width="80px"></vxe-column>
</vxe-table>
</div>
</el-tab-pane>
</el-tabs>
<el-tabs v-model="activeName" type="border-card" style="width: 820px">
<el-tab-pane :label="`变电站1 > 测试监测点1_异常指标详情`" name="first">
<div :style="height">
<vxe-table height="auto" :data="TableData1" v-bind="defaultAttribute">
<vxe-column type="seq" title="序号" width="60px"></vxe-column>
<vxe-column field="time" title="时间" min-width="120px"></vxe-column>
<vxe-column field="indexType" title="指标类型" min-width="100px"></vxe-column>
<vxe-column field="phase" title="相别" width="60px"></vxe-column>
<vxe-column field="range" title="合理范围" min-width="60px"></vxe-column>
<vxe-column field="max" title="最大" width="60px"></vxe-column>
<vxe-column field="min" title="最小" width="60px"></vxe-column>
<vxe-column field="average" title="平均" width="60px"></vxe-column>
<vxe-column field="cp95" title="CP95" width="60px"></vxe-column>
</vxe-table>
</div>
</el-tab-pane>
</el-tabs>
</div>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref, inject } from 'vue'
import { reactive } from 'vue'
import { defaultAttribute } from '@/components/table/defaultAttribute'
import { ElMessage } from 'element-plus'
import TableStore from '@/utils/tableStore' // 若不是列表页面弹框可删除
import { mainHeight } from '@/utils/layout'
const dialogVisible = ref(false)
const height = mainHeight(10, 2)
const title = ref('')
const activeName = 'first'
const TableData = ref([
{
time: '2025-01-01',
name: '测试监测点1',
fz: 100
},
{
time: '2025-01-01',
name: '测试监测点2',
fz: 100
},
{
time: '2025-01-01',
name: '测试监测点3',
fz: 100
},
{
time: '2025-01-01',
name: '测试监测点4',
fz: 100
}
])
const TableData1 = ref([
{
num: 1,
time: '2025/01/01 11:10:00',
indexType: '频率',
phase: 'T',
range: '42.5~57.5',
max: '/',
min: '/',
average: 60,
cp95: '/'
},
{
num: 2,
time: '2025/01/01 11:20:00',
indexType: '频率',
phase: 'T',
range: '42.5~57.5',
max: '/',
min: '/',
average: 60,
cp95: '/'
},
{
num: 3,
time: '2025/01/01 11:30:00',
indexType: '频率',
phase: 'T',
range: '42.5~57.5',
max: 65,
min: 60,
average: 62,
cp95: 61
},
{
num: 4,
time: '2025/01/01 11:40:00',
indexType: '频率',
phase: 'T',
range: '42.5~57.5',
max: 65,
min: 60,
average: 62,
cp95: 61
},
{
num: 5,
time: '2025/01/01 11:50:00',
indexType: '相电压',
phase: 'A',
range: '42.5~57.5',
max: '/',
min: 290,
average: '/',
cp95: '/'
},
{
num: 6,
time: '2025/01/01 12:10:00',
indexType: '相电压',
phase: 'B',
range: '42.5~57.5',
max: 220,
min: 290,
average: 220,
cp95: 220
},
{
num: 7,
time: '2025/01/01 12:20:00',
indexType: '相电压',
phase: 'C',
range: '42.5~57.5',
max: '/',
min: 290,
average: '/',
cp95: '/'
},
{
num: 8,
time: '2025/01/01 12:30:00',
indexType: '相电压',
phase: 'A',
range: '42.5~57.5',
max: 220,
min: 290,
average: 220,
cp95: 220
}
])
const open = (data: anyObj) => {
title.value = data.name + '_异常详情展示'
dialogVisible.value = true
}
defineExpose({ open })
</script>
<style lang="scss" scoped>
.time {
color: var(--el-color-primary);
cursor: pointer;
text-decoration: underline;
text-underline-offset: 4px;
}
</style>

View File

@@ -0,0 +1,720 @@
<!--业务用户管理界面-->
<template>
<div class="default-main">
<TableHeader date-picker>
<template v-slot:select>
<el-form-item label="对象类型">
<el-select
v-model="tableStore.table.params.supvObjType"
clearable
style="width: 100%"
placeholder="请选择对象类型"
>
<el-option
v-for="item in supvObjTypeList"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-radio-group v-model="tableStore.table.params.radio">
<el-radio-button label="异常数据" value="1" />
<el-radio-button label="告警数据" value="2" />
</el-radio-group>
</el-form-item>
</template>
<template v-slot:operation></template>
</TableHeader>
<div class="card-list pd10">
<div class="monitoringPoints">
<el-card style="height: 140px">
<template #header>
<div class="card-header">
<span>监测点统计</span>
</div>
</template>
<div class="statistics">
<div class="divBox">
<span class="iconfont icon-qiyezongshu" style="color: #57bc6e"></span>
<span class="divBox_title">总数</span>
<span class="divBox_num" style="color: #57bc6e">400</span>
</div>
<div class="divBox" style="width: 190px">
<span class="iconfont icon-igw-f-warning-data" style="color: #fca955"></span>
<span class="divBox_title">异常监测点</span>
<span class="divBox_num" style="color: #fca955">200</span>
</div>
<div class="divBox">
<span class="iconfont icon-shouruzhanbi" style="color: #06b6a9"></span>
<span class="divBox_title">占比</span>
<span class="divBox_num" style="color: #06b6a9">50%</span>
</div>
</div>
<!-- <MyEchart :options="finish" style="height: 230px"></MyEchart> -->
</el-card>
<el-card class="mt10">
<template #header>
<div class="card-header">
<span>异常指标统计</span>
</div>
</template>
<div class="header">
<span style="width: 180px; text-align: left">指标名称</span>
<span style="flex: 1">合理范围</span>
<span style="width: 100px">异常测点</span>
</div>
<div :style="indicatorHeight" style="overflow-y: auto">
<div v-for="o in abnormal" class="abnormal mb10">
<span style="width: 180px; height: 24px">
<span
class="iconFont iconfont icon-yichang"
:style="{ color: o.quantity > 0 ? '#ff9800' : '' }"
></span>
{{ o.name }}
</span>
<span style="flex: 1; text-align: center">
<!-- 合理范围 -->
<span style="color: #388e3c" class="text">{{ o.range }}</span>
{{ o.unit }}
</span>
<span style="width: 100px; text-align: center">
<span
style="color: #ff9800; cursor: pointer; text-decoration: underline"
class="text"
@click="quantityClick(o)"
>
{{ o.quantity }}
</span>
</span>
</div>
</div>
</el-card>
</div>
<el-card class="detail ml10" :style="pageHeight">
<template #header>
<div class="card-header">
<span>异常详情统计</span>
</div>
</template>
<div style="height: 350px">
<MyEchart :options="options"></MyEchart>
</div>
<el-form :inline="true" class="form">
<el-form-item label="告警持续天数"></el-form-item>
<el-form-item label="告警阀值(天)">
<el-input-number v-model="tableStore.table.params.alarm" :min="0" :step="1" step-strictly />
</el-form-item>
<el-form-item label="预警阀值(天)">
<el-input-number
v-model="tableStore.table.params.earlyWarning"
:min="0"
:step="1"
step-strictly
/>
</el-form-item>
<el-form-item class="form_but">
<el-button type="primary" icon="el-icon-Refresh">更新</el-button>
<el-button type="primary" icon="el-icon-Download">导出</el-button>
</el-form-item>
</el-form>
<!--表格-->
<Table ref="tableRef"></Table>
</el-card>
</div>
<anomalyDetails ref="anomalyDetailsRef" />
</div>
</template>
<script setup lang="ts">
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { deleteDeploy } from '@/api/process-boot/bpm'
import { onMounted, provide, ref } from 'vue'
import { useDictData } from '@/stores/dictData'
import { ElMessage } from 'element-plus'
import { CaretRight } from '@element-plus/icons-vue'
import { mainHeight } from '@/utils/layout'
import MyEchart from '@/components/echarts/MyEchart.vue'
import anomalyDetails from './components/anomalyDetails.vue'
defineOptions({
name: 'BusinessAdministrator/TerminalManagement/cleaning'
})
const anomalyDetailsRef = ref()
const dictData = useDictData()
//字典获取监督对象类型
const supvObjTypeList = dictData.getBasicData('supv_obj_type')
const pageHeight = mainHeight(105)
const indicatorHeight = mainHeight(352)
const tableRef = ref()
const abnormal = ref([
{
name: '频率',
range: '42.5~57.5',
unit: '',
quantity: 11
},
{
name: '频率偏差',
range: '-7.5~7.5',
unit: '',
quantity: 0
},
{
name: '相(线)电压有效值',
range: '0~150%U',
unit: '',
quantity: 0
},
{
name: '电压偏差',
range: '-20%~20%',
unit: '',
quantity: 0
},
{
name: '电流有效值',
range: '大于CT一次变比',
unit: '',
quantity: 0
},
{
name: '单相功率因数',
range: '-1~1',
unit: '',
quantity: 0
},
{
name: '单相基波功率因数',
range: '-1~1',
unit: '',
quantity: 0
},
{
name: '三相功率因数',
range: '-1~1',
unit: '',
quantity: 0
},
{
name: '基波功率因数',
range: '-1~1',
unit: '',
quantity: 0
},
{
name: '电压总谐波畸变率',
range: '0~30%',
unit: '',
quantity: 0
},
{
name: '相(线)电压基波有效值',
range: '0~150%U',
unit: '',
quantity: 0
},
{
name: '相(线)电压基波相角',
range: '-180~180',
unit: '',
quantity: 0
},
{
name: '谐波电压含有率',
range: '0~30%',
unit: '',
quantity: 0
},
{
name: '谐波电压相角',
range: '-180~180',
unit: '',
quantity: 0
},
{
name: '间谐波电压含有率',
range: '0~30%',
unit: '',
quantity: 0
},
{
name: '正序、负序和零序电压',
range: '0~150%U',
unit: '',
quantity: 0
},
{
name: '负序电压不平衡度',
range: '0~40%',
unit: '',
quantity: 0
},
{
name: '零序电压不平衡度',
range: '0~40%',
unit: '',
quantity: 0
},
{
name: '电压波动',
range: '0~40%',
unit: '',
quantity: 0
},
{
name: '短时间闪变值',
range: '0~20',
unit: '',
quantity: 0
},
{
name: '长时间闪变值',
range: '0~20',
unit: '',
quantity: 0
},
{
name: '电压暂降特征幅值',
range: '0~90%',
unit: '',
quantity: 0
},
{
name: '电压暂升特征幅值',
range: '110%~180%',
unit: '',
quantity: 0
}
])
const tableStore = new TableStore({
url: '/user-boot/user/getAllUserSimpleList',
method: 'GET',
isWebPaging: true,
showPage: false,
publicHeight: 480,
column: [
{ title: '序号', width: 80 },
{
title: '监测点名称',
field: 'name',
type: 'html',
formatter: (row, column) => {
return `<div class="table_name">${row.cellValue}</div>`
}
},
{
title: '所属终端名称',
field: 'name1',
type: 'html',
formatter: (row, column) => {
return `<div class="table_name">${row.cellValue}</div>`
}
},
{
title: '所属电站',
field: 'name2',
type: 'html',
formatter: (row, column) => {
return `<div class="table_name">${row.cellValue}</div>`
}
},
{ title: '监测对象类型', field: 'name3' },
{ title: '监测对象名称', field: 'name4' },
{ title: '电压等级', field: 'name5' },
{
title: '异常天数',
field: 'name6',
type: 'html',
formatter: (row, column) => {
return `<div class="table_name">${row.cellValue}</div>`
}
},
{
title: '严重度',
field: 'name7',
render: 'tag',
custom: {
0: 'warning',
1: 'danger'
},
replaceValue: {
0: '预警',
1: '告警'
}
},
{
title: '操作',
width: '120',
render: 'buttons',
buttons: [
{
name: 'edit',
title: '工单',
type: 'primary',
icon: 'el-icon-Plus',
render: 'basicButton',
click: row => {}
}
]
}
],
loadCallback: () => {
tableStore.table.data = [
{
name: '测试监测点1',
name1: '025875',
name2: '测试变电站',
name3: '测试光伏电站',
name4: '测试光伏电站',
name5: '110',
name6: '1',
name7: '0'
},
{
name: '测试监测点1',
name1: '025875',
name2: '测试变电站',
name3: '测试光伏电站',
name4: '测试光伏电站',
name5: '110',
name6: '1',
name7: '0'
},
{
name: '测试监测点1',
name1: '025875',
name2: '测试变电站',
name3: '测试光伏电站',
name4: '测试光伏电站',
name5: '110',
name6: '1',
name7: '0'
},
{
name: '测试监测点1',
name1: '025875',
name2: '测试变电站',
name3: '测试光伏电站',
name4: '测试光伏电站',
name5: '110',
name6: '1',
name7: '0'
},
{
name: '测试监测点1',
name1: '025875',
name2: '测试变电站',
name3: '测试光伏电站',
name4: '测试光伏电站',
name5: '110',
name6: '1',
name7: '0'
},
{
name: '测试监测点1',
name1: '025875',
name2: '测试变电站',
name3: '测试光伏电站',
name4: '测试光伏电站',
name5: '110',
name6: '1',
name7: '1'
},
{
name: '测试监测点1',
name1: '025875',
name2: '测试变电站',
name3: '测试光伏电站',
name4: '测试光伏电站',
name5: '110',
name6: '1',
name7: '1'
}
]
}
})
var getvalue = 90
const options = ref({
title: {
text: '监测点异常情况(2025-03-01~2025-03-10)'
},
legend: {
show: false
},
xAxis: {
name: '时间',
axisLine: {
show: true
},
data: ['03-01', '03-02', '03-03', '03-04', '03-05', '03-06', '03-07', '03-08', '03-09', '03-10']
},
yAxis: {
name: '数量' // 给X轴加单位
},
grid: {},
options: {
series: [
{
name: '告警监测点数量',
type: 'bar',
data: [11, 11, 11, 11, 0, 0, 0, 0, 0, 0]
}
]
}
})
const finish = ref({
options: {
toolbox: null,
dataZoom: null,
angleAxis: {
show: false,
max: 155, //-45度到225度二者偏移值是270度除360度
type: 'value',
startAngle: 205, //极坐标初始角度
splitLine: {
show: false
}
},
radiusAxis: {
show: false,
type: 'category'
},
tooltip: {
show: false
},
legend: {
show: false
},
//圆环位置和大小
polar: {
center: ['70%', '60%'],
radius: '180%'
},
series: [
{
type: 'bar',
data: [
{
//上层圆环,显示数据
value: getvalue
}
],
barGap: '-100%', //柱间距离,上下两层圆环重合
coordinateSystem: 'polar',
roundCap: true, //顶端圆角
z: 3 //圆环层级同zindex
},
{
//下层圆环,显示最大值
type: 'bar',
data: [
{
value: 100,
itemStyle: {
color: '#ccc',
opacity: 1,
borderWidth: 0
}
}
],
barGap: '-100%',
coordinateSystem: 'polar',
roundCap: true,
z: 1
},
//仪表盘
{
type: 'gauge',
startAngle: 225, //起始角度,同极坐标
endAngle: -45, //终止角度,同极坐标
axisLine: {
show: false
},
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitLabel: {
show: false
},
pointer: {
// 分隔线
shadowColor: 'auto', //默认透明
shadowBlur: 5,
length: '50%',
width: '2',
show: false
},
itemStyle: {
color: '#1598FF',
borderColor: '#1598FF',
borderWidth: 6
},
detail: {
formatter: function (params) {
return `{wcl|占比\n}{number|${getvalue + '%'}}`
},
rich: {
number: {
fontSize: 25,
textAlign: 'center',
color: '#000'
},
wcl: {
fontSize: 16,
textAlign: 'center',
color: '#000'
}
},
color: '#000',
lineHeight: 30,
offsetCenter: ['0', '0']
},
center: ['70%', '60%'],
title: {
show: false
},
data: [
{
value: getvalue
}
]
}
]
}
})
tableStore.table.params.radio = '1'
tableStore.table.params.alarm = 5
tableStore.table.params.earlyWarning = 1
const quantityClick = (e: any) => {
anomalyDetailsRef.value.open(e)
}
onMounted(() => {
// 加载数据
tableStore.index()
})
tableStore.table.params.name = ''
provide('tableStore', tableStore)
</script>
<style lang="scss" scoped>
.card-list {
display: flex;
.monitoringPoints {
width: 560px;
position: relative;
.statistics {
display: flex;
flex-wrap: wrap;
.divBox {
margin: 0 10px 10px 0;
width: 160px;
height: 70px;
padding: 10px;
display: flex;
.iconfont {
font-size: 40px;
margin-right: 5px;
}
.divBox_title {
font-weight: 550;
}
.divBox_num {
font-size: 20px;
font-weight: 550;
margin-left: auto;
font-family: AlimamaDongFangDaKai;
}
align-items: center;
// text-align: center;
border-radius: 5px;
&:nth-child(1) {
background-color: #eef8f0;
}
&:nth-child(2) {
background-color: #fff6ed;
}
&:nth-child(3) {
background-color: #e5f8f6;
}
}
}
}
.detail {
flex: 1;
}
.abnormal {
width: 100%;
background-color: #f3f6f9;
border-radius: 5px;
display: flex;
// justify-content: space-between;
align-items: center;
padding: 5px 0px 5px 10px;
.text {
font-weight: 700;
font-size: 16px;
font-family: 'Source Code Pro', monospace;
// font-feature-settings: 'tnum';
}
}
}
.header {
display: flex;
text-align: center;
font-weight: 700;
padding: 5px;
}
:deep(.el-card__header) {
padding: 10px;
span {
font-weight: 600;
}
}
:deep(.el-card__body) {
padding: 10px;
}
.iconFont {
font-size: 18px;
display: inline-block;
vertical-align: middle;
}
.form {
position: relative;
.form_but {
position: absolute;
right: -22px;
}
}
.card-header {
font-size: 16px;
}
:deep(.table_name) {
color: var(--el-color-primary);
cursor: pointer;
text-decoration: underline;
text-underline-offset: 4px;
}
</style>

View File

@@ -49,7 +49,7 @@
修改提交 修改提交
</el-button> </el-button>
</el-form-item> </el-form-item>
<el-form-item style="right: 0; position: absolute;overflow: hidden;"> <el-form-item style="right: 0; position: absolute; overflow: hidden">
<div class="title"> <div class="title">
<LocationInformation style="width: 16px; margin-right: 8px; color: #396" /> <LocationInformation style="width: 16px; margin-right: 8px; color: #396" />
<span style="font-size: 16px; font-weight: bold; color: #396">当前操作节点</span> <span style="font-size: 16px; font-weight: bold; color: #396">当前操作节点</span>
@@ -737,12 +737,7 @@
" "
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item <el-form-item class="form-item" label="合同号:">
class="form-item"
label="合同号:"
:prop="'deviceParam.' + index + '.contract'"
:rules="[{ required: true, message: '请输入合同号', trigger: 'blur' }]"
>
<el-input <el-input
v-model="item.contract" v-model="item.contract"
placeholder="请输入合同号" placeholder="请输入合同号"
@@ -753,12 +748,7 @@
" "
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item <el-form-item class="form-item" label="ISM卡号:">
class="form-item"
label="ISM卡号:"
:prop="'deviceParam.' + index + '.sim'"
:rules="[{ required: true, message: '请输入ISM卡号', trigger: 'blur' }]"
>
<el-input <el-input
v-model="item.sim" v-model="item.sim"
placeholder="请输入ISM卡号" placeholder="请输入ISM卡号"
@@ -1042,11 +1032,72 @@
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item
<el-form-item class="form-item" label="新能源场站:"> class="form-item"
label="接线类型:"
:prop="
'deviceParam.' +
[deviceIndex] +
'.subVoltageParam.' +
[busBarIndex] +
'.lineParam.' +
lIndex +
'.ptType'
"
:rules="{ required: true, message: '请选择接线类型', trigger: 'blur' }"
>
<el-select
v-model="lineItem.ptType"
placeholder="请选择接线类型"
:disabled="pageStatus == 1"
>
<el-option
v-for="option in wiringTypeArr"
:key="option.name"
:label="option.name"
:value="option.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
class="form-item"
label="测量点性质:"
:prop="
'deviceParam.' +
[deviceIndex] +
'.subVoltageParam.' +
[busBarIndex] +
'.lineParam.' +
lIndex +
'.powerFlag'
"
:rules="{
required: true,
message: '请选择测量点性质',
trigger: 'blur'
}"
>
<el-select
v-model="lineItem.powerFlag"
placeholder="请选择测量点性质"
:disabled="pageStatus == 1"
>
<el-option
v-for="option in lineNatureArr"
:key="option.name"
:label="option.name"
:value="option.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
class="form-item"
label="用户名称:"
v-if="lineItem.powerFlag == 1"
>
<el-select <el-select
v-model="lineItem.newStationId" v-model="lineItem.newStationId"
placeholder="请选择新能源场站" placeholder="请选择用户名称"
:disabled="pageStatus == 1" :disabled="pageStatus == 1"
clearable clearable
> >
@@ -1207,33 +1258,7 @@
></el-input> ></el-input>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item
class="form-item"
label="接线类型:"
:prop="
'deviceParam.' +
[deviceIndex] +
'.subVoltageParam.' +
[busBarIndex] +
'.lineParam.' +
lIndex +
'.ptType'
"
:rules="{ required: true, message: '请选择接线类型', trigger: 'blur' }"
>
<el-select
v-model="lineItem.ptType"
placeholder="请选择接线类型"
:disabled="pageStatus == 1"
>
<el-option
v-for="option in wiringTypeArr"
:key="option.name"
:label="option.name"
:value="option.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item <el-form-item
class="form-item" class="form-item"
label="干扰源类型:" label="干扰源类型:"
@@ -1265,6 +1290,60 @@
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item
class="form-item"
label="用户大类:"
:prop="
'deviceParam.' +
[deviceIndex] +
'.subVoltageParam.' +
[busBarIndex] +
'.lineParam.' +
lIndex +
'.businessType'
"
:rules="{ required: true, message: '请选择用户大类', trigger: 'blur' }"
>
<el-select
v-model="lineItem.businessType"
placeholder="请选择用户大类"
:disabled="pageStatus == 1"
>
<el-option
v-for="option in industryTypeArr"
:key="option.id"
:label="option.name"
:value="option.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item
class="form-item"
label="用户小类:"
:prop="
'deviceParam.' +
[deviceIndex] +
'.subVoltageParam.' +
[busBarIndex] +
'.lineParam.' +
lIndex +
'.businessType'
"
:rules="{ required: true, message: '请选择用户小类', trigger: 'blur' }"
>
<el-select
v-model="lineItem.businessType"
placeholder="请选择用户小类"
:disabled="pageStatus == 1"
>
<el-option
v-for="option in industryTypeArr"
:key="option.id"
:label="option.name"
:value="option.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item <el-form-item
class="form-item" class="form-item"
label="行业类型:" label="行业类型:"
@@ -1354,37 +1433,7 @@
placeholder="请输入对象名称" placeholder="请输入对象名称"
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item
class="form-item"
label="测量点性质:"
:prop="
'deviceParam.' +
[deviceIndex] +
'.subVoltageParam.' +
[busBarIndex] +
'.lineParam.' +
lIndex +
'.powerFlag'
"
:rules="{
required: true,
message: '请选择测量点性质',
trigger: 'blur'
}"
>
<el-select
v-model="lineItem.powerFlag"
placeholder="请选择测量点性质"
:disabled="pageStatus == 1"
>
<el-option
v-for="option in lineNatureArr"
:key="option.name"
:label="option.name"
:value="option.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item <el-form-item
class="form-item" class="form-item"
label="电压上偏差:" label="电压上偏差:"
@@ -1489,27 +1538,10 @@
placeholder="请输入拥有者职务" placeholder="请输入拥有者职务"
></el-input> ></el-input>
</el-form-item> --> </el-form-item> -->
<el-form-item <el-form-item class="form-item" label="电网侧变电站:">
class="form-item"
label="电网侧变电站:"
:prop="
'deviceParam.' +
[deviceIndex] +
'.subVoltageParam.' +
[busBarIndex] +
'.lineParam.' +
lIndex +
'.powerSubstationName'
"
:rules="{
required: true,
message: '请输入电网侧变电站',
trigger: 'blur'
}"
>
<el-input <el-input
v-model="lineItem.powerSubstationName" v-model="lineItem.powerSubstationName"
:disabled="pageStatus == 1" disabled
placeholder="请输入电网侧变电站" placeholder="请输入电网侧变电站"
></el-input> ></el-input>
</el-form-item> </el-form-item>
@@ -1578,7 +1610,8 @@ import {
delTerminal, delTerminal,
updateTerminal, updateTerminal,
addTerminal, addTerminal,
selectDown selectDown,
queryAllByType
} from '@/api/device-boot/Business' } from '@/api/device-boot/Business'
import { useDictData } from '@/stores/dictData' import { useDictData } from '@/stores/dictData'
import { ref, reactive, onMounted } from 'vue' import { ref, reactive, onMounted } from 'vue'
@@ -2048,12 +2081,12 @@ const add = () => {
subStationParam.value.scale = voltageLevelArr[0].id subStationParam.value.scale = voltageLevelArr[0].id
monitorPointDetail.value.businessType = industryTypeArr[0].value monitorPointDetail.value.businessType = industryTypeArr[0].value
monitorPointDetail.value.loadType = loadTypeArr[0].id monitorPointDetail.value.loadType = loadTypeArr[0].id
const scrollBox:any = document.getElementById('scrollBox'); const scrollBox: any = document.getElementById('scrollBox')
// 使用 scrollTo 方法,并启用平滑滚动 // 使用 scrollTo 方法,并启用平滑滚动
scrollBox.scrollTo({ scrollBox.scrollTo({
top: scrollBox.scrollHeight, // 滚动到内容的最底部 top: scrollBox.scrollHeight, // 滚动到内容的最底部
behavior: 'smooth' // 启用平滑滚动动画 behavior: 'smooth' // 启用平滑滚动动画
}); })
} }
//变电站变化 //变电站变化
const subStationChange = (e: any) => { const subStationChange = (e: any) => {
@@ -2391,7 +2424,7 @@ const queryNodeContent = () => {
} }
let data = { let data = {
id: nodeData.value.id, id: nodeData.value.id,
level: nodeLevel.value level: nodeData.value.plevel == 7 ? '700' : nodeLevel.value
} }
queryTerminal(data).then(res => { queryTerminal(data).then(res => {
// console.log("内容详情", res); // console.log("内容详情", res);
@@ -2981,11 +3014,11 @@ area()
animation: scroll 10s linear infinite; /* 滚动动画 */ animation: scroll 10s linear infinite; /* 滚动动画 */
} }
@keyframes scroll { @keyframes scroll {
0% { 0% {
transform: translateX(100%); /* 从右侧开始 */ transform: translateX(100%); /* 从右侧开始 */
} }
100% { 100% {
transform: translateX(-160%); /* 滚动到左侧 */ transform: translateX(-160%); /* 滚动到左侧 */
} }
} }
</style> </style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,631 @@
<template>
<div class="default-main">
<el-descriptions :column="2" border>
<el-descriptions-item label="所在地市">
{{ detailData.city }}
</el-descriptions-item>
<el-descriptions-item label="项目名称">
{{ detailData.projectName }}
</el-descriptions-item>
<el-descriptions-item label="工程预期投产日期">
{{ formatDate(detailData.expectedProductionDate, 'YYYY-MM-DD') }}
</el-descriptions-item>
<el-descriptions-item label="用户性质">
{{
userTypeList.find(item => {
return item.value == detailData.userType
})?.label
}}
</el-descriptions-item>
<el-descriptions-item label="归口管理部门">
{{ detailData.responsibleDepartment }}
</el-descriptions-item>
<el-descriptions-item label="用户状态">
{{
userStateList.find(item => {
return item.value == detailData.userStatus
})?.label
}}
</el-descriptions-item>
<el-descriptions-item label="厂站名称">
{{ detailData.substation }}
</el-descriptions-item>
<el-descriptions-item label="电压等级">
{{
voltageLevelList.find(item => {
return item.id == detailData.voltageLevel
})?.name
}}
</el-descriptions-item>
<el-descriptions-item label="非线性终端类型" v-if="detailData.userType == 0 || detailData.userType == 1">
{{ proviteData.nonlinearDeviceType ? proviteData.nonlinearDeviceType : '-' }}
</el-descriptions-item>
<el-descriptions-item label="预测评估单位">
{{ detailData.evaluationDept }}
</el-descriptions-item>
<el-descriptions-item label="预测评估结论" :span="2">
{{ detailData.evaluationConclusion }}
</el-descriptions-item>
<el-descriptions-item
:label="
detailData.userType == '4' || detailData.userType == '5' ? '非线性设备类型: ' : '非线性负荷类型:'
"
v-if="
detailData.userType == '2' ||
detailData.userType == '3' ||
detailData.userType == '4' ||
detailData.userType == '5'
"
>
{{ proviteData.nonlinearLoadType }}
</el-descriptions-item>
<el-descriptions-item label="是否需要治理">
<span v-if="detailData.userType == 0 || detailData.userType == 1">
{{ proviteData.needGovernance == 0 ? '否' : '是' }}
</span>
<span
v-if="
detailData.userType == 2 ||
detailData.userType == 3 ||
detailData.userType == 4 ||
detailData.userType == 5
"
>
{{ proviteData.needGovernance == 0 ? '否' : '是' }}
</span>
<span v-if="detailData.userType == 6">{{ proviteData.needGovernance == 0 ? '否' : '是' }}</span>
</el-descriptions-item>
<el-descriptions-item label="是否开展背景测试">
<span v-if="detailData.userType == 0 || detailData.userType == 1">
{{ proviteData.backgroundTestPerformed == 0 ? '否' : '是' }}
</span>
<span
v-if="
detailData.userType == 2 ||
detailData.userType == 3 ||
detailData.userType == 4 ||
detailData.userType == 5
"
>
{{ proviteData.backgroundTestPerformed == 0 ? '否' : '是' }}
</span>
<span v-if="detailData.userType == 6">
{{ proviteData.backgroundTestPerformed == 0 ? '否' : '是' }}
</span>
</el-descriptions-item>
<el-descriptions-item label="是否开展抗扰度测试" v-if="detailData.userType == 6">
<span>
{{ proviteData.antiInterferenceTest == 0 ? '否' : '是' }}
</span>
</el-descriptions-item>
<el-descriptions-item
label="用户协议容量MVA"
v-if="detailData.userType == 0 || detailData.userType == 1"
>
{{ proviteData.agreementCapacity }}
</el-descriptions-item>
<el-descriptions-item
label="PCC供电设备容量MVA"
v-if="
detailData.userType == '2' ||
detailData.userType == '3' ||
detailData.userType == '4' ||
detailData.userType == '5'
"
>
{{ proviteData.pccEquipmentCapacity }}
</el-descriptions-item>
<el-descriptions-item
label="基准短路容量MVA"
v-if="
detailData.userType == '2' ||
detailData.userType == '3' ||
detailData.userType == '4' ||
detailData.userType == '5'
"
>
{{ proviteData.baseShortCircuitCapacity }}
</el-descriptions-item>
<el-descriptions-item
label="系统最小短路容量MVA"
v-if="
detailData.userType == '2' ||
detailData.userType == '3' ||
detailData.userType == '4' ||
detailData.userType == '5'
"
>
{{ proviteData?.minShortCircuitCapacity }}
</el-descriptions-item>
<el-descriptions-item
label="用户用电协议容量MVA"
v-if="
detailData.userType == '2' ||
detailData.userType == '3' ||
detailData.userType == '4' ||
detailData.userType == '5'
"
>
{{ proviteData?.userAgreementCapacity }}
</el-descriptions-item>
<el-descriptions-item label="PCC点" v-if="detailData.userType != 0 && detailData.userType != 1">
{{ proviteData?.pccPoint }}
</el-descriptions-item>
<el-descriptions-item label="评估类型" v-if="detailData.userType != 0 && detailData.userType != 1">
{{
evaluationTypeList.find(item => {
return item.id == proviteData?.evaluationType
})?.name
}}
</el-descriptions-item>
<el-descriptions-item label="预测评估评审单位" v-if="detailData.userType != 0 && detailData.userType != 1">
{{ proviteData?.evaluationChekDept }}
</el-descriptions-item>
<el-descriptions-item label="行业" v-if="detailData.userType == 6">
{{
industryList.find(item => {
return item.id == proviteData.industry
})?.name
}}
</el-descriptions-item>
<el-descriptions-item label="敏感终端名称" v-if="detailData.userType == 6">
{{ proviteData.deviceName }}
</el-descriptions-item>
<!-- <el-descriptions-item label="供电电源数量" v-if="detailData.userType == 6">-->
<!-- {{ proviteData.powerSupplyCount }}-->
<!-- </el-descriptions-item>-->
<el-descriptions-item label="供电电源情况" v-if="detailData.userType == 6">
{{
powerSupplyInfoOptionList.find(item => {
return item.id == proviteData.powerSupplyInfo
})?.name
}}
</el-descriptions-item>
<el-descriptions-item label="供电电源" :span="2" v-if="detailData.userType == 6">
{{ proviteData.powerSupply }}
</el-descriptions-item>
<el-descriptions-item label="负荷级别" v-if="detailData.userType == 6">
{{
loadLevelOptionList.find(item => {
return item.id == proviteData.loadLevel
})?.name
}}
</el-descriptions-item>
<el-descriptions-item label="敏感电能质量指标" v-if="detailData.userType == 6">
{{
energyQualityIndexList.find(item => {
return item.id == proviteData.energyQualityIndex
})?.name
}}
</el-descriptions-item>
</el-descriptions>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref, reactive, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { formatDate } from '@/utils/formatTime'
import { propTypes } from '@/utils/propTypes'
import { getUserReportById, getUserReportUpdateById } from '@/api/supervision-boot/userReport/form'
import { getDictTreeById } from '@/api/system-boot/dictTree'
import { useDictData } from '@/stores/dictData'
import { getFileNameAndFilePath } from '@/api/system-boot/file'
import { Link, View } from '@element-plus/icons-vue'
import PreviewFile from '@/components/PreviewFile/index.vue'
import { getByDeptDevLine } from '@/api/supervision-boot/interfere/index'
import { addOrUpdateFile, getFileById } from '@/api/supervision-boot/interfere/index'
defineOptions({ name: 'BpmUserReportDetail' })
const { query } = useRoute() // 查询参数
const props = defineProps({
id: propTypes.string.def(undefined),
update: {
type: Boolean,
default: false
},
openType: {
type: String,
default: 'create'
}
})
const detailLoading = ref(false) // 表单的加载中
const detailData = ref<any>({}) // 详情数据
const devIdList = ref([])
const queryId = query.id as unknown as string // 从 URL 传递过来的 id 编号
const openFile = (name: any) => {
window.open(window.location.origin + '/#/previewFile?/supervision/' + name)
}
const netInReportList: any = ref([])
const governReportList: any = ref([])
//用户性质数组
const userTypeList = reactive([
{
label: '新建电网工程',
value: '0'
},
{
label: '扩建电网工程',
value: '1'
},
{
label: '新建非线性负荷用户',
value: '2'
},
{
label: '扩建非线性负荷用户',
value: '3'
},
{
label: '新建新能源发电站',
value: '4'
},
{
label: '扩建新能源发电站',
value: '5'
},
{
label: '敏感及重要用户',
value: '6'
}
])
//用户状态数组
const userStateList = reactive([
{
label: '可研',
value: '0'
},
{
label: '建设',
value: '1'
},
{
label: '运行',
value: '2'
},
{
label: '退运',
value: '3'
}
])
const form: any = ref({
NetReport: [], //入网设计方案审查报告:
governReport: [], //治理工程验收报告
informationSecurityTestReport: [], //信息安全检测报告
acceptanceInspectionReportSingle: [], //信息安全检测报告
acceptanceInspectionReport: [], //验收检验报告:
typeExperimentReport: [], //型式实验报告
factoryInspectionReport: [], //出厂检验报告:
performanceTestReport: [], //性能检测报告
mainWiringDiagram: [], //主接线图:
runTheReport: [] //试运行报告
})
const dictData = useDictData()
//字典获取所在地市
const areaOptionList = dictData.getBasicData('jibei_area')
//字典获取敏感电能质量指标
const energyQualityIndexList = dictData.getBasicData('Indicator_Type')
//字典获取行业类型
const industryList = dictData.getBasicData('industry_type_jb')
//字典电压等级
const voltageLevelList = dictData.getBasicData('Dev_Voltage_Stand')
//字典评估类型
const evaluationTypeList = dictData.getBasicData('Evaluation_Type')
//字典预测评估单位
const evaluationDeptList = dictData.getBasicData('evaluation_dept')
const loadLevelOptionList = dictData.getBasicData('load_level')
const powerSupplyInfoOptionList = dictData.getBasicData('supply_condition')
/** 获得数据 */
const getInfo = async () => {
detailLoading.value = true
try {
if (props.update) {
await getUserReportUpdateById(props.id || queryId).then(res => {
detailData.value = res.data.userReportMessageJson
getProviteData()
})
} else {
await getUserReportById(props.id || queryId).then(res => {
detailData.value = res.data
getProviteData()
})
}
} finally {
detailLoading.value = false
}
if (props.openType == 'sourcesOfInterference') {
queryFiles()
}
}
const proviteData = ref()
//可研报告
const feasibilityReportRef: any = ref(null)
//项目初步设计说明书
const preliminaryDesignDescriptionRef: any = ref(null)
//预测评估报告
const predictionEvaluationReportRef: any = ref(null)
//预测评估评审意见报告
const predictionEvaluationReviewOpinionsRef: any = ref(null)
//用户接入变电站主接线示意图
const substationMainWiringDiagramRef: any = ref(null)
//主要敏感终端清单
const sensitiveDevicesRef: any = ref(null)
//抗扰度测试报告
const antiInterferenceReportRef: any = ref(null)
//背景电能质量测试报告
const powerQualityReportRef: any = ref(null)
//其他附件
const additionalAttachmentsRef: any = ref(null)
//预览
const preview = (val: any, url: any) => {
nextTick(() => {
//可研报告
if (val == 'feasibilityReport') {
feasibilityReportRef?.value.open(url)
}
//项目初步设计说明书
if (val == 'preliminaryDesignDescription') {
preliminaryDesignDescriptionRef?.value.open(url)
}
//预测评估报告
if (val == 'predictionEvaluationReport') {
console.log(url, '9999999')
predictionEvaluationReportRef?.value.open(url)
}
//预测评估评审意见报告
if (val == 'predictionEvaluationReviewOpinions') {
predictionEvaluationReviewOpinionsRef?.value.open(url)
}
//用户接入变电站主接线示意图
if (val == 'substationMainWiringDiagram') {
substationMainWiringDiagramRef?.value.open(url)
}
//主要敏感终端清单
if (val == 'sensitiveDevices') {
sensitiveDevicesRef?.value.open(url)
}
//抗扰度测试报告
if (val == 'antiInterferenceReport') {
antiInterferenceReportRef?.value.open(url)
}
//背景电能质量测试报告
if (val == 'powerQualityReport') {
powerQualityReportRef?.value.open(url)
}
//其他附件
if (val == 'additionalAttachments') {
additionalAttachmentsRef?.value.open(url)
}
})
}
const queryFiles = () => {
getFileById({ id: props.id }).then(res => {
res.data.forEach((item: any) => {
if (item.url.length > 0) getFileNamePaths(item.url, item.name)
})
})
}
//判断userType选择取用的对象
const getProviteData = async () => {
if (detailData.value.userType == '0' || detailData.value.userType == '1') {
proviteData.value = detailData.value.userReportProjectPO
//查询非线性终端类型
await getDictTreeById(proviteData.value.nonlinearDeviceType).then(res => {
proviteData.value.nonlinearDeviceType = res.data?.name
})
} else if (
detailData.value.userType == '2' ||
detailData.value.userType == '3' ||
detailData.value.userType == '4' ||
detailData.value.userType == '5'
) {
proviteData.value = detailData.value.userReportSubstationPO
//查询非线性负荷类型
await getDictTreeById(proviteData.value.nonlinearLoadType).then(res => {
proviteData.value.nonlinearLoadType = res.data?.name
})
} else {
proviteData.value = detailData.value.userReportSensitivePO
}
//可研报告
if (proviteData.value.feasibilityReport) {
await getFileNamePath(proviteData.value.feasibilityReport, 'feasibilityReport')
}
//项目初步设计说明书
if (proviteData.value.preliminaryDesignDescription) {
await getFileNamePath(proviteData.value.preliminaryDesignDescription, 'preliminaryDesignDescription')
}
//预测评估报告
if (proviteData.value.predictionEvaluationReport) {
await getFileNamePath(proviteData.value.predictionEvaluationReport, 'predictionEvaluationReport')
}
//预测评估评审意见报告
if (proviteData.value.predictionEvaluationReviewOpinions) {
await getFileNamePath(
proviteData.value.predictionEvaluationReviewOpinions,
'predictionEvaluationReviewOpinions'
)
}
//用户接入变电站主接线示意图
if (proviteData.value.substationMainWiringDiagram) {
await getFileNamePath(proviteData.value.substationMainWiringDiagram, 'substationMainWiringDiagram')
}
//主要敏感终端清单
if (proviteData.value.sensitiveDevices) {
await getFileNamePath(proviteData.value.sensitiveDevices, 'sensitiveDevices')
}
//抗扰度测试报告
if (proviteData.value.antiInterferenceReport) {
await getFileNamePath(proviteData.value.antiInterferenceReport, 'antiInterferenceReport')
}
//背景电能质量测试报告
if (proviteData.value.powerQualityReport) {
await getFileNamePath(proviteData.value.powerQualityReport, 'powerQualityReport')
}
//其他附件
if (proviteData.value.additionalAttachments) {
getFileNamePath(proviteData.value.additionalAttachments, 'additionalAttachments')
}
// 入网评估报告
if (detailData.value.netInReport.length > 0) {
netInReportList.value = []
detailData.value.netInReport.forEach((item: any) => {
if (item != null) {
getFileNamePath(item, 'netInReport')
}
})
}
// 治理评估告"
if (detailData.value.governReport.length > 0) {
governReportList.value = []
detailData.value.governReport.forEach((item: any) => {
if (item != null) {
getFileNamePath(item, 'governReport')
}
})
}
// 调用关联终端接口
getByDeptDevLine({ id: detailData.value.orgId }).then(res => {
devIdList.value = res.data.filter((item: any) => item.devId == detailData.value.devId)
})
}
//根据文件名请求
const getFileNamePath = async (val: any, pathName: any) => {
await getFileNameAndFilePath({ filePath: val }).then(res => {
if (res.data && res.data.name && res.data.url) {
//可研报告
if (pathName == 'feasibilityReport' && proviteData.value.feasibilityReport) {
proviteData.value.feasibilityReport = {
name: res.data.fileName,
url: res.data.url
}
}
//项目初步设计说明书
else if (pathName == 'preliminaryDesignDescription' && proviteData.value.preliminaryDesignDescription) {
proviteData.value.preliminaryDesignDescription = {
name: res.data.fileName,
url: res.data.url
}
}
//预测评估报告
else if (pathName == 'predictionEvaluationReport' && proviteData.value.predictionEvaluationReport) {
proviteData.value.predictionEvaluationReport = {
name: res.data.fileName,
url: res.data.url
}
}
//预测评估评审意见报告
else if (
pathName == 'predictionEvaluationReviewOpinions' &&
proviteData.value.predictionEvaluationReviewOpinions
) {
proviteData.value.predictionEvaluationReviewOpinions = {
name: res.data.fileName,
url: res.data.url
}
}
//用户接入变电站主接线示意图
else if (pathName == 'substationMainWiringDiagram' && proviteData.value.substationMainWiringDiagram) {
proviteData.value.substationMainWiringDiagram = {
name: res.data.fileName,
url: res.data.url
}
}
//主要敏感终端清单
else if (pathName == 'sensitiveDevices' && proviteData.value.sensitiveDevices) {
proviteData.value.sensitiveDevices = {
name: res.data.fileName,
url: res.data.url
}
}
//抗扰度测试报告
else if (pathName == 'antiInterferenceReport' && proviteData.value.antiInterferenceReport) {
proviteData.value.antiInterferenceReport = {
name: res.data.fileName,
url: res.data.url
}
}
//背景电能质量测试报告
else if (pathName == 'powerQualityReport' && proviteData.value.powerQualityReport) {
proviteData.value.powerQualityReport = {
name: res.data.fileName,
url: res.data.url
}
}
//其他附件
else if (pathName == 'additionalAttachments' && proviteData.value.additionalAttachments) {
proviteData.value.additionalAttachments = {
name: res.data.fileName,
url: res.data.url
}
}
if (pathName == 'netInReport') {
netInReportList.value.push({
name: res.data.fileName,
url: res.data.url
})
} else if (pathName == 'governReport') {
governReportList.value.push({
name: res.data.fileName,
url: res.data.url
})
}
}
})
}
const getFileNamePaths = async (val: any, pathName: any) => {
let data = val.split(',')
for (let i = 0; i < data.length; i++) {
await getFileNameAndFilePath({ filePath: '/supervision/' + data[i] }).then(res => {
res.data.name = res.data.fileName
form.value[pathName].push(res.data)
})
}
}
defineExpose({ open: getInfo }) // 提供 open 方法,用于打开弹窗
watch(
() => props.id,
(val, oldVal) => {
val && getInfo()
}
)
/** 初始化 **/
onMounted(() => {
getInfo()
})
</script>
<style lang="scss">
::v-deep.el-icon svg {
// margin: 5px !important;
// position: absolute !important;
// top: 20px !important;
// float: right;
}
// .el-icon {
// float: left;
// }
// a {
// display: block;
// width: 200px;
// float: right;
// }
.elView {
cursor: pointer;
margin-right: 10px;
}
</style>

View File

@@ -0,0 +1,238 @@
<template>
<el-dialog
draggable
class='cn-operate-dialog'
v-model='eventDataUploadVisible'
:title='title'
style='width: 415px'
top='25vh'
>
<el-scrollbar>
<el-form :inline='false' :model='form' label-width='120px' ref='formRef'>
<el-form-item label='用户数据文件'>
<el-upload
v-model:file-list='fileList'
ref='uploadEventData'
action=''
:limit='1'
:on-exceed='handleExceed'
:auto-upload='false'
:on-change='choose'
>
<template #trigger>
<el-button type='primary'>选择数据文件</el-button>
</template>
</el-upload>
</el-form-item>
</el-form>
</el-scrollbar>
<template #footer>
<span class='dialog-footer'>
<el-button @click='eventDataUploadVisible = false'>取消</el-button>
<el-button type='primary' @click='submit'>确认</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang='ts'>
import { ref, reactive, inject } from 'vue'
import TableStore from '@/utils/tableStore'
import { ElMessage } from 'element-plus'
import type { UploadInstance, UploadProps, UploadRawFile, UploadUserFile } from 'element-plus'
import { genFileId } from 'element-plus'
import { importSensitiveUserData, importSensitiveReportData } from '@/api/supervision-boot/userReport/form'
const fileList = ref<UploadUserFile[]>([])
const formRef = ref()
const tableStore = inject('tableStore') as TableStore
const eventDataUploadVisible = ref(false)
const title = ref('')
const uploadEventData = ref<UploadInstance>()
// 注意不要和表单ref的命名冲突
const form = reactive({
file: null
})
//弹出界面,默认选择用户的第一个生产线的第一条进线进行数据导入
const open = async (text: string) => {
title.value = text
resetForm()
form.file = null
fileList.value = []
eventDataUploadVisible.value = true
}
//重置表单内容
const resetForm = () => {
if (formRef.value) {
formRef.value.resetFields()
}
}
/**
* 选择待上传文件
*/
const choose = (e: any) => {
form.file = e.raw
}
const handleExceed: UploadProps['onExceed'] = files => {
uploadEventData.value!.clearFiles()
const file = files[0] as UploadRawFile
file.uid = genFileId()
uploadEventData.value!.handleStart(file)
fileList.value = [{ name: file.name, url: '' }]
}
/**
* 提交用户表单数据
*/
const submit = async () => {
if (form.file) {
formRef.value.validate(async (valid: any) => {
if (valid) {
let data = new FormData()
data.append('file', form.file)
const allowedTypes = ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
if (!allowedTypes.includes(form.file.type)) {
return ElMessage.warning('只能上传 Excel 文件 (.xls 或 .xlsx)!')
}
if (title.value === '导入干扰源用户') {
await importSensitiveReportData(data)
.then(res => handleImportResponse(title.value, res))
.finally(() => {
tableStore.index()
eventDataUploadVisible.value = false
})
} else {
await importSensitiveUserData(data)
.then(res => handleImportResponse(title.value, res))
.finally(() => {
tableStore.index()
eventDataUploadVisible.value = false
})
}
// if (title.value == '导入干扰源用户') {
// await importSensitiveReportData(data)
// .then((res: any) => {
// if (res.type === 'application/json') {
// // 说明是普通对象数据,读取信息
// const fileReader = new FileReader()
// fileReader.onloadend = () => {
// try {
// const jsonData = JSON.parse(fileReader.result)
// // 后台信息
// if (jsonData.code === 'A0000') {
// ElMessage.success('导入成功')
// } else {
// ElMessage.error('导入失败,请查看下载附件!')
// }
// } catch (err) {
// console.log(err)
// }
// }
// fileReader.readAsText(res)
// } else {
// ElMessage.error('导入失败,请查看下载附件!')
// let blob = new Blob([res], {
// type: 'application/vnd.ms-excel'
// })
// const url = window.URL.createObjectURL(blob)
// const link = document.createElement('a')
// link.href = url
// link.download = '干扰源用户失败列表'
// document.body.appendChild(link)
// link.click()
// link.remove()
// }
// })
// .finally(() => {
// tableStore.index()
// eventDataUploadVisible.value = false
// })
// } else {
// await importSensitiveUserData(data)
// .then((res: any) => {
// if (res.type === 'application/json') {
// // 说明是普通对象数据,读取信息
// const fileReader = new FileReader()
// fileReader.onloadend = () => {
// try {
// const jsonData = JSON.parse(fileReader.result)
// // 后台信息
// if (jsonData.code === 'A0000') {
// ElMessage.success('导入成功')
// } else {
// ElMessage.error('导入失败,请查看下载附件!')
// }
// } catch (err) {
// console.log(err)
// }
// }
// fileReader.readAsText(res)
// } else {
// ElMessage.error('导入失败,请查看下载附件!')
// let blob = new Blob([res], {
// type: 'application/vnd.ms-excel'
// })
// const url = window.URL.createObjectURL(blob)
// const link = document.createElement('a')
// link.href = url
// link.download = '敏感及重要用户失败列表'
// document.body.appendChild(link)
// link.click()
// link.remove()
// }
// })
// .finally(() => {
// tableStore.index()
// eventDataUploadVisible.value = false
// })
// }
}
})
} else {
ElMessage.error('请选择数据文件')
}
}
async function handleImportResponse(title: any, res: any) {
if (res.type === 'application/json') {
const fileReader = new FileReader()
fileReader.onloadend = () => {
try {
const jsonData = JSON.parse(fileReader.result)
if (jsonData.code === 'A0000') {
ElMessage.success('导入成功')
} else {
ElMessage.error('导入失败,请查看下载附件!')
}
} catch (err) {
console.log(err)
}
}
fileReader.readAsText(res)
} else {
ElMessage.error('导入失败,请查看下载附件!')
let blob = new Blob([res], { type: 'application/vnd.ms-excel' })
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = title.includes('干扰源用户') ? '干扰源用户失败列表' : '敏感及重要用户失败列表'
document.body.appendChild(link)
link.click()
link.remove()
}
}
defineExpose({ open })
</script>
<style scoped>
.el-form-item__content div {
width: 100% !important;
}
</style>

View File

@@ -0,0 +1,301 @@
<template>
<div class="default-main">
<TableHeader ref="TableHeaderRef">
<template #select>
<el-form-item label="项目名称">
<el-input
style="width: 200px"
placeholder="请输入项目名称"
v-model="tableStore.table.params.projectName"
clearable
maxlength="32"
show-word-limit
></el-input>
</el-form-item>
<el-form-item label="所在地市">
<el-select v-model="tableStore.table.params.city" clearable placeholder="请选择所在地市">
<el-option
v-for="item in areaOptionList"
:key="item.id"
:label="item.name"
:value="item.name"
></el-option>
</el-select>
</el-form-item>
</template>
<template #operation>
<el-button icon="el-icon-Plus" type="primary" @click="addFormModel">新增</el-button>
<el-button icon="el-icon-Delete" type="primary" @click="deleteEven">删除</el-button>
<el-button icon="el-icon-Download" type="primary" @click="exportExcelTemplate" :loading="loading">
模板下载
</el-button>
<el-button icon="el-icon-Upload" type="primary" @click="importUserData">批量导入</el-button>
</template>
</TableHeader>
<Table ref="tableRef" :checkbox-config="checkboxConfig" />
<el-dialog title="详情" width="60%" v-model="dialogShow" v-if="dialogShow">
<DetailInfo :id="userId" :openType="'sourcesOfInterference'"></DetailInfo>
</el-dialog>
<!-- 批量导入 -->
<sensitive-user-popup ref="sensitiveUserPopup" />
<!-- 查看详情 detail 新增/修改 create-->
<addForm ref="addForms" @onSubmit="tableStore.index()" :openType="'sourcesOfInterference'"></addForm>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, provide, nextTick, watch } from 'vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import addForm from './components/addForm.vue'
import SensitiveUserPopup from './components/sensitiveUserPopup.vue'
import { useDictData } from '@/stores/dictData'
import { useRouter } from 'vue-router'
import { downloadSensitiveReportTemplate } from '@/api/supervision-boot/userReport/form'
import DetailInfo from './components/detail.vue'
import { cancelFormData, getUserReportById } from '@/api/supervision-boot/interfere/index'
import { deleteUserReport } from '@/api/supervision-boot/delete/index'
const addForms = ref()
const dictData = useDictData()
const sensitiveUserPopup = ref()
const TableHeaderRef = ref()
const loading = ref(false)
const areaOptionList = dictData.getBasicData('jibei_area')
const { push, options, currentRoute } = useRouter()
import { useAdminInfo } from '@/stores/adminInfo'
//获取登陆用户姓名和部门
const adminInfo = useAdminInfo()
const tableStore = new TableStore({
url: '/supervision-boot/userReport/getInterferenceUserPage',
// publicHeight: 65,
method: 'POST',
column: [
{
width: '60',
type: 'checkbox'
},
{
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ field: 'city', title: '所在地市', minWidth: 80 },
{ field: 'substation', title: '厂站名称', minWidth: 100 },
{ field: 'projectName', title: '项目名称', minWidth: 170 },
{
field: 'userType',
title: '用户性质',
minWidth: 150,
formatter: (obj: any) => {
const userType = obj.row.userType
return getUserTypeName(userType)
}
},
{ field: 'responsibleDepartment', title: '归口管理部门', minWidth: 130 },
{
title: '操作',
minWidth: 150,
fixed: 'right',
render: 'buttons',
buttons: [
{
name: 'productSetting',
title: '详细信息',
type: 'primary',
icon: 'el-icon-EditPen',
render: 'basicButton',
click: row => {
lookInfo(row.id)
}
},
{
name: 'edit',
title: '编辑',
type: 'primary',
icon: 'el-icon-Open',
render: 'basicButton',
click: row => {
addForms.value.filterUsers([6])
addForms.value.open({
title: '编辑',
row: row
})
}
},
]
}
],
beforeSearchFun: () => {
tableStore.table.params.orgNo = tableStore.table.params.deptIndex
}
})
tableStore.table.params.city = ''
tableStore.table.params.orgId = adminInfo.$state.deptId
tableStore.table.params.projectName = ''
tableStore.table.params.loadType = ''
tableStore.table.params.userName = ''
tableStore.table.params.relationUserName = ''
tableStore.table.params.aisFileUpload = ''
const userId = ref()
const dialogShow = ref(false)
const lookInfo = (id: string) => {
userId.value = id
dialogShow.value = true
}
provide('tableStore', tableStore)
onMounted(() => {
tableStore.index()
})
// 禁止点击
const checkboxConfig = reactive({
checkMethod: ({ row }) => {
return adminInfo.roleCode.includes('delete_info')
? true
: row.createBy == adminInfo.$state.id && row.status == 0
}
})
const deleteEven = () => {
if (tableStore.table.selection.length == 0) {
ElMessage({
type: 'warning',
message: '请选择要删除的数据'
})
} else {
ElMessageBox.confirm('此操作将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteUserReport(tableStore.table.selection.map(item => item.id)).then(res => {
ElMessage({
type: 'success',
message: '删除成功!'
})
tableStore.index()
})
})
}
}
/**取消流程操作*/
const cancelLeave = async (row: any) => {
// 二次确认
const { value } = await ElMessageBox.prompt('请输入取消原因', '取消流程', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputType: 'textarea',
inputPattern: /^[\s\S]*.*\S[\s\S]*$/, // 判断非空,且非空格
inputErrorMessage: '取消原因不能为空'
})
// 发起取消
let data = {
id: row.id,
processInstanceId: row.processInstanceId,
dataType: 1,
reason: value
}
await cancelFormData(data)
ElMessage.success('取消成功')
// 加载数据
tableStore.index()
}
// 新增
const addFormModel = () => {
addForms.value.filterUsers([6])
setTimeout(() => {
addForms.value.open({
title: '用户档案录入'
})
})
}
/**获取用户性质*/
const getUserTypeName = (userType: any) => {
if (userType === 0) {
return '新建电网工程'
}
if (userType === 1) {
return '扩建电网工程'
}
if (userType === 2) {
return '新建非线性负荷用户'
}
if (userType === 3) {
return '扩建非线性负荷用户'
}
if (userType === 4) {
return '新建新能源发电站'
}
if (userType === 5) {
return '扩建新能源发电站'
}
if (userType === 6) {
return '敏感及重要用户'
}
return '新建电网工程'
}
//导出模板
const exportExcelTemplate = async () => {
loading.value = true
await downloadSensitiveReportTemplate().then((res: any) => {
let blob = new Blob([res], {
type: 'application/vnd.ms-excel'
})
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = '干扰源用户台账模板'
document.body.appendChild(link)
link.click()
link.remove()
})
await setTimeout(() => {
loading.value = false
}, 0)
}
//批量导入用户数据
const importUserData = () => {
sensitiveUserPopup.value.open('导入干扰源用户')
}
const props = defineProps({ id: { type: String, default: 'null' } })
watch(
() => props.id,
async (newValue, oldValue) => {
if (newValue === 'null') return // 直接返回,避免后续逻辑执行
const fullId = newValue.split('@')[0]
let nowTime = Date.now()
const routeTime = Number(newValue.split('@')[1])
if (isNaN(routeTime) || nowTime - routeTime > import.meta.env.VITE_ROUTE_TIME_OUT) return // 路由时间超过500ms则不执行
await getUserReportById(fullId).then(res => {
if (res && res.code == 'A0000') {
addForms.value.setcontroFlag()
addForms.value.open({
title: '重新发起',
row: res.data
})
}
})
},
{ immediate: true }
)
</script>