From d57817d30107e15f870799953831f63d2f9087ce Mon Sep 17 00:00:00 2001
From: 潘志宝 <979469083@qq.com>
Date: 星期二, 24 九月 2024 15:17:38 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 src/views/data/ind/item/CalIndDefineForm.vue      |  436 +++++++++++++++
 src/views/data/ind/item/selectItemType.vue        |   96 +++
 src/views/model/pre/predict/index.vue             |   10 
 src/api/data/ind/item/item.ts                     |   66 ++
 src/views/data/ind/img/ATOM.png                   |    0 
 src/utils/dict.ts                                 |    5 
 src/views/model/pre/predict/MmPredictItemForm.vue |  324 ++++++----
 src/views/data/ind/img/CAL.png                    |    0 
 src/views/data/ind/item/DerIndDefineForm.vue      |  329 +++++++++++
 src/views/data/ind/img/DER.png                    |    0 
 src/views/data/ind/item/index.vue                 |  195 ++++++
 src/views/data/ind/item/AtomIndDefineForm.vue     |  263 +++++++++
 12 files changed, 1,588 insertions(+), 136 deletions(-)

diff --git a/src/api/data/ind/item/item.ts b/src/api/data/ind/item/item.ts
new file mode 100644
index 0000000..cd9d04e
--- /dev/null
+++ b/src/api/data/ind/item/item.ts
@@ -0,0 +1,66 @@
+import request from '@/config/axios'
+
+export type ItemVO = {
+  id: string | undefined
+  itemNo: string
+  itemName: string
+  itemType: string
+  itemCategory: string
+  coefficient: number
+  precision: number
+  timeGranularity: string
+  unit: string
+  remark: string
+  status: string
+  timeLabel: string
+  timeLimit: string
+  timeStart: string
+  timeEnd: string
+  dimension: string
+  expression: string
+}
+
+export type PageParam = {
+  itemNo: string
+  itemName: string
+  itemType: string
+  itemCategory: string
+}
+
+
+// 查询列表
+export const getItemPage = (params: PageParam) => {
+  return request.get({ url: '/data/ind-item/page', params })
+}
+
+// 查询详情
+export const getItem = (id: string) => {
+  return request.get({ url: '/data/ind-item/get?id=' + id })
+}
+
+// 新增
+export const createItem = (data: ItemVO) => {
+  return request.post({ url: '/data/ind-item/create', data })
+}
+
+// 修改
+export const updateItem = (data: ItemVO) => {
+  return request.put({ url: '/data/ind-item/update', data })
+}
+
+// 删除
+export const deleteItem = (id: number) => {
+  return request.delete({ url: '/data/ind-item/delete?id=' + id })
+}
+
+//获取下拉集合
+export const getItemList = (params: PageParam) => {
+  return request.get({ url: '/data/ind-item/getList', params})
+}
+
+export const validateAsNumber = (rule, value, callback) => {
+  const regex = /^(\-|\+)?\d+(\.\d+)?$/;
+  if (!regex.test(value)) {
+    callback(new Error('请输入数字!'));
+  }
+}
diff --git a/src/utils/dict.ts b/src/utils/dict.ts
index 5d9fac8..b1e134b 100644
--- a/src/utils/dict.ts
+++ b/src/utils/dict.ts
@@ -248,5 +248,8 @@
   OPCUA_SECURITY_MODE = 'opcua_security_mode',
   OPCUA_CONNECTION_TYPE = 'opcua_connection_type',
   HTTP_METHOD = 'http_method',
-
+  TIME_GRANULARITY = 'time_granularity',
+  STAT_FUNC = 'stat_func',
+  TIME_LIMIT = 'time_limit',
+  ITEM_TYPE = 'item_type',
 }
