From 13c97d76348b5451381320aa54efa0706f38ecb6 Mon Sep 17 00:00:00 2001 From: 潘志宝 <979469083@qq.com> Date: 星期四, 31 十月 2024 08:49:52 +0800 Subject: [PATCH] 测点列表.xlsx --- src/views/data/point/DaPointForm.vue | 667 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 543 insertions(+), 124 deletions(-) diff --git a/src/views/data/point/DaPointForm.vue b/src/views/data/point/DaPointForm.vue index 2cb149a..0279054 100644 --- a/src/views/data/point/DaPointForm.vue +++ b/src/views/data/point/DaPointForm.vue @@ -1,5 +1,5 @@ <template> - <Dialog v-model="dialogVisible" :title="dialogTitle" width="50%"> + <Dialog v-model="dialogVisible" :title="dialogTitle" width="60%"> <el-form ref="formRef" v-loading="formLoading" @@ -10,86 +10,276 @@ <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" 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.DATA_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.POINT_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.COM_IS_INT)" + :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="24"> + <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 v-if="formData.pointType === 'MEASURE'"> + <el-col :span="12"> + <el-form-item label="测量值类型" prop="measurePoint.valueType"> + <el-select + v-model="formData.measurePoint.valueType" + clearable + placeholder="请选择值类型" + > + <el-option + v-for="dict in getDictOptions(DICT_TYPE.MEASURE_VALUE_TYPE)" + :key="dict.value" + :label="dict.label" + :value="dict.value" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="平滑尺度(min)" prop="measurePoint.dimension"> + <el-input-number v-model="formData.measurePoint.dimension" style="width: 100%" + :min="0" :max="100" + :controls="false"/> + </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="60" + 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="测点" + min-width="160" + 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="运算值" + min-width="120" + 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="100" + 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="120" + align="center"> + <template #default="scope"> + <el-button + @click="addExpressionRow(scope.$index, expressionList)" + type="text" + size="mini"> + 添加 + </el-button> + <el-button + @click="deleteExpressionRow(scope.$index, expressionList)" + type="text" + size="mini"> + 删除 + </el-button> + </template> + </el-table-column> + </el-table> </el-form-item> </el-col> </el-row> @@ -102,16 +292,150 @@ </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"; -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({ + pointTypes: "MEASURE,CONSTANT", +}) +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: '', + valueType: '', + } +}) +const formRules = reactive({ + pointName: [{required: true, message: '测点名称不能为空', trigger: 'blur'}], + pointType: [{required: true, message: '测点类型不能为空', trigger: 'blur'}], + dataType: [{required: true, message: '数据类型不能为空', trigger: 'blur'}], + minfreqid: [{required: true, message: '采集频率不能为空', trigger: 'blur'}], + "measurePoint.valueType": [{required: true, message: '采集频率不能为空', trigger: 'blur'}], + "measurePoint.dimension": [{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 +444,180 @@ valueType: undefined, storeType: undefined, unit: undefined, - unittransfactor: undefined, - defaultValue: undefined, - maxValue: undefined, - minValue: undefined, + unittransfactor: 1, + defaultValue: 0, + maxValue: 100000000, + 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: { + id: '', + pointId: '', + expression: '' + }, + measurePoint: { + id: '', + pointId: '', + sourceType: '', + sourceId: '', + tagNo: '', + dimension: '1', + valueType: 'SIMULATE', } } - 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> -- Gitblit v1.9.3