liriming
2024-09-26 660c92fdd22f79bda5017d61fb719b158aa58ebb
测点列表页面修改
已修改4个文件
已添加1个文件
647 ■■■■ 文件已修改
src/api/data/channel/tag/index.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/data/da/point/index.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/dict.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/data/point/DaPointForm.vue 626 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/data/point/index.vue 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/data/channel/tag/index.ts
对比新文件
@@ -0,0 +1,7 @@
import request from '@/config/axios'
// 查询HttpApi列表
export const getTagTree = () => {
  return request.get({ url: `/data/channel/tag/tree`})
}
src/api/data/da/point/index.ts
@@ -40,7 +40,7 @@
// 新增DaPoint
export const createDaPoint = (data: DaPointVO) => {
  return request.post({ url: '/data/da/point/add', data })
  return request.post({ url: '/data/da/point/create', data })
}
// 修改DaPoint
src/utils/dict.ts
@@ -252,4 +252,7 @@
  STAT_FUNC = 'stat_func',
  TIME_LIMIT = 'time_limit',
  ITEM_TYPE = 'item_type',
  POINT_TYPE = 'point_type',
  DATA_TYPE = 'data_type',
  MINFREQID = 'minfreqid',
}
src/views/data/point/DaPointForm.vue
@@ -10,86 +10,250 @@
      <el-row>
        <el-col :span="12">
          <el-form-item label="测点编码" prop="pointNo">
            <el-input v-model="formData.pointNo" placeholder="请输入测点编码" />
            <el-input v-model="formData.pointNo" placeholder="请输入测点编码" disabled/>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="测点名称" prop="pointName">
            <el-input v-model="formData.pointName" placeholder="请输入测点名称" />
            <el-input v-model="formData.pointName" placeholder="请输入测点名称"/>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="测点类型" prop="pointType">
            <el-input v-model="formData.pointType" placeholder="请输入测点类型" />
            <el-select
              v-model="formData.pointType"
              clearable
              placeholder="请选择测点类型"
            >
              <el-option
                v-for="dict in getDictOptions(DICT_TYPE.POINT_TYPE)"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="数据类型" prop="dataType">
            <el-input v-model="formData.dataType" placeholder="请输入数据类型" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="值类型" prop="valueType">
            <el-input v-model="formData.valueType" placeholder="请输入值类型" />
            <el-select
              v-model="formData.dataType"
              clearable
              placeholder="请选择数据类型"
            >
              <el-option
                v-for="dict in getDictOptions(DICT_TYPE.DATA_TYPE)"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="存储类型" prop="storeType">
            <el-input v-model="formData.storeType" placeholder="请输入存储类型" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="测量单位" prop="unit">
            <el-input v-model="formData.unit" placeholder="请输入测量单位" />
            <el-input v-model="formData.unit" placeholder="请输入测量单位"/>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="单位转换" prop="unittransfactor">
            <el-input v-model="formData.unittransfactor" placeholder="请输入单位转换" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="默认值" prop="defaultValue">
            <el-input v-model="formData.defaultValue" placeholder="请输入默认值" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="最大值" prop="maxValue">
            <el-input v-model="formData.maxValue" placeholder="请输入最大值" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="最小值" prop="minValue">
            <el-input v-model="formData.minValue" placeholder="请输入最小值" />
            <el-input-number v-model="formData.unittransfactor" style="width: 100%"
                             :controls="false"/>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="采集频率" prop="minfreqid">
            <el-input v-model="formData.minfreqid" placeholder="请输入采集频率" />
            <el-select
              v-model="formData.minfreqid"
              clearable
              placeholder="请选择采集频率"
            >
              <el-option
                v-for="dict in getDictOptions(DICT_TYPE.MINFREQID)"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="备注" prop="remark">
            <el-input v-model="formData.remark" placeholder="请输入备注" />
          <el-form-item label="默认值" prop="defaultValue">
            <el-input-number v-model="formData.defaultValue" style="width: 100%" :controls="false"/>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="最大值" prop="maxValue">
            <el-input-number v-model="formData.maxValue" style="width: 100%" :controls="false"/>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="最小值" prop="minValue">
            <el-input-number v-model="formData.minValue" style="width: 100%" :controls="false"/>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="是否启用" prop="isEnable">
            <el-input v-model="formData.isEnable" placeholder="请输入是否启用" />
            <el-select
              v-model="formData.isEnable"
              clearable
              placeholder="请选择是否启用"
            >
              <el-option
                v-for="dict in getIntDictOptions(DICT_TYPE.IS_ENABLED)"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="备注" prop="remark">
            <el-input v-model="formData.remark" placeholder="请输入备注"/>
          </el-form-item>
        </el-col>
      </el-row>
      <!--计量点-->
      <el-row v-if="formData.pointType === 'MEASURE'">
        <el-col :span="12">
          <el-form-item prop="sourceOption" label="数据源">
            <el-cascader
              style="width: 100%;"
              v-model="formData.sourceOption"
              :options="sourceOptions"
              filterable/>
          </el-form-item>
        </el-col>
      </el-row>
      <!--计算点-->
      <el-row :gutter="20" v-if="formData.pointType === 'CALCULATE'">
        <el-col :span="24">
          <el-form-item label="表达式">
            <el-table
              :data="expressionList"
              border
              style="width: 100%">
