Files
pqs-9100_client/frontend/src/views/machine/standardDevice/components/standardDevicePopup.vue
2025-07-29 18:35:46 +08:00

319 lines
13 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" align-center>
<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="name" >
<el-input v-model='formContent.name' placeholder="请输入设备名称" 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='manufacturer'>
<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-divider >参数信息</el-divider>
<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" 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='inspectChannel' >
<el-select v-model="formContent.inspectChannel" multiple collapse-tags :max-collapse-tags="4" placeholder="请选择可检通道数" clearable>
<el-option
v-for="(option, index) in pqChannelArray"
:key="index"
:label="option.label"
:value="option.value"
/>
</el-select>
</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>
</div>
</el-tab-pane>
</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 IPAddress from '@/components/IpAddress/index.vue'
import { dialogBig } from '@/utils/elementBind'
import {type StandardDevice} from '@/api/device/interface/standardDevice.ts'
import { ElMessage, type FormItemRule } from 'element-plus'
import { addPqStandardDev, updatePqStandardDev} from '@/api/device/standardDevice/index.ts'
import { computed, reactive, type Ref, ref } from 'vue'
import { useDictStore } from '@/stores/modules/dict'
import { CirclePlus, Delete, EditPen } from '@element-plus/icons-vue'
import {type Device} from '@/api/device/interface/device.ts'
// 使用 dayjs 库格式化
import dayjs from 'dayjs'
// 存储设备类型选项
const devTypeOptions = ref<Device.ResDev[]>([])
const dictStore = useDictStore()
// 定义弹出组件元信息
const dialogFormRef = ref()
const pqChannelArray = ref([
{
value: '1',
label: '1',
},
{
value: '2',
label: '2',
},
{
value: '3',
label: '3',
},
{
value: '4',
label: '4',
},
])
function useMetaInfo() {
const dialogVisible = ref(false)
const titleType = ref('add')
const formContent = reactive<StandardDevice.ResPqStandardDevice>({
id: '',
name: '',
devType:'',
manufacturer:'',
protocol: 'MMS',
ip: '',
port: 102,
inspectChannel:'',
encryptionFlag: 0,
state: 1,
})
return { dialogVisible, titleType, formContent }
}
const { dialogVisible, titleType, formContent } = useMetaInfo()
// 清空formContent
const resetFormContent = () => {
Object.assign(
formContent,{
id: '',
name: '',
devType:'',
manufacturer:'',
protocol: 'MMS',
ip: '',
port: 102,
inspectChannel:'',
encryptionFlag: 0,
state: 1,
}
)
}
let dialogTitle = computed(() => {
return titleType.value === 'add' ? '新增标准设备' : '编辑标准设备'
})
//定义校验规则
const rules: Ref<Record<string, Array<FormItemRule>>> = ref({
name : [{ required: true, message: '设备名称必填!', trigger: 'blur' }],
devType: [{ required: true, message: '设备类型必选!', trigger: 'change' }],
manufacturer:[{ required: true, message: '生产厂家必选!', trigger: 'change' }],
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' }
],
inspectChannel:[ { required: true, message: '可检通道数必选', trigger: 'change' }],
encryptionFlag: [{ required: true, message: '是否加密必选!', trigger: 'change' }],
series: [{ required: true, message: '请输入识别码', trigger: 'blur' }],
devKey: [{ required: true, message: '请输入密钥', trigger: 'blur' }],
protocol: [{required: true, message: '通讯协议必选!', trigger: 'change'}],
})
// 关闭弹窗
const close = () => {
dialogVisible.value = false
// 清空dialogForm中的值
resetFormContent()
// 重置表单
dialogFormRef.value?.resetFields()
}
// 保存数据
const save = () => {
try {
dialogFormRef.value?.validate(async (valid: boolean) => {
if (formContent.encryptionFlag === 0) {
formContent.series = ''
formContent.devKey = ''
}
if (valid) {
//保存时判是否加密,把识别码密钥字段清空
if(formContent.encryptionFlag === 0){
formContent.series = null
formContent.devKey = null
}
// 可检通道转为字符串逗号分隔(保存前临时转换)
let originalInspectChannel = formContent.inspectChannel; // 保存原始值
//可检通道转为字符串逗号分隔
// 确保 inspectChannel 是数组再执行 join
if (Array.isArray(formContent.inspectChannel)) {
formContent.inspectChannel = formContent.inspectChannel
.map(Number) // 将值转为数字以保证正确排序
.sort((a, b) => a - b) // 数字升序排序
.map(String) // 恢复为字符串用于保存
.join(',');
}
try {
if (formContent.id) {
await updatePqStandardDev(formContent);
ElMessage.success({ message: `${dialogTitle.value}成功!` })
} else {
// 新增需要把通讯协议转成字典ID
const protocolItem = dictStore.getDictData('Protocol').find(item => item.name === formContent.protocol);
if (protocolItem) {
formContent.protocol = protocolItem.id;
}
await addPqStandardDev(formContent);
ElMessage.success({ message: `${dialogTitle.value}成功!` })
}
close()
// 刷新表格
await props.refreshTable!()
} catch (error) {
// 如果保存失败,恢复原始的 inspectChannel 值
formContent.inspectChannel = originalInspectChannel;
throw error;
}
} else {
// 验证失败也需要恢复原始 inspectChannel 格式(如果之前被转换过)
if (typeof formContent.inspectChannel === 'string' && formContent.inspectChannel.includes(',')) {
formContent.inspectChannel = formContent.inspectChannel.split(',').filter(Boolean);
}
}
})
} catch (err) {
console.error('验证过程中出现错误', err)
}
}
// 打开弹窗,可能是新增,也可能是编辑
const open = async (sign: string, data: StandardDevice.ResPqStandardDevice,devType:Device.ResDev[]) => {
// 重置表单
dialogFormRef.value?.resetFields()
devTypeOptions.value = devType
titleType.value = sign
if (data.id) {
Object.assign(formContent,{ ...data })
if (typeof formContent.inspectChannel === 'string') {
formContent.inspectChannel = formContent.inspectChannel.split(',').filter(Boolean)
}
//handleDevTypeChange(data.devType)
} else {
resetFormContent()
}
dialogVisible.value = true
}
const handleDevTypeChange = (value: string) => {
console.log('handleDevTypeChange', value)
// 在这里处理选中事件的逻辑
const dev = devTypeOptions.value.find(t =>t.id === value)
if (dev) {
const maxChannel = dev.devChns
// 动态设置 pqChannelArray 从 1 到 dev.devChns.length
pqChannelArray.value = Array.from({ length: dev.devChns }, (_, i) => ({
value: String(i + 1),
label: String(i + 1),
}))
//if(titleType.value == 'add') // 默认全选所有通道
formContent.inspectChannel = pqChannelArray.value.map(channel => channel.value)
// 过滤掉超出新通道数范围的选项
if (Array.isArray(formContent.inspectChannel)) {
formContent.inspectChannel = formContent.inspectChannel.filter(
(channel) => parseInt(channel, 10) <= maxChannel
)
}
} else {
// 可选:恢复默认值
pqChannelArray.value = [
{ value: '1', label: '1' },
{ value: '2', label: '2' },
{ value: '3', label: '3' },
{ value: '4', label: '4' },
]
}
}
// 对外映射
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
}>()
</script>