dongyukun
2025-05-26 b8f758793f0a1f3aecc8b3de57fb6de5985f001a
调度建议快照
已修改3个文件
已添加2个文件
287 ■■■■■ 文件已修改
src/api/model/sche/suggest/suggestSnapshotRecord.ts 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/sche/snapshotConf/det/configDetForm.vue 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/sche/snapshotConf/det/index.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/sche/suggest/suggestOperationRecord.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/sche/suggest/suggestSnapshot.vue 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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})
}
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
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)"/>
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
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>