<!--              <el-table-column
                type="index"
                align="center"
                width="50"
                label="序号"/>-->
              <el-table-column
                prop=""
                label="左括号"
                width="140"
                align="center">
                <template #default="scope">
                  <el-input
                    v-model="scope.row.parenthesesLeft"
                    placeholder=""
                    readonly
                    maxlength="16">
                    <template #prepend>
                      <el-button @click="addParenthesesLeft(scope.$index, scope.row)">+</el-button>
                    </template>
                    <template #append>
                      <el-button @click="removeParenthesesLeft(scope.$index, scope.row)">-</el-button>
                    </template>
                  </el-input>
                </template>
              </el-table-column>
              <el-table-column
                prop=""
                label="测点"
                align="center">
                <template #default="scope">
                  <el-select
                    v-model="scope.row.point"
                    filterable
                    placeholder="请选择">
                    <el-option
                      v-for="(item, index) in pointList"
                      :key="index"
                      :label="item.pointName"
                      :value="item.pointNo"/>
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column
                prop=""
                label="运算值"
                align="center">
                <template #default="scope">
                  <el-input
                    v-model="scope.row.point"
                    placeholder="运算值"
                    maxlength="16"
                    clearable/>
                </template>
              </el-table-column>
              <el-table-column
                prop=""
                label="右括号"
                width="140"
                align="center">
                <template #default="scope">
                  <el-input
                    v-model="scope.row.parenthesesRight"
                    placeholder=""
                    readonly
                    maxlength="16">
                    <template #prepend>
                      <el-button @click="addParenthesesRight(scope.$index, scope.row)">+</el-button>
                    </template>
                    <template #append>
                      <el-button @click="removeParenthesesRight(scope.$index, scope.row)">-</el-button>
                    </template>
                  </el-input>
                </template>
              </el-table-column>
              <el-table-column
                prop=""
                label="运算符"
                width="120"
                align="center">
                <template #default="scope">
                  <el-select v-model="scope.row.operator" clearable>
                    <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="140"
                align="center">
                <template #default="scope">
                  <el-button
                    @click="addExpressionRow(scope.$index, expressionList)"
                    type="text"
                    size="small">
                    添加
                  </el-button>
                  <el-button
                    @click="deleteExpressionRow(scope.$index, expressionList)"
                    type="text"
                    size="small">
                    删除
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-form-item>
        </el-col>
      </el-row>
