台账推送

This commit is contained in:
sjl
2025-10-17 14:37:31 +08:00
parent e7f38519b4
commit 6e5e289271
5 changed files with 200 additions and 29 deletions

View File

@@ -130,3 +130,20 @@ export function updateLine(data: any) {
}) })
} }
//推送日志台账信息
export function pushLog() {
return createAxios({
url: '/cs-device-boot/csTerminalLogs/pushCldInfo',
method: 'post',
})
}
//查询推送结果
export function queryPushResult() {
return createAxios({
url: '/cs-device-boot/csTerminalReply/queryData',
method: 'post',
})
}

View File

@@ -54,3 +54,4 @@ export function updateProcess(data: any) {
params: data params: data
}) })
} }

View File

@@ -1,5 +1,5 @@
<template> <template>
<Tree ref="treRef" :width="width" :data="tree" default-expand-all @changePointType="changePointType" /> <Tree ref="treRef" :width="width" :data="tree" default-expand-all @changePointType="changePointType" @onAdd="onAdd"/>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@@ -20,7 +20,7 @@ defineOptions({
name: 'govern/deviceTree' name: 'govern/deviceTree'
}) })
const emit = defineEmits(['init', 'checkChange', 'pointTypeChange', 'Policy']) const emit = defineEmits(['init', 'checkChange', 'pointTypeChange', 'Policy','onAdd'])
const config = useConfig() const config = useConfig()
const tree = ref() const tree = ref()
const dictData = useDictData() const dictData = useDictData()
@@ -148,6 +148,10 @@ const info = (selectedNodeId?: string) => {
const changePointType = (val: any, obj: any) => { const changePointType = (val: any, obj: any) => {
emit('pointTypeChange', val, obj) emit('pointTypeChange', val, obj)
} }
const onAdd = () => {
emit('onAdd')
}
if (props.template) { if (props.template) {
getTemplateByDept({ id: dictData.state.area[0].id }) getTemplateByDept({ id: dictData.state.area[0].id })
.then((res: any) => { .then((res: any) => {

View File

@@ -10,10 +10,24 @@
<Icon name='el-icon-Search' style='font-size: 16px' /> <Icon name='el-icon-Search' style='font-size: 16px' />
</template> </template>
</el-input> </el-input>
<el-tooltip placement="bottom" :hide-after="0">
<template #content>
<span>台账推送</span>
</template>
<Icon
name="el-icon-Promotion"
size="20"
class="fold ml10 menu-collapse"
style="cursor: pointer;"
:style="{ color: config.getColorVal('elementUiPrimary') }"
@click="onAdd" />
</el-tooltip>
<!-- <Icon @click='onMenuCollapse' :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'" <!-- <Icon @click='onMenuCollapse' :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
:class="menuCollapse ? 'unfold' : ''" size='18' class='fold ml10 menu-collapse' :class="menuCollapse ? 'unfold' : ''" size='18' class='fold ml10 menu-collapse'
style='cursor: pointer' v-if='props.canExpand' /> --> style='cursor: pointer' v-if='props.canExpand' /> -->
</div> </div>
<el-tree :style="{ height: 'calc(100vh - 200px)' }" <el-tree :style="{ height: 'calc(100vh - 200px)' }"
style=' overflow: auto;' ref='treeRef' :props='defaultProps' highlight-current style=' overflow: auto;' ref='treeRef' :props='defaultProps' highlight-current
@check-change="checkTreeNodeChange" :filter-node-method='filterNode' node-key='id' v-bind='$attrs'> @check-change="checkTreeNodeChange" :filter-node-method='filterNode' node-key='id' v-bind='$attrs'>
@@ -35,6 +49,7 @@ import { ElTree } from 'element-plus'
import { emit } from 'process'; import { emit } from 'process';
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import { t } from 'vxe-table'; import { t } from 'vxe-table';
import { useConfig } from '@/stores/config'
defineOptions({ defineOptions({
name: 'govern/tree' name: 'govern/tree'
@@ -49,6 +64,7 @@ const props = withDefaults(defineProps<Props>(), {
width: '280px', width: '280px',
canExpand: true canExpand: true
}) })
const config = useConfig()
const { proxy } = useCurrentInstance() const { proxy } = useCurrentInstance()
const menuCollapse = ref(false) const menuCollapse = ref(false)
const filterText = ref('') const filterText = ref('')
@@ -56,7 +72,7 @@ const defaultProps = {
label: 'name', label: 'name',
value: 'id' value: 'id'
} }
const emit = defineEmits(['checkTreeNodeChange']) const emit = defineEmits(['checkTreeNodeChange','onAdd'])
watch(filterText, val => { watch(filterText, val => {
treeRef.value!.filter(val) treeRef.value!.filter(val)
}) })
@@ -105,6 +121,11 @@ const checkTreeNodeChange = () => {
// console.log(treeRef.value?.getCheckedNodes(), "ikkkkkiisiiisis"); // console.log(treeRef.value?.getCheckedNodes(), "ikkkkkiisiiisis");
emit('checkTreeNodeChange', treeRef.value?.getCheckedNodes()) emit('checkTreeNodeChange', treeRef.value?.getCheckedNodes())
} }
const onAdd = () => {
emit('onAdd')
}
const treeRef = ref<InstanceType<typeof ElTree>>() const treeRef = ref<InstanceType<typeof ElTree>>()
defineExpose({ treeRef }) defineExpose({ treeRef })
</script> </script>

View File

@@ -2,7 +2,7 @@
<div class="default-main device-manage" :style="{ height: pageHeight.height }" v-loading="loading"> <div class="default-main device-manage" :style="{ height: pageHeight.height }" v-loading="loading">
<splitpanes style="height: 100%" class="default-theme" id="navigation-splitpanes"> <splitpanes style="height: 100%" class="default-theme" id="navigation-splitpanes">
<pane :size="size"> <pane :size="size">
<CloudDeviceEntryTree ref="TerminalRef" @node-click="nodeClick" @init="nodeClick"></CloudDeviceEntryTree> <CloudDeviceEntryTree ref="TerminalRef" @node-click="nodeClick" @init="nodeClick" @onAdd="onAdd"></CloudDeviceEntryTree>
</pane> </pane>
<pane style="background: #fff"> <pane style="background: #fff">
<div class="device-manage-right"> <div class="device-manage-right">
@@ -98,7 +98,7 @@
class="form-item" class="form-item"
label="省:" label="省:"
v-if="nodeLevel > 0 || pageStatus == 2" v-if="nodeLevel > 0 || pageStatus == 2"
prop="'engineeringParam.province'"
:rules="{ required: true, message: '请选择省', trigger: 'change' }" :rules="{ required: true, message: '请选择省', trigger: 'change' }"
> >
<el-select <el-select
@@ -122,7 +122,7 @@
class="form-item" class="form-item"
label="市:" label="市:"
v-if="(nodeLevel > 0 || pageStatus == 2)" v-if="(nodeLevel > 0 || pageStatus == 2)"
:prop="'engineeringParam.city'"
:rules="{ required: true, message: '请选择市', trigger: 'change' }" :rules="{ required: true, message: '请选择市', trigger: 'change' }"
> >
<el-select <el-select
@@ -185,7 +185,6 @@
<el-form-item <el-form-item
class="form-item" class="form-item"
label="项目名称:" label="项目名称:"
:prop="'projectInfoList.' + index + '.name'"
:rules="[{ required: true, message: '请输入项目名称', trigger: 'blur' }]" :rules="[{ required: true, message: '请输入项目名称', trigger: 'blur' }]"
> >
<el-input <el-input
@@ -328,6 +327,13 @@
placeholder="请输入网络设备ID" placeholder="请输入网络设备ID"
></el-input> ></el-input>
</el-form-item> --> </el-form-item> -->
<el-form-item class="form-item" label="合同号:">
<el-input
v-model="busItem.cntractNo"
placeholder="请输入合同号"
:disabled="!((nodeLevel == 3 && pageStatus == 3) || ((nodeLevel == 2 || (nodeLevel == 1 && pageStatus == 2)) && pageStatus == 2))"
></el-input>
</el-form-item>
<el-form-item <el-form-item
class="form-item" class="form-item"
label="所属前置机:" label="所属前置机:"
@@ -339,7 +345,7 @@
filterable filterable
v-model="busItem.nodeId" v-model="busItem.nodeId"
placeholder="请选择所属前置机" placeholder="请选择所属前置机"
:disabled="!((nodeLevel == 3 && pageStatus == 3) || ((nodeLevel == 2 || (nodeLevel == 1 && pageStatus == 2)) && pageStatus == 2))" :disabled="!(pageStatus == 2 && nodeLevel >= 2)"
> >
<el-option <el-option
v-for="option in affiliatiedFrontArr" v-for="option in affiliatiedFrontArr"
@@ -349,13 +355,14 @@
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item class="form-item" label="合同号:"> <el-form-item class="form-item" label="进程号:">
<el-input <el-input
v-model="busItem.cntractNo" v-model="busItem.nodeProcess"
placeholder="请输入合同号" placeholder="自动分配"
:disabled="!((nodeLevel == 3 && pageStatus == 3) || ((nodeLevel == 2 || (nodeLevel == 1 && pageStatus == 2)) && pageStatus == 2))" :disabled="true"
></el-input> ></el-input>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
class="form-item" class="form-item"
label="排序:" label="排序:"
@@ -532,6 +539,52 @@
</div> </div>
</pane> </pane>
</splitpanes> </splitpanes>
<el-dialog
v-model="resultDialogVisible"
title="台账推送结果"
width="50%"
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="true"
@close="handleDialogClose"
>
<div v-if="pushResult" style="padding: 20px;">
<el-result
:icon="pushResult.success ? 'success' : 'error'"
:title="pushResult.success ? '推送成功' : '推送失败'"
:sub-title="pushResult.message"
>
</el-result>
<!-- 日志展示区域 -->
<div style="margin-top: 20px;">
<h3>推送日志:</h3>
<div style="max-height: 300px; overflow-y: auto; border: 1px solid #ebeef5; border-radius: 4px; padding: 10px;">
<div
v-for="(log, index) in pushResult.logs"
:key="index"
style="padding: 5px 0; border-bottom: 1px solid #f0f0f0;"
>
<span style="margin-left: 10px;">{{ log.message }}</span>
</div>
<div v-if="pushResult.logs.length === 0" style="text-align: center; color: #999; padding: 20px;">
暂无日志信息
</div>
</div>
</div>
</div>
<div v-else style="text-align: center; padding: 20px;">
<el-icon :size="40" style="color: #409EFF;">
<Loading />
</el-icon>
<p style="margin-top: 15px; font-size: 16px;">正在推送台账信息,请稍候...</p>
<p style="margin-top: 10px; color: #999;">预计需要30秒左右</p>
<p style="margin-top: 10px; color: #999;">已等待: {{ countdown }}秒</p>
</div>
</el-dialog>
</div> </div>
</template> </template>
@@ -545,12 +598,13 @@ import { mainHeight } from '@/utils/layout'
import { useDictData } from '@/stores/dictData' import { useDictData } from '@/stores/dictData'
import { ref, reactive, onMounted, computed } from 'vue' import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import {getById,getEngineerById,getProjectById,getEquipmentById,getInfoById,nodeAllList,addLedger,deleteProject,deleteLine,deleteEquipment,updateEquipment,updateLine} from '@/api/cs-device-boot/cloudDeviceEntry' import {getById,getEngineerById,getProjectById,getEquipmentById,getInfoById,nodeAllList,addLedger,deleteProject,deleteLine,deleteEquipment,updateEquipment,updateLine,pushLog,queryPushResult} from '@/api/cs-device-boot/cloudDeviceEntry'
import tree from '@/assets/map/area.json' import tree from '@/assets/map/area.json'
import { queryByCode,queryCsDictTree } from '@/api/system-boot/dictTree' import { queryByCode,queryCsDictTree } from '@/api/system-boot/dictTree'
import MacAddressInput from '@/components/form/mac/MacAddressInput.vue' import MacAddressInput from '@/components/form/mac/MacAddressInput.vue'
import { auditEngineering } from '@/api/cs-device-boot/edData' import { auditEngineering } from '@/api/cs-device-boot/edData'
import { convertToObject } from 'typescript' import { convertToObject } from 'typescript'
import { Loading } from '@element-plus/icons-vue'
defineOptions({ defineOptions({
name: '/cs-device-boot/cloudDeviceEntry' name: '/cs-device-boot/cloudDeviceEntry'
@@ -640,6 +694,7 @@ interface DeviceInfo {
nodeId: string nodeId: string
cntractNo: string cntractNo: string
sort: number sort: number
nodeProcess:number
} }
// 设备信息列表 // 设备信息列表
const deviceInfoList = ref<DeviceInfo[]>([]) const deviceInfoList = ref<DeviceInfo[]>([])
@@ -654,6 +709,7 @@ interface LineInfo {
ct2Ratio: number ct2Ratio: number
volGrade: number | string volGrade: number | string
devMac: string devMac: string
} }
// 监测点信息列表 // 监测点信息列表
const lineInfoList = ref<LineInfo[]>([]) const lineInfoList = ref<LineInfo[]>([])
@@ -755,6 +811,8 @@ const nodeClick = (e: anyObj, data: any) => {
}else if(nodeData.value.level == 4){ //监测点 }else if(nodeData.value.level == 4){ //监测点
nodeLevel.value = 4 nodeLevel.value = 4
} }
// 更新 nextfalg 状态
nextfalg.value = nodeLevel.value >= 4;
// 根据节点层级清理不需要的数据 // 根据节点层级清理不需要的数据
cleanUnnecessaryData() cleanUnnecessaryData()
/**不是根节点请求数据 */ /**不是根节点请求数据 */
@@ -763,6 +821,81 @@ const nodeClick = (e: anyObj, data: any) => {
} }
const countdown = ref(0)
const resultDialogVisible = ref(false)
const pushResult = ref<{
success: boolean;
message: string;
logs: Array<{message: string }>
} | null>(null)
const timer = ref<number | null>(null)
const handleDialogClose = () => {
pushResult.value = null
resultDialogVisible.value = false
if (timer.value) {
clearInterval(timer.value)
timer.value = null
}
countdown.value = 0
}
//台账推送
const onAdd = async () => {
resultDialogVisible.value = true
pushResult.value = null
countdown.value = 0
// 启动倒计时
if (timer.value) clearInterval(timer.value)
timer.value = window.setInterval(() => {
countdown.value++
if (countdown.value >= 30) {
clearInterval(timer.value!)
timer.value = null
}
}, 1000)
try {
// 调用推送日志接口
await pushLog()
// 等待30秒
await new Promise(resolve => setTimeout(resolve, 30000))
// 30秒后调用查询推送结果接口
const result = await queryPushResult()
// 处理返回的日志数据
const logs = Array.isArray(result.data) ? result.data : []
// 根据结果进行处理
pushResult.value = {
success: true,
message: '台账推送成功',
logs: logs.map((item: any) => ({
message: item.message || JSON.stringify(item)
}))
}
} catch (error: any) {
pushResult.value = {
success: false,
message: error.message || '推送过程中发生错误',
logs: [{
message: error.message || '未知错误'
}]
}
} finally {
if (timer.value) {
clearInterval(timer.value)
timer.value = null
}
countdown.value = 0
}
}
/** /**
* 根据当前节点层级清理不需要的数据 * 根据当前节点层级清理不需要的数据
*/ */
@@ -894,7 +1027,8 @@ const add = () => {
ndid: '', ndid: '',
nodeId: '', nodeId: '',
cntractNo: '', cntractNo: '',
sort: 0 sort: 0,
nodeProcess: 1,
}) })
busBarIndex.value = (deviceInfoList.value.length - 1).toString() busBarIndex.value = (deviceInfoList.value.length - 1).toString()
// 清理监测点数据 // 清理监测点数据
@@ -1215,17 +1349,6 @@ const remove = () => {
} }
// 下一步 // 下一步
const next = async () => { const next = async () => {
console.log('mainForm',mainForm.value.validate)
await mainForm.value?.validate((valid: boolean) => {
console.log('valid', valid)
if (valid) {
}
})
}
const executeNextStep = () => {
// 在新增模式下pageStatus == 2保存当前数据并创建下一个层级的Tab // 在新增模式下pageStatus == 2保存当前数据并创建下一个层级的Tab
switch (nodeLevel.value) { switch (nodeLevel.value) {
case 0: // 工程层级下一步创建项目Tab case 0: // 工程层级下一步创建项目Tab
@@ -1257,7 +1380,8 @@ const executeNextStep = () => {
ndid: '', ndid: '',
nodeId: '', nodeId: '',
cntractNo: '', cntractNo: '',
sort: 0 sort: 0,
nodeProcess: 1,
}) })
busBarIndex.value = (deviceInfoList.value.length - 1).toString() busBarIndex.value = (deviceInfoList.value.length - 1).toString()
nextfalg.value = false nextfalg.value = false
@@ -1282,7 +1406,7 @@ const executeNextStep = () => {
devMac: '', devMac: '',
}) })
lineIndex.value = (lineInfoList.value.length - 1).toString() lineIndex.value = (lineInfoList.value.length - 1).toString()
nextfalg.value = false nextfalg.value = true
nodeLevel.value = 3 nodeLevel.value = 3
break break
case 3: // 监测点层级 case 3: // 监测点层级
@@ -1294,8 +1418,11 @@ const executeNextStep = () => {
nodeLevel.value = 4 nodeLevel.value = 4
break break
} }
} }
// 撤销 // 撤销
const black = () => { const black = () => {
pageStatus.value = 1 pageStatus.value = 1
@@ -1952,7 +2079,8 @@ const handleBusBarTabsEdit = (targetName: any, action: any) => {
ndid: '', ndid: '',
nodeId: '', nodeId: '',
cntractNo: '', cntractNo: '',
sort: 0 sort: 0,
nodeProcess: 1,
}) })
busBarIndex.value = (deviceInfoList.value.length - 1).toString() busBarIndex.value = (deviceInfoList.value.length - 1).toString()
} else if (action === 'remove') { } else if (action === 'remove') {