dongyukun
2024-11-15 59569559a1d90d7a4340e5474346353fb823a0c1
Merge remote-tracking branch 'origin/master'
已添加2个文件
已删除1个文件
已修改14个文件
513 ■■■■ 文件已修改
src/api/data/plan/item/index.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/data/video/image/index.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/model/mcs/index.ts 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/model/sche/model/index.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/hostMap.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/is.ts 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Home/Index.vue 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Login/components/LoginForm.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/bpm/model/index.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/bpm/simpleWorkflow/index.vue 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/data/video/camera/CameraImage.vue 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/data/video/camera/index.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/data/video/nvr/NvrCamera.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/data/video/nvr/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/pre/analysis/index.vue 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/pre/item/MmPredictItemForm.vue 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
types/env.d.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/data/plan/item/index.ts
@@ -50,7 +50,7 @@
//获取下拉集合
export const getItemList = (params: PageParam) => {
  return request.get({ url: '/data/plan-item/getList', params})
  return request.get({ url: '/data/plan-item/list', params})
}
// 查询Plan图表
src/api/data/video/image/index.ts
对比新文件
@@ -0,0 +1,50 @@
import request from '@/config/axios'
export interface ImageVO {
  id: undefined,
  cameraId: string,
  imagePath: string,
  imageUrl: string,
  createDate: undefined,
}
// 查询列表
export const getImagePage = (params: PageParam) => {
  return request.get({url: '/data/video/image/page', params})
}
// 获得
export const getImage = (id: number) => {
  return request.get({url: '/data/video/image/get?id=' + id})
}
// 查询应用列表
export const getImageList = () => {
  return request.get({url: '/data/video/image/list'})
}
// 新增
export const createImage = (data: ImageVO) => {
  return request.post({url: '/data/video/image/create', data})
}
// 修改
export const updateImage = (data: ImageVO) => {
  return request.put({url: '/data/video/image/update', data})
}
// 删除
export const deleteImage = (id: number) => {
  return request.delete({url: '/data/video/image/delete?id=' + id})
}
// 导出
export const exportImage = (params: ImageVO) => {
  return request.download({url: '/data/video/image/export-excel', params})
}
//预览摄像头截图
export const getPreviewUrl = (url: string) => {
  const host = import.meta.env.VITE_VIDEO_CAMERA_DOMAIN ? import.meta.env.VITE_VIDEO_CAMERA_DOMAIN : window.location.host
  return `http://${host}:8899` + url
}
src/api/model/mcs/index.ts
@@ -1,7 +1,7 @@
import request from '@/config/axios'
export interface PreDataBarLineReqVO {
  queryIds: string[],
  outIds: string[],
  predictTime: string,
  startTime: string,
  endTime: string
@@ -13,6 +13,9 @@
  endTime: string
}
export const getPredictItemTree = () => {
  return request.get({ url: '/model/api/mcs/predict-item/tree'})
}
export const getPreDataCharts = (data: PreDataBarLineReqVO) => {
  return request.post({ url: '/model/api/mcs/predict-data/charts', data })
src/api/model/sche/model/index.ts
@@ -1,7 +1,9 @@
import request from '@/config/axios'
import * as DataPointApi from '@/api/data/da/point'
import * as PredictItemApi from '@/api/model/pre/item'
import * as PlanItemApi from '@/api/data/plan/item'
import {CommonEnabled} from "@/utils/constants";
import {getItemList, ItemVO} from "@/api/data/plan/item";
export interface ScheduleModelVO {
  id: string
@@ -100,8 +102,25 @@
      )
    })
  }
  const planItemList = ref([] as PlanItemApi.ItemVO)
  planItemList.value = await PlanItemApi.getItemList({
  })
  const planList = []
  if (planItemList.value) {
    planItemList.value.forEach(item => {
      planList.push(
        {
          id: item.id,
          name:  item.itemName
        }
      )
    })
  }
  return {
    'DATAPOINT':pointList,
    'PREDICTITEM': itemList
    'PREDICTITEM': itemList,
    'PLAN': planList,
  }
}
src/utils/hostMap.ts
@@ -1,6 +1,6 @@
const map = {
  "//localhost:7200/": "//wujie-micro.github.io/demo-vue2/",
  "//localhost:90/": "//localhost:90/",
  "//localhost:9000/": "//localhost:9000/",
  "//localhost:8000/": "//wujie-micro.github.io/demo-main-vue/",
};
src/utils/is.ts
@@ -98,8 +98,9 @@
export const isClient = !isServer
export const isUrl = (path: string): boolean => {
  // fix:修复hash路由无法跳转的问题
  const reg =
    /(((^https?:(?:\/\/)?)(?:[-:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&%@.\w_]*)#?(?:[\w]*))?)$/
    /(((^https?:(?:\/\/)?)(?:[-:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%#\/.\w-_]*)?\??(?:[-\+=&%@.\w_]*)#?(?:[\w]*))?)$/
  return reg.test(path)
}
src/views/Home/Index.vue
@@ -19,7 +19,6 @@
import * as AppApi from '@/api/system/app'
import {Apps} from "@/views/Home/types";
import {CACHE_KEY, useCache} from "@/hooks/web/useCache";
import * as authUtil from "@/utils/auth";
defineOptions({ name: 'Home' })
@@ -35,7 +34,7 @@
  appList = Object.assign(appList, data)
}
const getAppMenuList = async (id) => {
const getAppMenuList = async (id, appCode) => {
  const data = await AppApi.getAppMenuList(id)
  let userInfo = wsCache.get(CACHE_KEY.USER)
  userInfo.menus = data
@@ -55,19 +54,24 @@
// 进入应用
const gotoApp = async (item) => {
  let path = window.location.pathname
  let appName = path.split("/")[0]
  console.log(appName)
  let id = item.id
  let type = item.type
  let appCode = item.appCode
  if(type === 0) {
    getAppMenuList(id)
    await getAppMenuList(id, appCode)
  } else {
    const data = await AppApi.getAppMenuList(id)
    let userInfo = wsCache.get(CACHE_KEY.USER)
    userInfo.menus = data
    wsCache.set(CACHE_KEY.USER, userInfo)
    wsCache.set(CACHE_KEY.ROLE_ROUTERS, data)
    // await OAuth2Login(formData.value)
    // window.open(item.appDomain + '/login?appid=' + item.id + "&username=" + authUtil.getLoginForm().username, '_blank')
    window.open(item.appDomain + '/index', '_blank')
    // window.open('/plat/shasteel', '_blank')
    // window.location.href = '/plat/shasteel'
    // window.location.href = `/plat/shasteel?key=energy&url=http://localhost:9000&energy=/energy/demo`
  }
}
@@ -80,6 +84,7 @@
  display: inline-block;
  background: transparent;
}
.card{
  border: thin dashed gainsboro;
  width: 150px;
src/views/Login/components/LoginForm.vue
@@ -199,7 +199,7 @@
      authUtil.removeLoginForm()
    }
    authUtil.setToken(res)
    if (!redirect.value) {
    if (!redirect.value || redirect.value == "/") {
      redirect.value = '/index'
    }
    // 判断是否为SSO登录
src/views/bpm/model/index.vue
@@ -163,14 +163,6 @@
          <el-button
            link
            type="primary"
            @click="handleSimpleDesign(scope.row.id)"
            v-hasPermi="['bpm:model:update']"
          >
            仿钉钉设计流程
          </el-button>
          <el-button
            link
            type="primary"
            @click="handleDeploy(scope.row)"
            v-hasPermi="['bpm:model:deploy']"
          >
@@ -328,15 +320,6 @@
const handleDesign = (row) => {
  push({
    name: 'BpmModelEditor',
    query: {
      modelId: row.id
    }
  })
}
const handleSimpleDesign = (row) => {
  push({
    name: 'SimpleWorkflowDesignEditor',
    query: {
      modelId: row.id
    }
src/views/bpm/simpleWorkflow/index.vue
文件已删除
src/views/data/video/camera/CameraImage.vue
对比新文件
@@ -0,0 +1,114 @@
<template>
  <el-dialog v-model="dialogVisible" :title="dialogTitle" :close="handleClose"
             style="width: 50%; margin-top: 20px; overflow: auto; z-index: 1">
    <!-- 列表 -->
    <el-table v-loading="loading" :data="list">
      <el-table-column
        label="截图时间"
        align="center"
        prop="createDate"
        :formatter="dateFormatter"
        width="200"
      />
      <el-table-column label="图片路径" align="center" prop="imagePath" width="500"
                       :show-overflow-tooltip="true"/>
      <el-table-column label="图片预览" align="center" prop="imageUrl">
        <template #default="scope">
          <el-image style="height: 50px; z-index: 1"
                    :src="getPreviewUrl(scope.row.imageUrl)"
                    :preview-src-list="getPreviewSrcList(scope.row.imageUrl)" fit="cover"
                    preview-teleported/>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" min-width="60" fixed="right">
        <template #default="scope">
          <el-button
            link
            type="danger"
            style="z-index: 1"
            @click="handleDelete(scope.row.id)"
            v-hasPermi="['video:camera:delete']"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <Pagination
      :total="total"
      v-model:page="queryParams.pageNo"
      v-model:limit="queryParams.pageSize"
      @pagination="open"
    />
  </el-dialog>
</template>
<script lang="ts" setup>
import * as ImageApi from '@/api/data/video/image'
import {getPreviewUrl} from "@/api/data/video/image";
import {dateFormatter} from "@/utils/formatTime";
defineOptions({name: 'CameraImage'})
const message = useMessage() // 消息弹窗
const {t} = useI18n() // 国际化
const dialogTitle = ref('截图列表')
const loading = ref(true) // 列表的加载中
const total = ref(0) // 列表的总页数
const list = ref([]) // 列表的数据
const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  id: undefined,
  brand: undefined,
  code: undefined,
  device: undefined,
  cameraId: '',
  imagePath: undefined,
  imageUrl: undefined,
  createDate: undefined,
})
const cameraId = ref('')
const dialogVisible = ref(false)
/** 查询列表 */
const open = async (camera_id: string) => {
  dialogVisible.value = true
  cameraId.value = camera_id
  queryParams.cameraId = camera_id
  loading.value = true
  try {
    const data = await ImageApi.getImagePage(queryParams)
    list.value = data.list
    total.value = data.total
  } finally {
    loading.value = false
  }
}
defineExpose({open}) // 提供 open 方法,用于打开弹窗
const handleClose = async () => {
  dialogVisible.value = false
}
const getPreviewSrcList = (imageUrl: string) => {
  let previewSrcList: string[] = []
  previewSrcList.push(getPreviewUrl(imageUrl))
  return previewSrcList
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    await ImageApi.deleteImage(id)
    message.success(t('common.delSuccess'))
    // 刷新列表
    await open(cameraId.value)
  } catch {
  }
}
</script>
src/views/data/video/camera/index.vue
@@ -102,7 +102,8 @@
      <el-table-column label="设备类型" align="center" prop="device" width="200"/>
      <el-table-column label="编码" align="center" prop="code" width="200"/>
      <el-table-column label="IP" align="center" prop="ip" />
      <el-table-column label="端口" align="center" prop="port" width="100"/>
      <el-table-column label="端口" align="center" prop="port" width="80"/>
      <el-table-column label="通道" align="center" prop="channel" width="80"/>
      <el-table-column label="用户名" align="center" prop="username" width="100"/>
      <el-table-column label="状态" prop="status" width="80">
        <template #default="scope">
@@ -129,6 +130,14 @@
          >
            删除
          </el-button>
          <el-button
            link
            type="success"
            @click="imageHandle(scope.row.id)"
            v-hasPermi="['video:image:query']"
          >
            查看截图
          </el-button>
        </template>
      </el-table-column>
    </el-table>
@@ -144,6 +153,7 @@
  <!-- 表单弹窗:添加/修改 -->
  <CameraForm ref="formRef" @success="getList" />
  <CameraImage ref="imageFormRef"/>
</template>
<script lang="ts" setup>
@@ -151,6 +161,8 @@
  import download from '@/utils/download'
  import * as CameraApi from '@/api/data/video/camera'
  import CameraForm from './CameraForm.vue'
import CameraImage from './CameraImage.vue'
  defineOptions({name: 'Camera'})
@@ -195,6 +207,7 @@
  /** 重置按钮操作 */
  const resetQuery = () => {
    queryFormRef.value.resetFields()
  queryParams.brand = undefined
    handleQuery()
  }
@@ -218,6 +231,12 @@
    }
  }
/** 查看截图 */
const imageFormRef = ref()
const imageHandle = (id: string) => {
  imageFormRef.value.open(id)
}
  /** 导出按钮操作 */
  const handleExport = async () => {
    try {
src/views/data/video/nvr/NvrCamera.vue
@@ -79,6 +79,14 @@
          >
            删除
          </el-button>
            <el-button
              link
              type="success"
              @click="imageHandle(scope.row.id)"
              v-hasPermi="['video:image:query']"
            >
              查看截图
            </el-button>
        </template>
      </el-table-column>
    </el-table>
@@ -95,6 +103,7 @@
  <!-- 表单弹窗:添加/修改 -->
  <NvrCameraForm ref="formRef" @success="getList" />
  <CameraImage ref="imageFormRef"/>
</template>
<script lang="ts" setup>
@@ -102,6 +111,7 @@
import * as CameraApi from '@/api/data/video/camera'
import NvrCameraForm from './NvrCameraForm.vue'
import {DICT_TYPE} from "@/utils/dict";
import CameraImage from "../camera/CameraImage.vue";
defineOptions({name: 'NvrCamera'})
@@ -148,6 +158,12 @@
  }
}
/** 查看截图 */
const imageFormRef = ref()
const imageHandle = (id: string) => {
  imageFormRef.value.open(id)
}
/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNo = 1
@@ -156,7 +172,7 @@
/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value.resetFields()
  queryParams.location = undefined
  handleQuery()
}
src/views/data/video/nvr/index.vue
@@ -100,7 +100,6 @@
          <dict-tag :type="DICT_TYPE.NVR_ONLINE_STATUS" :value="scope.row.status" />
        </template>
      </el-table-column>
      <el-table-column label="位置" align="center" prop="position" />
      <el-table-column label="备注" align="center" prop="remark" width="150"/>
      <el-table-column label="操作" align="center" min-width="110" fixed="right">
        <template #default="scope">
@@ -120,7 +119,8 @@
          >
            删除
          </el-button>
          <el-button link type="success" size="small" @click="cameraHandle(scope.row.id)">摄像头</el-button>
          <el-button link type="success" size="small" @click="cameraHandle(scope.row.id)">摄像头
          </el-button>
        </template>
      </el-table-column>
    </el-table>
@@ -195,6 +195,7 @@
  /** 重置按钮操作 */
  const resetQuery = () => {
    queryFormRef.value.resetFields()
  queryParams.brand = undefined
    handleQuery()
  }
src/views/model/pre/analysis/index.vue
@@ -4,37 +4,42 @@
      <el-form :inline="true" :model="formData" label-width="80px">
        <el-form-item label="开始时间">
          <el-date-picker
              size="mini"
              v-model="formData.startTime"
              type="datetime"
            format="YYYY-MM-DD HH:mm:00"
            value-format="YYYY-MM-DD HH:mm:00"
              placeholder="选择日期时间"/>
        </el-form-item>
        <el-form-item label="结束时间">
          <el-date-picker
              size="mini"
              v-model="formData.endTime"
              type="datetime"
            format="YYYY-MM-DD HH:mm:00"
            value-format="YYYY-MM-DD HH:mm:00"
              placeholder="选择日期时间"/>
        </el-form-item>
        <el-form-item label="预测时间">
          <el-date-picker
              size="mini"
              v-model="formData.predictTime"
              type="datetime"
            format="YYYY-MM-DD HH:mm:00"
            value-format="YYYY-MM-DD HH:mm:00"
              placeholder="选择日期时间"/>
        </el-form-item>
        <el-form-item label="预测频率">
          <el-input-number size="mini" v-model="formData.predictFreq" controls-position="right" :min="1"
          <el-input-number v-model="formData.predictFreq" controls-position="right"
                           :min="1"
                           :max="10"/>
        </el-form-item>
        <el-form-item>
          <el-button-group>
            <el-button size="mini" type="primary" plain :icon="ArrowLeft"
                       v-loading="loading1" @click="leftSearchDataByRange()"/>
            <el-button size="mini" type="primary" plain :icon="Search"
                       v-loading="loading1" @click="getList()">查询</el-button>
            <el-button size="mini" type="primary" plain :icon="ArrowRight"
                       v-loading="loading1" @click="rightSearchDataByRange()"/>
            <el-button type="primary" plain :icon="ArrowLeft"
                       :loading="loading1" @click="leftSearchDataByRange()"/>
            <el-button type="primary" plain :icon="Search"
                       :loading="loading1" @click="getList()">查询
            </el-button>
            <el-button type="primary" plain :icon="ArrowRight"
                       :loading="loading1" @click="rightSearchDataByRange()"/>
          </el-button-group>
        </el-form-item>
@@ -53,35 +58,41 @@
          </div>
          <div class="his-body-right">
            <div class="his-body-chart">
              <el-form :inline="true" :model="calRateForm" :rules="formRules" ref="calRateForm" label-width="108px">
              <el-form :inline="true" :model="calRateForm" :rules="formRules" ref="calRateFormRef"
                       label-width="108px">
                <el-row>
                  <el-col :span="6" >
                    <el-form-item label="预测项" prop="calItem" style="width: 90%">
                      <el-select v-model="calRateForm.calItem" @change="calItemBaseVale" placeholder="请选择">
                      <el-select size="small" v-model="calRateForm.calItem"
                                 @change="calItemBaseVale"
                                 placeholder="请选择">
                        <el-option
                            v-for="item in formData.checkedItemData"
                            :key="item.id"
                            :label="item.label"
                            :value="item.id"/>
                          v-for="itemOut in formData.checkedItemData"
                          :key="itemOut.id"
                          :label="itemOut.label"
                          :value="itemOut.id"/>
                      </el-select>
                    </el-form-item>
                  </el-col>
                  <el-col :span="6">
                    <el-form-item label="精准度偏差" prop="IN_DEVIATION">
                      <el-input-number size="mini" v-model="calRateForm.IN_DEVIATION" controls-position="right" :min="1"
                      <el-input-number size="small" v-model="calRateForm.IN_DEVIATION"
                                       controls-position="right" :min="1"
                                       :max="10"/>
                    </el-form-item>
                  </el-col>
                  <el-col :span="6">
                    <el-form-item label="不可信率偏差" prop="OUT_DEVIATION">
                      <el-input-number size="mini" v-model="calRateForm.OUT_DEVIATION" controls-position="right"
                      <el-input-number size="small" v-model="calRateForm.OUT_DEVIATION"
                                       controls-position="right"
                                       :min="1"
                                       :max="20"/>
                    </el-form-item>
                  </el-col>
                  <el-col :span="4">
                    <el-form-item>
                      <el-button size="mini" type="primary" plain :loading="loading2" @click="calAccuracyRate">计算精准度
                      <el-button size="small" type="primary" plain :loading="loading2"
                                 @click="calAccuracyRate">计算精准度
                      </el-button>
                    </el-form-item>
                  </el-col>
@@ -146,20 +157,25 @@
                  <el-col :span="12">
                    <el-form-item label="数据类型">
                      <el-checkbox-group v-model="formData.chartCheck" @change="changeChartCheck">
                        <el-checkbox v-for="item in formData.chartOptions" :label="item" :key="item">{{item}}
                        <el-checkbox v-for="item in formData.chartOptions" :label="item"
                                     :key="item">{{ item }}
                        </el-checkbox>
                      </el-checkbox-group>
                    </el-form-item>
                  </el-col>
                  <el-col :span="6">
                    <el-form-item>
                      <el-radio v-model="formData.isMultipleY" :label="false" @input="onChangeMultipleY">单坐标轴</el-radio>
                      <el-radio v-model="formData.isMultipleY" :label="true" @input="onChangeMultipleY">多坐标轴</el-radio>
                      <el-radio v-model="formData.isMultipleY" :label="false"
                                @input="onChangeMultipleY">单坐标轴
                      </el-radio>
                      <el-radio v-model="formData.isMultipleY" :label="true"
                                @input="onChangeMultipleY">多坐标轴
                      </el-radio>
                    </el-form-item>
                  </el-col>
                </el-row>
              </el-form>
              <div id="data-analysis" style="height: 500px;"></div>
              <div ref="dataAnalysisChart" style="height: 500px;"></div>
            </div>
          </div>
        </div>
@@ -169,29 +185,19 @@
</template>
<script lang="ts" setup>
  import {getYMDHMS} from "@/utils/dateUtil"
  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/item'
import * as McsApi from '@/api/model/mcs'
  import * as echarts from "echarts";
  import { onMounted, ref } from 'vue';
  import { Search, ArrowLeft, ArrowRight,} from '@element-plus/icons-vue'
  defineOptions({name: 'AnalysisformData'})
  const message = useMessage() // 消息弹窗
  const { t } = useI18n() // 国际化
  const dataCategoryList = ref([] as CategoryApi.IndItemCategoryVO[])
const dataAnalysisChart = ref(null);
  const loading1 = ref(false) // 列表的加载中
  const loading2 = ref(false) // 列表的加载中
  const total = ref(0) // 列表的总页数
  const list = ref([]) // 字典表格数据
  const queryParams = reactive({
    pageNo: 1,
    pageSize: 10,
    itemno: '',
    itemname: '',
  })
  let formData = ref({
    rangeDate: '',
    startTime: '',
@@ -219,8 +225,9 @@
    isMultipleY: false,
    predictFreq: 3,
  })
  let calRateForm = ref({
    calItem: '',
const calRateFormRef = ref()
const calRateForm = ref({
  calItem: undefined,
    IN_DEVIATION: 0,
    OUT_DEVIATION: 0,
    IN_ACCURACY_RATE: 0,
@@ -239,22 +246,21 @@
    chart: {},
    option: {}
  })
  const chartContainer = ref(null);
  const treeData = ref([])
  const itemDataObject = ref()
  const timer = ref()
let myChart = null;
  const formRules = reactive({
    calItem: [{required: true, message: '预测项不能为空', trigger: 'blur'}],
    IN_DEVIATION: [{required: true, message: '精准度偏差不能为空', trigger: 'blur'}],
    OUT_DEVIATION: [{required: true, message: '不可信率偏差不能为空', trigger: 'blur'}],
  })
  //const myChart = echarts.init(document.getElementById("data-analysis"));
  /** 查询列表 */
  const getList = async () => {
    loading1.value = true
    try {
      const data = formData.value
      if (!formData.value.chartCheck) {
        formData.value.chartCheck = ['真实值']
      }
@@ -263,24 +269,21 @@
        itemData.value.option = {};
        return;
      }
      let itemIdList = formData.value.checkedItemData.map(item => {
    let outIds = formData.value.checkedItemData.map(item => {
        return item.id
      })
      const params = ref({
        itemIds: itemIdList.join(','),
    const params = reactive({
      outIds: outIds,
        predictTime: formData.value.predictTime,
        startTime: formData.value.startTime,
        endTime: formData.value.endTime
      })
      const res = await MmPredictItem.getViewCharts(params)
      if (res.code !== 0) {
        return message.error(res.msg)
      }
      formData.value.predictTime = res.data.predictTime;
      formData.value.startTime = res.data.startTime
      formData.value.endTime = res.data.endTime
    const data = await McsApi.getPreDataCharts(params)
    formData.value.predictTime = data.predictTime;
    formData.value.startTime = data.startTime
    formData.value.endTime = data.endTime
      let xAxisData = res.data.categories;
    let xAxisData = data.categories;
      let yAxisData = [];
      let offset = 0;
      let yAxisIndex = 0;
@@ -311,9 +314,9 @@
        },
      });
      itemDataObject.value = {}
      for (let i = 0; i < res.data.dataViewList.length; i++) {
        let dataView = res.data.dataViewList[i]
        itemDataObject.value.dataView.itemId = dataView;
    for (let i = 0; i < data.dataViewList.length; i++) {
      let dataView = data.dataViewList[i]
      itemDataObject.value[dataView.outId] = dataView;
        let maxValue = dataView.maxValue;
        let minValue = dataView.minValue;
        yAxisIndex = formData.value.isMultipleY ? i : 0;
@@ -358,7 +361,7 @@
        })
        offset = offset + 40
        if (chartCheckArray.indexOf('真实值') !== -1) {
          let legendName = dataView.itemName + '(真实)';
        let legendName = dataView.resultstr + '(真实)';
          legendData.push(legendName);
          seriesData.push({
            name: legendName,
@@ -368,12 +371,12 @@
            showSymbol: false,
            smooth: true,
            lineStyle: {
              width: 3
            width: 2
            }
          });
        }
        if (chartCheckArray.indexOf('T+N') !== -1) {
          let legendName = dataView.itemName + '(T+N)';
        let legendName = dataView.resultstr + '(T+N)';
          seriesData.push({
            name: legendName,
            data: dataView.preDataN || [],
@@ -382,12 +385,12 @@
            showSymbol: false,
            smooth: true,
            lineStyle: {
              width: 3
            width: 2
            }
          });
        }
        if (chartCheckArray.indexOf('T+L') !== -1) {
          let legendName = dataView.itemName + '(T+L)';
        let legendName = dataView.resultstr + '(T+L)';
          legendData.push(legendName);
          seriesData.push({
            name: legendName,
@@ -398,12 +401,12 @@
            yAxisIndex: yAxisIndex,
            smooth: true,
            lineStyle: {
              width: 3
            width: 2
            }
          });
        }
        if (chartCheckArray.indexOf('当时') !== -1) {
          let legendName = dataView.itemName + '(当时)';
        let legendName = dataView.resultstr + '(当时)';
          legendData.push(legendName);
          seriesData.push({
            name: legendName,
@@ -413,12 +416,12 @@
            showSymbol: false,
            smooth: true,
            lineStyle: {
              width: 3
            width: 2
            }
          });
        }
        if (chartCheckArray.indexOf('调整值') !== -1) {
          let legendName = dataView.itemName + '(调整值)';
        let legendName = dataView.resultstr + '(调整值)';
          legendData.push(legendName);
          seriesData.push({
            name: legendName,
@@ -429,7 +432,7 @@
            connectNulls: true,
            smooth: true,
            lineStyle: {
              width: 3,
            width: 2,
              type: 'dashed'
            }
          });
@@ -445,6 +448,7 @@
          }
        }
      }
    myChart = echarts.init(dataAnalysisChart.value);
      let option = {
        title: {
          text: ''
@@ -458,7 +462,7 @@
          top: 10
        },
        grid: {
          top: 50,
        top: '20%',
          left: '3%',
          right: '6%',
          bottom: '3%',
@@ -487,19 +491,20 @@
        ],
        series: seriesData
      }
      //chart.setOption(option)
    myChart.clear()
    myChart.setOption(option)
    } finally {
      loading1.value = false
    }
  }
  onMounted(() => {
  resetForm()
    getPreItemTree()
    getList()
  })
  async function getPreItemTree() {
    treeData.value = await MmPredictItem.getMmPredictItemTree()
  treeData.value = await McsApi.getPredictItemTree()
  }
  function leftSearchDataByRange() {
@@ -538,8 +543,7 @@
    if (checked.checkedNodes) {
      formData.value.checkedItemData = [...checked.checkedNodes]
    }
    //myChart.clear()
    debounce(getList(), 1000);
  debounce(getList, 1000);
  }
  function debounce(func, wait) {
@@ -563,9 +567,8 @@
      calRateForm.value.itemMin = 0;
      calRateForm.value.itemAvg = 0;
      calRateForm.value.realCumulant = 0;
      return
    } else {
      let dataView = itemDataObject[calRateForm.value.calItem]
    let dataView = itemDataObject.value[calRateForm.value.calItem]
      calRateForm.value.itemPreMax = dataView.preMax;
      calRateForm.value.itemPreMin = dataView.preMin;
      calRateForm.value.itemPreAvg = dataView.preAvg;
@@ -651,6 +654,52 @@
    getList();
  }
/** 重置表单 */
const resetForm = () => {
  formData.value = {
    rangeDate: '',
    startTime: '',
    endTime: '',
    predictTime: '',
    predictTimeStr: '',
    startTimeStr: '',
    endTimeStr: '',
    predictTimeStamp: 0,
    startTimeStamp: 0,
    endTimeStamp: 0,
    currentStamp: '',
    currentStamp60: '',
    predictStamp: '',
    chartCheck: ['T+L', '真实值'],
    chartOptions: ['T+N', 'T+L', '当时', '真实值', '调整值'],
    checkedItemData: [],
    backItem: '',
    backValue: 0,
    backCoe: 1,
    preCumulant: 0,
    realCumulant: 0,
    queryStep: 2,
    isMultipleYRadio: '单坐标轴',
    isMultipleY: false,
    predictFreq: 3,
  }
  calRateForm.value = {
    calItem: undefined,
    IN_DEVIATION: 0,
    OUT_DEVIATION: 0,
    IN_ACCURACY_RATE: 0,
    OUT_ACCURACY_RATE: 0,
    itemAvg: 0,
    itemMax: 0,
    itemMin: 0,
    itemPreAvg: 0,
    itemPreMax: 0,
    itemPreMin: 0,
    preCumulant: 0,
    realCumulant: 0
  }
  calRateFormRef.value?.resetFields()
}
</script>
<style scoped>
  .el-form-item {
src/views/model/pre/item/MmPredictItemForm.vue
@@ -17,7 +17,8 @@
        </el-col>
        <el-col :span="12">
          <el-form-item label="编号" prop="mmPredictItem.itemno">
            <el-input v-model="dataForm.mmPredictItem.itemno" placeholder="编号" maxlength="50" readonly/>
            <el-input v-model="dataForm.mmPredictItem.itemno" placeholder="编号" maxlength="50"
                      readonly/>
          </el-form-item>
        </el-col>
      </el-row>
@@ -233,7 +234,9 @@
        </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"/>
            <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">
@@ -290,7 +293,9 @@
        <el-table-column prop="modelparamorder" label="序号" width="60" align="center"/>
        <el-table-column prop="" label="类型" width="200" align="center">
          <template #default="scope">
            <el-select v-model="scope.row.modelparamtype" placeholder="请选择">
            <el-select v-model="scope.row.modelparamtype"
                       @change="changeModelparamtype(scope.row)"
                       placeholder="请选择">
              <el-option
                v-for="dict in getStrDictOptions(DICT_TYPE.MODEL_PARAM_TYPE)"
                :key="dict.value"
@@ -761,7 +766,7 @@
  dataForm.value.itemtypename = itemTypeMap[value]
}
function changeModelparamtype(value, row) {
function changeModelparamtype(row) {
  row.modelparamid = ''
}
@@ -792,10 +797,12 @@
  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('不能全部删除!')
@@ -804,6 +811,7 @@
  rows.splice(index, 1)
  orderItemOutput(rows)
}
function orderItemOutput(list) {
  list.sort((a, b) => a.outputorder - b.outputorder);
  let outputorder = 1
types/env.d.ts
@@ -25,6 +25,7 @@
  readonly VITE_UPLOAD_URL: string
  readonly VITE_API_URL: string
  readonly VITE_BASE_PATH: string
  readonly VITE_VIDEO_CAMERA_DOMAIN: string
  readonly VITE_DROP_DEBUGGER: string
  readonly VITE_DROP_CONSOLE: string
  readonly VITE_SOURCEMAP: string