diff --git a/src/views/data/ind/img/ATOM.png b/src/views/data/ind/img/ATOM.png
new file mode 100644
index 0000000..425336f
--- /dev/null
+++ b/src/views/data/ind/img/ATOM.png
Binary files differ
diff --git a/src/views/data/ind/img/CAL.png b/src/views/data/ind/img/CAL.png
new file mode 100644
index 0000000..453c44a
--- /dev/null
+++ b/src/views/data/ind/img/CAL.png
Binary files differ
diff --git a/src/views/data/ind/img/DER.png b/src/views/data/ind/img/DER.png
new file mode 100644
index 0000000..14ee68f
--- /dev/null
+++ b/src/views/data/ind/img/DER.png
Binary files differ
diff --git a/src/views/data/ind/item/AtomIndDefineForm.vue b/src/views/data/ind/item/AtomIndDefineForm.vue
new file mode 100644
index 0000000..f9eaa74
--- /dev/null
+++ b/src/views/data/ind/item/AtomIndDefineForm.vue
@@ -0,0 +1,263 @@
+<template>
+  <Dialog v-model="dialogVisible" :title="dialogTitle" width="55%">
+    <el-form
+      ref="formRef"
+      v-loading="formLoading"
+      :model="formData"
+      :rules="formRules" label-width="100px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="指标编码" prop="itemNo">
+            <el-input v-model="formData.itemNo" disabled/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="指标名称" prop="itemName">
+            <el-input v-model="formData.itemName" placeholder="请输入指标名称"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="指标分类" prop="itemCategory">
+            <el-select v-model="formData.itemCategory" clearable placeholder="请选择指标分类">
+              <el-option
+                v-for="item in dataCategoryList"
+                :key="item.id"
+                :label="item.label"
+                :value="item.id + ''"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="时间粒度" prop="timeGranularity">
+            <el-select v-model="formData.timeGranularity" placeholder="请选择">
+              <el-option
+                v-for="dict in getStrDictOptions(DICT_TYPE.TIME_GRANULARITY)"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="指标精度" prop="precision">
+            <el-input v-model="formData.precision"/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="转换系数" prop="coefficient">
+            <el-input v-model="formData.coefficient"/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="数量单位" prop="unit">
+            <el-input v-model="formData.unit"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="备注" prop="remark">
+            <el-input v-model="formData.remark" type="textarea" maxlength="100"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="数据集" prop="atomItem.dataSet">
+            <el-select v-model="formData.atomItem.dataSet" clearable placeholder="请选择数据集" @change="handleDataSetChange($event)">
+              <el-option
+                v-for="item in dataSetList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id + ''"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="使用字段" prop="atomItem.usingField">
+            <el-select v-model="formData.atomItem.usingField" clearable placeholder="请选择字段">
+              <el-option
+                v-for="item in dataSetFieldList"
+                :key="item.id"
+                :label="item.fieldCode"
+                :value="item.id + ''"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="统计方式" prop="statFunc">
+            <el-select v-model="formData.atomItem.statFunc" placeholder="请选择">
+              <el-option
+                v-for="dict in getStrDictOptions(DICT_TYPE.STAT_FUNC)"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <template #footer>
+      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+<script lang="ts" setup>
+  import {DICT_TYPE, getStrDictOptions} from '@/utils/dict'
+  import * as ItemApi from '@/api/data/ind/item/item'
+  import * as DataSetApi from '@/api/data/ind/data/data.set'
+  import * as DataSetFieldApi from '@/api/data/ind/data/data.field'
+  import * as CategoryApi from '@/api/data/ind/category/index'
+
+
+  defineOptions({name: 'IndDataSetForm'})
+
+  const {t} = useI18n() // 国际化
+  const message = useMessage() // 消息弹窗
+
+  const dialogVisible = ref(false) // 弹窗的是否展示
+  const dialogTitle = ref('') // 弹窗的标题
+  const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+  const formType = ref('') // 表单的类型:create - 新增;update - 修改
+  let formData = ref({
+    id: undefined,
+    itemNo: '',
+    itemName: '',
+    itemType: '',
+    itemCategory: '',
+    coefficient: '',
+    precision: '',
+    businessType: '',
+    timeRange: '',
+    timeGranularity: '',
+    remark: '',
+    atomItem:{
+      dataSource:'',
+      dataSet: '',
+      usingField: '',
+      statFunc: ''
+    }
+  })
+  const validateAsNumber = (rule, value, callback) => {
+    const regex = /^(\-|\+)?\d+(\.\d+)?$/;
+    if (!regex.test(value)) {
+      callback(new Error('请输入数字!'));
+    }
+  }
+  const formRules = reactive({
+    itemName: [{required: true, message: '指标名称不能为空', trigger: 'blur'}],
+    itemCategory: [{required: true, message: '指标分类不能为空', trigger: 'blur'}],
+    precision: [{validator: validateAsNumber, trigger: 'blur' }],
+    coefficient: [{validator: validateAsNumber, trigger: 'blur' }],
+    "atomItem.dataSet": [{required: true, message: '数据集不能为空', trigger: 'blur'}],
+    "atomItem.usingField":[{required: true, message: '使用字段不能为空', trigger: 'blur'}]
+  })
+  const formRef = ref() // 表单 Ref
+  const dataSetList = ref([] as DataSetApi.DataSetVO[])
+  const dataSetFieldList = ref([] as DataSetFieldApi.DataSetFieldVO[])
+  const dataCategoryList = ref([])
+  /** 打开弹窗 */
+  const open = async (type: string, id?: string) => {
+    dialogVisible.value = true
+    dialogTitle.value = '原子指标'
+    formType.value = type
+    resetForm()
+    // 加载数据源列表
+    dataSetList.value = await DataSetApi.getDataSetList()
+    dataCategoryList.value = await CategoryApi.getCategoryListAllSimple()
+    // 修改时,设置数据
+    if (id) {
+      formLoading.value = true
+      try {
+        formData.value = await ItemApi.getItem(id)
+        if(formData.value.atomItem.dataSet !== null){
+          const queryParams = reactive({
+            dataSetId: formData.value.atomItem.dataSet,
+          })
+          dataSetFieldList.value = (await DataSetFieldApi.getDataSetFieldPage(queryParams)).list
+        }
+      } finally {
+        formLoading.value = false
+      }
+    }
+
+  }
+  defineExpose({open}) // 提供 open 方法,用于打开弹窗
+
+  /** 提交表单 */
+  const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+  const submitForm = async () => {
+    // 校验表单
+    if (!formRef) return
+    const valid = await formRef.value.validate()
+    if (!valid) return
+    // 提交请求
+    formLoading.value = true
+    try {
+      formData.value.itemType = 'ATOM'
+      for (let index in dataSetList.value){
+        if(formData.value.atomItem.dataSet === dataSetList.value[index].id){
+          formData.value.atomItem.dataSource = dataSetList.value[index].dataSource
+        }
+      }
+      const data = formData.value as ItemApi.ItemVO
+      if (formType.value === 'create') {
+        await ItemApi.createItem(data)
+        message.success(t('common.createSuccess'))
+      } else {
+        await ItemApi.updateItem(data)
+        message.success(t('common.updateSuccess'))
+      }
+      dialogVisible.value = false
+      // 发送操作成功的事件
+      emit('success')
+    } finally {
+      formLoading.value = false
+    }
+  }
+
+  /** 重置表单 */
+  const resetForm = () => {
+    formData.value = {
+      id: '',
+      itemNo: '',
+      itemName: '',
+      itemType: '',
+      itemCategory: '',
+      coefficient: '',
+      precision: '',
+      businessType: '',
+      timeRange: '',
+      timeGranularity: '',
+      remark: '',
+      atomItem:{
+        dataSource:'',
+        dataSet: '',
+        usingField: '',
+        statFunc: ''
+      }
+    }
+    dataSetFieldList.value = []
+    formRef.value?.resetFields()
+  }
+
+  async function handleDataSetChange(event) {
+    if (event !== null && event !== undefined) {
+      const queryParams = reactive({
+        dataSetId: event,
+      })
+      dataSetFieldList.value = (await DataSetFieldApi.getDataSetFieldPage(queryParams)).list
+    }
+  }
+
+</script>
diff --git a/src/views/data/ind/item/CalIndDefineForm.vue b/src/views/data/ind/item/CalIndDefineForm.vue
new file mode 100644
index 0000000..0d5fc81
--- /dev/null
+++ b/src/views/data/ind/item/CalIndDefineForm.vue
@@ -0,0 +1,436 @@
+<template>
+  <Dialog v-model="dialogVisible" :title="dialogTitle" width="55%">
+    <el-form
+      ref="formRef"
+      v-loading="formLoading"
+      :model="formData"
+      :rules="formRules" label-width="100px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="指标编码" prop="itemNo">
+            <el-input v-model="formData.itemNo" disabled/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="指标名称" prop="itemName">
+            <el-input v-model="formData.itemName" placeholder="请输入指标名称"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="指标分类" prop="itemCategory">
+            <el-select v-model="formData.itemCategory" clearable placeholder="请选择指标分类">
+              <el-option
+                v-for="item in dataCategoryList"
+                :key="item.id"
+                :label="item.label"
+                :value="item.id + ''"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="时间粒度" prop="timeGranularity">
+            <el-select v-model="formData.timeGranularity" placeholder="请选择">
+              <el-option
+                v-for="dict in getStrDictOptions(DICT_TYPE.TIME_GRANULARITY)"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="指标精度" prop="precision">
+            <el-input v-model="formData.precision"/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="转换系数" prop="coefficient">
+            <el-input v-model="formData.coefficient"/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="数量单位" prop="unit">
+            <el-input v-model="formData.unit"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="备注" prop="remark">
+            <el-input v-model="formData.remark" type="textarea" maxlength="100"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="表达式">
+            <el-table :data="expressionList" border style="width: 100%">
+              <el-table-column type="index" align="center" width="60" label="序号"/>
+              <el-table-column prop="" label="左括号" width="100" align="center">
+                <template #default="scope">
+                  <el-input size="small" v-model="scope.row.parenthesesLeft" placeholder="" readonly maxlength="10"/>
+                  <el-button size="small" @click="addParenthesesLeft(scope.$index, scope.row)">+</el-button>
+                  <el-button size="small" @click="removeParenthesesLeft(scope.$index, scope.row)">-</el-button>
+                </template>
+              </el-table-column>
+              <el-table-column prop="" label="指标" align="center">
+                <template #default="scope">
+                  <el-select size="mini" v-model="scope.row.itemNo" filterable placeholder="请选择">
+                    <el-option v-for="(item, index) in itemList"
+                               :key="index"
+                               :label="item.itemName"
+                               :value="item.itemNo"/>
+                  </el-select>
+                </template>
+              </el-table-column>
+              <el-table-column prop="" label="运算值" align="center">
+                <template #default="scope">
+                  <el-input size="mini" v-model="scope.row.itemNo" placeholder="运算值" clearable/>
+                </template>
+              </el-table-column>
+              <el-table-column prop="" label="右括号" width="100" align="center">
+                <template #default="scope">
+                  <el-input size="small" v-model="scope.row.parenthesesRight" placeholder="" readonly/>
+                    <el-button size="small" @click="addParenthesesRight(scope.$index, scope.row, ')')">+
+                    </el-button>
+                    <el-button size="small" @click="removeParenthesesRight(scope.$index, scope.row)">-
+                    </el-button>
+                </template>
+              </el-table-column>
+              <el-table-column prop="" label="运算符" width="100" align="center">
+                <template #default="scope">
+                  <el-select size="mini" v-model="scope.row.operator" clearable placeholder="请选择"
+                             style="font-weight: 600;">
+                    <el-option v-for="item in operatorList"
+                               :key="item"
+                               :label="item"
+                               :value="item"/>
+                  </el-select>
+                </template>
+              </el-table-column>
+              <el-table-column prop="" label="操作" width="100" align="center">
+                <template #default="scope">
+                  <el-button @click="addExpressionRow(scope.$index, expressionList)" link type="primary" size="small">添加</el-button>
+                  <el-button @click="deleteExpressionRow(scope.$index, expressionList)" link type="danger" size="small">删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <template #footer>
+      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+<script lang="ts" setup>
+  import {DICT_TYPE, getStrDictOptions} from '@/utils/dict'
+  import * as DataSetApi from '@/api/data/ind/data/data.set'
+  import {CommonStatusEnum} from '@/utils/constants'
+  import * as DataSourceConfigApi from "@/api/infra/dataSourceConfig";
+  import * as ItemApi from '@/api/data/ind/item/item'
+  import { ElMessage } from 'element-plus'
+  import * as CategoryApi from '@/api/data/ind/category/index'
+
+  defineOptions({name: 'IndDataSetForm'})
+
+  const {t} = useI18n() // 国际化
+  const message = useMessage() // 消息弹窗
+
+  const dialogVisible = ref(false) // 弹窗的是否展示
+  const dialogTitle = ref('') // 弹窗的标题
+  const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+  const formType = ref('') // 表单的类型:create - 新增;update - 修改
+  const itemList = ref([] as ItemApi.ItemVO[])
+  let formData = ref({
+    id: undefined,
+    itemNo: '',
+    itemName: '',
+    itemType: '',
+    itemCategory: '',
+    coefficient: '',
+    precision: '',
+    businessType: '',
+    timeRange: '',
+    timeGranularity: '',
+    remark: '',
+    calItem: {
+      id: '',
+      expression: '',
+    }
+  })
+  let expressionList = ref([{
+    parenthesesLeft: '',
+    itemNo: '',
+    parenthesesRight: '',
+    operator: ''
+  }])
+
+  const validateAsNumber = (rule, value, callback) => {
+    const regex = /^(\-|\+)?\d+(\.\d+)?$/;
+    if (!regex.test(value)) {
+      callback(new Error('请输入数字!'));
+    }
+  }
+  const operatorList = ref(['+', '-', '*', '/', '&', '|', '!', '>', '<'])
+  const formRules = reactive({
+    itemName: [{required: true, message: '指标名称不能为空', trigger: 'blur'}],
+    itemCategory: [{required: true, message: '指标类型不能为空', trigger: 'blur'}],
+    precision: [{validator: validateAsNumber, trigger: 'blur' }],
+    coefficient: [{validator: validateAsNumber, trigger: 'blur' }],
+  })
+  const formRef = ref() // 表单 Ref
+  const dataSourceList = ref([] as DataSourceConfigApi.DataSourceConfigVO[])
+  const queryParams = reactive({})
+  const dataCategoryList = ref([] as CategoryApi.IndItemCategoryVO[])
+  /** 打开弹窗 */
+  const open = async (type: string, id?: number) => {
+    dialogVisible.value = true
+    dialogTitle.value = '复合指标'
+    formType.value = type
+    resetForm()
+
+    // 加载数据源列表
+    dataCategoryList.value = await CategoryApi.getCategoryListAllSimple()
+    itemList.value = await ItemApi.getItemList(queryParams)
+    // 修改时,设置数据
+    if (id) {
+      formLoading.value = true
+      try {
+        formData.value = await ItemApi.getItem(id)
+        expressionList.value = []
+        let expression = formData.value.calItem.expression
+        do {
+          let indexArray = [
+            expression.indexOf('+'),
+            expression.indexOf('-'),
+            expression.indexOf('*'),
+            expression.indexOf('/'),
+            expression.indexOf('&'),
+            expression.indexOf('|'),
+            expression.indexOf('!'),
+            expression.indexOf('>'),
+            expression.indexOf('<')
+          ].sort(numAscSort)
+          if (indexArray[indexArray.length - 1] !== -1) {
+            let endIndex = 0
+            for (let key in indexArray) {
+              if (indexArray[key] > -1) {
+                endIndex = indexArray[key]
+                break
+              }
+            }
+            // 运算值
+            let itemNoStr = expression.substring(0, endIndex)
+
+            // 运算符
+            let operator = expression.substr(endIndex, 1)
+            let indexOfParenthesesLeft = itemNoStr.indexOf('(')
+            let lastIndexOfParenthesesLeft = itemNoStr.lastIndexOf('(')
+
+            // 左括号
+            let parenthesesLeft = ''
+            if (indexOfParenthesesLeft !== -1 && lastIndexOfParenthesesLeft !== -1) {
+              parenthesesLeft = itemNoStr.substring(indexOfParenthesesLeft, lastIndexOfParenthesesLeft + 1)
+              itemNoStr = itemNoStr.substring(lastIndexOfParenthesesLeft + 1)
+            }
+
+            let indexOfParenthesesRight = itemNoStr.indexOf(')')
+            let lastIndexOfParenthesesRight = itemNoStr.lastIndexOf(')')
+
+            // 右括号
+            let parenthesesRight = ''
+            if (indexOfParenthesesRight !== -1 && lastIndexOfParenthesesRight !== -1) {
+              parenthesesRight = itemNoStr.substring(indexOfParenthesesRight, lastIndexOfParenthesesRight + 1)
+              itemNoStr = itemNoStr.substring(0, indexOfParenthesesRight)
+            }
+            expressionList.value.push({
+              parenthesesLeft: parenthesesLeft,
+              itemNo: itemNoStr,
+              parenthesesRight: parenthesesRight,
+              operator: operator
+            })
+            expression = expression.substring(endIndex + 1)
+          } else {
+            let pointStr = expression
+            let indexOfParenthesesLeft = pointStr.indexOf('(')
+            let lastIndexOfParenthesesLeft = pointStr.lastIndexOf('(')
+            let parenthesesLeft = ''
+            if (indexOfParenthesesLeft !== -1 && lastIndexOfParenthesesLeft !== -1) {
+              parenthesesLeft = pointStr.substring(indexOfParenthesesLeft, lastIndexOfParenthesesLeft + 1)
+              pointStr = pointStr.substring(lastIndexOfParenthesesLeft + 1)
+            }
+            let indexOfParenthesesRight = pointStr.indexOf(')')
+            let lastIndexOfParenthesesRight = pointStr.lastIndexOf(')')
+            let parenthesesRight = ''
+            if (indexOfParenthesesRight !== -1 && lastIndexOfParenthesesRight !== -1) {
+              parenthesesRight = pointStr.substring(indexOfParenthesesRight, lastIndexOfParenthesesRight + 1)
+              pointStr = pointStr.substring(0, indexOfParenthesesRight)
+            }
+            expressionList.value.push({
+              parenthesesLeft: parenthesesLeft,
+              itemNo: pointStr,
+              parenthesesRight: parenthesesRight,
+              operator: ''
+            })
+            expression = ''
+          }
+        } while (expression && expression.length > 0)
+
+      } finally {
+        formLoading.value = false
+      }
+    }
+  }
+  function numAscSort(a, b) {
+    return a - b
+  }
+
+  defineExpose({open}) // 提供 open 方法,用于打开弹窗
+
+  /** 提交表单 */
+  const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+  const submitForm = async () => {
+    // 校验表单
+    if (!formRef) return
+    const valid = await formRef.value.validate()
+    if (!valid) return
+    // 提交请求
+    formLoading.value = true
+    try {
+      if (expressionList.value && expressionList.value.length > 0) {
+        let parenthesesLeftRex = /^[(]*$/
+        let parenthesesRightRex = /^[)]*$/
+        let expression = ''
+        for (let i = 0; i < expressionList.value.length; i++) {
+          let value = expressionList.value[i]
+          if (!parenthesesLeftRex.test(value.parenthesesLeft)) {
+            ElMessage({
+              message: `第${i + 1}行左括号输入不正确!`,
+              type: 'error',
+              duration: 1500
+            })
+            return
+          }
+          if (!parenthesesRightRex.test(value.parenthesesRight)) {
+            ElMessage({
+              message: `第${i + 1}行右括号输入不正确!`,
+              type: 'error',
+              duration: 1500
+            })
+            return
+          }
+          if (i !== (expressionList.value.length - 1) && !value.operator) {
+            ElMessage({
+              message: `第${i + 1}行运算符不能为空!`,
+              type: 'error',
+              duration: 1500
+            })
+            return
+          }
+          expression = expression + value.parenthesesLeft + value.itemNo + value.parenthesesRight + (i === (expressionList.value.length - 1) ? '' : value.operator)
+        }
+        formData.value.calItem.expression = expression
+      } else {
+        ElMessage({
+          message: `表达式不可以为空`,
+          type: 'error',
+          duration: 1500
+        })
+        return
+      }
+      formData.value.itemType = 'CAL'
+      const data = formData.value as ItemApi.ItemVO
+      if (formType.value === 'create') {
+        await ItemApi.createItem(data)
+        message.success(t('common.createSuccess'))
+      } else {
+        await ItemApi.updateItem(data)
+        message.success(t('common.updateSuccess'))
+      }
+      dialogVisible.value = false
+      // 发送操作成功的事件
+      emit('success')
+    } finally {
+      formLoading.value = false
+    }
+  }
+
+  function addExpressionRow(index, rows) {
+    let row = JSON.parse(JSON.stringify(rows[index]))
+    rows.splice(index, 0, row)
+  }
+
+  function addParenthesesLeft(index, row) {
+    if (row.parenthesesLeft) {
+      row.parenthesesLeft = row.parenthesesLeft + '('
+    } else {
+      row.parenthesesLeft = '('
+    }
+  }
+
+  function removeParenthesesLeft(index, row) {
+    if (row.parenthesesLeft) {
+      row.parenthesesLeft = row.parenthesesLeft.substring(0, row.parenthesesLeft.length - 1)
+    } else {
+      row.parenthesesLeft = ''
+    }
+  }
+
+  function addParenthesesRight(index, row) {
+    if (row.parenthesesRight) {
+      row.parenthesesRight = row.parenthesesRight + ')'
+    } else {
+      row.parenthesesRight = ')'
+    }
+  }
+
+  function removeParenthesesRight(index, row) {
+    if (row.parenthesesRight) {
+      row.parenthesesRight = row.parenthesesRight.substring(0, row.parenthesesRight.length - 1)
+    } else {
+      row.parenthesesRight = ''
+    }
+  }
+
+  function deleteExpressionRow(index, rows) {
+    if (!rows || rows.length === 1) {
+      ElMessage({
+        message: '不能全部删除!',
+        type: 'error',
+        duration: 1500
+      })
+      return
+    }
+    rows.splice(index, 1)
+  }
+
+  /** 重置表单 */
+  const resetForm = () => {
+    formData.value = {
+      id: undefined,
+      itemNo: '',
+      itemName: '',
+      itemType: '',
+      itemCategory: '',
+      coefficient: '',
+      precision: '',
+      businessType: '',
+      timeRange: '',
+      timeGranularity: '',
+      remark: '',
+      calItem: {
+        id: '',
+        expression: '',
+      }}
+    formRef.value?.resetFields()
+  }
+</script>
diff --git a/src/views/data/ind/item/DerIndDefineForm.vue b/src/views/data/ind/item/DerIndDefineForm.vue
new file mode 100644
index 0000000..2d7d1d9
--- /dev/null
+++ b/src/views/data/ind/item/DerIndDefineForm.vue
@@ -0,0 +1,329 @@
+<template>
+  <Dialog v-model="dialogVisible" :title="dialogTitle" width="55%">
+    <el-form
+      ref="formRef"
+      v-loading="formLoading"
+      :model="formData"
+      :rules="formRules" label-width="100px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="原子指标" prop="atomItem.id">
+            <el-select v-model="selected" clearable placeholder="请选择原子指标"
+                       @change="handleChange($event)">
+              <el-option
+                v-for="item in atomItemList"
+                :key="item.id"
+                :label="item.itemNo"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="原子指标名称" prop="atomItem.itemName">
+            <el-input v-model="formData.atomItem.itemName" disabled/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="指标编码" prop="itemNo">
+            <el-input v-model="formData.itemNo" disabled/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="指标名称" prop="itemName">
+            <el-input v-model="formData.itemName"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="指标分类" prop="itemCategory">
+            <el-select v-model="formData.itemCategory" clearable placeholder="请选择指标分类">
+              <el-option
+                v-for="item in dataCategoryList"
+                :key="item.id"
+                :label="item.label"
+                :value="item.id + ''"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="时间粒度" prop="timeGranularity">
+            <el-select v-model="formData.timeGranularity" placeholder="请选择">
+              <el-option
+                v-for="dict in getStrDictOptions(DICT_TYPE.TIME_GRANULARITY)"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="指标精度" prop="precision">
+            <el-input v-model="formData.precision"/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="转换系数" prop="coefficient">
+            <el-input v-model="formData.coefficient"/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="6">
+          <el-form-item label="数量单位" prop="unit">
+            <el-input v-model="formData.unit"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="20">
+          <el-form-item label="备注" prop="remark">
+            <el-input v-model="formData.remark" type="textarea" maxlength="100"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="时间标识" prop="timeLabel">
+            <el-select v-model="formData.derItem.timeLabel" clearable placeholder="请选择时间标识">
+              <el-option
+                v-for="item in dataSetFieldList"
+                :key="item.id"
+                :label="item.fieldCode"
+                :value="item.id + ''"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="时间限定" prop="timeLimit">
+            <el-select v-model="formData.timeLimit" placeholder="请选择"
+                       @change="handleTimeLimitChange($event)">
+              <el-option
+                v-for="dict in getStrDictOptions(DICT_TYPE.TIME_LIMIT)"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row v-if="showTimeChange">
+        <el-col :span="12">
+          <el-form-item label="开始时间" prop="timeStart">
+            <el-date-picker
+              v-model="formData.derItem.timeStart"
+              type="datetime"
+              placeholder="请选择开始时间"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="结束时间" prop="timeEnd">
+            <el-date-picker
+              v-model="formData.derItem.timeEnd"
+              type="datetime"
+              placeholder="请选择结束时间"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="分析维度" prop="dimension">
+            <el-select v-model="formData.derItem.dimension" clearable placeholder="请选择分析维度" multiple>
+              <el-option
+                v-for="item in dataSetFieldList"
+                :key="item.id"
+                :label="item.fieldCode"
+                :value="item.id + ''"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <template #footer>
+      <el-button :="formLoading" type="primary" @click="submitForm">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+<script lang="ts" setup>
+  import {DICT_TYPE, getStrDictOptions} from '@/utils/dict'
+  import * as DataSetApi from '@/api/data/ind/data/data.set'
+  import * as ItemApi from '@/api/data/ind/item/item'
+  import {CommonStatusEnum} from '@/utils/constants'
+  import * as DataSourceConfigApi from "@/api/infra/dataSourceConfig";
+  import {PageParam} from "@/api/data/ind/item/item";
+  import * as CategoryApi from "@/api/data/ind/category";
+  import * as DataSetFieldApi from "@/api/data/ind/data/data.field";
+
+  defineOptions({name: 'IndDataSetForm'})
+
+  const {t} = useI18n() // 国际化
+  const message = useMessage() // 消息弹窗
+
+  const dialogVisible = ref(false) // 弹窗的是否展示
+  const dialogTitle = ref('') // 弹窗的标题
+  const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+  const formType = ref('') // 表单的类型:create - 新增;update - 修改
+  let formData = ref({
+    id: undefined,
+    itemNo: '',
+    itemName: '',
+    itemType: '',
+    itemCategory: '',
+    coefficient: '',
+    precision: '',
+    businessType: '',
+    timeRange: '',
+    timeGranularity: '',
+    atomItem: {
+      id: '',
+      itemNo: '',
+      itemName: '',
+    },
+    derItem: {
+      atomItemId: '',
+      timeLabel: '',
+      timeLimit: '',
+      timeStart: '',
+      timeEnd: '',
+      dimension: ''
+    }
+  })
+  const queryParams = ref({
+    itemType: 'ATOM'
+  })
+
+  const validateAsNumber = (rule, value, callback) => {
+    const regex = /^(\-|\+)?\d+(\.\d+)?$/;
+    if (!regex.test(value)) {
+      callback(new Error('请输入数字!'));
+    }
+  }
+
+  const formRules = reactive({
+    itemName: [{required: true, message: '指标名称不能为空', trigger: 'blur'}],
+    itemCategory: [{required: true, message: '指标类型不能为空', trigger: 'blur'}],
+    precision: [{validator: validateAsNumber, trigger: 'blur' }],
+    coefficient: [{validator: validateAsNumber, trigger: 'blur' }],
+    "atomItem.id": [{required: true, message: '原子指标不能为空', trigger: 'blur'}]
+  })
+  const formRef = ref() // 表单 Ref
+  const dataSourceList = ref([] as DataSourceConfigApi.DataSourceConfigVO[])
+  const atomItemList = ref([] as ItemApi.ItemVO[])
+  const selected = ref(null)
+  const showTimeChange = ref(false)
+  const dataCategoryList = ref([] as CategoryApi.IndItemCategoryVO[])
+  const dataSetFieldList = ref([] as DataSetFieldApi.DataSetFieldVO[])
+
+  /** 打开弹窗 */
+  const open = async (type: string, id?: string) => {
+    dialogVisible.value = true
+    dialogTitle.value = '派生指标'
+    formType.value = type
+    resetForm()
+    // 加载数据源列表
+    dataCategoryList.value = await CategoryApi.getCategoryListAllSimple()
+    atomItemList.value = await ItemApi.getItemList(queryParams)
+    selected.value = null
+    // 修改时,设置数据
+    if (id) {
+      formLoading.value = true
+      try {
+        formData.value = await ItemApi.getItem(id)
+      } finally {
+        formLoading.value = false
+      }
+    }
+  }
+  defineExpose({open}) // 提供 open 方法,用于打开弹窗
+
+  /** 提交表单 */
+  const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+  const submitForm = async () => {
+    // 校验表单
+    if (!formRef) return
+    const valid = await formRef.value.validate()
+    if (!valid) return
+    // 提交请求
+    formLoading.value = true
+    try {
+      formData.value.itemType = 'DER'
+      formData.value.derItem.atomItemId = formData.value.atomItem.id
+      if(formData.value.derItem.dimension.length > 0){
+        let dimension = ''
+        for (let index in formData.value.derItem.dimension){
+          dimension = dimension + formData.value.derItem.dimension[index] + ','
+        }
+        formData.value.derItem.dimension = dimension.substring(0, dimension.length - 1)
+      }
+      const data = formData.value as ItemApi.ItemVO
+      if (formType.value === 'create') {
+        await ItemApi.createItem(data)
+        message.success(t('common.createSuccess'))
+      } else {
+        await ItemApi.updateItem(data)
+        message.success(t('common.updateSuccess'))
+      }
+      dialogVisible.value = false
+      // 发送操作成功的事件
+      emit('success')
+    } finally {
+      formLoading.value = false
+    }
+  }
+  /** 重置表单 */
+  const resetForm = () => {
+    formData.value = {
+      id: undefined,
+      itemNo: '',
+      itemName: '',
+      itemType: '',
+      itemCategory: '',
+      coefficient: '',
+      precision: '',
+      businessType: '',
+      timeRange: '',
+      timeGranularity: '',
+      remark: '',
+      atomItem: {
+        id: '',
+        itemNo: '',
+        itemName: '',
+      },
+      derItem: {
+        atomItemId: '',
+        timeLabel: '',
+        timeLimit: '',
+        timeStart: '',
+        timeEnd: '',
+        dimension: ''
+      }
+    }
+  }
+
+  async function handleChange(event) {
+    if (event !== null && event !== undefined) {
+      const itemData = await ItemApi.getItem(event)
+      formData.value.atomItem.itemName = itemData.itemName
+      formData.value.atomItem.id = itemData.atomItem.id
+      const queryParams = reactive({
+        dataSetId: itemData.atomItem.dataSet,
+      })
+      dataSetFieldList.value = (await DataSetFieldApi.getDataSetFieldPage(queryParams)).list
+    }
+  }
+
+  function handleTimeLimitChange(event) {
+    showTimeChange.value = event === 'CUSTOM';
+  }
+</script>
diff --git a/src/views/data/ind/item/index.vue b/src/views/data/ind/item/index.vue
new file mode 100644
index 0000000..281115e
--- /dev/null
+++ b/src/views/data/ind/item/index.vue
@@ -0,0 +1,195 @@
+<template>
+  <!-- 搜索工作栏 -->
+  <ContentWrap>
+    <el-form ref="queryFormRef" :inline="true" :model="queryParams" class="-mb-15px"
+             label-width="68px">
+      <el-form-item label="指标编码" prop="name">
+        <el-input v-model="queryParams.itemNo" class="!w-240px" clearable placeholder="请输入指标编码"
+                  @keyup.enter="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="指标名称" prop="name">
+        <el-input v-model="queryParams.itemName" class="!w-240px" clearable placeholder="请输入指标名称"
+                  @keyup.enter="handleQuery"/>
+      </el-form-item>
+      <el-form-item>
+        <el-button @click="handleQuery">
+          <Icon class="mr-5px" icon="ep:search"/>
+          搜索
+        </el-button>
+        <el-button @click="resetQuery">
+          <Icon class="mr-5px" icon="ep:refresh"/>
+          重置
+        </el-button>
+        <el-button
+          v-hasPermi="['data:ind-item:create']"
+          plain
+          type="primary"
+          @click="openForm('create')"
+        >
+          <Icon class="mr-5px" icon="ep:plus"/>
+          新增
+        </el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <el-table v-loading="loading" :data="list">
+      <el-table-column prop="itemNo" label="指标编码" header-align="center" align="center" min-width="80"/>
+      <el-table-column prop="itemName" label="指标名称" header-align="center" align="center" min-width="120"/>
+      <el-table-column prop="itemCategoryName" label="指标分类" header-align="center" align="center" min-width="100"/>
+      <el-table-column prop="itemType" label="指标类型" header-align="center" align="center" min-width="60">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.ITEM_TYPE" :value="scope.row.itemType" />
+        </template>
+      </el-table-column>
+      <el-table-column prop="coefficient" label="系数" header-align="center" align="center" min-width="60"/>
+      <el-table-column prop="precision" label="指标精度" header-align="center" align="center" min-width="60"/>
+      <el-table-column prop="timeGranularity" label="时间粒度" header-align="center" align="center" min-width="40">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.TIME_GRANULARITY" :value="scope.row.timeGranularity" />
+        </template>
+      </el-table-column>
+      <el-table-column
+        :formatter="dateFormatter"
+        align="center"
+        label="创建时间"
+        prop="createTime"
+        width="180"/>
+      <el-table-column align="center" label="操作">
+        <template #default="scope">
+          <el-button
+            v-hasPermi="['data:ind-item:update']"
+            link
+            type="primary"
+            @click="openForm('update', scope.row)">
+            修改
+          </el-button>
+          <el-button
+            v-hasPermi="['data:ind-item:delete']"
+            link
+            type="danger"
+            @click="handleDelete(scope.row.id)">
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      v-model:limit="queryParams.pageSize"
+      v-model:page="queryParams.pageNo"
+      :total="total"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <!-- 表单弹窗:添加/修改 -->
+  <AtomIndDefineForm ref="atomFormRef" @success="getList" />
+  <DerIndDefineForm ref="derFormRef" @success="getList" />
+  <CalIndDefineForm ref="calFormRef" @success="getList" />
+  <SelectItemType ref="itemTypeSel"/>
+</template>
+
+<script lang="ts" setup>
+  import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
+  import { dateFormatter } from '@/utils/formatTime'
+  import * as DataSetApi from '@/api/data/ind/data/data.set'
+  import AtomIndDefineForm from './AtomIndDefineForm.vue'
+  import DerIndDefineForm from './DerIndDefineForm.vue'
+  import CalIndDefineForm from './CalIndDefineForm.vue'
+  import SelectItemType from './selectItemType.vue'
+  import download from '@/utils/download'
+  import * as ItemApi from '@/api/data/ind/item/item'
+  import * as CategoryApi from "@/api/data/ind/category";
+
+  defineOptions({ name: 'IndDataSet' })
+
+  const message = useMessage() // 消息弹窗
+  const { t } = useI18n() // 国际化
+  const dataCategoryList = ref([] as CategoryApi.IndItemCategoryVO[])
+  const loading = ref(true) // 列表的加载中
+  const total = ref(0) // 列表的总页数
+  const list = ref([]) // 字典表格数据
+  const queryParams = reactive({
+    pageNo: 1,
+    pageSize: 10,
+    itemNo: '',
+    itemName: '',
+    itemType: '',
+    itemCategory: ''
+  })
+  const queryFormRef = ref() // 搜索的表单
+  const exportLoading = ref(false) // 导出的加载中
+
+  /** 查询字典类型列表 */
+  const getList = async () => {
+    loading.value = true
+    try {
+      const data = await ItemApi.getItemPage(queryParams)
+      list.value = data.list
+      total.value = data.total
+      dataCategoryList.value = await CategoryApi.getCategoryListAllSimple()
+    } finally {
+      loading.value = false
+    }
+  }
+
+  /** 搜索按钮操作 */
+  const handleQuery = () => {
+    queryParams.pageNo = 1
+    getList()
+  }
+
+  /** 重置按钮操作 */
+  const resetQuery = () => {
+    queryFormRef.value.resetFields()
+    handleQuery()
+  }
+
+  /** 添加/修改操作 */
+  const atomFormRef = ref()
+  const derFormRef = ref()
+  const calFormRef = ref()
+  const itemTypeSel = ref()
+
+  const openForm = (type: string, row) => {
+    if(row !== null && row !==undefined){
+      if(row.itemType === 'ATOM'){
+        if (row.id){
+          atomFormRef.value.open(type,row.id)
+        }
+      }else if(row.itemType === 'CAL'){
+        if (row.id){
+          calFormRef.value.open(type,row.id)
+        }
+      }else if(row.itemType === 'DER'){
+        if (row.id){
+          derFormRef.value.open(type,row.id)
+        }
+      }
+    }else {
+      itemTypeSel.value.open(type)
+    }
+
+  }
+
+  /** 删除按钮操作 */
+  const handleDelete = async (id: number) => {
+    try {
+      // 删除的二次确认
+      await message.delConfirm()
+      // 发起删除
+      await ItemApi.deleteItem(id)
+      message.success(t('common.delSuccess'))
+      // 刷新列表
+      await getList()
+    } catch {}
+  }
+
+  /** 初始化 **/
+  onMounted(() => {
+    getList()
+  })
+</script>
diff --git a/src/views/data/ind/item/selectItemType.vue b/src/views/data/ind/item/selectItemType.vue
new file mode 100644
index 0000000..2b09ee2
--- /dev/null
+++ b/src/views/data/ind/item/selectItemType.vue
@@ -0,0 +1,96 @@
+<template>
+  <Dialog v-model="dialogVisible" :title="dialogTitle" width="47%">
+    <div class="card" @click="openForm('ATOM')">
+      <img src="../img/ATOM.png" alt="Card Image" class="card-img"/>
+      <div class="card-body">
+        <p class="card-title-text">{{ "原子指标" }}</p>
+        <p class="card-text">{{ "从0开始创建一个新指标" }}</p>
+      </div>
+    </div>
+    <div class="card" @click="openForm('DER')">
+      <img src="../img/DER.png" alt="Card Image" class="card-img"/>
+      <div class="card-body">
+        <p class="card-title-text">{{ "派生指标" }}</p>
+        <p class="card-text">{{ "基于单个原子指标通过条件过滤派生出的新指标" }}</p>
+      </div>
+    </div>
+    <div class="card" @click="openForm('CAL')">
+      <img src="../img/CAL.png" alt="Card Image" class="card-img"/>
+      <div class="card-body">
+        <p class="card-title-text">{{ "复合指标" }}</p>
+        <p class="card-text">{{ "基于一组原子指标通过条件过滤派生出的新指标" }}</p>
+      </div>
+    </div>
+  </Dialog>
+  <AtomIndDefineForm ref="atomFormRef" @success="getList" />
+  <DerIndDefineForm ref="derFormRef" @success="getList" />
+  <CalIndDefineForm ref="calFormRef" @success="getList" />
+</template>
+<script lang="ts" setup>
+  import * as DataSetApi from '@/api/data/ind/data/data.set'
+  import AtomIndDefineForm from './AtomIndDefineForm.vue'
+  import DerIndDefineForm from './DerIndDefineForm.vue'
+  import CalIndDefineForm from './CalIndDefineForm.vue'
+
+  defineOptions({ name: 'IndDataSetForm' })
+
+  const { t } = useI18n() // 国际化
+  const message = useMessage() // 消息弹窗
+
+  const dialogVisible = ref(false) // 弹窗的是否展示
+  const dialogTitle = ref('') // 弹窗的标题
+  const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+  const formType = ref('') // 表单的类型:create - 新增;update - 修改
+
+  /** 打开弹窗 */
+  const open = async (type: string) => {
+    dialogVisible.value = true
+    dialogTitle.value = t('action.' + type)
+    formType.value = type
+  }
+  defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+  const atomFormRef = ref()
+  const derFormRef = ref()
+  const calFormRef = ref()
+  const openForm = (category: string) => {
+    if(category === 'ATOM'){
+      atomFormRef.value.open("create",null)
+    }else if(category === 'DER'){
+      derFormRef.value.open("create",null)
+    }else if(category === 'CAL'){
+      calFormRef.value.open("create",null)
+    }
+  }
+</script>
+
+<style scoped>
+  .card {
+    width: 25vh;
+    margin: 10px 16px;
+    display: inline-block;
+    vertical-align: top;
+    border: 1px solid #ddd;
+    border-radius: 4px;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+    height: 30vh;
+    cursor: pointer;
+  }
+  .card-img {
+    width: 100%;
+    height: 150px;
+    object-fit: cover;
+  }
+
+  .card-body {
+    padding: 10px;
+    text-align: center;
+  }
+  .card-title-text{
+    font-size: larger;
+  }
+  .card-text {
+    font-size: smaller;
+    margin: 0;
+  }
+</style>
diff --git a/src/views/model/pre/predict/MmPredictItemForm.vue b/src/views/model/pre/predict/MmPredictItemForm.vue
index 7e1b8b9..fbc3506 100644
--- a/src/views/model/pre/predict/MmPredictItemForm.vue
+++ b/src/views/model/pre/predict/MmPredictItemForm.vue
@@ -10,24 +10,20 @@
       <el-divider content-position="left">基本信息</el-divider>
       <el-row>
         <el-col :span="12">
