添加工程信息管理 页面

This commit is contained in:
guanj
2026-02-02 13:56:50 +08:00
parent cf4291ed9a
commit dd0dab7643
20 changed files with 1152 additions and 470 deletions

View File

@@ -1,41 +1,82 @@
import request from '@/utils/request' import request from '@/utils/request'
// 新增程序版本 // 新增程序版本
export const addEdData = (data) => { export const addEdData = data => {
return request({ return request({
url: '/cs-device-boot/edData/addEdData', url: '/cs-device-boot/edData/addEdData',
method: 'post', method: 'post',
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data'
}, },
data: data, data: data
}) })
} }
export const auditEdData = (data) => { export const auditEdData = data => {
return request({ return request({
url: '/cs-device-boot/edData/auditEdData', url: '/cs-device-boot/edData/auditEdData',
method: 'post', method: 'post',
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data'
}, },
data: data, data: data
}) })
} }
// 修改-删除工程 // 修改-删除工程
export const auditEngineering = (data:any)=> { export const auditEngineering = (data: any) => {
return request({ return request({
url: '/cs-device-boot/engineering/auditEngineering', url: '/cs-device-boot/engineering/auditEngineering',
method: 'post', method: 'post',
data: data, data: data
}) })
} }
// 修改项目 // 修改项目
export const updateProject = (data:any) => { export const updateProject = (data: any) => {
return request({ return request({
url: '/cs-device-boot/project/updateProject', url: '/cs-device-boot/project/updateProject',
method: 'post', method: 'post',
data: data, data: data
}) })
} }
// 新增工程
export const addEngineering = (data: any) => {
return request({
url: '/cs-device-boot/engineeringProjectRelation/addEngineering',
method: 'post',
data: data
})
}
// 修改工程
export const updateEngineering = (data: any) => {
return request({
url: '/cs-device-boot/engineeringProjectRelation/updateEngineering',
method: 'post',
data: data
})
}
// 刪除工程
export const deleteEngineering = (data: any) => {
return request({
url: '/cs-device-boot/engineeringProjectRelation/deleteEngineering',
method: 'post',
params: data
})
}
// 刪除項目
export const deleteProject = (data: any) => {
return request({
url: '/cs-device-boot/engineeringProjectRelation/deleteProject',
method: 'post',
params: data
})
}
// 新增项目
export const addProject = (data: any) => {
return request({
url: '/cs-device-boot/engineeringProjectRelation/addProject',
method: 'post',
data: data
})
}

View File

