From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/views/iot/thingmodel/dataSpecs/ThingModelStructDataSpecs.vue |  167 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 167 insertions(+), 0 deletions(-)

diff --git a/src/views/iot/thingmodel/dataSpecs/ThingModelStructDataSpecs.vue b/src/views/iot/thingmodel/dataSpecs/ThingModelStructDataSpecs.vue
new file mode 100644
index 0000000..529a798
--- /dev/null
+++ b/src/views/iot/thingmodel/dataSpecs/ThingModelStructDataSpecs.vue
@@ -0,0 +1,167 @@
+<!-- dataType锛歴truct 鏁扮粍绫诲瀷 -->
+<template>
+  <!-- struct 鏁版嵁灞曠ず -->
+  <el-form-item
+    :rules="[{ required: true, validator: validateList, trigger: 'change' }]"
+    label="JSON 瀵硅薄"
+  >
+    <div
+      v-for="(item, index) in dataSpecsList"
+      :key="index"
+      class="w-1/1 struct-item flex justify-between px-10px mb-10px"
+    >
+      <span>鍙傛暟鍚嶇О锛歿{ item.name }}</span>
+      <div class="btn">
+        <el-button link type="primary" @click="openStructForm(item)">缂栬緫</el-button>
+        <el-divider direction="vertical" />
+        <el-button link type="danger" @click="deleteStructItem(index)">鍒犻櫎</el-button>
+      </div>
+    </div>
+    <el-button link type="primary" @click="openStructForm(null)">+鏂板鍙傛暟</el-button>
+  </el-form-item>
+
+  <!-- struct 琛ㄥ崟 -->
+  <Dialog v-model="dialogVisible" :title="dialogTitle" append-to-body>
+    <el-form
+      ref="structFormRef"
+      v-loading="formLoading"
+      :model="formData"
+      :rules="ThingModelFormRules"
+      label-width="100px"
+    >
+      <el-form-item label="鍙傛暟鍚嶇О" prop="name">
+        <el-input v-model="formData.name" placeholder="璇疯緭鍏ュ姛鑳藉悕绉�" />
+      </el-form-item>
+      <el-form-item label="鏍囪瘑绗�" prop="identifier">
+        <el-input v-model="formData.identifier" placeholder="璇疯緭鍏ユ爣璇嗙" />
+      </el-form-item>
+      <!-- 灞炴�ч厤缃� -->
+      <ThingModelProperty v-model="formData.property" is-struct-data-specs />
+    </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 { useVModel } from '@vueuse/core'
+import ThingModelProperty from '../ThingModelProperty.vue'
+import { isEmpty } from '@/utils/is'
+import { IoTDataSpecsDataTypeEnum } from '@/views/iot/utils/constants'
+import { ThingModelFormRules } from '@/api/iot/thingmodel'
+
+/** Struct 鍨嬬殑 dataSpecs 閰嶇疆缁勪欢 */
+defineOptions({ name: 'ThingModelStructDataSpecs' })
+
+const props = defineProps<{ modelValue: any }>()
+const emits = defineEmits(['update:modelValue'])
+const dataSpecsList = useVModel(props, 'modelValue', emits) as Ref<any[]>
+const dialogVisible = ref(false) // 寮圭獥鐨勬槸鍚﹀睍绀�
+const dialogTitle = ref('鏂板鍙傛暟') // 寮圭獥鐨勬爣棰�
+const formLoading = ref(false) // 琛ㄥ崟鐨勫姞杞戒腑锛�1锛変慨鏀规椂鐨勬暟鎹姞杞斤紱2锛夋彁浜ょ殑鎸夐挳绂佺敤
+const structFormRef = ref() // 琛ㄥ崟 ref
+const formData = ref<any>({
+  property: {
+    dataType: IoTDataSpecsDataTypeEnum.INT,
+    dataSpecs: {
+      dataType: IoTDataSpecsDataTypeEnum.INT
+    }
+  }
+})
+
+/** 鎵撳紑 struct 琛ㄥ崟 */
+const openStructForm = (val: any) => {
+  dialogVisible.value = true
+  resetForm()
+  if (isEmpty(val)) {
+    return
+  }
+  // 缂栬緫鏃跺洖鏄炬暟鎹�
+  formData.value = {
+    identifier: val.identifier,
+    name: val.name,
+    description: val.description,
+    property: {
+      dataType: val.childDataType,
+      dataSpecs: val.dataSpecs,
+      dataSpecsList: val.dataSpecsList
+    }
+  }
+}
+
+/** 鍒犻櫎 struct 椤� */
+const deleteStructItem = (index: number) => {
+  dataSpecsList.value.splice(index, 1)
+}
+
+/** 娣诲姞鍙傛暟 */
+const submitForm = async () => {
+  await structFormRef.value.validate()
+
+  try {
+    const data = unref(formData)
+    // 鏋勫缓鏁版嵁瀵硅薄
+    const item = {
+      identifier: data.identifier,
+      name: data.name,
+      description: data.description,
+      dataType: IoTDataSpecsDataTypeEnum.STRUCT,
+      childDataType: data.property.dataType,
+      dataSpecs:
+        !!data.property.dataSpecs && Object.keys(data.property.dataSpecs).length > 1
+          ? data.property.dataSpecs
+          : undefined,
+      dataSpecsList: isEmpty(data.property.dataSpecsList) ? undefined : data.property.dataSpecsList
+    }
+
+    // 鏂板鎴栦慨鏀瑰悓 identifier 鐨勫弬鏁�
+    const existingIndex = dataSpecsList.value.findIndex(
+      (spec) => spec.identifier === data.identifier
+    )
+    if (existingIndex > -1) {
+      dataSpecsList.value[existingIndex] = item
+    } else {
+      dataSpecsList.value.push(item)
+    }
+  } finally {
+    dialogVisible.value = false
+  }
+}
+
+/** 閲嶇疆琛ㄥ崟 */
+const resetForm = () => {
+  formData.value = {
+    property: {
+      dataType: IoTDataSpecsDataTypeEnum.INT,
+      dataSpecs: {
+        dataType: IoTDataSpecsDataTypeEnum.INT
+      }
+    }
+  }
+  structFormRef.value?.resetFields()
+}
+
+/** 鏍¢獙 struct 涓嶈兘涓虹┖ */
+const validateList = (_: any, __: any, callback: any) => {
+  if (isEmpty(dataSpecsList.value)) {
+    callback(new Error('struct 涓嶈兘涓虹┖'))
+    return
+  }
+  callback()
+}
+
+/** 缁勪欢鍒濆鍖� */
+onMounted(async () => {
+  await nextTick()
+  // 棰勯槻 dataSpecsList 绌烘寚閽�
+  isEmpty(dataSpecsList.value) && (dataSpecsList.value = [])
+})
+</script>
+
+<style lang="scss" scoped>
+.struct-item {
+  background-color: #e4f2fd;
+}
+</style>

--
Gitblit v1.8.0