-          <el-form-item label="预测项名" prop="mmPredictItem.itemname">
-            <el-input v-model="dataForm.mmPredictItem.itemname" placeholder="预测项名"
-                      maxlength="50"
-                      clearable/>
+          <el-form-item label="预测项名" prop="itemname">
+            <el-input v-model="dataForm.mmPredictItem.itemname" placeholder="预测项名"/>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="编号" prop="mmPredictItem.itemno">
-            <el-input v-model="dataForm.mmPredictItem.itemno" placeholder="编号" maxlength="50"
-                      clearable/>
+          <el-form-item label="编号" prop="itemno">
+            <el-input v-model="dataForm.mmPredictItem.itemno" placeholder="编号" maxlength="50"/>
           </el-form-item>
         </el-col>
       </el-row>
       <el-row>
         <el-col :span="12">
-          <el-form-item label="类型" prop="mmPredictItem.itemtypeid">
-            <el-select v-model="dataForm.mmPredictItem.itemtypeid"
-                       @change="changeItemtype"
+          <el-form-item label="类型" prop="itemtypeid">
+            <el-select v-model="dataForm.mmPredictItem.itemtypeid" @change="changeItemtype"
                        placeholder="请选择">
               <el-option
                 v-for="item in itemTypeList"
@@ -38,15 +34,15 @@
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="粒度" prop="mmPredictItem.granularity">
-            <el-input v-model="dataForm.mmPredictItem.granularity" placeholder="粒度" maxlength="5"
-                      clearable/>
+          <el-form-item label="粒度" prop="granularity">
+            <el-input v-model="dataForm.mmPredictItem.granularity" placeholder="粒度"
+                      maxlength="5"/>
           </el-form-item>
         </el-col>
       </el-row>
       <el-row>
         <el-col :span="12">