@@ -143,7 +143,7 @@ const tableStore: any = new TableStore({
}, },
loadCallback: () => { loadCallback: () => {
// 定义 x 轴标签顺序 // 定义 x 轴标签顺序
const xAxisLabels = ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡'] const xAxisLabels = ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
// 根据指标名称顺序提取对应的 extent 数据 // 根据指标名称顺序提取对应的 extent 数据
const chartData = xAxisLabels.map(label => { const chartData = xAxisLabels.map(label => {

View File

@@ -85,7 +85,7 @@ const tableStore: any = new TableStore({
width: '150' width: '150'
}, },
{ {
title: '闪变越限(%)', title: '长时闪变越限(%)',
field: 'flickerOvertime', field: 'flickerOvertime',
width: '90', width: '90',
render: 'customTemplate', render: 'customTemplate',

View File

@@ -88,7 +88,7 @@ const initEcharts = () => {
xAxis: { xAxis: {
// name: '(区域)', // name: '(区域)',
data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡'] data: ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
}, },
yAxis: { yAxis: {
@@ -149,7 +149,7 @@ const tableStore: any = new TableStore({
title: '越限占比(%)', title: '越限占比(%)',
children: [ children: [
{ {
title: '闪变', title: '长时闪变',
field: 'flicker', field: 'flicker',
minWidth: '70', minWidth: '70',
render: 'customTemplate', render: 'customTemplate',

View File

@@ -136,7 +136,7 @@ const initProbabilityData = () => {
// 处理接口返回的数据,转换为图表所需格式 // 处理接口返回的数据,转换为图表所需格式
if (res.data && Array.isArray(res.data)) { if (res.data && Array.isArray(res.data)) {
// 定义指标类型顺序 // 定义指标类型顺序
const indicatorOrder = ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相电压不平衡度', '频率偏差'] const indicatorOrder = ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相电压不平衡度', '频率偏差']
// 按照指定顺序排序数据 // 按照指定顺序排序数据
const sortedData = [...res.data].sort((a, b) => { const sortedData = [...res.data].sort((a, b) => {
return indicatorOrder.indexOf(a.indexName) - indicatorOrder.indexOf(b.indexName) return indicatorOrder.indexOf(a.indexName) - indicatorOrder.indexOf(b.indexName)

View File

@@ -135,7 +135,7 @@ const initProbabilityData = () => {
// 处理接口返回的数据,转换为图表所需格式 // 处理接口返回的数据,转换为图表所需格式
if (res.data && Array.isArray(res.data)) { if (res.data && Array.isArray(res.data)) {
// 定义指标类型顺序 // 定义指标类型顺序
const indicatorOrder = ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相电压不平衡度', '频率偏差'] const indicatorOrder = ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相电压不平衡度', '频率偏差']
// 按照指定顺序排序数据 // 按照指定顺序排序数据
const sortedData = [...res.data].sort((a, b) => { const sortedData = [...res.data].sort((a, b) => {
return indicatorOrder.indexOf(a.indexName) - indicatorOrder.indexOf(b.indexName) return indicatorOrder.indexOf(a.indexName) - indicatorOrder.indexOf(b.indexName)

View File

@@ -12,7 +12,7 @@
multiple multiple
:multiple-limit="2" :multiple-limit="2"
collapse-tags collapse-tags
collapse-tags-tooltip collapse-tags-tooltip
v-model="searchForm.index" v-model="searchForm.index"
placeholder="请选择统计指标" placeholder="请选择统计指标"
@change="onIndexChange($event)" @change="onIndexChange($event)"
@@ -66,7 +66,7 @@
<el-option <el-option
v-for="vv in item.countOptions" v-for="vv in item.countOptions"
:key="vv" :key="vv"
:label="item.name.includes('间谐波') ? vv - 0.5 : vv" :label="item.name.includes('间谐波') ? vv - 0.5 : vv"
:value="vv" :value="vv"
></el-option> ></el-option>
</el-select> </el-select>
@@ -81,12 +81,8 @@
</template> </template>
</TableHeader> </TableHeader>
</div> </div>
<div class="history_chart" :style="pageHeight" v-loading="loading"> <div class="history_chart" :style="pageHeight" v-loading="loading">
<MyEchart <MyEchart ref="historyChart" :options="echartsData" v-if="showEchart" />
ref="historyChart"
:options="echartsData"
v-if="showEchart"
/>
<el-empty :style="pageHeight" v-else description="暂无数据" /> <el-empty :style="pageHeight" v-else description="暂无数据" />
</div> </div>
</el-dialog> </el-dialog>
@@ -160,28 +156,40 @@ const countOptions: any = ref([])
const legendDictList: any = ref([]) const legendDictList: any = ref([])
const initCode = (field: string, title: string) => { const initCode = (field: string, title: string) => {
queryByCode('steady_state_limit_trend').then(res => { queryByCode('gridSide_exceedTheLimit').then(res => {
queryCsDictTree(res.data.id).then(item => { queryCsDictTree(res.data.id).then(item => {
//排序 //排序
indexOptions.value = item.data.sort((a: any, b: any) => { indexOptions.value = item.data.sort((a: any, b: any) => {
return a.sort - b.sort return a.sort - b.sort
}) })
const titleMap: Record<string, number> = { // const titleMap: Record<string, number> = {
flickerOvertime: 0, // flickerOvertime: 0,
uaberranceOvertime: 3, // uaberranceOvertime: 3,
ubalanceOvertime: 4, // ubalanceOvertime: 4,
freqDevOvertime: 5 // freqDevOvertime: 5
} // }
let defaultIndex = 0 // 默认值 // let defaultIndex = 0 // 默认值
if (field in titleMap) { // if (field in titleMap) {
defaultIndex = titleMap[field] // defaultIndex = titleMap[field]
} else if (field.includes('uharm')) { // } else if (field.includes('uharm')) {
defaultIndex = 1 // defaultIndex = 1
} else if (field.includes('iharm')) { // } else if (field.includes('iharm')) {
defaultIndex = 2 // defaultIndex = 2
} // }
let codeKey = field.includes('flickerOvertime')
? '闪变'
: field.includes('uharm')
? '谐波电压'
: field.includes('iharm')
? '谐波电流'
: field.includes('voltageDevOvertime')
? '电压偏差'
: field.includes('ubalanceOvertime')
? '不平衡'
: ''
let defaultIndex = indexOptions.value.findIndex((item: any) => item.name.includes(codeKey)) || 0
searchForm.value.index[0] = indexOptions.value[defaultIndex].id searchForm.value.index[0] = indexOptions.value[defaultIndex].id
}) })
@@ -294,7 +302,7 @@ const init = async () => {
} }
lists[index] = { lists[index] = {
statisticalId: item.index, statisticalId: item.index,
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : '' frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
} }
}) })
let obj = { let obj = {
@@ -579,7 +587,6 @@ const setTimeControl = () => {
} }
const selectChange = (flag: boolean, height: any) => { const selectChange = (flag: boolean, height: any) => {
pageHeight.value = mainHeight(height * 1.6, 1.6) pageHeight.value = mainHeight(height * 1.6, 1.6)
} }
//导出 //导出

View File

@@ -86,7 +86,7 @@ const tableStore: any = new TableStore({
width: '150' width: '150'
}, },
{ {
title: '闪变越限(分钟)', title: '越限(分钟)',
field: 'flickerOvertime', field: 'flickerOvertime',
width: '90', width: '90',
render: 'customTemplate', render: 'customTemplate',
@@ -101,6 +101,14 @@ const tableStore: any = new TableStore({
{ {
title: '谐波电流越限(分钟)', title: '谐波电流越限(分钟)',
children: loop50('iharm') children: loop50('iharm')
}, {
title: '电压偏差越限(分钟)',
field: 'uaberranceOvertime',
width: '100',
render: 'customTemplate',
customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>`
}
}, },
{ {
title: '三相不平衡度越限(分钟)', title: '三相不平衡度越限(分钟)',
@@ -111,24 +119,16 @@ const tableStore: any = new TableStore({
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
} }
}, },
{
title: '电压偏差越限(分钟)', // {
field: 'uaberranceOvertime', // title: '频率偏差越限(分钟)',
width: '100', // field: 'freqDevOvertime',
render: 'customTemplate', // width: '100',
customTemplate: (row: any) => { // render: 'customTemplate',
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>` // customTemplate: (row: any) => {
} // return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
}, // }
{ // }
title: '频率偏差越限(分钟)',
field: 'freqDevOvertime',
width: '100',
render: 'customTemplate',
customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
}
}
], ],
beforeSearchFun: () => { beforeSearchFun: () => {
}, },

View File

@@ -69,7 +69,7 @@ const tableStore: any = new TableStore({
width: '150' width: '150'
}, },
{ {
title: '闪变越限(分钟)', title: '长时闪变越限(分钟)',
field: 'flicker', field: 'flicker',
width: '80' width: '80'
}, },
@@ -99,26 +99,7 @@ const tableStore: any = new TableStore({
], ],
beforeSearchFun: () => {}, beforeSearchFun: () => {},
loadCallback: () => { loadCallback: () => {
tableStore.table.data = [
{
time: '2024-01-01 00:00:00',
name: '35kV进线',
flicker: '0',
},
{
time: '2024-01-01 00:00:00',
name: '35kV进线',
flicker: '0',
},
{
time: '2024-01-01 00:00:00',
name: '35kV进线',
flicker: '0',
},
]
} }
}) })

View File

@@ -84,7 +84,7 @@ const tableStore: any = new TableStore({
width: '150' width: '150'
}, },
{ {
title: '闪变越限(分钟)', title: '长时闪变越限(分钟)',
field: 'flicker', field: 'flicker',
width: '80', width: '80',
render: 'customTemplate', render: 'customTemplate',

View File

@@ -85,7 +85,7 @@ const tableStore: any = new TableStore({
width: '150' width: '150'
}, },
{ {
title: '闪变越限(%)', title: '长时闪变越限(%)',
field: 'flickerOvertime', field: 'flickerOvertime',
width: '90', width: '90',
render: 'customTemplate', render: 'customTemplate',
@@ -101,16 +101,7 @@ const tableStore: any = new TableStore({
title: '谐波电流越限(%)', title: '谐波电流越限(%)',
children: loop50('iharm') children: loop50('iharm')
}, },
{ {
title: '三相不平衡度越限(%)',
field: 'ubalanceOvertime',
width: '100',
render: 'customTemplate',
customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
}
},
{
title: '电压偏差越限(%)', title: '电压偏差越限(%)',
field: 'voltageDevOvertime', field: 'voltageDevOvertime',
width: '100', width: '100',
@@ -120,14 +111,24 @@ const tableStore: any = new TableStore({
} }
}, },
{ {
title: '频率偏差越限(%)', title: '三相不平衡度越限(%)',
field: 'freqDevOvertime', field: 'ubalanceOvertime',
width: '100', width: '100',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
} }
} },
// {
// title: '频率偏差越限(%)',
// field: 'freqDevOvertime',
// width: '100',
// render: 'customTemplate',
// customTemplate: (row: any) => {
// return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
// }
// }
], ],
beforeSearchFun: () => { beforeSearchFun: () => {
}, },

View File

@@ -85,7 +85,7 @@ const tableStore: any = new TableStore({
width: '150' width: '150'
}, },
{ {
title: '闪变越限(%)', title: '长时闪变越限(%)',
field: 'flickerOvertime', field: 'flickerOvertime',
width: '90', width: '90',
render: 'customTemplate', render: 'customTemplate',

View File

@@ -89,7 +89,7 @@ const initEcharts = () => {
xAxis: { xAxis: {
// name: '(区域)', // name: '(区域)',
data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡'] data: ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
}, },
yAxis: { yAxis: {
@@ -150,7 +150,7 @@ const tableStore: any = new TableStore({
title: '越限占比(%)', title: '越限占比(%)',
children: [ children: [
{ {
title: '闪变', title: '长时闪变',
field: 'flicker', field: 'flicker',
minWidth: '70', minWidth: '70',
render: 'customTemplate', render: 'customTemplate',

View File

@@ -481,7 +481,33 @@
:disabled="true" :disabled="true"
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item
class="form-item"
label="日志等级:"
:prop="'deviceInfoList[' + bIndex + '].devLogLevel'"
>
<el-select
clearable
filterable
v-model="busItem.devLogLevel"
placeholder="请选择日志等级"
style="width: 100%"
:disabled="
!(
(nodeLevel == 3 && pageStatus == 3) ||
((nodeLevel == 2 || (nodeLevel == 1 && pageStatus == 2)) &&
pageStatus == 2)
)
"
>
<el-option
v-for="value in logList"
:key="value.value"
:label="value.label"
:value="value.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item <el-form-item
class="form-item" class="form-item"
label="排序:" label="排序:"
@@ -939,7 +965,7 @@
class="form-item" class="form-item"
label="是否治理:" label="是否治理:"
:prop="'lineInfoList[' + lIndex + '].govern'" :prop="'lineInfoList[' + lIndex + '].govern'"
:rules="{ required: true, message: '请选择是否治理', trigger: 'blur' }" :rules="{ required: true, message: '请选择是否治理', trigger: 'change' }"
> >
<el-select <el-select
clearable clearable
@@ -985,6 +1011,35 @@
<el-option label="退运" :value="4" /> <el-option label="退运" :value="4" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item
class="form-item"
label="日志等级:"
:prop="'lineInfoList[' + lIndex + '].lineLogLevel'"
:rules="{ required: true, message: '请选择日志等级', trigger: 'change' }"
>
<!-- 0运行1检修2停运3调试4退运 -->
<el-select
clearable
filterable
v-model="lineItem.lineLogLevel"
placeholder="请选择日志等级"
:disabled="
!(
(nodeLevel == 4 && pageStatus == 3) ||
((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) &&
pageStatus == 2)
)
"
>
<el-option
v-for="value in logList"
:key="value.value"
:label="value.label"
:value="value.value"
></el-option>
</el-select>
</el-form-item>
</div> </div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
@@ -1159,6 +1214,24 @@ const lineSpaceArr = ref([
{ name: '5分钟', value: 5 }, { name: '5分钟', value: 5 },
{ name: '10分钟', value: 10 } { name: '10分钟', value: 10 }
]) ])
const logList = ref([
{
value: 'DEBUG',
label: 'DEBUG'
},
{
value: 'NORMAL',
label: 'NORMAL'
},
{
value: 'WARN',
label: 'WARN'
},
{
value: 'ERROR',
label: 'ERROR'
}
])
//工程 //工程
// const engineeringParam = ref({ // const engineeringParam = ref({
// city: '', // city: '',
@@ -1179,6 +1252,7 @@ interface DeviceInfo {
devModel: string devModel: string
devType: string devType: string
devAccessMethod: string devAccessMethod: string
devLogLevel: string
mac: string mac: string
ndid: string ndid: string
nodeId: string nodeId: string
@@ -1203,6 +1277,7 @@ interface LineInfo {
monitorObj: string monitorObj: string
position: string position: string
govern: string | number govern: string | number
lineLogLevel: string
runStatus: string | number runStatus: string | number
basicCapacity: number basicCapacity: number
shortCircuitCapacity: number shortCircuitCapacity: number
@@ -1555,6 +1630,7 @@ const add = () => {
devModel: '', devModel: '',
devType: '', devType: '',
devAccessMethod: 'CLD', devAccessMethod: 'CLD',
devLogLevel: 'WARN',
mac: '', mac: '',
ndid: '', ndid: '',
nodeId: '', nodeId: '',
@@ -1583,6 +1659,7 @@ const add = () => {
monitorObj: '', monitorObj: '',
position: '', position: '',
govern: 0, govern: 0,
lineLogLevel: 'WARN',
runStatus: 0, runStatus: 0,
basicCapacity: 0, basicCapacity: 0,
shortCircuitCapacity: 0, shortCircuitCapacity: 0,
@@ -1695,8 +1772,9 @@ const updateEquipmentFunc = (id: any) => {
id: id, // 设备ID用于修改 id: id, // 设备ID用于修改
name: currentDevice.name, name: currentDevice.name,
devModel: currentDevice.devModel, devModel: currentDevice.devModel,
devType: currentDevice.devType, devType: currentDevice.devType,
devAccessMethod: currentDevice.devAccessMethod, devAccessMethod: currentDevice.devAccessMethod,
devLogLevel: currentDevice.devLogLevel,
mac: currentDevice.mac, mac: currentDevice.mac,
nodeId: currentDevice.nodeId, nodeId: currentDevice.nodeId,
cntractNo: currentDevice.cntractNo, cntractNo: currentDevice.cntractNo,
@@ -1760,6 +1838,7 @@ const updateLineFunc = (id: any) => {
monitorObj: currentLine.monitorObj || '', monitorObj: currentLine.monitorObj || '',
position: currentLine.position || '', position: currentLine.position || '',
govern: currentLine.govern, govern: currentLine.govern,
lineLogLevel: currentLine.lineLogLevel,
runStatus: currentLine.runStatus, runStatus: currentLine.runStatus,
basicCapacity: currentLine.basicCapacity || 0, basicCapacity: currentLine.basicCapacity || 0,
shortCircuitCapacity: currentLine.shortCircuitCapacity || 0, shortCircuitCapacity: currentLine.shortCircuitCapacity || 0,
@@ -1925,6 +2004,7 @@ const next = async () => {
devModel: '', devModel: '',
devType: '', devType: '',
devAccessMethod: 'CLD', devAccessMethod: 'CLD',
devLogLevel: 'WARN',
mac: '', mac: '',
ndid: '', ndid: '',
nodeId: '', nodeId: '',
@@ -1957,6 +2037,7 @@ const next = async () => {
monitorObj: '', monitorObj: '',
position: '', position: '',
govern: 0, govern: 0,
lineLogLevel:'WARN',
runStatus: 0, runStatus: 0,
basicCapacity: 0, basicCapacity: 0,
shortCircuitCapacity: 0, shortCircuitCapacity: 0,
@@ -2361,6 +2442,8 @@ const resetAllForms = () => {
device.devModel = '' device.devModel = ''
device.devType = '' device.devType = ''
device.devAccessMethod = 'CLD' device.devAccessMethod = 'CLD'
device.devLogLevel = 'WARN'
device.mac = '' device.mac = ''
device.nodeId = '' device.nodeId = ''
device.cntractNo = '' device.cntractNo = ''
@@ -2382,6 +2465,7 @@ const resetAllForms = () => {
line.monitorObj = '' line.monitorObj = ''
line.position = '' line.position = ''
line.govern = 0 line.govern = 0
line.lineLogLevel = 'WARN'
line.runStatus = 0 line.runStatus = 0
line.basicCapacity = 0 line.basicCapacity = 0
line.shortCircuitCapacity = 0 line.shortCircuitCapacity = 0
@@ -2480,6 +2564,7 @@ const submitData = () => {
devModel: currentDevice.devModel, devModel: currentDevice.devModel,
devType: currentDevice.devType, devType: currentDevice.devType,
devAccessMethod: currentDevice.devAccessMethod, devAccessMethod: currentDevice.devAccessMethod,
devLogLevel: currentDevice.devLogLevel,
mac: currentDevice.mac, mac: currentDevice.mac,
nodeId: currentDevice.nodeId, nodeId: currentDevice.nodeId,
cntractNo: currentDevice.cntractNo, cntractNo: currentDevice.cntractNo,
@@ -2550,6 +2635,7 @@ const submitData = () => {
monitorObj: currentLine.monitorObj, monitorObj: currentLine.monitorObj,
position: currentLine.position, position: currentLine.position,
govern: currentLine.govern, govern: currentLine.govern,
lineLogLevel: currentLine.lineLogLevel,
runStatus: currentLine.runStatus, runStatus: currentLine.runStatus,
basicCapacity: currentLine.basicCapacity, basicCapacity: currentLine.basicCapacity,
shortCircuitCapacity: currentLine.shortCircuitCapacity, shortCircuitCapacity: currentLine.shortCircuitCapacity,
@@ -2664,6 +2750,7 @@ const handleBusBarTabsEdit = (targetName: any, action: any) => {
devModel: '', devModel: '',
devType: '', devType: '',
devAccessMethod: 'CLD', devAccessMethod: 'CLD',
devLogLevel: 'WARN',
mac: '', mac: '',
ndid: '', ndid: '',
nodeId: '', nodeId: '',
@@ -2740,6 +2827,7 @@ const handleLineTabsEdit = (targetName: any, action: any) => {
monitorObj: '', monitorObj: '',
position: '', position: '',
govern: 0, govern: 0,
lineLogLevel: 'WARN',
runStatus: 0, runStatus: 0,
basicCapacity: 0, basicCapacity: 0,
shortCircuitCapacity: 0, shortCircuitCapacity: 0,

View File

@@ -1,213 +1,211 @@
<template> <template>
<div class="default-main" :style="{ height: pageHeight.height }"> <div class="default-main" :style="{ height: pageHeight.height }">
<vxe-table <vxe-table
v-loading="tableStore.table.loading" v-loading="tableStore.table.loading"
height="auto" height="auto"
auto-resize auto-resize
ref="tableRef" ref="tableRef"
v-bind="defaultAttribute" v-bind="defaultAttribute"
:data="tableStore.table.data" :data="tableStore.table.data"
:column-config="{ resizable: true }" :column-config="{ resizable: true }"
:tree-config="{ expandAll: true }" :tree-config="{ expandAll: true }"
> >
<vxe-column field="name" align="left" title="名称" tree-node></vxe-column> <vxe-column field="name" align="left" title="名称" tree-node></vxe-column>
<vxe-column field="area" title="区域"> <vxe-column field="area" title="区域">
<template #default="{ row }"> <template #default="{ row }">
{{ row.area || '/' }} {{ row.area || '/' }}
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="remark" title="备注"> <vxe-column field="remark" title="备注">
<template #default="{ row }"> <template #default="{ row }">
{{ row.remark || '/' }} {{ row.remark || '/' }}
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="remark" title="操作" width="150px"> <vxe-column field="remark" title="操作" width="150px">
<template #default="{ row }"> <template #default="{ row }">
<el-button type="primary" link @click="edit(row)" v-if="!row.path">编辑</el-button> <el-button type="primary" link @click="edit(row)" v-if="!row.path">编辑</el-button>
<el-popconfirm <el-popconfirm
title="确定删除吗?" title="确定删除吗?"
confirm-button-type="danger" confirm-button-type="danger"
@confirm="deletes(row)" @confirm="deletes(row)"
v-if="!row.path" v-if="!row.path"
> >
<template #reference> <template #reference>
<el-button type="danger" link>删除</el-button> <el-button type="danger" link>删除</el-button>
</template> </template>
</el-popconfirm> </el-popconfirm>
</template> </template>
</vxe-column> </vxe-column>
</vxe-table> </vxe-table>
<el-dialog v-model="dialogVisible" title="编辑" width="500"> <el-dialog v-model="dialogVisible" title="编辑" width="500">
<el-form :model="form" ref="ruleFormRef" label-width="80px" :rules="rules"> <el-form :model="form" ref="ruleFormRef" label-width="80px" :rules="rules">
<el-form-item label="名称" prop="name"> <el-form-item label="名称" prop="name">
<el-input v-model="form.name" clearable placeholder="请输入名称" /> <el-input v-model="form.name" clearable placeholder="请输入名称" />
</el-form-item> </el-form-item>
<el-form-item label="区域" :prop="form.pid == '0' ? 'city' : 'area'"> <el-form-item label="区域" :prop="form.pid == '0' ? 'city' : 'area'">
<!-- <el-input v-model="form.city" clearable placeholder="请输入区域" /> --> <!-- <el-input v-model="form.city" clearable placeholder="请输入区域" /> -->
<el-cascader <el-cascader
v-model="form.city" v-model="form.city"
v-if="form.pid == '0'" v-if="form.pid == '0'"
style="width: 100%" style="width: 100%"
:options="areaTree" :options="areaTree"
:props="props" :props="props"
clearable clearable
filterable filterable
placeholder="请输入区域" placeholder="请输入区域"
/> />
<el-input v-else v-model="form.area" clearable placeholder="请输入区域" /> <el-input v-else v-model="form.area" clearable placeholder="请输入区域" />
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="description"> <el-form-item label="备注" prop="description">
<el-input v-model="form.description" :rows="2" type="textarea" clearable placeholder="请输入备注" /> <el-input v-model="form.description" :rows="2" type="textarea" clearable placeholder="请输入备注" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button> <el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="save">保存</el-button> <el-button type="primary" @click="save">保存</el-button>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, provide, nextTick } from 'vue' import { ref, onMounted, provide, nextTick } from 'vue'
import TableStore from '@/utils/tableStore' import TableStore from '@/utils/tableStore'
import { useDictData } from '@/stores/dictData' import { useDictData } from '@/stores/dictData'
import { defaultAttribute } from '@/components/table/defaultAttribute' import { defaultAttribute } from '@/components/table/defaultAttribute'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import { ElMessageBox, ElMessage } from 'element-plus' import { ElMessageBox, ElMessage } from 'element-plus'
import { auditEngineering, updateProject } from '@/api/cs-device-boot/edData' import { auditEngineering, updateProject } from '@/api/cs-device-boot/edData'
import { activateUser, deluser, passwordConfirm } from '@/api/user-boot/user' import { activateUser, deluser, passwordConfirm } from '@/api/user-boot/user'
import tree from '@/assets/map/area.json' import tree from '@/assets/map/area.json'
defineOptions({ defineOptions({
name: 'govern/manage/engineering' name: 'govern/manage/engineering'
}) })
const dictData = useDictData() const dictData = useDictData()
const tableRef = ref() const tableRef = ref()
const dialogVisible = ref(false) const dialogVisible = ref(false)
const pageHeight = mainHeight(20) const pageHeight = mainHeight(20)
const tableStore = new TableStore({ const tableStore = new TableStore({
url: '/cs-device-boot/csLedger/getProjectTree', url: '/cs-device-boot/csLedger/getProjectTree',
method: 'POST', method: 'POST',
column: [], column: [],
loadCallback: () => { loadCallback: () => {
setTimeout(() => { setTimeout(() => {
tableRef.value.setAllTreeExpand(true) tableRef.value.setAllTreeExpand(true)
}, 500) }, 500)
} }
}) })
const ruleFormRef = ref() const ruleFormRef = ref()
const rules = ref({ const rules = ref({
name: [{ required: true, message: '请输入名称', trigger: 'blur' }], name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
city: [{ required: true, message: '请输入区域', trigger: 'blur' }], city: [{ required: true, message: '请输入区域', trigger: 'blur' }],
area: [{ required: true, message: '请输入区域', trigger: 'blur' }], area: [{ required: true, message: '请输入区域', trigger: 'blur' }],
description: [{ required: true, message: '请输入描述', trigger: 'blur' }] description: [{ required: true, message: '请输入描述', trigger: 'blur' }]
}) })
console.log("🚀 ~ dictData.state.areaTree:", dictData.state)
const areaTree: any = tree
const areaTree: any = tree const props = {
const props = { label: 'text',
label: 'text', value: 'value',
value: 'value', children: 'children',
children: 'children', checkStrictly: true
checkStrictly: true }
} const form = ref({
const form = ref({ id: '',
id: '', pid: '',
pid: '', area: '',
area: '', name: '',
name: '', city: '',
city: '', description: ''
description: '' })
}) provide('tableStore', tableStore)
provide('tableStore', tableStore)
onMounted(() => {
onMounted(() => { tableStore.index()
tableStore.index() // setTimeout(() => {
// setTimeout(() => { // tableRef.value.setAllTreeExpand(true)
// tableRef.value.setAllTreeExpand(true) // }, 500)
// }, 500) })
}) const deletes = (row: any) => {
const deletes = (row: any) => { ElMessageBox.prompt('二次校验密码确认', '·', {
ElMessageBox.prompt('二次校验密码确认', '·', { confirmButtonText: '确认',
confirmButtonText: '确认', cancelButtonText: '取消',
cancelButtonText: '取消', customClass: 'customInput',
customClass: 'customInput', inputType: 'text',
inputType: 'text', beforeClose: (action, instance, done) => {
beforeClose: (action, instance, done) => { if (action === 'confirm') {
if (action === 'confirm') { if (instance.inputValue == null) {
if (instance.inputValue == null) { return ElMessage.warning('请输入密码')
return ElMessage.warning('请输入密码') } else if (instance.inputValue?.length > 32) {
} else if (instance.inputValue?.length > 32) { return ElMessage.warning('密码长度不能超过32位,当前密码长度为' + instance.inputValue.length)
return ElMessage.warning('密码长度不能超过32位,当前密码长度为' + instance.inputValue.length) } else {
} else { done()
done() }
} } else {
} else { done()
done() }
} }
} }).then(({ value }) => {
}).then(({ value }) => { passwordConfirm(value).then(res => {
passwordConfirm(value).then(res => { auditEngineering({
auditEngineering({ id: row.id,
id: row.id, status: 0
status: 0 }).then((res: any) => {
}).then((res: any) => { ElMessage.success('删除成功')
ElMessage.success('删除成功') tableStore.index()
tableStore.index() })
}) })
}) })
}) }
}
// 编辑
// 编辑 const edit = (row: any) => {
const edit = (row: any) => { form.value = {
form.value = { id: row.id,
id: row.id, pid: row.pid,
pid: row.pid, name: row.name,
name: row.name, city: row.cityId,
city: row.cityId, area: row.area,
area: row.area, description: row.remark
description: row.remark }
} dialogVisible.value = true
dialogVisible.value = true }
} const save = () => {
const save = () => { ruleFormRef.value.validate((valid: any) => {
ruleFormRef.value.validate((valid: any) => { if (valid) {
if (valid) { if (form.value.pid == '0') {
if (form.value.pid == '0') { auditEngineering({ ...form.value, city: form.value.city[form.value.city.length - 1] }).then(
auditEngineering({ ...form.value, city: form.value.city[form.value.city.length - 1] }).then( (res: any) => {
(res: any) => { ElMessage.success('保存成功')
ElMessage.success('保存成功') dialogVisible.value = false
dialogVisible.value = false tableStore.index()
tableStore.index() }
} )
) } else {
} else { let params = new FormData()
let params = new FormData() params.append('id', form.value.id)
params.append('id', form.value.id) params.append('area', form.value.area)
params.append('area', form.value.area) params.append('description', form.value.description)
params.append('description', form.value.description) params.append('name', form.value.name)
params.append('name', form.value.name)
updateProject(form.value).then((res: any) => {
updateProject(form.value).then((res: any) => { ElMessage.success('保存成功')
ElMessage.success('保存成功') dialogVisible.value = false
dialogVisible.value = false tableStore.index()
tableStore.index() })
}) }
} }
} })
}) }
} </script>
<style lang="scss">
</script> .customInput {
<style lang="scss"> .el-input__inner {
.customInput { -webkit-text-security: disc !important;
.el-input__inner { }
-webkit-text-security: disc !important; }
} </style>
}
</style>

View File

@@ -0,0 +1,221 @@
<template>
<el-dialog draggable class="cn-operate-dialog" width="520px" v-model.trim="dialogVisible" :title="title">
<el-form :inline="false" ref="formRef" :model="form" label-width="auto" class="form-one" :rules="rules">
<el-form-item label="项目名称" prop="name">
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入项目名称" />
</el-form-item>
<el-form-item label="所属工程" prop="engineeringId">
<el-select v-model="form.engineeringId" filterable placeholder="请选择工程" clearable>
<el-option
v-for="item in engineeringList"
:key="item.engineeringId"
:label="item.engineeringName"
:value="item.engineeringId"
/>
</el-select>
</el-form-item>
<el-form-item label="区域" prop="area">
<el-input v-model="form.area" clearable placeholder="请输入区域" />
</el-form-item>
<el-form-item label="备注" prop="description">
<el-input v-model="form.description" :rows="2" type="textarea" clearable placeholder="请输入备注" />
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input maxlength="32" show-word-limit-number v-model.number="form.sort" :min="0" />
</el-form-item>
<el-form-item label="拓扑图" prop="sort">
<div class="image-radio-group">
<div
class="image-radio-item"
v-for="item in images"
:key="item.id"
@click="handleSelect(item.id)"
>
<el-radio :label="item.id" v-model="form.topoIds" class="hidden-radio">
{{ item.name }}
</el-radio>
<div class="image-container" :class="{ selected: form.topoIds === item.id }">
<img :src="item.url" v-if="item.url" class="image-preview" />
<div v-else style="width: 120px; height: 90px; text-align: center; line-height: 90px">
暂无图片
</div>
<div class="image-overlay" v-if="form.topoIds === item.id">
<el-icon class="check-icon"><Check /></el-icon>
</div>
</div>
<div class="image-name">{{ item.name }}</div>
</div>
</div>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submit">确认</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref, inject } from 'vue'
import { reactive } from 'vue'
import TableStore from '@/utils/tableStore'
import { ElMessage } from 'element-plus'
import { add, update } from '@/api/user-boot/role'
import { useAdminInfo } from '@/stores/adminInfo'
import { addProject, updateProject } from '@/api/cs-device-boot/edData'
import { getTopoTemplate } from '@/api/cs-device-boot/topologyTemplate'
import { getFileUrl } from '@/api/system-boot/file'
const adminInfo = useAdminInfo()
const tableStore = inject('tableStore') as TableStore
// do not use same name with ref
const form = reactive({
name: '',
id: '',
engineeringId: '',
area: '',
sort: 100,
description: '',
topoIds: ''
})
const engineeringList: any = ref([])
const rules = {
name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
area: [{ required: true, message: '请输入区域', trigger: 'blur' }],
engineeringId: [{ required: true, message: '请输入工程', trigger: 'blur' }],
description: [{ required: true, message: '请输入描述', trigger: 'blur' }],
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }]
}
const dialogVisible = ref(false)
const title = ref('新增菜单')
const formRef = ref()
const props = {
label: 'text',
value: 'value',
children: 'children'
// checkStrictly: true
}
const open = (text: string, List: any, data?: anyObj, id?: string) => {
getImageList().catch(() => {})
formRef.value?.resetFields()
title.value = text
dialogVisible.value = true
engineeringList.value = List
if (data) {
form.id = data.projectId
form.name = data.projectName
form.area = data.projectArea
form.description = data.projectRemark
form.sort = data.projectSort
form.engineeringId = id || ''
form.topoIds = data.topologyInfoId || ''
} else {
form.id = ''
form.name = ''
form.area = ''
form.description = ''
form.engineeringId = ''
form.topoIds = ''
form.sort = 100
}
}
const submit = async () => {
formRef.value.validate(async valid => {
console.log("🚀 ~ submit ~ form.topoIds:", form.topoIds)
if (valid) {
if (form.id) {
await updateProject({ ...form ,topoIds:[form.topoIds]})
} else {
await addProject({ ...form,topoIds:[form.topoIds] })
}
ElMessage.success('保存成功')
tableStore.index()
dialogVisible.value = false
}
})
}
const images: any = ref([])
const getImageList = async () => {
getTopoTemplate().then(res => {
images.value = res.data
images.value.forEach(async item => {
let row = await getFileUrl({ filePath: item.filePath })
item.url = row.data
})
})
}
const handleSelect = (filePath: any) => {
form.topoIds = filePath
}
defineExpose({ open })
</script>
<style scoped>
.image-radio-group {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
.image-radio-item {
cursor: pointer;
text-align: center;
}
.hidden-radio {
display: none;
}
.image-container {
position: relative;
border: 2px solid #dcdfe6;
border-radius: 8px;
overflow: hidden;
transition: all 0.3s;
}
.image-container:hover {
border-color: var(--el-color-primary);
}
.image-container.selected {
border-color: var(--el-color-primary);
/* box-shadow: 0 0 8px rgba(64, 158, 255, 0.3); */
}
.image-preview {
width: 120px;
height: 90px;
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* background-color: rgba(64, 158, 255, 0.1); */
display: flex;
align-items: center;
justify-content: center;
}
.check-icon {
color: var(--el-color-primary);
font-size: 24px;
}
.image-name {
margin-top: 8px;
font-size: 14px;
width: 120px;
white-space: nowrap; /* 强制文字单行显示,不换行 */
overflow: hidden; /* 隐藏超出容器的文字 */
text-overflow: ellipsis; /* 超出部分显示省略号(点点点) */
}
</style>

View File

@@ -0,0 +1,106 @@
<template>
<el-dialog draggable class="cn-operate-dialog" width="500px" v-model.trim="dialogVisible" :title="title">
<el-form :inline="false" ref="formRef" :model="form" label-width="auto" class="form-one" :rules="rules">
<el-form-item label="工程名称" prop="name">
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入工程名称" />
</el-form-item>
<el-form-item label="区域" prop="city">
<el-cascader
v-model="form.city"
style="width: 100%"
:options="areaTree"
:props="props"
clearable
filterable
placeholder="请选择区域"
/>
</el-form-item>
<el-form-item label="备注" prop="description">
<el-input v-model="form.description" :rows="2" type="textarea" clearable placeholder="请输入备注" />
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input maxlength="32" show-word-limit-number v-model.number="form.sort" :min="0" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submit">确认</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref, inject } from 'vue'
import { reactive } from 'vue'
import TableStore from '@/utils/tableStore'
import { ElMessage } from 'element-plus'
import { add, update } from '@/api/user-boot/role'
import { useAdminInfo } from '@/stores/adminInfo'
import { addEngineering, updateEngineering } from '@/api/cs-device-boot/edData'
const adminInfo = useAdminInfo()
const tableStore = inject('tableStore') as TableStore
import tree from '@/assets/map/area.json'
// do not use same name with ref
const form = reactive({
name: '',
id: '',
pid: 0,
city: '',
sort: 100,
description: ''
})
const areaTree: any = tree
const rules = {
name: [{ required: true, message: '请输入工程名称', trigger: 'blur' }],
city: [{ required: true, message: '请输入区域', trigger: 'blur' }],
area: [{ required: true, message: '请输入区域', trigger: 'blur' }],
description: [{ required: true, message: '请输入描述', trigger: 'blur' }],
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }]
}
const dialogVisible = ref(false)
const title = ref('新增菜单')
const formRef = ref()
const props = {
label: 'text',
value: 'value',
children: 'children',
// checkStrictly: true
}
const open = (text: string, data?: anyObj) => {
formRef.value?.resetFields()
title.value = text
dialogVisible.value = true
if (data) {
form.id = data.engineeringId
form.name = data.engineeringName
form.city = [data.provinceId,data.cityId]
form.description = data.engineeringRemark
form.sort = data.engineeringSort
} else {
form.id = ''
form.name = ''
form.city = ''
form.description = ''
form.sort = 100
}
}
const submit = async () => {
formRef.value.validate(async valid => {
if (valid) {
if (form.id) {
await updateEngineering({ ...form, province: form.city[0], city: form.city[1] || '' })
} else {
await addEngineering({ ...form, province: form.city[0], city: form.city[1]||'' })
}
ElMessage.success('保存成功')
tableStore.index()
dialogVisible.value = false
}
})
}
defineExpose({ open })
</script>

View File

@@ -0,0 +1,239 @@
<template>
<div class="default-main">
<div style="display: flex">
<div style="width: 800px">
<div class="custom-table-header">
<div class="title">工程列表</div>
<el-button :icon="Plus" type="primary" @click="addRole" class="ml10">新增工程</el-button>
</div>
<Table ref="tableRef" @currentChange="currentChange" />
</div>
<div style="flex: 1">
<div class="custom-table-header">
<div class="title">項目列表</div>
<el-button type="primary" icon="el-icon-Plus" @click="add">新增項目</el-button>
</div>
<div :style="height">
<vxe-table
ref="tableRef1"
v-bind="defaultAttribute"
:data="itemList"
height="auto"
style="width: 100%"
>
<vxe-column field="projectName" title="项目名称"></vxe-column>
<vxe-column field="projectArea" title="地址"></vxe-column>
<vxe-column title="拓扑图">
<template #default="{ row }">
<el-image
:hide-on-click-modal="true"
:preview-teleported="true"
:preview-src-list="[row.topologyImageUrl]"
:src="getUrl(row) ? row.topologyImageUrl : ''"
></el-image>
</template>
</vxe-column>
<vxe-column field="projectRemark" title="备注"></vxe-column>
<vxe-column field="projectSort" title="排序" width="80px"></vxe-column>
<vxe-column title="操作" width="180px">
<template #default="{ row }">
<el-button
style="margin-left: 4px"
type="primary"
link
size="small"
@click="itemModification(row)"
class="ml10 mr10"
>
编辑
</el-button>
<el-popconfirm
@confirm="itemeRemove(row)"
title="确定删除吗?"
confirm-button-type="danger"
>
<template #reference>
<el-button style="margin-left: 4px" type="danger" size="small" link>
刪除
</el-button>
</template>
</el-popconfirm>
</template>
</vxe-column>
</vxe-table>
</div>
</div>
</div>
<!-- 新增工程 -->
<popup ref="popupRef" @save="save" />
<!-- 新增項目 -->
<itemAdd ref="itemAddRef" @save="save" />
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, provide, nextTick } from 'vue'
import { Plus } from '@element-plus/icons-vue'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import { delTemplate, deleteSysExcel, bandRelation, queryList } from '@/api/harmonic-boot/luckyexcel'
import { deleteProject ,deleteEngineering} from '@/api/cs-device-boot/edData'
import { useDictData } from '@/stores/dictData'
import { ElMessage } from 'element-plus'
import { defaultAttribute } from '@/components/table/defaultAttribute'
import { mainHeight } from '@/utils/layout'
import popup from './components/popup.vue'
import itemAdd from './components/itemAdd.vue'
const dictData = useDictData()
defineOptions({
name: 'govern/manage/engineering'
})
const height = mainHeight(80)
const volConTypeList: any = dictData.getBasicData('Dev_Connect')
import { getFileUrl } from '@/api/system-boot/file'
const popupRef = ref()
const tableRef = ref()
const tableRef1 = ref()
const itemList = ref([])
const menuListId = ref([])
const itemAddRef = ref()
const engineeringId = ref('')
const tableStore: any = new TableStore({
url: '/cs-device-boot/engineeringProjectRelation/list',
method: 'POST',
publicHeight: 60,
showPage: false,
column: [
{ field: 'engineeringName', title: '工程名称' },
{
field: 'engineeringAreaName',
title: '区域'
},
{
field: 'engineeringRemark',
title: '备注'
},
{
field: 'engineeringSort',
title: '排序',
width: '80px'
},
{
title: '操作',
fixed: 'right',
width: '150',
render: 'buttons',
buttons: [
{
name: 'edit',
title: '编辑',
type: 'primary',
icon: 'el-icon-Plus',
render: 'basicButton',
click: row => {
popupRef.value.open('编辑工程', row)
}
},
{
name: 'del',
text: '删除',
type: 'danger',
icon: 'el-icon-Delete',
render: 'confirmButton',
popconfirm: {
confirmButtonText: '确认',
cancelButtonText: '取消',
confirmButtonType: 'danger',
title: '确定删除?'
},
click: row => {
deleteEngineering({ id: row.engineeringId }).then(res => {
engineeringId.value = ''
ElMessage.success('删除成功')
tableStore.index()
})
}
}
]
}
],
loadCallback: () => {
if (engineeringId.value == '') {
engineeringId.value = tableStore.table.data[0].engineeringId
}
let list = tableStore.table.data.filter((item: any) => item.engineeringId == engineeringId.value)
tableRef.value.getRef().setCurrentRow(list[0])
itemList.value = list[0].projectInfoList
}
})
provide('tableStore', tableStore)
// 修改模版
const itemModification = (row: any) => {
itemAddRef.value.open('新增项目', tableStore.table.data, row, engineeringId.value)
}
// 删除模版
const itemeRemove = (row: any) => {
deleteProject({ id: row.projectId }).then(res => {
ElMessage.success('删除成功')
tableStore.index()
})
}
const addRole = () => {
// add()
popupRef.value.open('新增工程')
}
const add = () => {
itemAddRef.value.open('新增项目', tableStore.table.data)
}
// 查询绑定模版
const currentChange = (data: any) => {
engineeringId.value = data.row.engineeringId
itemList.value = data.row.projectInfoList
}
// 保存模版
const save = () => {
bandRelation({
modelIds: tableRef1.value.getCheckboxRecords().map(item => item.id),
id: menuListId.value
})
.then(() => {
ElMessage.success('操作成功!')
})
.catch(() => {})
}
const imgList = ref([])
// 获取拓扑图
const getUrl = async (row: any) => {
if (!row.topologyInfo || row.topologyInfo === '/') return false
try {
const res = await getFileUrl({ filePath: row.topologyInfo })
row.topologyImageUrl = res.data
return true
} catch (error) {
return false
}
}
onMounted(() => {
tableStore.index()
})
</script>
<style scoped>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
.el-image {
height: 36px;
}
</style>

View File

@@ -6,7 +6,7 @@
maxlength="32" maxlength="32"
show-word-limit show-word-limit
v-model.trim="form.modelTypeName" v-model.trim="form.modelTypeName"
placeholder="请输入菜单名称" placeholder="请输入报表名称"
/> />
</el-form-item> </el-form-item>
<el-form-item label="报表类型" prop="modelType"> <el-form-item label="报表类型" prop="modelType">

View File

@@ -1,152 +1,152 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader date-picker area> <TableHeader date-picker area>
<template v-slot:select> <template v-slot:select>
<el-form-item label="干扰源类型"> <el-form-item label="干扰源类型">
<el-select multiple clearable collapse-tags v-model.trim="interferenceSourceForm" placeholder="请选择" <el-select multiple clearable collapse-tags v-model.trim="interferenceSourceForm" placeholder="请选择"
@change="onLoadTypeChange"> @change="onLoadTypeChange">
<el-option v-for="item in interferenceSource" :key="item.id" :label="item.name" <el-option v-for="item in interferenceSource" :key="item.id" :label="item.name"
:value="item.id" /> :value="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="电压等级"> <el-form-item label="电压等级">
<el-select multiple clearable collapse-tags v-model.trim="scaleForm" placeholder="请选择" <el-select multiple clearable collapse-tags v-model.trim="scaleForm" placeholder="请选择"
@change="onScaleChange"> @change="onScaleChange">
<el-option v-for="item in level" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in level" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="通讯状态"> <el-form-item label="通讯状态">
<el-select multiple clearable collapse-tags v-model.trim="tableStore.table.params.comFlag" <el-select multiple clearable collapse-tags v-model.trim="tableStore.table.params.comFlag"
placeholder="请选择"> placeholder="请选择">
<el-option label="正常" value="1" /> <el-option label="正常" value="1" />
<el-option label="中断" value="0" /> <el-option label="中断" value="0" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue"
placeholder="根据变电站,终端编号,型号或网络参数查询" /> placeholder="根据变电站,终端编号,型号或网络参数查询" />
</el-form-item> </el-form-item>
</template> </template>
</TableHeader> </TableHeader>
<Table isGroup ref="tableRef" /> <Table isGroup ref="tableRef" />
</div> </div>
</template> </template>
<script setup lang="tsx"> <script setup lang="tsx">
import { ref, onMounted, provide, reactive } from 'vue' import { ref, onMounted, provide, reactive } from 'vue'
import TableStore from '@/utils/tableStore' import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue' import Table from '@/components/table/index.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 Area from '@/components/form/area/index.vue' import Area from '@/components/form/area/index.vue'
defineOptions({ defineOptions({
name: 'voltage/sags/operationsManagement/point' name: 'voltage/sags/operationsManagement/point'
}) })
const dictData = useDictData() const dictData = useDictData()
const interferenceSource = dictData.getBasicData('Interference_Source') const interferenceSource = dictData.getBasicData('Interference_Source')
const level = dictData.getBasicData('Dev_Voltage_Stand') const level = dictData.getBasicData('Dev_Voltage_Stand')
const interferenceSourceForm = ref<string[]>([]) const interferenceSourceForm = ref<string[]>([])
const scaleForm = ref<string[]>([]) const scaleForm = ref<string[]>([])
const tableStore = new TableStore({ const tableStore = new TableStore({
isWebPaging: true, isWebPaging: true,
url: '/device-boot/runManage/getLineLedger', url: '/device-boot/runManage/getLineLedger',
method: 'POST', method: 'POST',
column: [ column: [
{ field: 'areaName', title: '省公司', width: 120 }, { field: 'areaName', title: '省公司', width: 120 },
{ field: 'gdName', title: '市公司', width: 120 }, { field: 'gdName', title: '市公司', width: 120 },
{ field: 'scale', title: '监测点电压等级', width: 150 }, { field: 'scale', title: '监测点电压等级', width: 150 },
{ field: 'lineName', title: '监测点名称', width: 120 }, { field: 'lineName', title: '监测点名称', width: 120 },
{ field: 'bdName', title: '所属变电站', width: 120 }, { field: 'bdName', title: '所属变电站', width: 120 },
{ field: 'loadType', title: '干扰源类型', width: 120 }, { field: 'loadType', title: '干扰源类型', width: 120 },
{ field: 'objName', title: '监测对象名称', width: 180 }, { field: 'objName', title: '监测对象名称', width: 180 },
{ field: 'shortCapacity', title: '最小短路容量(MVA)', width: 190 }, { field: 'shortCapacity', title: '最小短路容量(MVA)', width: 190 },
{ field: 'devCapacity', title: '供电设备容量(MVA )', width: 190 }, { field: 'devCapacity', title: '供电设备容量(MVA )', width: 190 },
{ field: 'dealCapacity', title: '用户协议容量(MVA)', width: 190 }, { field: 'dealCapacity', title: '用户协议容量(MVA)', width: 190 },
{ field: 'comFlag', title: '通讯状态 ', width: 120 }, { field: 'comFlag', title: '通讯状态 ', width: 120 },
{ field: 'id', title: '监测点序号', width: 120 }, { field: 'id', title: '监测点序号', width: 120 },
{ field: 'devName', title: '监测终端编号 ', width: 140 }, { field: 'devName', title: '监测终端编号 ', width: 140 },
{ field: 'ptType', title: '监测终端接线方式', width: 160 }, { field: 'ptType', title: '监测终端接线方式', width: 160 },
{ field: 'voltageDev', title: '电压偏差上限(%)', width: 160 }, { field: 'voltageDev', title: '电压偏差上限(%)', width: 160 },
{ field: 'uvoltageDev', title: '电压偏差下限(%)', width: 160 }, { field: 'uvoltageDev', title: '电压偏差下限(%)', width: 160 },
{ {
field: 'limitValue', field: 'limitValue',
title: '限值', title: '限值',
children: [ children: [
{ field: 'freqDev', title: '频率(Hz)', width: 120 }, { field: 'freqDev', title: '频率(Hz)', width: 120 },
{ field: 'ubalance', title: '三相电压不平衡度(%)', width: 190 }, { field: 'ubalance', title: '三相电压不平衡度(%)', width: 190 },
{ field: 'ineg', title: '负序电流(A)', width: 120 }, { field: 'ineg', title: '负序电流(A)', width: 120 },
{ field: 'flicker', title: '长时闪变', width: 120 }, { field: 'flicker', title: '长时闪变', width: 120 },
{ field: 'uaberrance', title: '电压总谐波畸变率(%)', width: 190 }, { field: 'uaberrance', title: '电压总谐波畸变率(%)', width: 190 },
{ field: 'oddHarm', title: '奇数次谐波电压(%)', width: 180 }, { field: 'oddHarm', title: '奇数次谐波电压(%)', width: 180 },
{ field: 'evenHarm', title: '偶数次谐波电压(%)', width: 180 } { field: 'evenHarm', title: '偶数次谐波电压(%)', width: 180 }
] ]
}, },
{ {
field: 'evaluate', field: 'evaluate',
title: '电流限值', title: '电流限值',
children: [ children: [
{ field: 'iharm2', title: '2次谐波(A)', width: 120 }, { field: 'iharm2', title: '2次谐波(A)', width: 120 },
{ field: 'iharm3', title: '3次谐波(A)', width: 120 }, { field: 'iharm3', title: '3次谐波(A)', width: 120 },
{ field: 'iharm4', title: '4次谐波(A)', width: 120 }, { field: 'iharm4', title: '4次谐波(A)', width: 120 },
{ field: 'iharm5', title: '5次谐波(A)', width: 120 }, { field: 'iharm5', title: '5次谐波(A)', width: 120 },
{ field: 'iharm6', title: '6次谐波(A)', width: 120 }, { field: 'iharm6', title: '6次谐波(A)', width: 120 },
{ field: 'iharm7', title: '7次谐波(A)', width: 120 }, { field: 'iharm7', title: '7次谐波(A)', width: 120 },
{ field: 'iharm8', title: '8次谐波(A)', width: 120 }, { field: 'iharm8', title: '8次谐波(A)', width: 120 },
{ field: 'iharm9', title: '9次谐波(A)', width: 120 }, { field: 'iharm9', title: '9次谐波(A)', width: 120 },
{ field: 'iharm10', title: '10次谐波(A)', width: 140 }, { field: 'iharm10', title: '10次谐波(A)', width: 140 },
{ field: 'iharm11', title: '11次谐波(A)', width: 140 }, { field: 'iharm11', title: '11次谐波(A)', width: 140 },
{ field: 'iharm12', title: '12次谐波(A)', width: 140 }, { field: 'iharm12', title: '12次谐波(A)', width: 140 },
{ field: 'iharm13', title: '13次谐波(A)', width: 140 }, { field: 'iharm13', title: '13次谐波(A)', width: 140 },
{ field: 'iharm14', title: '14次谐波(A)', width: 140 }, { field: 'iharm14', title: '14次谐波(A)', width: 140 },
{ field: 'iharm15', title: '15次谐波(A)', width: 140 }, { field: 'iharm15', title: '15次谐波(A)', width: 140 },
{ field: 'iharm16', title: '16次谐波(A)', width: 140 }, { field: 'iharm16', title: '16次谐波(A)', width: 140 },
{ field: 'iharm17', title: '17次谐波(A)', width: 140 }, { field: 'iharm17', title: '17次谐波(A)', width: 140 },
{ field: 'iharm18', title: '18次谐波(A)', width: 140 }, { field: 'iharm18', title: '18次谐波(A)', width: 140 },
{ field: 'iharm19', title: '19次谐波(A)', width: 140 }, { field: 'iharm19', title: '19次谐波(A)', width: 140 },
{ field: 'iharm10', title: '20次谐波(A)', width: 140 }, { field: 'iharm10', title: '20次谐波(A)', width: 140 },
{ field: 'iharm21', title: '21次谐波(A)', width: 140 }, { field: 'iharm21', title: '21次谐波(A)', width: 140 },
{ field: 'iharm22', title: '22次谐波(A)', width: 140 }, { field: 'iharm22', title: '22次谐波(A)', width: 140 },
{ field: 'iharm23', title: '23次谐波(A)', width: 140 }, { field: 'iharm23', title: '23次谐波(A)', width: 140 },
{ field: 'iharm24', title: '24次谐波(A)', width: 140 }, { field: 'iharm24', title: '24次谐波(A)', width: 140 },
{ field: 'iharm25', title: '25次谐波(A)', width: 140 }, { field: 'iharm25', title: '25次谐波(A)', width: 140 },
{ field: 'inUharm', title: '0.5-1.5次间谐波(A)', width: 180 }, { field: 'inUharm', title: '0.5-1.5次间谐波(A)', width: 180 },
{ field: 'inUharm16', title: '2.5-15.5次间谐波(A)', width: 190 } { field: 'inUharm16', title: '2.5-15.5次间谐波(A)', width: 190 }
] ]
} }
], ],
resetCallback: () => { resetCallback: () => {
interferenceSourceForm.value = [] interferenceSourceForm.value = []
scaleForm.value = [] scaleForm.value = []
} }
}) })
tableStore.table.params.scale = [] tableStore.table.params.scale = []
tableStore.table.params.comFlag = [] tableStore.table.params.comFlag = []
tableStore.table.params.loadType = [] tableStore.table.params.loadType = []
tableStore.table.params.statisticalType = {} tableStore.table.params.statisticalType = {}
tableStore.table.params.serverName = 'event-boot' tableStore.table.params.serverName = 'event-boot'
tableStore.table.params.searchValue = '' tableStore.table.params.searchValue = ''
provide('tableStore', tableStore) provide('tableStore', tableStore)
onMounted(() => { onMounted(() => {
tableStore.index() tableStore.index()
}) })
const onLoadTypeChange = () => { const onLoadTypeChange = () => {
tableStore.table.params.loadType = interferenceSource tableStore.table.params.loadType = interferenceSource
.filter(item => { .filter(item => {
return interferenceSourceForm.value.includes(item.id) return interferenceSourceForm.value.includes(item.id)
}) })
.map(item => { .map(item => {
return { ...item, label: item.name, value: item.id } return { ...item, label: item.name, value: item.id }
}) })
} }
const onScaleChange = () => { const onScaleChange = () => {
tableStore.table.params.scale = level tableStore.table.params.scale = level
.filter(item => { .filter(item => {
return scaleForm.value.includes(item.id) return scaleForm.value.includes(item.id)
}) })
.map(item => { .map(item => {
return { ...item, label: item.name, value: item.id } return { ...item, label: item.name, value: item.id }
}) })
} }
</script> </script>