@@ -102,16 +266,147 @@
</template>
<script lang="ts" setup>
import * as DaPoint from '@/api/data/da/point'
import * as TagApi from '@/api/data/channel/tag'
import {DICT_TYPE, getDictOptions, getIntDictOptions} from "@/utils/dict";
import {getTagTree} from "@/api/data/channel/tag";
defineOptions({ name: 'DataDaPointForm' })
defineOptions({name: 'DataDaPointForm'})
  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 formData = ref({
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 sourceOptions = ref([])
const expressionList = ref([])
const pointList = ref([{
  pointName: '',
  pointNo: ''
}])
const queryParams = reactive({
  pointType: "MEASURE"
})
const operatorList = ref(['+', '-', '*', '/', '&', '|', '!', '>', '<'])
const formData = ref({
  id: undefined,
  pointNo: undefined,
  pointName: undefined,
  pointType: undefined,
  dataType: undefined,
  valueType: undefined,
  storeType: undefined,
  unit: undefined,
  unittransfactor: undefined,
  defaultValue: undefined,
  maxValue: undefined,
  minValue: undefined,
  minfreqid: undefined,
  remark: undefined,
  isEnable: undefined,
  sourceOption: [],
  mathPoint: {
    id: '',
    pointId: '',
    expression: ''
  },
  measurePoint: {
    id: '',
    pointId: '',
    sourceType: '',
    sourceId: '',
    tagNo: '',
    dimension: '',
  }
})
const formRules = reactive({
  pointName: [{required: true, message: '测点名称不能为空', trigger: 'blur'}],
  pointType: [{required: true, message: '测点类型不能为空', trigger: 'blur'}],
  dataType: [{required: true, message: '数据类型不能为空', trigger: 'blur'}],
})
const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
  dialogVisible.value = true
  dialogTitle.value = t('action.' + type)
  formType.value = type
  resetForm()
  getSourceOption()
  getPointList()
  // 修改时,设置数据
  if (id) {
    formLoading.value = true
    try {
      getInfo(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 {
    if (formData.value.pointType === 'CALCULATE' &&
      expressionList.value && expressionList.value.length > 0) {
      let parenthesesLeftRex = /^[(]*$/
      let parenthesesRightRex = /^[)]*$/
      let expression = ''
      debugger
      for (let i = 0; i < expressionList.value.length; i++) {
        let value = expressionList.value[i]
        if (!parenthesesLeftRex.test(value.parenthesesLeft)) {
          message.error('第${i + 1}行左括号输入不正确!')
          return
        }
        if (!parenthesesRightRex.test(value.parenthesesRight)) {
          message.error('第${i + 1}行右括号输入不正确!')
          return
        }
        if (i !== (expressionList.value.length - 1) && !value.operator) {
          message.error('第${i + 1}行运算符不能为空!')
          return
        }
        expression = expression + value.parenthesesLeft + value.point + value.parenthesesRight + (i === (expressionList.value.length - 1) ? '' : value.operator)
      }
      formData.value['mathPoint']['expression'] = expression
    } else {
      formData.value['mathPoint'] = {}
    }
    const data = formData.value as unknown as DaPoint.DaPointVO
    if (formType.value === 'create') {
      await DaPoint.createDaPoint(data)
      message.success(t('common.createSuccess'))
    } else {
      await DaPoint.updateDaPoint(data)
      message.success(t('common.updateSuccess'))
    }
    dialogVisible.value = false
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}
/** 重置表单 */
const resetForm = () => {
  expressionList.value = [{
    parenthesesLeft: '',
    point: '',
    parenthesesRight: '',
    operator: ''
  }]
  formData.value = {
    id: undefined,
    pointNo: undefined,
    pointName: undefined,
@@ -120,85 +415,168 @@
    valueType: undefined,
    storeType: undefined,
    unit: undefined,
    unittransfactor: undefined,
    defaultValue: undefined,
    maxValue: undefined,
    minValue: undefined,
    unittransfactor: 1,
    defaultValue: 10,
    maxValue: 1000000,
    minValue: 0,
    minfreqid: undefined,
    remark: undefined,
    isEnable: undefined,
  })
  const formRules = reactive({
    pointNo: [{ required: true, message: '测点编码不能为空', trigger: 'blur' }],
    pointName: [{ required: true, message: '测点名称不能为空', trigger: 'blur' }],
    pointType: [{ required: true, message: '测点类型不能为空', trigger: 'blur' }],
    dataType: [{ required: true, message: '数据类型不能为空', trigger: 'blur' }],
  })
  const formRef = ref() // 表单 Ref
  /** 打开弹窗 */
  const open = async (type: string, id?: number) => {
    dialogVisible.value = true
    dialogTitle.value = t('action.' + type)
    formType.value = type
    resetForm()
    // 修改时,设置数据
    if (id) {
      formLoading.value = true
      try {
        formData.value = await DaPoint.getDaPoint(id)
      } finally {
        formLoading.value = false
      }
    }
    isEnable: 1,
    sourceOption: [],
    mathPoint: {},
    measurePoint: {},
  }
  defineExpose({ open }) // 提供 open 方法,用于打开弹窗
  formRef.value?.resetFields()
}
  /** 提交表单 */
  const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
  const submitForm = async () => {
    // 校验表单
    if (!formRef) return
    const valid = await formRef.value.validate()
    if (!valid) return
    // 提交请求
    formLoading.value = true
    try {
      const data = formData.value as unknown as DaPoint.DaPointVO
      if (formType.value === 'create') {
        await DaPoint.createDaPoint(data)
        message.success(t('common.createSuccess'))
function deleteExpressionRow(index, rows) {
  if (!rows || rows.length === 1) {
    message.error('不能全部删除!')
    return
  }
  rows.splice(index, 1)
}
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 numAscSort(a, b) {
  return a - b
}
// 获取数据源选项
const getSourceOption = async () => {
  sourceOptions.value = await TagApi.getTagTree()
}
const getPointList = async () => {
  pointList.value = await DaPoint.getPointList(queryParams)
}
const getInfo = async (id) => {
  formData.value = await DaPoint.getDaPoint(id)
  expressionList.value = []
  if (formData.value.pointType &&
    formData.value.pointType === 'CALCULATE' &&
    formData.value.mathPoint.expression) {
    let expression = formData.value.mathPoint.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 pointStr = expression.substring(0, endIndex)
        debugger
        // 运算符
        let operator = expression.substr(endIndex, 1)
        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,
          point: pointStr,
          parenthesesRight: parenthesesRight,
          operator: operator
        })
        expression = expression.substring(endIndex + 1)
      } else {
        await DaPoint.updateDaPoint(data)
        message.success(t('common.updateSuccess'))
        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,
          point: pointStr,
          parenthesesRight: parenthesesRight,
          operator: ''
        })
        expression = ''
      }
      dialogVisible.value = false
      // 发送操作成功的事件
      emit('success')
    } finally {
      formLoading.value = false
    }
    } while (expression && expression.length > 0)
  }
}
  /** 重置表单 */
  const resetForm = () => {
    formData.value = {
      id: undefined,
      pointNo: undefined,
      pointName: undefined,
      pointType: undefined,
      dataType: undefined,
      valueType: undefined,
      storeType: undefined,
      unit: undefined,
      unittransfactor: undefined,
      defaultValue: undefined,
      maxValue: undefined,
      minValue: undefined,
      minfreqid: undefined,
      remark: undefined,
      isEnable: undefined,
    }
    formRef.value?.resetFields()
  }