-          <el-form-item label="是否检查" prop="mmPredictItem.workchecked">
+          <el-form-item label="是否检查" prop="workchecked">
             <el-select v-model="dataForm.mmPredictItem.workchecked" placeholder="请选择">
               <el-option
                 v-for="item in isList"
@@ -57,7 +53,7 @@
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="是否启用" prop="dmModuleItem.status">
+          <el-form-item label="是否启用" prop="status">
             <el-select v-model="dataForm.dmModuleItem.status" placeholder="请选择">
               <el-option
                 v-for="item in isList"
@@ -70,7 +66,7 @@
       </el-row>
       <el-row>
         <el-col :span="12">
-          <el-form-item label="管网" prop="dmModuleItem.moduleid">
+          <el-form-item label="管网" prop="moduleid">
             <el-select v-model="dataForm.dmModuleItem.moduleid" placeholder="请选择">
               <el-option
                 v-for="item in moduleList"
@@ -81,21 +77,19 @@
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="类别" prop="dmModuleItem.categoryid">
-            <el-input v-model="dataForm.dmModuleItem.categoryid" placeholder="类别" maxlength="64"
-                      clearable/>
+          <el-form-item label="类别" prop="categoryid">
+            <el-input v-model="dataForm.dmModuleItem.categoryid" placeholder="类别" maxlength="64"/>
           </el-form-item>
         </el-col>
       </el-row>
       <el-row>
         <el-col :span="12">
