dongyukun
2024-11-15 1d160a52bb6d146d6130e449af0f57ba92cbe015
Merge remote-tracking branch 'origin/master'
已添加3个文件
已删除4个文件
已修改10个文件
1437 ■■■■ 文件已修改
src/api/model/mcs/index.ts 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/model/pre/dm/index.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/model/pre/item/index.ts 145 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/model/pre/predict/index.ts 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/model/pre/result/index.ts 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/model/pre/type/index.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/model/sche/model/index.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/dict.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/data/point/DaPointChart.vue 265 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/pre/analysis/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/pre/item/MmPredictItemChart.vue 253 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/pre/item/MmPredictItemForm.vue 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/pre/item/index.vue 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/pre/result/MmResultTableForm.vue 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/pre/result/index.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/pre/type/ItemTypeForm.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/pre/type/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/model/mcs/index.ts
对比新文件
@@ -0,0 +1,23 @@
import request from '@/config/axios'
export interface PreDataBarLineReqVO {
  queryIds: string[],
  predictTime: string,
  startTime: string,
  endTime: string
}
export interface PreDataItemChartReqVO {
  itemId: string,
  startTime: string,
  endTime: string
}
export const getPreDataCharts = (data: PreDataBarLineReqVO) => {
  return request.post({ url: '/model/api/mcs/predict-data/charts', data })
}
export const getPreDataItemChart = (data: PreDataItemChartReqVO) => {
  return request.post({ url: '/model/api/mcs/predict-data/item-chart', data })
}
src/api/model/pre/dm/index.ts
@@ -1,7 +1,7 @@
import request from '@/config/axios'
export interface DmModuleVO {
  id: string
  id: string,
  modulename: string,
  moduletype: string,
  cycle: string
src/api/model/pre/item/index.ts
@@ -1,43 +1,140 @@
import request from '@/config/axios'
import {UploadRequestOptions} from "element-plus/es/components/upload/src/upload";
export interface MmItemTypeVO {
  id: string
export interface MmPredictItemVO {
  id: string,
  itemtypename: string,
  itemclasstype: string,
  assemblyname: string
  mmPredictItem: {
    id: string,
    itemno: string,
    itemname: string,
    caltypeid: string,
    itemtypeid: string,
    predictlength: string,
    granularity: number,
    status: string,
    isfuse: number,
    predictphase: string,
    workchecked: number,
    unittransfactor: string,
    saveindex: string
  },
  dmModuleItem: {
    id: string,
    moduleid: string,
    itemid: string,
    itemorder: number,
    status: number,
    categoryid: string
  },
  mmItemOutput: {
    id: string,
    itemid: string,
    pointid: string,
    resulttableid: string,
    tagname: string,
    outputorder: number
  },
  mmPredictModel: {
    id: string,
    modelno: string,
    modelname: string,
    itemid: string,
    arithid: string,
    trainsamplength: number,
    predictsamplength: string,
    isonlinetrain: string,
    modelpath: string,
    isnormal: string,
    normalmax: string,
    normalmin: string,
    status: number,
    classname: string,
    methodname: string,
    modelparamstructure: string,
    resultstrid: string,
    settingmap: string
  },
  mmPredictMergeItem: {
    id: string,
    itemid: string,
    expression: string,
    num: string
  },
  modelparamtypeList: [],
  mmModelArithSettingsList: [],
  mmModelParamList: []
}
export interface MmItemTypePageReqVO extends PageParam {
  itemtypename?: string
export interface MmPredictItemPageReqVO extends PageParam {
  itemno?: string,
  itemname?: string,
}
// 查询MmItemType列表
export const getMmItemTypePage = (params: MmItemTypePageReqVO) => {
  return request.get({ url: '/model/pre/item-type/page', params })
// 查询MmPredictItem列表
export const getMmPredictItemPage = (params: MmPredictItemPageReqVO) => {
  return request.get({ url: '/model/pre/item/page', params })
}
// 查询MmItemType详情
export const getMmItemType = (id: number) => {
  return request.get({ url: `/model/pre/item-type/get/${id}`})
// 查询MmPredictItem详情
export const getMmPredictItem = (id: number) => {
  return request.get({ url: `/model/pre/item/get/${id}`})
}
// 新增MmItemType
export const createMmItemType = (data: MmItemTypeVO) => {
  return request.post({ url: '/model/pre/item-type/create', data })
// 新增MmPredictItem
export const createMmPredictItem = (data: MmPredictItemVO) => {
  return request.post({ url: '/model/pre/item/create', data })
}
// 修改MmItemType
export const updateMmItemType = (data: MmItemTypeVO) => {
  return request.put({ url: '/model/pre/item-type/update', data })
// 修改MmPredictItem
export const updateMmPredictItem = (data: MmPredictItemVO) => {
  return request.put({ url: '/model/pre/item/update', data })
}
// 删除MmItemType
export const deleteMmItemType = (id: number) => {
  return request.delete({ url: '/model/pre/item-type/delete?id=' + id })
// 删除MmPredictItem
export const deleteMmPredictItem = (id: number) => {
  return request.delete({ url: '/model/pre/item/delete?id=' + id })
}
// 查询MmPredictItem列表
export const getMmPredictItemList = (params) => {
  return request.get({ url: `/model/pre/item/list`, params})
}
// 查询getItemTypeList详情
export const getItemTypeList = () => {
  return request.get({ url: `/model/pre/item-type/list`})
export const updateModel = (data: any) => {
  return request.upload({ url: '/model/pre/item/upload-model', data })
}
export const useUpload = () => {
  const uploadUrl = import.meta.env.VITE_BASE_URL + '/admin-api/model/pre/item/upload-model'
  const httpRequest = async (options: UploadRequestOptions) => {
    return new Promise((resolve, reject) => {
      updateModel({ file: options.file })
        .then((res) => {
          if (res.code === 0) {
            resolve(res)
          } else {
            reject(res)
          }
        })
        .catch((res) => {
          reject(res)
        })
    })
  }
  return {
    uploadUrl,
    httpRequest
  }
}
export const getMmPredictItemTree = () => {
  return request.get({ url: `/model/pre/item/tree`})
}
export const getViewCharts = (params) => {
  return request.get({ url: `/model/pre/item/view-charts`,params})
}
src/api/model/pre/predict/index.ts
文件已删除
src/api/model/pre/result/index.ts
文件已删除
src/api/model/pre/type/index.ts
对比新文件
@@ -0,0 +1,43 @@
import request from '@/config/axios'
export interface MmItemTypeVO {
  id: string
  itemtypename: string,
  itemclasstype: string,
  assemblyname: string
}
export interface MmItemTypePageReqVO extends PageParam {
  itemtypename?: string
}
// 查询MmItemType列表
export const getMmItemTypePage = (params: MmItemTypePageReqVO) => {
  return request.get({ url: '/model/pre/item-type/page', params })
}
// 查询MmItemType详情
export const getMmItemType = (id: number) => {
  return request.get({ url: `/model/pre/item-type/get/${id}`})
}
// 新增MmItemType
export const createMmItemType = (data: MmItemTypeVO) => {
  return request.post({ url: '/model/pre/item-type/create', data })
}
// 修改MmItemType
export const updateMmItemType = (data: MmItemTypeVO) => {
  return request.put({ url: '/model/pre/item-type/update', data })
}
// 删除MmItemType
export const deleteMmItemType = (id: number) => {
  return request.delete({ url: '/model/pre/item-type/delete?id=' + id })
}
// 查询getItemTypeList详情
export const getItemTypeList = () => {
  return request.get({ url: `/model/pre/item-type/list`})
}
src/api/model/sche/model/index.ts
@@ -1,6 +1,6 @@
import request from '@/config/axios'
import * as DataPointApi from '@/api/data/da/point'
import * as PredictItemApi from '@/api/model/pre/predict'
import * as PredictItemApi from '@/api/model/pre/item'
import {CommonEnabled} from "@/utils/constants";
export interface ScheduleModelVO {
src/utils/dict.ts
@@ -162,6 +162,8 @@
  MODEL_TYPE = 'model_type',
  MODEL_METHOD_SETTING_TYPE = 'model_method_setting_type',
  MODEL_METHOD_SETTING_VALUE_TYPE = 'model_method_setting_value_type',
  PRED_GRANULARITY = 'pred_granularity',
  ITEM_RUN_STATUS = 'item_run_status',
  // ========== DATA - 数据平台模块  ==========
  DATA_FIELD_TYPE = 'data_field_type',
@@ -183,4 +185,5 @@
  NVR_ONLINE_STATUS = 'nvr_online_status',
  CAMERA_BRAND = 'camera_brand',
  CAPTURE_TYPE = 'capture_type',
  MODEL_RESULT_TYPE = 'model_result_type',
}
src/views/data/point/DaPointChart.vue
@@ -41,7 +41,8 @@
          :loading="exportLoading"
          v-hasPermi="['data:point:export']"
        >
          <Icon icon="ep:download" />导出
          <Icon icon="ep:download"/>
          导出
        </el-button>
      </el-form-item>
    </el-form>
@@ -50,143 +51,147 @@
</template>
<script lang="ts" setup>
  import {ref} from 'vue';
  import * as echarts from 'echarts';
  import * as DaPoint from '@/api/data/da/point/daPointChart'
  import {getYMDHM0} from "@/utils/dateUtil"
  import download from "@/utils/download";
  const message = useMessage() // 消息弹窗
  const visible = ref(false);
  const chartDom = ref(null);
  let myChart = null;
  const chartParams = reactive({
    codes:[],
    startDate : undefined,
    endDate: undefined,
  })
  const dataForm = ref({
    id: "",
    pointNo: "",
    pointName: "",
    pointTypeName: "",
    startTime: getYMDHM0(new Date() - 60 * 60 * 1000),
    endTime: "",
  });
import {ref} from 'vue';
import * as echarts from 'echarts';
import * as DaPoint from '@/api/data/da/point/daPointChart'
import {getYMDHM0} from "@/utils/dateUtil"
import download from "@/utils/download";
  /** 打开弹窗 */
  const open = async (row: object) => {
    visible.value = true
    dataForm.value.id = row.id;
    dataForm.value.pointNo = row.pointNo;
    dataForm.value.pointName = row.pointName;
    getDataList();
  }
const message = useMessage() // 消息弹窗
const visible = ref(false);
const chartDom = ref(null);
let myChart = null;
const chartParams = reactive({
  codes: [],
  pointNo: undefined,
  startDate: undefined,
  endDate: undefined,
})
const dataForm = ref({
  id: "",
  pointNo: "",
  pointName: "",
  pointTypeName: "",
  startTime: getYMDHM0(new Date() - 60 * 60 * 1000),
  endTime: "",
});
  defineExpose({open}) // 提供 open 方法,用于打开弹窗
/** 打开弹窗 */
const open = async (row: object) => {
  visible.value = true
  dataForm.value.id = row.id;
  dataForm.value.pointNo = row.pointNo;
  dataForm.value.pointName = row.pointName;
  getDataList();
}
  async function getDataList() {
    visible.value = true;
    if (dataForm.value.id) {
      try {
        chartParams.codes=[dataForm.value.pointNo];
        chartParams.startDate = dataForm.value.startTime;
        chartParams.endDate = dataForm.value.endTime;
        const data = await DaPoint.getPointDaChart(chartParams)
        let seriesData = []
        data.series.forEach(item => {
          seriesData.push({
            name: item.name,
            type: "line",
            data: item.data,
            showSymbol: true,
            smooth: false,
            lineStyle: {
              normal: {
                color: "#5B8FF9",
                width: 1,
              },
            },
          });
        })
defineExpose({open}) // 提供 open 方法,用于打开弹窗
        myChart = echarts.init(chartDom.value);
        const option = {
          title: {
            text: dataForm.value.pointName,
            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: data.categories,
          },
          yAxis: {
            type: "value",
          },
          dataZoom: [
            {
              type: "inside",
            },
          ],
          series: seriesData,
        };
        myChart.setOption(option);
      } catch (error) {
        console.error(error)
      }
    }
  }
  /** 导出按钮操作 */
  const exportLoading = ref(false)
  const handleExport = async () => {
    chartParams.codes=[dataForm.value.pointNo];
    chartParams.startDate = dataForm.value.startTime;
    chartParams.endDate = dataForm.value.endTime;
async function getDataList() {
  visible.value = true;
  if (dataForm.value.id) {
    try {
      // 导出的二次确认
      await message.exportConfirm()
      // 发起导出
      exportLoading.value = true
      const data = await DaPoint.exportDaPointValue(chartParams)
      download.excel(data, dataForm.value.pointName +'.xls')
    } catch {
    } finally {
      exportLoading.value = false
      chartParams.codes = [dataForm.value.pointNo];
      chartParams.startDate = dataForm.value.startTime;
      chartParams.endDate = dataForm.value.endTime;
      const data = await DaPoint.getPointDaChart(chartParams)
      let seriesData = []
      data.series.forEach(item => {
        seriesData.push({
          name: item.name,
          type: "line",
          data: item.data,
          showSymbol: true,
          smooth: false,
          lineStyle: {
            normal: {
              color: "#5B8FF9",
              width: 1,
            },
          },
        });
      })
      myChart = echarts.init(chartDom.value);
      const option = {
        title: {
          text: dataForm.value.pointName,
          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: data.categories,
        },
        yAxis: {
          type: "value",
        },
        dataZoom: [
          {
            type: "inside",
          },
        ],
        series: seriesData,
      };
      myChart.setOption(option);
    } catch (error) {
      console.error(error)
    }
  }
}
/** 导出按钮操作 */
const exportLoading = ref(false)
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const data = await DaPoint.exportDaPointValue({
      pointNo: dataForm.value.pointNo,
      start: dataForm.value.startTime,
      end: dataForm.value.endTime
    })
    download.excel(data, dataForm.value.pointName + '.xls')
  } catch {
  } finally {
    exportLoading.value = false
  }
}
</script>
<style>
  .el-select {
    width: 100%;
  }
.el-select {
  width: 100%;
}
  .result-chart {
    height: 500px;
  }
.result-chart {
  height: 500px;
}
</style>
src/views/model/pre/analysis/index.vue
@@ -164,7 +164,6 @@
          </div>
        </div>
      </el-form>
    </div>
  </el-card>
</template>
@@ -173,7 +172,7 @@
  import * as CategoryApi from "@/api/data/ind/category";
  import * as DmModule from '@/api/model/pre/dm'
  import * as ItemApi from "@/api/data/ind/item/item";
  import * as MmPredictItem from '@/api/model/pre/predict'
  import * as MmPredictItem from '@/api/model/pre/item'
  import * as echarts from "echarts";
  import { onMounted, ref } from 'vue';
  import { Search, ArrowLeft, ArrowRight,} from '@element-plus/icons-vue'
@@ -684,7 +683,7 @@
  .his-body {
    width: 100%;
    height: calc(calc(100vh - 48px - 38px - 130px));
    height: calc(calc(100vh - 68px - 38px - 160px));
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
src/views/model/pre/item/MmPredictItemChart.vue
对比新文件
@@ -0,0 +1,253 @@
<template>
  <el-dialog
    title="预测数据"
    :close-on-click-modal="false"
    width="50%"
    v-model="visible"
  >
    <el-form
      :inline="true"
      :model="dataForm"
      @keydown.enter="getDataList()"
    >
      <el-form-item label="开始时间">
        <el-date-picker
          size="mini"
          v-model="dataForm.startTime"
          format="YYYY-MM-DD HH:mm:00"
          value-format="YYYY-MM-DD HH:mm:00"
          type="datetime"
          :clearable="false"
          placeholder="选择日期时间"/>
      </el-form-item>
      <el-form-item label="结束时间">
        <el-date-picker
          size="mini"
          v-model="dataForm.endTime"
          format="YYYY-MM-DD HH:mm:00"
          value-format="YYYY-MM-DD HH:mm:00"
          type="datetime"
          :clearable="false"
          placeholder="选择日期时间"/>
      </el-form-item>
      <el-form-item>
        <el-button @click="getDataList()">查询</el-button>
      </el-form-item>
      <el-form-item>
        <el-button
          type="success"
          plain
          @click="handleExport"
          :loading="exportLoading"
        >
          <Icon icon="ep:download"/>
          导出
        </el-button>
      </el-form-item>
    </el-form>
    <div ref="chartDomPre" class="result-chart"></div>
  </el-dialog>
</template>
<script lang="ts" setup>
import {ref} from 'vue';
import * as echarts from 'echarts';
import * as McsApi from '@/api/model/mcs'
import {getYMDHM0} from "@/utils/dateUtil"
import download from "@/utils/download";
const message = useMessage() // 消息弹窗
const visible = ref(false);
const chartDomPre = ref(null);
let myChart = null;
const chartParams = reactive({
  itemId: undefined,
  startTime: undefined,
  endTime: undefined,
})
const dataForm = ref({
  id: "",
  itemName: "",
  startTime: getYMDHM0(new Date() - 60 * 60 * 1000),
  endTime: getYMDHM0(new Date() + 60 * 60 * 1000),
});
/** 打开弹窗 */
const open = async (row: object) => {
  visible.value = true
  resetForm()
  dataForm.value.id = row.id;
  dataForm.value.itemName = row.itemname;
  if (row.id) {
    getDataList();
  }
}
defineExpose({open}) // 提供 open 方法,用于打开弹窗
async function getDataList() {
  visible.value = true;
  if (dataForm.value.id) {
    try {
      chartParams.itemId = dataForm.value.id;
      chartParams.startTime = dataForm.value.startTime;
      chartParams.endTime = dataForm.value.endTime;
      const data = await McsApi.getPreDataItemChart(chartParams)
      let legendData = []
      if (data.legend && data.legend.length > 0) {
        data.legend.forEach(item => {
          legendData.push(item + ":" + '真实值')
          legendData.push(item + ":" + '预测值')
        })
      }
      let seriesData = []
      if (data.lastTime) {
        seriesData.push({
          name: '',
          data: [null],
          type: 'line',
          smooth: true,
          color: 'green',
          markLine: {
            silent: true,
            lineStyle: {
              color: '#32a487',
              width: 2
            },
            data: [{
              xAxis: data.lastTime
            }],
            label: {
              normal: {
                formatter: data.lastTime
              }
            },
            symbol: ['circle', 'none'],
          },
        });
      }
      if (data.viewMap) {
        Object.keys(data.viewMap).forEach(key => {
          let viewData = data.viewMap[key]
          seriesData.push({
            name: key + ":" + '真实值',
            type: "line",
            data: viewData.realData,
            showSymbol: false,
            smooth: false,
            lineStyle: {
              normal: {
                width: 1,
              },
            },
          })
          seriesData.push({
            name: key + ":" + '预测值',
            type: "line",
            data: viewData.preDataN,
            showSymbol: false,
            smooth: false,
            lineStyle: {
              normal: {
                width: 1,
              },
            },
          })
        })
      }
      myChart = echarts.init(chartDomPre.value);
      const option = {
        title: {
          text: dataForm.value.itemName,
          top: 0,
          left: "1%",
          textStyle: {
            fontSize: 14,
          },
        },
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "line",
            lineStyle: {
              color: "#cccccc",
              width: "1",
              type: "dashed",
            },
          },
        },
        legend: {
          show: true,
          top: 20,
          data: legendData
        },
        grid: {
          top: "20%",
          left: "3%",
          right: "5%",
          bottom: 10,
          containLabel: true,
        },
        xAxis: {
          type: "category",
          boundaryGap: false,
          data: data.categories,
        },
        yAxis: {
          type: "value",
        },
        dataZoom: [
          {
            type: "inside",
          },
        ],
        series: seriesData,
      };
      myChart.setOption(option);
    } catch (error) {
      console.error(error)
    }
  }
}
/** 导出按钮操作 */
const exportLoading = ref(false)
const handleExport = async () => {
  chartParams.itemId = dataForm.value.id;
  chartParams.startTime = dataForm.value.startTime;
  chartParams.endTime = dataForm.value.endTime;
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    /*const data = await DaPoint.exportDaPointValue(chartParams)
    download.excel(data, dataForm.value.pointName + '.xls')*/
  } catch {
  } finally {
    exportLoading.value = false
  }
}
/** 重置表单 */
const resetForm = () => {
  dataForm.value = {
    id: undefined,
    itemName: undefined,
    startTime: undefined,
    endTime: undefined
  }
}
</script>
<style>
.el-select {
  width: 100%;
}
.result-chart {
  height: 500px;
}
</style>
src/views/model/pre/item/MmPredictItemForm.vue
@@ -39,7 +39,7 @@
          <el-form-item label="粒度" prop="mmPredictItem.granularity">
            <el-select v-model="dataForm.mmPredictItem.granularity" placeholder="请选择">
              <el-option
                v-for="dict in getIntDictOptions(DICT_TYPE.TIME_GRANULARITY)"
                v-for="dict in getIntDictOptions(DICT_TYPE.PRED_GRANULARITY)"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
@@ -99,21 +99,6 @@
                             controls-position="right"/>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="数据点" prop="mmItemOutput.pointid">
            <el-select
              v-model="dataForm.mmItemOutput.pointid"
              filterable
              @change="changeOutputPoint"
              placeholder="请选择">
              <el-option
                v-for="item in pointList"
                :key="item.id"
                :label="item.pointName"
                :value="item.id"/>
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row v-if="dataForm.itemtypename === 'MergeItem'">
        <el-col :span="12">
@@ -143,6 +128,7 @@
            :on-success="uploadModelSuccess"
            :on-error="uploadModelError"
            :action="uploadUrl"
            :show-file-list="false"
            :http-request="httpRequest">
            <el-button type="primary" @click="setReplaceModelOnly(false)">
              <Icon icon="ep:upload"/>
@@ -158,18 +144,7 @@
        </el-col>
      </el-row>
      <el-row v-if="dataForm.itemtypename === 'NormalItem'">
        <el-col :span="8">
          <el-form-item label="结果">
            <el-select v-model="dataForm.mmPredictModel.resultstrid" placeholder="请选择">
              <el-option
                v-for="item in resultstridList"
                :key="item.id"
                :label="item.resultstr"
                :value="item.id"/>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="8">
        <el-col :span="12">
          <el-form-item label="关联项目">
            <el-select v-model="dataForm.mmPredictModel.mpkprojectid" placeholder="请选择">
              <el-option
@@ -180,7 +155,7 @@
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="8">
        <el-col :span="12">
          <el-form-item label="编号">
            <el-input
              v-model="dataForm.mmPredictModel.modelno" placeholder="编号" maxlength="30" readonly
@@ -222,14 +197,81 @@
          </el-form-item>
        </el-col>
      </el-row>
      <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">模型输出
      </el-divider>
      <el-button
        @click="addItemOutput(dataForm.mmItemOutputList)"
        type="primary"
        size="small">
        添加
      </el-button>
      <el-table
        v-if="dataForm.itemtypename === 'NormalItem'"
        :data="dataForm.mmItemOutputList"
        border
        style="width: 100%; margin-top: 5px;">
        <el-table-column prop="outputorder" label="排序" align="center" width="80px" />
        <el-table-column label="结果" align="center" width="150px">
          <template #default="scope">
            <el-input v-model="scope.row.resultstr" placeholder="请输入"/>
          </template>
        </el-table-column>
        <el-table-column label="结果数据类型" align="center"  width="150px">
          <template #default="scope">
            <el-select
              v-model="scope.row.resultType"
              @change="(value) => resultTypeChange(value,scope.row)"
              filterable
              placeholder="请选择">
              <el-option
                v-for="dict in getIntDictOptions(DICT_TYPE.MODEL_RESULT_TYPE)"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"/>
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="索引" align="center" width="120px">
          <template #default="scope">
            <el-input-number style="width:100%;hight:100%" :disabled="scope.row.resultType !== 2" v-model="scope.row.resultIndex" :min="0" step-strictly controls-position="right"/>
          </template>
        </el-table-column>
        <el-table-column label="数据点" align="center">
          <template #default="scope">
            <el-select
              v-model="scope.row.pointid"
              filterable
              @change="(value) => changeOutputPoint(value,scope.row)"
              placeholder="请选择">
              <el-option
                v-for="item in pointList"
                :key="item.id"
                :label="item.pointName"
                :value="item.id"/>
            </el-select>
          </template>
        </el-table-column>
        <el-table-column prop="" label="操作" width="80" align="center">
          <template #default="scope">
            <el-button
              @click="deleteItemOutput(scope.$index, dataForm.mmItemOutputList)"
              type="text"
              size="small">
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">模型设置参数
      </el-divider>
      <el-table
        v-if="dataForm.itemtypename === 'NormalItem'"
        :data="dataForm.mmModelArithSettingsList"
        border
        style="width: 100%; margin-top: 5px;">
        <el-table-column prop="key" label="键" align="center"/>
        <el-table-column prop="name" label="名称" align="center"/>
        <el-table-column prop="valuetype" label="类型" align="center"/>
        <el-table-column prop="key" label="键" align="center" min-width="150"/>
        <el-table-column prop="name" label="名称" align="center" min-width="150"/>
        <el-table-column prop="valuetype" label="类型" align="center" min-width="150"/>
        <el-table-column prop="" label="值" align="center" min-width="150">
          <template #default="scope">
            <el-input size="mini" v-model="scope.row.value" maxlength="256"
@@ -237,7 +279,7 @@
          </template>
        </el-table-column>
      </el-table>
      <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">输入参数
      <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">模型输入参数
      </el-divider>
      <el-table
        v-if="dataForm.itemtypename === 'NormalItem'"
@@ -280,18 +322,18 @@
                             style="width:100%;hight:100%"/>
          </template>
        </el-table-column>
        <el-table-column prop="" label="操作" width="140" align="center">
        <el-table-column prop="" label="操作" width="120" align="center">
          <template #default="scope">
            <el-button
              @click="addRow(scope.$index, dataForm.mmModelParamList)"
              type="text"
              size="small">
              size="mini">
              添加
            </el-button>
            <el-button
              @click="deleteRow(scope.$index, dataForm.mmModelParamList)"
              type="text"
              size="small">
              size="mini">
              删除
            </el-button>
          </template>
@@ -316,8 +358,8 @@
              <el-option
                v-for="(item, index) in predictItemList"
                :key="index"
                :label="item.name"
                :value="item.code"/>
                :label="item.itemname"
                :value="item.itemno"/>
            </el-select>
          </template>
        </el-table-column>
@@ -330,7 +372,7 @@
          label="运算符"
          align="center">
          <template #default="scope">
            <el-select v-model="scope.row.operator" placeholder="请选择">
            <el-select v-model="scope.row.operator" placeholder="请选择" clearable>
              <el-option
                v-for="item in operatorList"
                :key="item"
@@ -369,13 +411,12 @@
</template>
<script lang="ts" setup>
import {DICT_TYPE, getIntDictOptions, getStrDictOptions} from '@/utils/dict'
import * as MmPredictItem from '@/api/model/pre/predict'
import * as MmItemType from '@/api/model/pre/item'
import * as MmPredictItem from '@/api/model/pre/item'
import * as MmItemType from '@/api/model/pre/type'
import * as DmModule from '@/api/model/pre/dm'
import * as MmResultTable from '@/api/model/pre/result'
import * as ProjectApi from '@/api/model/mpk/project'
import * as DaPoint from '@/api/data/da/point'
import {useUpload} from '@/api/model/pre/predict'
import {useUpload} from '@/api/model/pre/item'
import * as ScheduleModelApi from '@/api/model/sche/model'
const {uploadUrl, httpRequest} = useUpload()
@@ -391,7 +432,6 @@
const itemTypeList = ref([])
const itemTypeMap = ref({})
const moduleList = ref([])
const resultstridList = ref([])
const mpkProjectList = ref([])
const pointNoList = ref([])
const pointList = ref([])
@@ -435,14 +475,7 @@
    status: undefined,
    categoryid: undefined
  },
  mmItemOutput: {
    id: undefined,
    itemid: undefined,
    pointid: undefined,
    resulttableid: undefined,
    tagname: undefined,
    outputorder: undefined
  },
  mmItemOutputList: [],
  mmPredictModel: {
    id: undefined,
    modelno: undefined,
@@ -489,7 +522,6 @@
  'mmPredictItem.status': [{required: true, message: '是否启用不能为空', trigger: 'blur'}],
  'dmModuleItem.moduleid': [{required: true, message: '管网不能为空', trigger: 'blur'}],
  'dmModuleItem.itemorder': [{required: true, message: '排序不能为空', trigger: 'blur'}],
  'mmItemOutput.pointid': [{required: true, message: '数据点不能为空', trigger: 'blur'}],
})
const formRef = ref() // 表单 Ref
@@ -503,15 +535,6 @@
  resetForm()
  resetFields(dataForm.value)
  setDefaultFields()
  // 修改时,设置数据
  if (id) {
    formLoading.value = true
    try {
      getInfo(id)
    } finally {
      /*formLoading.value = false*/
    }
  }
  // 加载参数列表
  modelparamListMap.value = await ScheduleModelApi.getModelParamList()
@@ -524,26 +547,37 @@
  if (!dataForm.value.id) {
    dataForm.value.mmPredictItem.itemtypeid = itemTypeList.value[0].id
  }
  dataForm.value.itemtypename = itemTypeMap[dataForm.value.mmPredictItem.itemtypeid]
  // 获取管网列表
  moduleList.value = await DmModule.getModuleList()
  // 获取结果字符串列表
  resultstridList.value = await MmResultTable.getResultstridList()
  // 获取mpk项目列表
  mpkProjectList.value = await ProjectApi.list()
  // 获取normal列表
  predictItemList.value = await MmPredictItem.getMmPredictItemList({
    itemtypename: 'NormalItem'
  })
  // 获取数据点列表
  pointNoList.value = await DaPoint.getPointList(queryParams)
  if (pointNoList.value.length > 0) {
    pointList.value = []
    pointNoList.value.forEach(function (value) {
      pointList.value.push(value)
      pointMap[value.id] = value.pointname
      pointMap[value.id] = value.pointName
    })
  }
  // 修改时,设置数据
  if (id) {
    formLoading.value = true
    try {
      getInfo(id)
    } finally {
      formLoading.value = false
    }
  }
  formLoading.value = false
}
defineExpose({open}) // 提供 open 方法,用于打开弹窗
@@ -555,6 +589,22 @@
  if (!formRef) return
  const valid = await formRef.value.validate()
  if (!valid) return
  //校验模型输出
  if (dataForm.value.mmItemOutputList == undefined || dataForm.value.mmItemOutputList.length <= 0) {
    message.error("模型输出不为空")
    return
  }
  let flag = false
  dataForm.value.mmItemOutputList.forEach(e => {
    if (e.resultstr == undefined || e.resultstr === '' || e.resultType == undefined || e.resultType === '' || e.pointid == undefined || e.pointid === '' || (e.resultType === 2 && (e.resultIndex == undefined || e.resultIndex === ''))) {
      message.error("模型输出数据异常")
      flag = true
    }
  })
  if (flag) return
  // 提交请求
  formLoading.value = true
  try {
@@ -608,6 +658,7 @@
const getInfo = async (id) => {
  dataForm.value = await MmPredictItem.getMmPredictItem(id)
  dataForm.value.itemtypename = itemTypeMap[dataForm.value.mmPredictItem.itemtypeid]
  expressionList.value = []
  if (dataForm.value.mmPredictMergeItem && dataForm.value.mmPredictMergeItem.expression) {
    let expression = dataForm.value.mmPredictMergeItem.expression
@@ -714,8 +765,8 @@
  row.modelparamid = ''
}
function changeOutputPoint(value) {
  dataForm.value.mmItemOutput.tagname = pointMap[value]
function changeOutputPoint(value,row) {
  row.tagname = pointMap[value]
}
function deleteExpressionRow(index, rows) {
@@ -740,6 +791,34 @@
  let row = JSON.parse(JSON.stringify(rows[index]))
  rows.splice(index, 0, row)
  orderRow(rows)
}
function addItemOutput(list) {
  list.push({})
  orderItemOutput(list)
}
function deleteItemOutput(index: string, rows) {
  if (!rows || rows.length === 1) {
    message.error('不能全部删除!')
    return
  }
  rows.splice(index, 1)
  orderItemOutput(rows)
}
function orderItemOutput(list) {
  list.sort((a, b) => a.outputorder - b.outputorder);
  let outputorder = 1
  list.forEach(function (value) {
    value.outputorder = outputorder
    outputorder++
  })
}
function resultTypeChange(value, row) {
  if (value === 1) {
    row.resultIndex = undefined
  }else if (value === 2) {
    row.resultIndex = 0
  }
}
function orderRow(rows) {
@@ -766,8 +845,7 @@
  dataForm.value.mmPredictModel.trainsamplength = 60
  dataForm.value.mmPredictModel.isonlinetrain = 0
  dataForm.value.mmPredictModel.status = 1
  dataForm.value.mmItemOutput.outputorder = 1
  dataForm.value.mmItemOutput.resulttableid = '3cc2b483-3a01-40f7-a419-0c260210d8eb'
  dataForm.value.mmItemOutputList = []
  expressionList.value = [{
    point: '',
    operator: ''
@@ -805,14 +883,7 @@
      status: 1,
      categoryid: ''
    },
    mmItemOutput: {
      id: '',
      itemid: '',
      pointid: '',
      resulttableid: '3cc2b483-3a01-40f7-a419-0c260210d8eb',
      tagname: '',
      outputorder: 1
    },
    mmItemOutputList: [],
    mmPredictModel: {
      id: '',
      modelno: '',
src/views/model/pre/item/index.vue
@@ -51,9 +51,9 @@
  <!-- 列表 -->
  <ContentWrap>
    <el-table v-loading="loading" :data="list">
      <el-table-column label="编号" align="center" prop="itemno"/>
      <el-table-column label="编号" align="center" min-width="150" prop="itemno"/>
      <el-table-column label="预测项名" header-align="center" align="left" min-width="200" prop="itemname"/>
      <el-table-column label="类型名称" align="center" prop="itemtypename">
      <el-table-column label="类型名称" align="center" min-width="120" prop="itemtypename">
        <template #default="scope">
          <el-tag v-if="scope.row.itemtypename === 'NormalItem'" size="small" type="success">{{scope.row.itemtypename}}</el-tag>
          <el-tag v-else size="small" type="primary">{{scope.row.itemtypename}}</el-tag>
@@ -62,7 +62,7 @@
      <el-table-column label="预测长度" align="center" prop="predictlength"/>
      <el-table-column label="粒度" align="center" prop="granularity">
        <template #default="scope">
          <dict-tag :type="DICT_TYPE.TIME_GRANULARITY" :value="scope.row.granularity" />
          <dict-tag :type="DICT_TYPE.PRED_GRANULARITY" :value="scope.row.granularity" />
        </template>
      </el-table-column>
      <el-table-column label="是否融合" align="center" prop="isfuse">
@@ -80,21 +80,29 @@
          <dict-tag :type="DICT_TYPE.COM_IS_INT" :value="scope.row.status" />
        </template>
      </el-table-column>
      <el-table-column label="数据点名称" align="center" prop="tagname"/>
      <el-table-column label="存放表" align="center" prop="tablename"/>
      <el-table-column label="操作" align="center" min-width="110" fixed="right">
      <el-table-column label="运行时间" min-width="150" align="center" prop="lastTime"/>
      <el-table-column label="运行状态" align="center" prop="runStatus">
        <template #default="scope">
          <dict-tag :type="DICT_TYPE.ITEM_RUN_STATUS" :value="scope.row.runStatus" />
        </template>
      </el-table-column>
      <el-table-column label="运行耗时(s)" align="center" prop="duration"/>
      <el-table-column label="操作" align="center" min-width="120" fixed="right">
        <template #default="scope">
          <el-button
            link
            type="primary"
            size="mini"
            @click="openForm('update', scope.row.id, scope.row.itemtypename)"
            v-hasPermi="['model:pre-item:update']"
          >
            编辑
          </el-button>
          <el-button link size="mini" type="primary" @click="chartHandle(scope.row)">数据</el-button>
          <el-button
            link
            type="danger"
            size="mini"
            @click="handleDelete(scope.row.id)"
            v-hasPermi="['model:pre-item:delete']"
          >
@@ -115,10 +123,14 @@
  <!-- 表单弹窗:添加/修改 -->
  <MmPredictItemForm ref="formRef" @success="getList"/>
  <!-- 表单弹窗:数据 -->
  <MmPredictItemChart ref="chartView" @success="getList"/>
</template>
<script lang="ts" setup>
import MmPredictItemForm from './MmPredictItemForm.vue'
import * as MmPredictItem from '@/api/model/pre/predict'
import MmPredictItemChart from './MmPredictItemChart.vue'
import * as MmPredictItem from '@/api/model/pre/item'
import {DICT_TYPE} from "@/utils/dict";
defineOptions({name: 'DataMmPredictItem'})
@@ -171,6 +183,12 @@
  handleQuery()
}
/** 查看数据操作 */
const chartView  = ref()
const chartHandle = (raw: object) => {
  chartView.value.open(raw)
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number, itemtypename?: string) => {
src/views/model/pre/result/MmResultTableForm.vue
文件已删除
src/views/model/pre/result/index.vue
文件已删除
src/views/model/pre/type/ItemTypeForm.vue
@@ -36,7 +36,7 @@
  </Dialog>
</template>
<script lang="ts" setup>
import * as MmItemType from '@/api/model/pre/item'
import * as MmItemType from '@/api/model/pre/type'
defineOptions({name: 'DataMmItemTypeForm'})
src/views/model/pre/type/index.vue
@@ -82,7 +82,7 @@
</template>
<script lang="ts" setup>
import MmItemTypeForm from './ItemTypeForm.vue'
import * as MmItemType from '@/api/model/pre/item'
import * as MmItemType from '@/api/model/pre/type'
defineOptions({name: 'DataMmItemType'})