<template>
|
<Dialog v-model="dialogVisible" :title="dialogTitle" width="60%">
|
<el-form
|
ref="formRef"
|
v-loading="formLoading"
|
:model="formData"
|
:rules="formRules"
|
label-width="120px"
|
>
|
<el-row>
|
<el-col :span="12">
|
<el-form-item label="测点编码" prop="pointNo">
|
<el-input v-model="formData.pointNo" disabled/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="测点名称" prop="pointName">
|
<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-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-col :span="12">
|
<el-form-item label="数据类型" prop="dataType">
|
<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="unit">
|
<el-input v-model="formData.unit" placeholder="请输入测量单位"/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="单位转换" prop="unittransfactor">
|
<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-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="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-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>
|
<!--累计点-->
|
<el-row :gutter="20" v-if="formData.pointType === 'CUMULATE'">
|
<el-col :span="24">
|
<el-form-item label="瞬时测点" prop="cumulatePoint.momentPoint">
|
<el-select
|
v-model="formData.cumulatePoint.momentPoint"
|
filterable
|
placeholder="请选择">
|
<el-option
|
v-for="(item, index) in pointList2"
|
:key="index"
|
:label="item.pointName"
|
:value="item.pointNo"/>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="累计长度" prop="cumulatePoint.length">
|
<el-input-number v-model="formData.cumulatePoint.length" style="width: 100%"
|
:min="1" :max="3000"
|
:controls="false"/>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="除数" prop="cumulatePoint.divisor">
|
<el-input-number v-model="formData.cumulatePoint.divisor" style="width: 100%"
|
:min="1" :max="3000"
|
:controls="false"/>
|
</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 * as DaPoint from '@/api/data/da/point'
|
import * as TagApi from '@/api/data/channel/tag'
|
import {DICT_TYPE, getDictOptions, getIntDictOptions} from "@/utils/dict";
|
import {getPointSimpleList} from "@/api/data/da/point";
|
|
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 sourceOptions = ref([])
|
const expressionList = ref([])
|
const pointList = ref([{
|
pointName: '',
|
pointNo: ''
|
}])
|
const queryParams = reactive({
|
pointTypes: "MEASURE,CONSTANT",
|
})
|
const pointList2 = ref([{
|
pointName: '',
|
pointNo: ''
|
}])
|
const queryParams2 = reactive({
|
pointTypes: "MEASURE,CONSTANT,CALCULATE",
|
})
|
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: '',
|
},
|
cumulatePoint: {
|
id: '',
|
pointId: '',
|
momentPoint: '',
|
length: '',
|
divisor: ''
|
}
|
})
|
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'}],
|
"cumulatePoint.momentPoint": [{required: true, message: '累计测点不能为空', trigger: 'blur'}],
|
"cumulatePoint.length": [{required: true, message: '累计长度不能为空', trigger: 'blur'}],
|
"cumulatePoint.divisor": [{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()
|
getPointList2()
|
// 修改时,设置数据
|
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,
|
pointType: undefined,
|
dataType: undefined,
|
valueType: undefined,
|
storeType: undefined,
|
unit: undefined,
|
unittransfactor: 1,
|
defaultValue: 0,
|
maxValue: 100000000,
|
minValue: 0,
|
minfreqid: undefined,
|
remark: undefined,
|
isEnable: 1,
|
sourceOption: [],
|
mathPoint: {
|
id: '',
|
pointId: '',
|
expression: ''
|
},
|
measurePoint: {
|
id: '',
|
pointId: '',
|
sourceType: '',
|
sourceId: '',
|
tagNo: '',
|
dimension: '1',
|
valueType: 'SIMULATE',
|
},
|
cumulatePoint: {
|
id: '',
|
pointId: '',
|
momentPoint: '',
|
length: 60,
|
divisor: 60
|
}
|
}
|
formRef.value?.resetFields()
|
}
|
|
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.getPointSimpleList(queryParams)
|
}
|
|
const getPointList2 = async () => {
|
pointList2.value = await DaPoint.getPointSimpleList(queryParams2)
|
}
|
|
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 {
|
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 = ''
|
}
|
} while (expression && expression.length > 0)
|
}
|
}
|
|
</script>
|
<style>
|
.el-select {
|
width: 100%
|
}
|
</style>
|