-          <el-form-item label="排序" prop="dmModuleItem.itemorder">
-            <el-input v-model="dataForm.dmModuleItem.itemorder" placeholder="排序" maxlength="36"
-                      clearable/>
+          <el-form-item label="排序" prop="itemorder">
+            <el-input v-model="dataForm.dmModuleItem.itemorder" placeholder="排序" maxlength="36"/>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="数据点" prop="mmItemOutput.pointid">
+          <el-form-item label="数据点" prop="pointid">
             <el-select
               v-model="dataForm.mmItemOutput.pointid"
               filterable
@@ -112,7 +106,7 @@
       </el-row>
       <el-row>
         <el-col :span="12">
-          <el-form-item label="保存点位" prop="mmPredictItem.saveindex">
+          <el-form-item label="保存点位" prop="saveindex">
             <el-select v-model="dataForm.mmPredictItem.saveindex" placeholder="请选择">
               <el-option
                 v-for="item in saveIndexList"
@@ -125,10 +119,9 @@
       </el-row>
       <el-row v-if="dataForm.itemtypename === 'MergeItem'">
         <el-col :span="12">
-          <el-form-item label="预测长度" prop="mmPredictItem.predictlength">
+          <el-form-item label="预测长度" prop="predictlength">
             <el-input v-model="dataForm.mmPredictItem.predictlength" placeholder="预测长度"
