From b8f758793f0a1f3aecc8b3de57fb6de5985f001a Mon Sep 17 00:00:00 2001 From: dongyukun <1208714201@qq.com> Date: 星期一, 26 五月 2025 18:25:28 +0800 Subject: [PATCH] 调度建议快照 --- src/views/model/sche/suggest/suggestOperationRecord.vue | 21 ++++ src/views/model/sche/snapshotConf/det/index.vue | 3 src/views/model/sche/suggest/suggestSnapshot.vue | 219 +++++++++++++++++++++++++++++++++++++++++++ src/api/model/sche/suggest/suggestSnapshotRecord.ts | 16 +++ src/views/model/sche/snapshotConf/det/configDetForm.vue | 28 +++-- 5 files changed, 276 insertions(+), 11 deletions(-) diff --git a/src/api/model/sche/suggest/suggestSnapshotRecord.ts b/src/api/model/sche/suggest/suggestSnapshotRecord.ts new file mode 100644 index 0000000..009734d --- /dev/null +++ b/src/api/model/sche/suggest/suggestSnapshotRecord.ts @@ -0,0 +1,16 @@ +// 建议快照记录 +import request from "@/config/axios"; + +export interface ChartListReqVO extends PageParam { + chooseDataList: [] +} + +// 列表 +export const getList = (id) => { + return request.get({ url: '/model/suggest/snapshot/record/list?operationId=' + id }) +} + +// 图表 +export const getChartList = (params: ChartListReqVO) => { + return request.get({ url: '/model/suggest/snapshot/record/chartList' , params}) +} diff --git a/src/views/model/sche/snapshotConf/det/configDetForm.vue b/src/views/model/sche/snapshotConf/det/configDetForm.vue index ee9ab76..470a342 100644 --- a/src/views/model/sche/snapshotConf/det/configDetForm.vue +++ b/src/views/model/sche/snapshotConf/det/configDetForm.vue @@ -7,67 +7,73 @@ :rules="formRules" label-width="80px" > - <el-row :gutter="20"> + <el-row :gutter="24"> <el-col :span="12"> <el-form-item label="数据类型" prop="dataType"> <el-input v-model="formData.dataType" placeholder=""/> </el-form-item> </el-col> <el-col :span="12"> - <el-form-item label="数据编号" prop="dataNo"> - <el-input v-model="formData.dataNo" placeholder=""/> + <el-form-item label="数据名称" prop="dataName"> + <el-input v-model="formData.dataName" placeholder=""/> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="数据编号" prop="dataNo"> + <el-input v-model="formData.dataNo" placeholder=""/> + </el-form-item> + </el-col> <el-col :span="12"> <el-form-item label="左侧长度" prop="leftLength"> <el-input v-model="formData.leftLength" placeholder=""/> </el-form-item> </el-col> + </el-row> + <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="右侧长度" prop="rightLength"> <el-input v-model="formData.rightLength" placeholder=""/> </el-form-item> </el-col> - </el-row> - <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="排序" prop="sort"> <el-input v-model="formData.sort" placeholder=""/> </el-form-item> </el-col> + </el-row> + <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="拓展字段1" prop="ext1"> <el-input v-model="formData.ext1" placeholder=""/> </el-form-item> </el-col> - </el-row> - <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="拓展字段2" prop="ext2"> <el-input v-model="formData.ext2" placeholder=""/> </el-form-item> </el-col> + </el-row> + <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="拓展字段3" prop="ext3"> <el-input v-model="formData.ext3" placeholder=""/> </el-form-item> </el-col> - </el-row> - <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="拓展字段4" prop="ext4"> <el-input v-model="formData.ext4" placeholder=""/> </el-form-item> </el-col> + </el-row> + <el-row :gutter="20"> <el-col :span="12"> <el-form-item label="拓展字段5" prop="ext5"> <el-input v-model="formData.ext5" placeholder=""/> </el-form-item> </el-col> </el-row> - </el-form> <template #footer> <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> @@ -92,6 +98,7 @@ id: undefined, confId: undefined, dataType: undefined, + dataName: undefined, dataNo: undefined, leftLength: undefined, rightLength: undefined, @@ -104,6 +111,7 @@ }) const formRules = reactive({ dataType: [{ required: true, message: '不能为空', trigger: 'blur' }], + dataName: [{ required: true, message: '不能为空', trigger: 'blur' }], dataNo: [{ required: true, message: '不能为空', trigger: 'blur' }], }) const formRef = ref() // 表单 Ref diff --git a/src/views/model/sche/snapshotConf/det/index.vue b/src/views/model/sche/snapshotConf/det/index.vue index 0fad67a..36fd064 100644 --- a/src/views/model/sche/snapshotConf/det/index.vue +++ b/src/views/model/sche/snapshotConf/det/index.vue @@ -1,7 +1,7 @@ <template> <el-drawer v-model="drawer" - size="40%" + size="60%" title="参数列表" direction="rtl" :before-close="handleClose" @@ -61,6 +61,7 @@ row-key="id" > <el-table-column prop="dataType" label="数据类型"/> + <el-table-column prop="dataName" label="数据名称"/> <el-table-column prop="dataNo" label="数据编号"/> <el-table-column prop="leftLength" label="左侧长度(min)"/> <el-table-column prop="rightLength" label="右侧侧长度(min)"/> diff --git a/src/views/model/sche/suggest/suggestOperationRecord.vue b/src/views/model/sche/suggest/suggestOperationRecord.vue index 2fd69eb..e666add 100644 --- a/src/views/model/sche/suggest/suggestOperationRecord.vue +++ b/src/views/model/sche/suggest/suggestOperationRecord.vue @@ -50,6 +50,18 @@ align="center" min-width="150" /> + <el-table-column label="快照" align="center" min-width="100" fixed="right"> + <template #default="scope"> + <el-button + link + type="primary" + @click="openSnapshot(scope.row.id)" + v-if="scope.row.operate=='采纳建议'" + > + 快照 + </el-button> + </template> + </el-table-column> </el-table> <!-- 分页 --> <Pagination @@ -60,10 +72,13 @@ /> </ContentWrap> </el-drawer> + <!-- 快照弹窗 --> + <SuggestSnapshot ref="suggestSnapshotRef" @success="getList" /> </template> <script lang="ts" setup> import type {DrawerProps} from 'element-plus' import { getSuggestOperationRecordPage } from '@/api/model/sche/suggest/suggestOperationRecord'; + import SuggestSnapshot from './suggestSnapshot.vue' import {ref} from "vue"; defineOptions({name: 'SuggestOperationRecord'}) @@ -103,6 +118,12 @@ getList() } + /** 快照 */ + const suggestSnapshotRef = ref() + const openSnapshot = (id?: string) => { + suggestSnapshotRef.value.openSnapshot(id) + } + /** 打开弹窗 */ const open = async (modelId?: string, scheduleTime?: string) => { drawer.value = true diff --git a/src/views/model/sche/suggest/suggestSnapshot.vue b/src/views/model/sche/suggest/suggestSnapshot.vue new file mode 100644 index 0000000..31ea85d --- /dev/null +++ b/src/views/model/sche/suggest/suggestSnapshot.vue @@ -0,0 +1,219 @@ +<template> + <el-dialog + title="历史值" + :close-on-click-modal="false" + width="80%" + v-model="visible" + > + <div class="flex-container"> + <el-tag + v-for="item in dataList" + :key="item.dataCode" + class="data-tag" + :type="selectedData.includes(item.dataCode) ? '' : 'info'" + @click="toggleDataSelection(item)" + > + {{ item.dataName }} + </el-tag> + </div> + <div class="right-panel"> + <div + v-for="chart in charts" + :key="chart.id" + class="chart-container" + ref="chartDom" + v-loading="loading" + ></div> + </div> + </el-dialog> +</template> + +<script lang="ts" setup> + import { ref, reactive, nextTick } from 'vue' + import * as echarts from 'echarts' + import * as suggestSnapshotApi from '@/api/model/sche/suggest/suggestSnapshotRecord'; + + const message = useMessage() + const visible = ref(false) + const dataList = ref([]) + const selectedData = ref([]) + const charts = ref([]) + const chartInstances = ref([]) + const loading = ref(false) + + const dataForm = reactive({ + id: "", + }) + + /** 打开弹窗 */ + const open = async (id: string) => { + visible.value = true + dataForm.id = id + await getDataList() + } + + defineExpose({ open }) + + /** 获取数据列表 */ + const getDataList = async () => { + try { + const res = await suggestSnapshotApi.getList(dataForm.id) + dataList.value = res + } catch (error) { + console.error(error) + message.error('获取数据列表失败') + } + } + + /** 切换数据选择 */ + const toggleDataSelection = (item) => { + const index = selectedData.value.indexOf(item.dataCode) + if (index === -1) { + selectedData.value.push(item.dataCode) + } else { + selectedData.value.splice(index, 1) + } + refreshCharts() + } + + /** 刷新图表 */ + const refreshCharts = async () => { + if (selectedData.value.length === 0) { + charts.value = [] + return + } + + loading.value = true + try { + const params = { + chooseDataList: selectedData.value, + } + const chartData = await suggestSnapshotApi.getChartList(params) + + // 销毁之前的图表实例 + chartInstances.value.forEach(instance => instance.dispose()) + chartInstances.value = [] + + // 准备新的图表数据 + charts.value = selectedData.value.map((code, index) => { + const item = dataList.value.find(d => d.dataCode === code) + return { + id: `chart-${index}`, + name: item?.dataName || code, + data: chartData[index] // 假设返回数据是按顺序对应的 + } + }) + + // 渲染新图表 + await nextTick() + renderCharts() + } catch (error) { + console.error(error) + message.error('获取图表数据失败') + } finally { + loading.value = false + } + } + + /** 渲染所有图表 */ + const renderCharts = () => { + const chartContainers = document.querySelectorAll('.chart-container') + + chartContainers.forEach((container, index) => { + const chart = echarts.init(container) + const chartInfo = charts.value[index] + + const option = { + title: { + text: chartInfo.name, + top: 0, + left: "1%", + textStyle: { + fontSize: 14, + }, + }, + tooltip: { + trigger: "axis", + axisPointer: { + type: "line", + lineStyle: { + color: "#cccccc", + width: "1", + type: "dashed", + }, + }, + }, + legend: { + show: false, + top: 10, + }, + grid: { + top: 30, + left: "3%", + right: "5%", + bottom: 10, + containLabel: true, + }, + xAxis: { + type: "category", + boundaryGap: false, + data: chartInfo.data.categories, + }, + yAxis: { + type: "value", + }, + dataZoom: [ + { + type: "inside", + }, + ], + series: [{ + name: chartInfo.name, + type: "line", + data: chartInfo.data.series[0].data, + showSymbol: true, + smooth: false, + lineStyle: { + normal: { + color: "#5B8FF9", + width: 1, + }, + }, + }], + } + + chart.setOption(option) + chartInstances.value.push(chart) + }) + } +</script> + +<style scoped> + .flex-container { + display: flex; + height: 600px; + } + + .left-panel { + width: 250px; + padding-right: 20px; + border-right: 1px solid #eee; + overflow-y: auto; + } + + .right-panel { + flex: 1; + padding-left: 20px; + overflow-y: auto; + } + + .data-tag { + margin: 5px; + cursor: pointer; + } + + .chart-container { + height: 300px; + margin-bottom: 20px; + } +</style> -- Gitblit v1.9.3