Files
pqs-9100_client/frontend/src/views/machine/standardDevice/components/standardDevicePopup.vue

311 lines
12 KiB
Vue
Raw Normal View History

<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>
2025-07-21 13:47:56 +08:00
<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>
2025-07-21 13:47:56 +08:00
<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
}
//可检通道转为字符串逗号分隔
// 确保 inspectChannel 是数组再执行 join
if (Array.isArray(formContent.inspectChannel)) {
formContent.inspectChannel = formContent.inspectChannel
.map(Number) // 将值转为数字以保证正确排序
.sort((a, b) => a - b) // 数字升序排序
.map(String) // 恢复为字符串用于保存
.join(',');
}
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 (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)
}
2025-07-21 13:47:56 +08:00
//handleDevTypeChange(data.devType)
} else {
resetFormContent()
}
dialogVisible.value = true
}
const handleDevTypeChange = (value: string) => {
// 在这里处理选中事件的逻辑
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),
}))
2025-07-21 13:47:56 +08:00
//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>