-                      maxlength="5"
-                      clearable/>
+                      maxlength="5"/>
           </el-form-item>
         </el-col>
       </el-row>
@@ -136,16 +129,14 @@
       </el-divider>
       <el-row v-if="dataForm.itemtypename === 'NormalItem'">
         <el-col :span="24">
-          <el-form-item label="模型名称" prop="mmPredictModel.modelname">
+          <el-form-item label="模型名称" prop="modelname">
             <el-input v-model="dataForm.mmPredictModel.modelname" placeholder="模型名称"
-                      maxlength="50"
-                      clearable/>
+                      maxlength="50"/>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="编号" prop="mmPredictModel.modelno" v-if="!!dataForm.id">
+          <el-form-item label="编号" prop="modelno" v-if="!!dataForm.id">
             <el-input v-model="dataForm.mmPredictModel.modelno" placeholder="编号" maxlength="32"
-                      clearable
                       disabled/>
           </el-form-item>
         </el-col>
@@ -170,7 +161,7 @@
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="结果" prop="mmPredictModel.resultstrid">
+          <el-form-item label="结果" prop="resultstrid">
             <el-select v-model="dataForm.mmPredictModel.resultstrid" placeholder="请选择">
               <el-option
                 v-for="item in resultstridList"
@@ -183,35 +174,31 @@
       </el-row>
       <el-row v-if="dataForm.itemtypename === 'NormalItem'">
         <el-col :span="24">