</script>
<style>
.el-select {
  width: 100%
}
</style>
src/views/data/point/index.vue
@@ -50,20 +50,15 @@
  <!-- 列表 -->
  <ContentWrap>
    <el-table v-loading="loading" :data="list">
      <el-table-column label="测点编码" header-align="center" align="left" min-width="100" prop="pointNo" />
    <el-table border stripe v-loading="loading" :data="list">
      <el-table-column fixed label="测点编码" header-align="center" align="left" min-width="100" prop="pointNo" />
      <el-table-column label="测点名称" header-align="center" align="left" min-width="100" prop="pointName" />
      <el-table-column label="测点类型" align="center" prop="pointType" />
      <el-table-column label="数据类型" align="center" prop="dataType" />
      <el-table-column label="值类型" align="center" prop="valueType" />
      <el-table-column label="存储类型" align="center" prop="storeType" />
      <el-table-column label="测量单位" align="center" prop="unit" />
      <el-table-column label="单位转换" align="center" prop="unittransfactor" />
      <el-table-column label="默认值" align="center" prop="defaultValue" />
      <el-table-column label="最大值" align="center" prop="maxValue" />
      <el-table-column label="最小值" align="center" prop="minValue" />
      <el-table-column label="采集频率" align="center" prop="minfreqid" />
      <el-table-column label="备注" align="center" prop="remark" />
      <el-table-column label="是否启用" align="center" prop="isEnable">
        <template #default="scope">
          <el-tag v-if="scope.row.isEnable === 1" size="small">是</el-tag>