Przeglądaj źródła

fea: 设备增加扩展属性信息功能

vera_min 1 rok temu
rodzic
commit
f3e6b78dbf

+ 1 - 0
src/api/system/index.ts

@@ -186,4 +186,5 @@ export default {
     detail: (params: object) => get('/system/monitor/lastLinesLog', params),
     down: (params: object) => file('system/monitor/downloadLog', params),
   },
+  getInfoByKey: (params: object) => get('/common/config/getInfoByKey', params)
 }

+ 9 - 0
src/components/upload/index.vue

@@ -75,6 +75,10 @@ const props = defineProps({
 		type: String,
 		default: '',
 	},
+	// keyName: {
+	// 	type: String,
+	// 	default: '',
+	// },
 })
 
 const fileList = ref<any[]>([
@@ -103,6 +107,11 @@ const updateImg = () => {
 		emit('setImg', props.widthHost ? img : img.replace(getOrigin(import.meta.env.VITE_SERVER_URL + '/'), ''));
 	} else {
 		emit('setImgs', list)
+		// if(props.keyName) {
+		// 	emit('setImgs', { list: list, keyName: props.keyName})
+		// }else {
+		// 	emit('setImgs', list)
+		// }
 	}
 }
 

+ 72 - 12
src/views/iot/device/instance/component/edit.vue

@@ -62,6 +62,15 @@
         <el-form-item label="备注" prop="desc">
           <el-input v-model="ruleForm.desc" type="textarea" placeholder="请输入内容"></el-input>
         </el-form-item>
+        <el-form-item label="设备图片">
+					<upload-vue :imgs="phone" @set-imgs="setImgsPhone" :limit="deviceImgLimit"></upload-vue>
+				</el-form-item>
+        <el-form-item label="设备说明">
+          <el-input v-model="intro" type="textarea" placeholder="请输入设备说明"></el-input>
+        </el-form-item>
+        <el-form-item label="证书图片">
+					<upload-vue :imgs="certificate" @set-imgs="setImgsCertificate" :limit="deviceImgLimit"></upload-vue>
+				</el-form-item>
       </el-form>
       <template #footer>
         <span class="dialog-footer">
@@ -76,12 +85,15 @@
 </template>
 
 <script lang="ts">
-import { reactive, toRefs, defineComponent, ref, unref, nextTick } from 'vue';
+import { reactive, toRefs, defineComponent, ref, unref, nextTick, onMounted } from 'vue';
 import api from '/@/api/device';
+import apiSystem from '/@/api/system';
 import { ElMessage } from "element-plus";
-import tagVue from './tag.vue'
-import Map from './map.vue'
+import tagVue from './tag.vue';
+import Map from './map.vue';
+import UploadVue from '/@/components/upload/index.vue';
 import certApi from '/@/api/certificateManagement';
+import { json } from 'stream/consumers';
 
 interface RuleFormState {
   id: number;
@@ -98,6 +110,7 @@ interface RuleFormState {
   authPasswd: string;
   accessToken: string;
   certificateId: string;
+  extensionInfo: string;
 }
 
 const form: RuleFormState = {
@@ -114,7 +127,8 @@ const form: RuleFormState = {
   authPasswd: '',
   accessToken: '',
   certificateId: '',
-  desc: ''
+  desc: '',
+  extensionInfo: ''
 }
 
 interface DicState {
@@ -122,7 +136,12 @@ interface DicState {
   product: any;
   isShowDialog: boolean;
   ruleForm: RuleFormState;
-  rules: {}
+  rules: {};
+  deviceImgLimit: number;
+  certificateLimit: number;
+  phone: any[];
+  certificate: any[];
+  intro: string;
 }
 interface Tag {
   key: string;
@@ -135,6 +154,7 @@ export default defineComponent({
   components: {
     tagVue,
     Map,
+    UploadVue
   },
   setup(prop, { emit }) {
     const formRef = ref<HTMLElement | null>(null);
@@ -156,7 +176,12 @@ export default defineComponent({
           { required: true, message: "设备标识不能为空", trigger: "blur" }
         ],
         productId: [{ required: true, message: '所属产品不能为空', trigger: 'blur' }],
-      }
+      },
+      deviceImgLimit: 0,
+      certificateLimit: 0,
+      phone: [],
+      certificate: [],
+      intro: ""
     });
 
     //地图选点
@@ -178,11 +203,11 @@ export default defineComponent({
 
 
       if (row) {
-        // api.dict.getType(row.id).then((res:any)=>{
-        //   state.ruleForm = res.data.dictType
-        // })
         state.ruleForm = row;
-        state.ruleForm.tags = row.tags || []
+        state.ruleForm.tags = row.tags || [];
+        state.phone = JSON.parse(row.extensionInfo).phone;
+        state.certificate = JSON.parse(row.extensionInfo).certificate;
+        state.intro = JSON.parse(row.extensionInfo).intro;
         productIdChange(row.productId as number)
       }
       state.isShowDialog = true;
@@ -192,6 +217,14 @@ export default defineComponent({
         ...form
       }
     };
+    // 上传设备图
+    const setImgsPhone = (res:any) => {
+      state.phone = res;
+    }
+    // 上传设备资格证书
+    const setImgsCertificate = (res:any) => {
+      state.certificate = res;
+    }
     // 关闭弹窗
     const closeDialog = () => {
       state.isShowDialog = false;
@@ -208,14 +241,30 @@ export default defineComponent({
         if (valid) {
           if (state.ruleForm.id !== 0) {
             //修改
-            api.instance.edit(state.ruleForm).then(() => {
+            const params = {
+              ...state.ruleForm,
+              extensionInfo: JSON.stringify({
+                "phone": state.phone,
+                "certificate": state.certificate,
+                "intro": state.intro
+              })
+            }
+            api.instance.edit(params).then(() => {
               ElMessage.success('设备类型修改成功');
               closeDialog(); // 关闭弹窗
               emit('typeList')
             })
           } else {
             //添加
-            api.instance.add(state.ruleForm).then(() => {
+            const params = {
+              ...state.ruleForm,
+              extensionInfo: JSON.stringify({
+                "phone": state.phone,
+                "certificate": state.certificate,
+                "intro": state.intro
+              })
+            }
+            api.instance.add(params).then(() => {
               ElMessage.success('设备类型添加成功');
               closeDialog(); // 关闭弹窗
               emit('typeList')
@@ -254,6 +303,15 @@ export default defineComponent({
       state.ruleForm.lat = data.lat;
     }
 
+    onMounted(() => {
+      apiSystem.getInfoByKey({ ConfigKey: 'sys.device.phone.limit' }).then((res: any) => {
+        state.deviceImgLimit = parseInt(res.data.configValue);
+      });
+      apiSystem.getInfoByKey({ ConfigKey: 'sys.device.certificate.limit' }).then((res: any) => {
+        state.certificateLimit = parseInt(res.data.configValue);
+      });
+    })
+
     return {
       certList,
       productIdChange,
@@ -268,6 +326,8 @@ export default defineComponent({
       closeDialog,
       onCancel,
       onSubmit,
+      setImgsPhone,
+      setImgsCertificate,
       formRef,
       ...toRefs(state),
     };

+ 23 - 0
src/views/iot/device/instance/detail.vue

@@ -357,6 +357,20 @@
           </div>
 
         </el-tab-pane>
+        <el-tab-pane label="设备扩展属性信息" name="6">
+          <el-form :model="ruleForm" ref="formRef" :rules="rules" size="default" label-width="110px">
+            <el-form-item v-if="phone.length" label="设备图片">
+              <img class="mr20" style="border: 1px solid #e5e5e5;border-radius: 8px;width: 100px;height: 100px;object-fit: contain;" :src="item" v-for="(item, index) in phone" :key="index" />
+            </el-form-item>
+            <el-form-item v-if="certificate.length" label="证书图片">
+              <img class="mr20" style="border: 1px solid #e5e5e5;border-radius: 8px;width: 100px;height: 100px;object-fit: contain;" :src="item" v-for="(item, index) in certificate" :key="index" />
+            </el-form-item>
+            <el-form-item label="设备说明">
+              <el-input disabled v-model="intro" type="textarea" placeholder="请输入设备说明"></el-input>
+            </el-form-item>
+
+          </el-form>
+        </el-tab-pane>
       </el-tabs>
     </div>
     <EditDic ref="editDicRef" @typeList="typeList" />
@@ -403,6 +417,9 @@ import datahub from '/@/api/datahub';
 import { useRoute } from 'vue-router';
 
 interface TableDataState {
+  phone: any[];
+  certificate: any[];
+  intro: string;
   ids: number[];
   detail: any;
   deviceKeyList: string[];
@@ -463,6 +480,9 @@ export default defineComponent({
     const subDeviceRef = ref();
     const mutipleBindRef = ref();
     const state = reactive<TableDataState>({
+      certificate: [],
+      phone: [],
+      intro: '',
       deviceKeyList: [],
       areaData: [],
       isShowDialog: false,
@@ -522,6 +542,9 @@ export default defineComponent({
         api.product.detail(res.data.product.id).then((res: any) => {
           state.prodetail = res.data;
         });
+        state.phone = JSON.parse(res.data.extensionInfo).phone;
+        state.certificate = JSON.parse(res.data.extensionInfo).certificate;
+        state.intro = JSON.parse(res.data.extensionInfo).intro;
 
         //加载全部属性
         datahub.node.getpropertyList({ key: state.detail.product.key }).then((re: any) => {

+ 5 - 11
src/views/iot/device/instance/index.vue

@@ -97,13 +97,10 @@
       <el-table :data="tableData.data" style="width: 100%" @selection-change="handleSelectionChange"
         v-loading="tableData.loading">
         <el-table-column type="selection" width="55" align="center" />
-        <!--        <el-table-column label="ID" align="center" prop="id" width="60" v-col="'id'" />-->
-        <el-table-column label="标识" prop="key" width="130" :show-overflow-tooltip="true" v-col="'key'" />
-        <el-table-column label="设备名称" prop="name" :show-overflow-tooltip="true" v-col="'name'" />
-        <el-table-column label="设备类型" prop="product.deviceType" :show-overflow-tooltip="true" v-col="'deviceType'" />
-        <el-table-column label="产品名称" prop="productName" :show-overflow-tooltip="true" v-col="'productName'" />
-        <!-- <el-table-column label="组织" prop="deptName" :show-overflow-tooltip="true" v-col="'deptName'"/> -->
-
+        <el-table-column label="标识" prop="key" width="130" show-overflow-tooltip v-col="'key'" />
+        <el-table-column label="设备名称" prop="name" show-overflow-tooltip v-col="'name'" />
+        <el-table-column label="设备类型" prop="product.deviceType" show-overflow-tooltip v-col="'deviceType'" />
+        <el-table-column label="产品名称" prop="productName" show-overflow-tooltip v-col="'productName'" />
         <el-table-column prop="status" label="状态" width="100" align="center" v-col="'status'">
           <template #default="scope">
             <el-tag type="info" size="small" v-if="scope.row.status == 1">离线</el-tag>
@@ -113,13 +110,10 @@
         </el-table-column>
         <el-table-column prop="createdAt" label="创建时间" align="center" width="160"
           v-col="'registryTime'"></el-table-column>
-        <!--        <el-table-column prop="lastOnlineTime" label="最后上线时间" align="center" width="150" v-col="'lastOnlineTime'"></el-table-column>-->
-        <el-table-column prop="desc" label="说明" v-col="'desc'"></el-table-column>
+        <el-table-column prop="desc" label="说明" show-overflow-tooltip v-col="'desc'"></el-table-column>
 
         <el-table-column label="操作" width="200" align="center" fixed="right">
           <template #default="scope">
-
-            <!-- <el-button size="small" text type="primary" @click="onOpenDetail(scope.row)">详情</el-button> -->
             <router-link :to="'/iotmanager/device/instance/' + scope.row.id" class="link-type"
               style="padding-right: 12px;font-size: 12px;color: #409eff;" v-auth="'detail'">
               <span>详情</span>