-          <el-form-item label="路径" prop="mmPredictModel.modelpath">
+          <el-form-item label="路径" prop="modelpath">
             <el-input v-model="dataForm.mmPredictModel.modelpath" placeholder="路径" maxlength="32"
-                      clearable
                       disabled/>
           </el-form-item>
         </el-col>
       </el-row>
       <el-row v-if="dataForm.itemtypename === 'NormalItem'">
         <el-col :span="24">
-          <el-form-item label="类名" prop="mmPredictModel.classname">
+          <el-form-item label="类名" prop="classname">
             <el-input v-model="dataForm.mmPredictModel.classname" placeholder="类名" maxlength="32"
-                      clearable
                       disabled/>
           </el-form-item>
         </el-col>
       </el-row>
       <el-row v-if="dataForm.itemtypename === 'NormalItem'">
         <el-col :span="12">
-          <el-form-item label="方法名" prop="mmPredictModel.methodname">
+          <el-form-item label="方法名" prop="methodname">
             <el-input v-model="dataForm.mmPredictModel.methodname" placeholder="方法名"
-                      maxlength="32" clearable
-                      disabled/>
+                      maxlength="32" disabled/>
           </el-form-item>
         </el-col>
         <el-col :span="12">
-          <el-form-item label="参数" prop="mmPredictModel.modelparamstructure">
+          <el-form-item label="参数" prop="modelparamstructure">
             <el-input v-model="dataForm.mmPredictModel.modelparamstructure" placeholder="参数"
-                      maxlength="32" clearable
-                      disabled/>
+                      maxlength="32" disabled/>
           </el-form-item>
         </el-col>
       </el-row>
@@ -226,8 +213,7 @@
         <el-table-column prop="valuetype" label="类型" align="center"/>
         <el-table-column prop="" label="值" align="center">
           <template #default="scope">
-            <el-input v-model="scope.row.value" maxlength="256" clearable
-                      style="width:100%;hight:100%"/>
+            <el-input v-model="scope.row.value" maxlength="256" style="width:100%;height:100%"/>
           </template>
         </el-table-column>
       </el-table>
@@ -269,7 +255,7 @@
         </el-table-column>
         <el-table-column prop="" label="参数长度" width="120" align="center">
           <template #default="scope">
-            <el-input v-model="scope.row.datalength" maxlength="50" clearable
+            <el-input v-model="scope.row.datalength" maxlength="50"
                       style="width:100%;hight:100%"/>
           </template>
         </el-table-column>
@@ -365,7 +351,6 @@
 import * as DmModule from '@/api/model/pre/dm'
 import * as MmResultTable from '@/api/model/pre/result'
 import * as DaPoint from '@/api/data/da/point'
-import request from "@/config/axios";
 import * as ScheduleModelApi from '@/api/model/sche/model'
 
 defineOptions({name: 'DataMmPredictItemForm'})
@@ -497,11 +482,18 @@
   dialogTitle.value = t('action.' + type)
   formType.value = type
   resetForm()
+  setDefaultFields()
+  // getItemTypeList()
+  // getModuleList()
+  getPointList()
+  // getModelparamList()
+  // getResulttableList()
+  // getResultstridList()
   // 修改时,设置数据
   if (id) {
     formLoading.value = true
     try {
-      dataForm.value = await MmPredictItem.getMmPredictItem(id)
+      getInfo(id)
     } finally {
       formLoading.value = false
     }
@@ -534,10 +526,40 @@
     formLoading.value = false
   }
 }
