Files
pqs-9100_client/frontend/src/views/machine/device/components/devicePopup.vue
caozehui a5177860de 微调
2025-09-03 14:23:05 +08:00

484 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig">
<el-tabs type="border-card">
<el-tab-pane label="设备台账信息">
<div>
<el-form :model='formContent' ref='dialogFormRef' :rules='rules' :disabled="false" label-width="auto" class="form-three">
<el-divider>设备信息</el-divider>
<el-form-item label="装置编号" prop="createId">
<el-input v-model="formContent.createId" placeholder="请输入装置编号" @input="handleInput" maxlength="32" show-word-limit/>
</el-form-item>
<el-form-item label="设备名称" prop="name">
<el-input v-model='formContent.name' placeholder="请输入设备名称" :disabled="scene === '1'" maxlength="32" show-word-limit/>
</el-form-item>
<el-form-item label='设备类型' prop='devType'>
<el-select v-model="formContent.devType" filterable clearable placeholder="请选择设备类型" @change="handleDevTypeChange">
<el-option
v-for="item in devTypeOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label='预投计划' prop='preinvestmentPlan' v-if="scene ==='1'">
<el-select v-model="formContent.preinvestmentPlan" clearable placeholder="请选择预投计划">
<el-option
v-for="item in dictStore.getDictData('Preinvestment_Plan')"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<!-- <el-form-item label='设备模式' prop='pattern' >-->
<!-- <el-select v-model="formContent.pattern" clearable placeholder="请选择设备模式" disabled>-->
<!-- <el-option -->
<!-- v-for="item in dictStore.getDictData('Pattern')"-->
<!-- :key="item.id"-->
<!-- :label="item.name"-->
<!-- :value="item.id"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item> -->
<el-form-item label='设备厂家' prop='manufacturer' v-if="scene != '1'">
<el-select v-model="formContent.manufacturer" clearable placeholder="请选择设备厂家">
<el-option
v-for="item in dictStore.getDictData('Dev_Manufacturers')"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="出厂日期" prop="createDate" v-if="scene === '0'">
<el-date-picker
v-model="formContent.createDate"
placeholder="请选择出厂日期"
:disabled-date="disabledDate"
/>
</el-form-item>
<el-form-item label="固件版本" prop="hardwareVersion" v-if="scene === '0'">
<el-input v-model="formContent.hardwareVersion" placeholder="请输入固件版本"/>
</el-form-item>
<el-form-item label="软件版本" prop="softwareVersion" v-if="scene === '0'">
<el-input v-model="formContent.softwareVersion" placeholder="请输入软件版本"/>
</el-form-item>
<el-divider>参数信息</el-divider>
<el-form-item label="通道数" prop="devChns">
<el-input v-model='formContent.devChns' :disabled="true"/>
</el-form-item>
<el-form-item label="额定电压(V)" prop="devVolt">
<el-input v-model='formContent.devVolt' :disabled="true"/>
</el-form-item>
<el-form-item label="额定电流(A)" prop="devCurr">
<el-input v-model='formContent.devCurr' :disabled="true"/>
</el-form-item>
<el-form-item label='通讯协议' prop='protocol'>
<el-select v-model="formContent.protocol" clearable placeholder="请选择通讯协议">
<el-option
v-for="item in dictStore.getDictData('Protocol')"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<!-- <el-form-item label="IP地址" prop="ip">
<IPAddress v-model:value="formContent.ip"/>
</el-form-item> -->
<el-form-item label="IP地址" prop="ip" placeholder="请输入IP地址">
<el-input v-model="formContent.ip"/>
</el-form-item>
<el-form-item label="端口号" prop="port" placeholder="请输入端口号">
<el-input v-model="formContent.port"/>
</el-form-item>
<el-form-item label='是否加密' prop='encryptionFlag'>
<el-select v-model="formContent.encryptionFlag" clearable placeholder="请选择是否加密">
<el-option label="是" :value="1"></el-option>
<el-option label="否" :value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item label='识别码' prop='series' clearable v-if="formContent.encryptionFlag">
<el-input v-model='formContent.series' placeholder="请输入识别码" show-password/>
</el-form-item>
<el-form-item label='密钥' prop='devKey' clearable v-if="formContent.encryptionFlag">
<el-input v-model='formContent.devKey' placeholder="请输入密钥" show-password/>
</el-form-item>
<el-form-item label='样品编号' prop='sampleId' clearable v-if="DevIsShow && scene === '0'">
<el-input v-model='formContent.sampleId' placeholder="请输入样品编号"/>
</el-form-item>
<el-form-item label='送样日期' prop='arrivedDate' v-if="scene === '0'">
<el-date-picker
v-model="formContent.arrivedDate"
placeholder="请选择送样日期"
:disabled-date="disabledDate"
/>
</el-form-item>
<el-form-item label='委托方' prop='delegate' v-if="scene === '0'">
<el-select v-model="formContent.delegate" clearable placeholder="请选择委托方">
<el-option
v-for="item in dictStore.getDictData('Delegate')"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label='所属地市' prop='cityName' clearable placeholder="请输入所属地市" v-if="MonIsShow">
<el-input v-model='formContent.cityName'/>
</el-form-item>
<el-form-item label='所属供电公司' prop='gDName' clearable placeholder="请输入所属供电公司" v-if="MonIsShow">
<el-input v-model='formContent.gDName'/>
</el-form-item>
<el-form-item label='所属电站' prop='subName' clearable placeholder="请输入所属电站" v-if="MonIsShow">
<el-input v-model='formContent.subName'/>
</el-form-item>
<el-form-item v-auth.device="'factorFlag'" label="是否支持系数校准" prop='factorFlag' v-if="scene === '1'">
<el-radio-group v-model="formContent.factorFlag">
<el-radio :value="1"></el-radio>
<el-radio :value="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</div>
</el-tab-pane>
<!-- 监测点台账信息 tab pane -->
<MonitorTable :MonIsShow="MonIsShow"/>
</el-tabs>
<template #footer>
<div>
<el-button @click='close()'> </el-button>
<el-button type="primary" @click='save()'>保存</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang='ts'>
import {dialogBig} from '@/utils/elementBind'
import {type Device} from '@/api/device/interface/device'
import {ElMessage, type FormItemRule} from 'element-plus'
import {addPqDev, updatePqDev} from '@/api/device/device'
import {computed, ref} from 'vue'
import {useDictStore} from '@/stores/modules/dict'
// 使用 dayjs 库格式化
import dayjs from 'dayjs'
import MonitorTable from '@/views/machine/device/components/monitorTab.vue';
import {useAppSceneStore} from "@/stores/modules/mode";
const AppSceneStore = useAppSceneStore()
const MonIsShow = ref(false)
const DevIsShow = ref(false)
// 存储设备类型选项
const devTypeOptions = ref<Device.ResDev[]>([])
// const IsPasswordShow = ref(false)
const dictStore = useDictStore()
const mode = ref()
const scene = ref('')
// 定义弹出组件元信息
const dialogFormRef = ref()
const disabledDate = (time: Date) => {
return time.getTime() > Date.now()
}
function useMetaInfo() {
const dialogVisible = ref(false)
const titleType = ref('add')
const formContent = ref<Device.ResPqDev>({
id: '',
name: '',
pattern: mode.value,
devType: '',
devChns: 1,
devVolt: 57.74,
devCurr: 5,
manufacturer: '',
createDate: dayjs().format('YYYY-MM-DD'),
createId: '',
hardwareVersion: '',
softwareVersion: '',
protocol: 'MMS',
ip: '172.17.102.222',
port: 102,
encryptionFlag: 0,
reCheckNum: 0,
state: 1,
factorFlag: 1,
icdId: '',
power: '',
preinvestmentPlan: '',
delegate: ''
})
return {dialogVisible, titleType, formContent}
}
const {dialogVisible, titleType, formContent} = useMetaInfo()
// 清空formContent
const resetFormContent = () => {
formContent.value = {
id: '',
name: '',
pattern: mode.value,
devType: '',
devChns: 1,
devVolt: 57.74,
devCurr: 5,
manufacturer: '',
createDate: dayjs().format('YYYY-MM-DD'),
createId: '',
hardwareVersion: '',
softwareVersion: '',
protocol: 'MMS',
ip: '172.17.102.222',
port: 102,
encryptionFlag: 0,
reCheckNum: 0,
state: 1,
factorFlag: 1,
icdId: '',
power: '',
preinvestmentPlan: '',
delegate: ''
}
}
let dialogTitle = computed(() => {
return titleType.value === 'add' ? '新增被检设备' : '编辑被检设备'
})
// 定义表单校验规则
const baseRules: Record<string, Array<FormItemRule>> = {
devType: [{required: true, message: '设备类型必选!', trigger: 'change'}],
pattern: [{required: true, message: '设备模式必填!', trigger: 'blur'}],
devChns: [
{required: true, message: '设备通道数必填!', trigger: 'blur'},
{pattern: /^[1-9]\d*$/, message: '设备通道数为大于1的整数', trigger: 'blur'}
],
devVolt: [
{required: true, message: '额定电压必填!', trigger: 'blur'},
{pattern: /^\d+(\.\d+)?$/, message: '额定电压格式错误', trigger: 'blur'}
],
devCurr: [
{required: true, message: '额定电流必填!', trigger: 'blur'},
{pattern: /^\d+(\.\d+)?$/, message: '额定电流格式错误', trigger: 'blur'}
],
createId: [{required: true, message: '装置编号必填!', trigger: 'blur'}
],
ip: [
{required: true, message: 'IP地址必填', trigger: 'blur'},
{pattern: /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/, message: 'IP地址格式错误', trigger: 'blur'}
],
port: [
{required: true, message: '端口号必填!', trigger: 'blur'},
{pattern: /^(6553[0-5]|655[0-2][0-9]|64[0-9]{3}|[1-5]?[0-9]{1,4})$/, message: '端口号范围0到65535的整数', trigger: 'blur'}
],
encryptionFlag: [{required: true, message: '是否加密必选!', trigger: 'change'}],
protocol: [{required: true, message: '通讯协议必选!', trigger: 'change'}],
series: [{required: true, message: '请输入识别码', trigger: 'blur'}],
devKey: [{required: true, message: '请输入密钥', trigger: 'blur'}]
};
// 使用计算属性根据 scene 动态生成规则
const rules = computed(() => {
const dynamicRules = {...baseRules};
if (scene.value === '0') {//只有电科院需要展示
dynamicRules.createDate = [{required: true, message: '出厂日期必填!', trigger: 'blur'}];
}
if (scene.value === '1') {//只有楼下出厂需要展示
dynamicRules.preinvestmentPlan = [{required: true, message: '预投计划必选!', trigger: 'change'}];
dynamicRules.createId = [{required: true, message: '装置编号必填!', trigger: 'blur'},
{pattern: /^\d+$/, message: '装置编号为数字', trigger: 'blur'}
];
}
if (scene.value !== '0') {
dynamicRules.name = [{required: true, message: '设备名称必填!', trigger: 'blur'}];
dynamicRules.hardwareVersion = [{required: true, message: '固件版本必填!', trigger: 'blur'}];
dynamicRules.softwareVersion = [{required: true, message: '软件版本必填!', trigger: 'blur'}];
dynamicRules.manufacturer = [{required: true, message: '生产厂家必选!', trigger: 'change'}];
}
if (scene.value !== '2') {
dynamicRules.name = [{required: true, message: '设备名称必填!', trigger: 'blur'}];
dynamicRules.manufacturer = [{required: true, message: '生产厂家必选!', trigger: 'change'}];
}
return dynamicRules;
});
// 关闭弹窗
const close = () => {
dialogVisible.value = false
// 清空dialogForm中的值
resetFormContent()
// 重置表单
dialogFormRef.value?.resetFields()
}
// 保存数据
const save = () => {
try {
dialogFormRef.value?.validate(async (valid: boolean) => {
if (formContent.value.encryptionFlag === 0) {
formContent.value.series = ''
formContent.value.devKey = ''
}
if (valid) {
formContent.value.createDate = dayjs(formContent.value.createDate).format('YYYY-MM-DD');
if (AppSceneStore.currentScene === '1') {
formContent.value.name = formContent.value.createId
}
if (formContent.value.arrivedDate) {
formContent.value.arrivedDate = dayjs(formContent.value.arrivedDate).format('YYYY-MM-DD');
}
//保存时判是否加密,把识别码密钥字段清空
if (formContent.value.encryptionFlag === 0) {
formContent.value.series = null
formContent.value.devKey = null
}
if (formContent.value.id) {
await updatePqDev(formContent.value);
ElMessage.success({message: `${dialogTitle.value}成功!`})
} else {
// 新增需要把设备模式转成字典ID
const patternItem = dictStore.getDictData('Pattern').find(item => item.name === formContent.value.pattern);
if (patternItem) {
formContent.value.pattern = patternItem.id;
}
// 新增需要把通讯协议转成字典ID
const protocolItem = dictStore.getDictData('Protocol').find(item => item.name === formContent.value.protocol);
if (protocolItem) {
formContent.value.protocol = protocolItem.id;
}
await addPqDev(formContent.value);
ElMessage.success({message: `${dialogTitle.value}成功!`})
}
close()
// 刷新表格
await props.refreshTable!()
}
})
} catch (err) {
console.error('验证过程中出现错误', err)
}
}
// 打开弹窗,可能是新增,也可能是编辑
const open = async (sign: string, data: Device.ResPqDev, currentMode: string, currentScene: string, devType: Device.ResDev[]) => {
devTypeOptions.value = devType
mode.value = currentMode
scene.value = currentScene
titleType.value = sign
dialogVisible.value = true
if (currentMode === '比对式') {
DevIsShow.value = false
MonIsShow.value = true
} else {
DevIsShow.value = true
MonIsShow.value = false
}
if (data.encryptionFlag === 1) {
//handleEncryptionChange(1)
} else {
//handleEncryptionChange(0)
}
if (data.id) {
formContent.value = {...data}
} else {
resetFormContent()
if (scene.value === '2') {
const manufacturers = dictStore.getDictData('Dev_Manufacturers');
const nanjingCanxuan = manufacturers.find(item => item.name === '南京灿能');
if (nanjingCanxuan) {
formContent.value.manufacturer = nanjingCanxuan.id;
}
}
//handleEncryptionChange(1)
}
// 重置表单
dialogFormRef.value?.resetFields()
}
// const handleEncryptionChange = (value: number) => {
// // 根据是否加密来显示或隐藏识别码和密钥
// if(value === 1){
// IsPasswordShow.value = true
//
// }else
// {
// IsPasswordShow.value = false
// // formContent.value.series = ''
// // formContent.value.devKey = ''
// // rules.value.series = [];
// // rules.value.devKey = [];
// }
// }
const handleDevTypeChange = (value: string) => {
// 在这里处理选中事件的逻辑
const dev = devTypeOptions.value.find(t => t.id === value)
if (dev) {
formContent.value.devChns = dev.devChns; // 默认值为1
formContent.value.devCurr = dev.devCurr; // 默认值为1
formContent.value.devVolt = dev.devVolt; // 默认值为1
formContent.value.icdId = dev.icd
formContent.value.power = dev.power
if(scene.value === '1'){
if (dev.name.includes('NPQS-581') || dev.name.includes('NPQS-580') || dev.name.includes('PQ-COM')) {
formContent.value.encryptionFlag = 1
formContent.value.series = 'Pqs&cn870299'
formContent.value.devKey = '!qaz@wsx3edc4rfv'
} else {
formContent.value.encryptionFlag = 0
formContent.value.series = null
formContent.value.devKey = null
}
}
} else {
formContent.value.devChns = 1; // 默认值为1
formContent.value.devCurr = 1; // 默认值为1
formContent.value.devVolt = 57.74; // 默认值为1
//formContent.value.ip = '172.17.102.200'
}
}
const handleInput = (value: string) => {
// 在这里处理选中事件的逻辑
if (scene.value === '1') {
formContent.value.name = value
}
}
// 对外映射
defineExpose({open})
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
}>()
</script>