style:设备模型/物联设备-采集点管理-点位类型下拉框改为弹框table形式

main
黄伟杰 6 days ago
parent f2ed3238cd
commit 9ee8622992

@ -10,11 +10,13 @@ v-model="formData.attributeCode" :placeholder="t('DataCollection.Device.placehol
<el-input v-model="formData.attributeName" :placeholder="t('DataCollection.Device.placeholderAttributeName')" />
</el-form-item>
<el-form-item :label="t('DataCollection.Device.attributeType')" prop="attributeType">
<el-select
v-model="formData.attributeType" clearable filterable
:placeholder="t('DataCollection.Device.placeholderAttributeType')" @change="handleAttributeTypeChange">
<el-option v-for="item in typeList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-input
v-model="formData.typeName"
readonly
:placeholder="t('DataCollection.Device.placeholderAttributeType')"
class="cursor-pointer"
@click="openAttributeTypeSelectDialog"
/>
</el-form-item>
<el-form-item :label="t('DataCollection.Device.dataType')" prop="dataType">
<el-select
@ -53,11 +55,21 @@ v-model="formData.remark" :placeholder="t('DataCollection.Device.placeholderRema
</el-button>
</template>
</Dialog>
<TableSelectDialog
ref="attributeTypeSelectDialogRef"
:title="t('DataCollection.Device.attributeType')"
:columns="attributeTypeColumns"
:fetch-api="fetchAttributeTypePage"
selection-type="single"
row-key="id"
@confirm="handleAttributeTypeSelectConfirm"
/>
</template>
<script setup lang="ts">
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { DeviceApi } from '@/api/iot/device'
import { DeviceAttributeTypeApi, DeviceAttributeTypeVO } from '@/api/iot/deviceattributetype'
import TableSelectDialog from '@/components/TableSelectDialog/TableSelectDialog.vue'
import { ProductUnitApi, ProductUnitVO } from '@/api/erp/product/unit'
const { t } = useI18n() //
@ -68,18 +80,6 @@ const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const unitList = ref<ProductUnitVO[]>([]) //
const typeList = ref<DeviceAttributeTypeVO[]>([])
const loadTypeList = async () => {
if (typeList.value.length > 0) {
return
}
try {
const data = await DeviceAttributeTypeApi.getDeviceAttributeTypePage({ pageNo: 1, pageSize: 10 })
typeList.value = data?.list ?? []
} catch {
typeList.value = []
}
}
const formData = ref({
id: undefined as number | undefined,
@ -101,12 +101,6 @@ const handleAttributeCodeInput = (val: string) => {
}
const handleAttributeTypeChange = (val: number | string) => {
const matched = typeList.value.find(
(item) => item.id === val || String(item.id) === String(val)
)
formData.value.typeName = matched?.name
}
const formRules = reactive({
attributeCode: [
@ -194,7 +188,6 @@ const open = async (type: string, id?: number, deviceId: number) => {
//
unitList.value = await ProductUnitApi.getProductUnitSimpleList()
formData.value.deviceId = deviceId
await loadTypeList()
//
if (id) {
formLoading.value = true
@ -203,20 +196,18 @@ const open = async (type: string, id?: number, deviceId: number) => {
if (!(formData.value as any)?.deviceId) {
; (formData.value as any).deviceId = deviceId
}
const currentType = (formData.value as any)?.attributeType
if (currentType !== undefined && currentType !== null && currentType !== '') {
const matched = typeList.value.find(
(item) =>
item.id === currentType ||
String(item.id) === String(currentType) ||
item.name === currentType ||
item.code === currentType
)
if (matched) {
; (formData.value as any).attributeType = matched.id
; (formData.value as any).typeName = matched.name
const currentAttributeType = (formData.value as any)?.attributeType
const currentTypeId = Number(currentAttributeType)
if (Number.isFinite(currentTypeId) && currentTypeId > 0) {
try {
const selectedType = await DeviceAttributeTypeApi.getDeviceAttributeType(currentTypeId)
;(formData.value as any).attributeType = selectedType.id
;(formData.value as any).typeName = selectedType.name
} catch {
// Keep the value returned by the detail API when the type no longer exists.
}
} else if (!(formData.value as any)?.typeName && currentAttributeType != null) {
;(formData.value as any).typeName = String(currentAttributeType)
}
} finally {
formLoading.value = false
@ -249,6 +240,35 @@ const submitForm = async () => {
}
}
const attributeTypeSelectDialogRef = ref()
const attributeTypeColumns = [
{ label: t('DataCollection.DeviceAttributeType.code'), prop: 'code', minWidth: 140 },
{ label: t('DataCollection.DeviceAttributeType.name'), prop: 'name', minWidth: 160 },
{ label: t('DataCollection.DeviceAttributeType.sort'), prop: 'sort', minWidth: 100 },
{ label: t('DataCollection.DeviceAttributeType.remark'), prop: 'remark', minWidth: 160 },
{ label: t('DataCollection.DeviceAttributeType.createTime'), prop: 'createTime', minWidth: 180 }
]
const fetchAttributeTypePage = (params: Record<string, any>) => {
return DeviceAttributeTypeApi.getDeviceAttributeTypePage(params)
}
const openAttributeTypeSelectDialog = () => {
const currentTypeId = formData.value.attributeType
const currentTypeName = formData.value.typeName
const selectedRows = currentTypeId != null && currentTypeName
? [{ id: currentTypeId, name: currentTypeName }]
: []
attributeTypeSelectDialogRef.value?.open(selectedRows)
}
const handleAttributeTypeSelectConfirm = (payload: { rows: DeviceAttributeTypeVO[] }) => {
const row = payload.rows?.[0]
if (!row) return
formData.value.attributeType = row.id
formData.value.typeName = row.name
formRef.value?.clearValidate('attributeType')
}
/** 重置表单 */
const resetForm = () => {
formData.value = {

@ -19,15 +19,13 @@
:placeholder="t('DataCollection.DeviceModel.placeholderAttributeName')" />
</el-form-item>
<el-form-item :label="t('DataCollection.DeviceModel.attributeType')" prop="attributeType">
<el-select
v-model="formData.attributeType"
clearable
filterable
<el-input
v-model="formData.typeName"
readonly
:placeholder="t('DataCollection.DeviceModel.placeholderAttributeType')"
@change="handleAttributeTypeChange"
>
<el-option v-for="item in typeList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
class="cursor-pointer"
@click="openAttributeTypeSelectDialog"
/>
</el-form-item>
<el-form-item :label="t('DataCollection.DeviceModel.dataType')" prop="dataType">
<el-select
@ -78,11 +76,21 @@
<el-button @click="dialogVisible = false">{{ t('DataCollection.DeviceModel.dialogCancel') }}</el-button>
</template>
</Dialog>
<TableSelectDialog
ref="attributeTypeSelectDialogRef"
:title="t('DataCollection.DeviceModel.attributeType')"
:columns="attributeTypeColumns"
:fetch-api="fetchAttributeTypePage"
selection-type="single"
row-key="id"
@confirm="handleAttributeTypeSelectConfirm"
/>
</template>
<script setup lang="ts">
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { DeviceModelAttributeApi } from '@/api/iot/devicemodelattribute'
import { DeviceAttributeTypeApi, DeviceAttributeTypeVO } from '@/api/iot/deviceattributetype'
import TableSelectDialog from '@/components/TableSelectDialog/TableSelectDialog.vue'
import { ProductUnitApi, ProductUnitVO } from '@/api/erp/product/unit'
/** 采集设备模型-点位管理 表单 */
@ -91,20 +99,6 @@ defineOptions({ name: 'DeviceModelAttributeForm' })
const { t } = useI18n() //
const message = useMessage() //
const typeList = ref<DeviceAttributeTypeVO[]>([])
const typeListLoaded = ref(false)
const loadTypeList = async () => {
if (typeListLoaded.value) {
return
}
try {
const data = await DeviceAttributeTypeApi.getDeviceAttributeTypePage({ pageNo: 1, pageSize: 10 })
typeList.value = data?.list ?? []
typeListLoaded.value = true
} catch {
typeList.value = []
}
}
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
@ -124,7 +118,19 @@ const formData = ref({
deviceModelId: undefined,
})
const formRules = reactive({
attributeCode: [{ required: true, message: t('DataCollection.DeviceModel.validatorAttributeCodeRequired'), trigger: 'blur' }],
attributeCode: [
{ required: true, message: t('DataCollection.DeviceModel.validatorAttributeCodeRequired'), trigger: 'blur' },
{
validator: (_rule: any, value: string, callback: any) => {
if (!value || /^[A-Za-z_][A-Za-z0-9_]*$/.test(value)) {
callback()
return
}
callback(new Error('仅支持英文字母、数字和下划线,且必须以字母或下划线开头'))
},
trigger: ['blur', 'change']
}
],
attributeName: [{ required: true, message: t('DataCollection.DeviceModel.validatorAttributeNameRequired'), trigger: 'blur' }],
dataType: [{ required: true, message: t('DataCollection.DeviceModel.validatorDataTypeRequired'), trigger: 'change' }],
attributeType: [{ required: true, message: '点位类型不能为空', trigger: 'change' }]
@ -189,7 +195,6 @@ const open = async (type: string, id: number, modelId: number) => {
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
await loadTypeList()
//
unitList.value = await ProductUnitApi.getProductUnitSimpleList()
formData.value.deviceModelId = modelId
@ -197,21 +202,19 @@ const open = async (type: string, id: number, modelId: number) => {
formLoading.value = true
try {
formData.value = await DeviceModelAttributeApi.getDeviceModelAttribute(id)
const currentType = (formData.value as any)?.attributeType
if (currentType !== undefined && currentType !== null && currentType !== '') {
const matched = typeList.value.find(
(item) =>
item.id === currentType ||
String(item.id) === String(currentType) ||
item.name === currentType ||
item.code === currentType
)
if (matched) {
;(formData.value as any).attributeType = matched.id
;(formData.value as any).typeName = matched.name
}
}
const currentAttributeType = (formData.value as any)?.attributeType
const currentTypeId = Number(currentAttributeType)
if (Number.isFinite(currentTypeId) && currentTypeId > 0) {
try {
const selectedType = await DeviceAttributeTypeApi.getDeviceAttributeType(currentTypeId)
;(formData.value as any).attributeType = selectedType.id
;(formData.value as any).typeName = selectedType.name
} catch {
// Keep the value returned by the detail API when the type no longer exists.
}
} else if (!(formData.value as any)?.typeName && currentAttributeType != null) {
;(formData.value as any).typeName = String(currentAttributeType)
}
} finally {
formLoading.value = false
}
@ -243,13 +246,36 @@ const submitForm = async () => {
}
}
const handleAttributeTypeChange = (val: number | string) => {
const matched = typeList.value.find(
(item) => item.id === val || String(item.id) === String(val)
)
;(formData.value as any).typeName = matched?.name
const attributeTypeSelectDialogRef = ref()
const attributeTypeColumns = [
{ label: t('DataCollection.DeviceAttributeType.code'), prop: 'code', minWidth: 140 },
{ label: t('DataCollection.DeviceAttributeType.name'), prop: 'name', minWidth: 160 },
{ label: t('DataCollection.DeviceAttributeType.sort'), prop: 'sort', minWidth: 100 },
{ label: t('DataCollection.DeviceAttributeType.remark'), prop: 'remark', minWidth: 160 },
{ label: t('DataCollection.DeviceAttributeType.createTime'), prop: 'createTime', minWidth: 180 }
]
const fetchAttributeTypePage = (params: Record<string, any>) => {
return DeviceAttributeTypeApi.getDeviceAttributeTypePage(params)
}
const openAttributeTypeSelectDialog = () => {
const currentTypeId = formData.value.attributeType
const currentTypeName = formData.value.typeName
const selectedRows = currentTypeId != null && currentTypeName
? [{ id: currentTypeId, name: currentTypeName }]
: []
attributeTypeSelectDialogRef.value?.open(selectedRows)
}
const handleAttributeTypeSelectConfirm = (payload: { rows: DeviceAttributeTypeVO[] }) => {
const row = payload.rows?.[0]
if (!row) return
formData.value.attributeType = row.id as any
formData.value.typeName = row.name
formRef.value?.clearValidate('attributeType')
}
/** 重置表单 */
const resetForm = () => {
formData.value = {

Loading…
Cancel
Save