-const setReplaceModelOnly = (value) => {
+
+function getInfo(id) {
+  debugger
+  const res = MmPredictItem.getMmPredictItem(id)
+  console.info(res)
+  expressionList.value = []
+  if (res.mmPredictMergeItem && res.mmPredictMergeItem.expression) {
+    let expression = res.mmPredictMergeItem.expression
+    do {
+      let indexPlus = expression.indexOf('+')
+      let indexSub = expression.indexOf('-')
+      if (indexPlus !== -1 || indexSub !== -1) {
+        let endIndex = (indexSub == -1 || (indexPlus < indexSub && indexPlus !== -1)) ? indexPlus : indexSub
+        expressionList.value.push({
+          point: expression.substring(0, endIndex),
+          operator: expression.substr(endIndex, 1)
+        })
+        expression = expression.substring(endIndex + 1)
+      } else {
+        expressionList.value.push({
+          point: expression,
+          operator: ''
+        })
+        expression = ''
+      }
+    } while (expression && expression.length > 0)
+  }
+}
+
+function setReplaceModelOnly(value) {
   replaceModelOnly.value = value
 }
-const beforeUpload = (file) => {
+
+function beforeUpload(file) {
   let fileName = file.name
   let first = fileName.lastIndexOf('.')
   let nameLength = fileName.length
@@ -547,7 +569,8 @@
     return
   }
 }
-const uploadModelSuccess = (response, file, fileList) => {
+
+function uploadModelSuccess(response, file, fileList) {
   if (response.code === 0) {
     message.success(t('上传成功'))
     dataForm.value.mmModelArithSettingsList = []
@@ -557,7 +580,7 @@
     dataForm.value.mmPredictModel.modelpath = ''
     dataForm.value.mmPredictModel.modelparamstructure = ''
     if (response.data.loadFieldSetList && response.data.loadFieldSetList[0].propertyList) {
-      response.data.loadFieldSetList[0].propertyList.forEach((value) => {
+      response.data.loadFieldSetList[0].propertyList.forEach(function (value) {
         if (value.key !== 'data1') {
           dataForm.value.mmModelArithSettingsList.push({
             key: value.key,
@@ -597,28 +620,36 @@
   }
   fileList = []
 }
-const uploadModelError = (file, err, fileList) => {
+
+function uploadModelError(file, err, fileList) {
 }
-const changeModelparam = (row) => {
+
+function changeModelparam(row) {
   row.modelparamname = modelparamMap[row.modelparamid]
 }
-const changeItemtype = (value) => {
+
+function changeItemtype(value) {
   dataForm.value.itemtypename = itemTypeMap[value]
 }
-const changeModelparamtype = (value, row) => {
+
+function changeModelparamtype(value, row) {
   row.modelparamid = ''
 }
-const changeOutputPoint = (value) => {
+
+function changeOutputPoint(value) {
   dataForm.value.mmItemOutput.tagname = pointMap[value]
 }
-const deleteExpressionRow = (index, rows) => {
+
+function deleteExpressionRow(index, rows) {
   rows.splice(index, 1)
 }
-const addExpressionRow = (index, rows) => {
+
+function addExpressionRow(index, rows) {
   let row = JSON.parse(JSON.stringify(rows[index]))
   rows.splice(index, 0, row)
 }
-const deleteRow = (index: string, rows) => {
+
+function deleteRow(index: string, rows) {
   if (!rows || rows.length === 1) {
     message.error('不能全部删除!')
     return
@@ -626,13 +657,14 @@
   rows.splice(index, 1)
   orderRow(rows)
 }
-const addRow = (index: string, rows) => {
+
+function addRow(index: string, rows) {
   let row = JSON.parse(JSON.stringify(rows[index]))
   rows.splice(index, 0, row)
   orderRow(rows)
 }
 
-const orderRow = (rows) => {
+function orderRow(rows) {
   let modelparamorder = 0
   let modelparamportorder = 0
   rows.forEach(function (value) {
@@ -644,108 +676,145 @@
     modelparamorder++
   })
 }
+
 // 获取预测项类型列表
-const getItemTypeList = async () => {
+function getItemTypeList() {
   itemTypeList.value = []
-  itemTypeList.value = await MmItemType.getItemTypeList()
-  itemTypeList.value.forEach((value) => {
+  itemTypeList.value = MmItemType.getItemTypeList()
+  itemTypeList.value.forEach(function (value) {
     itemTypeMap[value.id] = value.itemtypename
   })
   if (!dataForm.value.id) {
     // dataForm.value.mmPredictItem.itemtypeid = itemTypeList[0].id
   }
 }
+
 // 获取管网列表
-const getModuleList = async () => {
+function getModuleList() {
   moduleList.value = []
-  moduleList.value = await DmModule.getModuleList()
+  moduleList.value = DmModule.getModuleList()
 }
 
-const getResulttableList = async () => {
+function getResulttableList() {
   resulttableList.value = []
-  resulttableList.value = await MmResultTable.getResulttableList()
+  resulttableList.value = MmResultTable.getResulttableList()
 }
-const getResultstridList = async () => {
+
+function getResultstridList() {
   resultstridList.value = []
-  resultstridList.value = await MmResultTable.getResultstridList()
+  resultstridList.value = MmResultTable.getResultstridList()
 }
-const getPointList = async () => {
+
+function getPointList() {
   pointLoading.value = true
-  pointList.value = await DaPoint.getPointList(queryParams)
-  pointList.value.forEach((value) => {
-    pointList.value.push(value)
-    pointMap[value.id] = value.pointname
-  })
+  pointList.value = DaPoint.getPointList(queryParams)
+  if (pointList.value.length > 0) {
+    pointList.value.forEach(function (value) {
+      pointList.value.push(value)
+      pointMap[value.id] = value.pointname
+    })
+  }
 }
-const getModelparamList = async () => {
+
+function getModelparamList() {
   modelparamListMap.value = []
   modelparamList.value = []
   predictItemList.value = []
-  let pointRes = await DaPoint.getPointList(queryParams)
+  pointList.value = DaPoint.getPointList(queryParams)
   let paramList = []
-  pointRes.forEach((value) => {
-    paramList.push({
-      id: value.id,
-      code: value.pointno,
-      name: value.pointname,
-      type: 'DATAPOINT'
+  if (pointList.value.length > 0) {
+    pointList.value.forEach(function (value) {
+      paramList.push({
+        id: value.id,
+        code: value.pointno,
+        name: value.pointname,
+        type: 'DATAPOINT'
+      })
+      modelparamMap[value.id] = value.pointname
     })
-    modelparamMap[value.id] = value.pointname
-  })
-  modelparamListMap['DATAPOINT'] = paramList;
+    modelparamListMap['DATAPOINT'] = paramList;
+  }
 
-  let predictRes = await MmPredictItem.getMmPredictItemList
+  let predictRes = MmPredictItem.getMmPredictItemList
   paramList = []
-  predictRes.forEach((value) => {
-    paramList.push({
-      id: value.id,
-      code: value.itemno,
-      name: value.itemname,
-      type: 'PREDICTITEM'
-    })
-    if (value.id !== dataForm.value.id) {
-      predictItemList.push({
+  if (predictRes.value.length > 0) {
+    predictRes.forEach(function (value) {
+      paramList.push({
         id: value.id,
         code: value.itemno,
-        name: value.itemname
+        name: value.itemname,
+        type: 'PREDICTITEM'
       })
-    }
-    modelparamMap[value.id] = value.itemname
-  })
-  modelparamListMap['PREDICTITEM'] = paramList;
+      if (value.id !== dataForm.value.id) {
+        predictItemList.push({
+          id: value.id,
+          code: value.itemno,
+          name: value.itemname
+        })
+      }
+      modelparamMap[value.id] = value.itemname
+    })
+    modelparamListMap['PREDICTITEM'] = paramList;
+  }
 
   const dayParams = {
     'processType': '日计划'
   }
-  let dayScheduleRes = await ScheduleModelApi.getScheduleWorkPrecessList(dayParams)
+  let dayScheduleRes = ScheduleModelApi.getScheduleWorkPrecessList(dayParams)
   paramList = []
-  dayScheduleRes.forEach((value) => {
-    paramList.push({
-      id: value.id,
-      code: value.code,
-      name: value.aliasName,
-      type: 'DAYWORKPROCESSPLAN'
+  if (dayScheduleRes !== null) {
+    dayScheduleRes.forEach(function (value) {
+      paramList.push({
+        id: value.id,
+        code: value.code,
+        name: value.aliasName,
+        type: 'DAYWORKPROCESSPLAN'
+      })
+      modelparamMap[value.id] = value.aliasName
     })
-    modelparamMap[value.id] = value.aliasName
-  })
-  modelparamListMap['DAYWORKPROCESSPLAN'] = paramList;
+    modelparamListMap['DAYWORKPROCESSPLAN'] = paramList;
+  }
 
   const monthParams = {
     'processType': '月计划'
   }
-  let monthScheduleRes = await ScheduleModelApi.getScheduleWorkPrecessList(monthParams)
+  let monthScheduleRes = ScheduleModelApi.getScheduleWorkPrecessList(monthParams)
   paramList = []
-  monthScheduleRes.forEach((value) => {
-    paramList.push({
-      id: value.id,
-      code: value.code,
-      name: value.aliasName,
-      type: 'MONTHWORKPROCESSPLAN'
+  if (monthScheduleRes !== null) {
+    monthScheduleRes.forEach(function (value) {
+      paramList.push({
+        id: value.id,
+        code: value.code,
+        name: value.aliasName,
+        type: 'MONTHWORKPROCESSPLAN'
+      })
+      modelparamMap[value.id] = value.aliasName
     })
-    modelparamMap[value.id] = value.aliasName
-  })
-  modelparamListMap['MONTHWORKPROCESSPLAN'] = paramList;
+    modelparamListMap['MONTHWORKPROCESSPLAN'] = paramList;
+  }
 }
+
+function setDefaultFields() {
+  dataForm.value.mmPredictItem.workchecked = 0
+  dataForm.value.mmPredictItem.predictlength = 60
+  dataForm.value.mmPredictItem.status = 1
+  dataForm.value.mmPredictItem.isfuse = 0
+  dataForm.value.mmPredictItem.predictphase = 0
+  dataForm.value.mmPredictItem.unittransfactor = 1
+  dataForm.value.mmPredictItem.saveindex = '2'
+  dataForm.value.dmModuleItem.status = 1
+  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'
+  expressionList.value = [{
+    point: '',
+    operator: ''
+  }]
+  fileList.value = []
+}
+
 /** 重置表单 */
 const resetForm = () => {
   dataForm.value = {
@@ -819,12 +888,7 @@
   init()
 })
 
-const init = async () => {
-  getItemTypeList()
-  getModuleList()
-  getPointList()
-  getModelparamList()
-  getResulttableList()
-  getResultstridList()
+function init() {
+
 }
 </script>
diff --git a/src/views/model/pre/predict/index.vue b/src/views/model/pre/predict/index.vue
index 1e6ff7f..f9c37e2 100644
--- a/src/views/model/pre/predict/index.vue
+++ b/src/views/model/pre/predict/index.vue
@@ -53,18 +53,18 @@
     <el-table v-loading="loading" :data="list">
       <el-table-column label="编号" align="center" prop="itemno" />
       <el-table-column label="预测项名" align="center" prop="itemname" />
-      <el-table-column label="类型ID" align="center" prop="itemtypeid" />
+<!--      <el-table-column label="类型ID" align="center" prop="itemtypeid" />-->
       <el-table-column label="类型名称" align="center" prop="itemtypename" />
       <el-table-column label="粒度" align="center" prop="granularity" />
       <el-table-column label="是否融合" align="center" prop="isfuse" />
       <el-table-column label="是否检查" align="center" prop="workchecked" />
-      <el-table-column label="模块ID" align="center" prop="moduleid" />
+<!--      <el-table-column label="模块ID" align="center" prop="moduleid" />-->
       <el-table-column label="排序" align="center" prop="itemorder" />
       <el-table-column label="是否启用" align="center" prop="status" />
-      <el-table-column label="类别ID" align="center" prop="categoryid" />
-      <el-table-column label="数据点ID" align="center" prop="pointid" />
+<!--      <el-table-column label="类别ID" align="center" prop="categoryid" />-->
+<!--      <el-table-column label="数据点ID" align="center" prop="pointid" />-->
       <el-table-column label="数据点名称" align="center" prop="tagname" />
-      <el-table-column label="存放表ID" align="center" prop="resulttableid" />
+<!--      <el-table-column label="存放表ID" align="center" prop="resulttableid" />-->
       <el-table-column label="存放表" align="center" prop="tablename" />
 
       <el-table-column label="操作" align="center" min-width="110" fixed="right">

--
Gitblit v1.9.3