Ver Fonte

产品详情

yukai há 3 anos atrás
pai
commit
d58be2f634

+ 3 - 2
src/api/device/index.ts

@@ -8,11 +8,12 @@ export default {
     getList: (params: object) => get('/product/page_list', params),
     getLists: (params: object) => get('/product/list', params),
     add: (data: object) => post('/product/add', data),
-    delete: (id: number) => del('/product/del', { id }),
+    delete: (ids: number) => del('/product/del', { ids }),
     edit: (data: object) => put('/product/edit', data),
     detail: (id: number) => get('/product/detail', { id }),
     message_protocol_list: (params: object) => get('/product/protocol/message_protocol_list', params),
     trunsport_protocol_list: (params: object) => get('/product/protocol/trunsport_protocol_list', params),
+    getDataType: (params: object) => get('/product/tsl/data_type', params),
   },
   category:{
     getList: (params: object) => get('/product/category/list', params),
@@ -24,7 +25,7 @@ export default {
     getList: (params: object) => get('/product/device/page_list', params),
     add: (data: object) => post('/product/device/add', data),
     edit: (data: object) => put('/product/device/edit', data),
-    del: (id: number) => del('/product/device/del', { id }),
+    del: (ids: number) => del('/product/device/del', { ids }),
   },
   dept: {
     getList: (params: object) => get('/system/dept/tree', params),

+ 4 - 3
src/views/device/instance/component/edit.vue

@@ -2,13 +2,14 @@
 	<div class="system-edit-dic-container">
 		<el-dialog :title="(ruleForm.id!==0?'修改':'添加')+'设备'" v-model="isShowDialog" width="769px">
 			<el-form :model="ruleForm" ref="formRef" :rules="rules" size="default" label-width="110px">
+       <el-form-item label="设备标识" prop="key">
+          <el-input v-model="ruleForm.key" placeholder="请输入设备标识" />
+        </el-form-item>
         <el-form-item label="设备名称" prop="name">
           <el-input v-model="ruleForm.name" placeholder="请输入设备名称" />
         </el-form-item>
 
-         <el-form-item label="设备标识" prop="key">
-          <el-input v-model="ruleForm.key" placeholder="请输入设备标识" />
-        </el-form-item>
+        
 
            <el-form-item label="所属产品" prop="productId">
        

+ 1 - 1
src/views/device/instance/index.vue

@@ -69,7 +69,7 @@
          <el-table-column prop="lastOnlineTime" label="最后上线时间" align="center" width="180"></el-table-column> 
         <el-table-column label="操作" width="200" align="center">
           <template #default="scope">
-		   <router-link :to="'/device/instance/detail/id/' + scope.row.id" class="link-type" style="padding-right: 10px;color: #409eff;">
+		   <router-link :to="'/device/instance/detail/' + scope.row.id" class="link-type" style="padding-right: 10px;color: #409eff;">
               <span>详情</span>
             </router-link>
             <el-button size="small" text type="warning" @click="onOpenEditDic(scope.row)">修改</el-button>

+ 232 - 0
src/views/device/product/component/editAttr.vue

@@ -0,0 +1,232 @@
+<template>
+	<div class="system-edit-dic-container">
+		<el-dialog :title="(ruleForm.id!==0?'修改':'添加')+'属性'" v-model="isShowDialog" width="769px">
+			<el-form :model="ruleForm" ref="formRef" :rules="rules" size="default" label-width="90px">
+        <el-form-item label="属性标识" prop="key">
+          <el-input v-model="ruleForm.key" placeholder="请输入属性标识" />
+        </el-form-item>
+        <el-form-item label="属性名称" prop="name">
+          <el-input v-model="ruleForm.name" placeholder="请输入属性名称" />
+        </el-form-item>
+    
+    
+
+
+           
+         <el-form-item label="数据类型" prop="valueType">
+
+             <!--    <el-select v-model="ruleForm.valueType" placeholder="请选择数据类型">
+              <el-option
+                v-for="item in typeData"
+                :key="item.key"
+                :label="item.name"
+                :value="item.key"
+              />
+            </el-select> -->
+
+             <el-select v-model="ruleForm.valueType" placeholder="请选择数据类型">
+              <el-option-group
+                v-for="group in typeData"
+                :key="group"
+                :label="group"
+              >
+                <el-option
+                  v-for="item in group.options"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-option-group>
+            </el-select>
+            </el-form-item> 
+
+          
+
+      
+        <el-form-item label="是否只读" prop="accessMode">
+          <el-radio-group v-model="ruleForm.accessMode" model-value="0">
+            <el-radio label="0">读写</el-radio>
+
+            <el-radio label="1">只读</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="属性描述	" prop="desc">
+          <el-input v-model="ruleForm.desc" type="textarea" placeholder="请输入属性描述"></el-input>
+        </el-form-item>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="onCancel" size="default">取 消</el-button>
+					<el-button type="primary" @click="onSubmit" size="default">{{ruleForm.id!==0?'修 改':'添 加'}}</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, defineComponent,ref, unref } from 'vue';
+import api from '/@/api/device';
+import uploadVue from '/@/components/upload/index.vue';
+import {ElMessage,UploadProps} from "element-plus";
+
+interface RuleFormState {
+  id:number;
+  name:string;
+  dictType:string;
+  status:number;
+  desc:string;
+}
+interface DicState {
+	isShowDialog: boolean;
+	ruleForm: RuleFormState;
+  typeData: RuleFormState[];
+  rules:{}
+}
+
+export default defineComponent({
+	name: 'deviceEditPro',
+  components: { uploadVue },
+	setup(prop,{emit}) {
+    const formRef = ref<HTMLElement | null>(null);
+    const baseURL:string|undefined|boolean = import.meta.env.VITE_API_URL
+
+		const state = reactive<DicState>({
+			isShowDialog: false,
+    	typeData: [], // 
+    	
+
+			ruleForm: {
+        id:0,
+        name:'',
+        key:'',
+        transportProtocol:'',
+        accessMode:'0',
+        status:1,
+        desc:''
+			},
+      rules: {
+        name: [
+          { required: true, message: "属性名称不能为空", trigger: "blur" }
+        ],
+         key: [
+          { required: true, message: "属性标识不能为空", trigger: "blur" }
+        ],
+        accessMode: [{ required: true, message: '属性分类不能为空', trigger: 'blur' }],
+        deptId: [{ required: true, message: '所属部门不能为空', trigger: 'blur' }],
+        deviceType: [{ required: true, message: '设备类型不能为空', trigger: 'blur' }],
+      }
+		});
+
+		// 打开弹窗
+		const openDialog = (row: RuleFormState|null) => {
+      resetForm();
+   
+        api.product.getDataType({ status: -1 }).then((res: any) => {
+        
+       
+            // const  datat=Object.values(res.dataType);
+            // datat.forEach((item, index) => {
+
+            // });
+          
+                state.typeData = res.dataType || [];
+           
+         
+        });
+       
+      if (row){
+        // api.dict.getType(row.dictId).then((res:any)=>{
+        //   state.ruleForm = res.data.dictType
+        // }
+        console.log(row);
+        state.ruleForm = row;
+      }
+			state.isShowDialog = true;
+		};
+    const resetForm = ()=>{
+      state.ruleForm = {
+        id:0, 
+        name:'',
+        dictType:'',
+        status:1,
+        desc:''
+      }
+    };
+		// 关闭弹窗
+		const closeDialog = () => {
+			state.isShowDialog = false;
+		};
+		// 取消
+		const onCancel = () => {
+			closeDialog();
+		};
+		// 新增
+		const onSubmit = () => {
+      const formWrap = unref(formRef) as any;
+      if (!formWrap) return;
+      formWrap.validate((valid: boolean) => {
+        if (valid) {
+          if(state.ruleForm.id!==0){
+            //修改
+            api.product.edit(state.ruleForm).then(()=>{
+              ElMessage.success('属性类型修改成功');
+              closeDialog(); // 关闭弹窗
+              emit('typeList')
+            })
+          }else{
+            //添加
+            console.log(state.ruleForm);
+            api.product.add(state.ruleForm).then(()=>{
+              ElMessage.success('属性类型添加成功');
+              closeDialog(); // 关闭弹窗
+              emit('typeList')
+            })
+          }
+        }
+      });
+		};
+
+
+		return {
+			openDialog,
+			closeDialog,
+			onCancel,
+			onSubmit,
+      formRef,
+			...toRefs(state),
+		};
+	},
+});
+</script>
+
+<style scoped>
+.avatar-uploader .avatar {
+  width: 178px;
+  height: 178px;
+  display: block;
+}
+</style>
+
+<style>
+.avatar-uploader .el-upload {
+  border: 1px dashed var(--el-border-color);
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  transition: var(--el-transition-duration-fast);
+}
+
+.avatar-uploader .el-upload:hover {
+  border-color: var(--el-color-primary);
+}
+
+.el-icon.avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 178px;
+  height: 178px;
+  text-align: center;
+}
+</style>

+ 232 - 0
src/views/device/product/component/editEvent.vue

@@ -0,0 +1,232 @@
+<template>
+	<div class="system-edit-dic-container">
+		<el-dialog :title="(ruleForm.id!==0?'修改':'添加')+'事件定义'" v-model="isShowDialog" width="769px">
+			<el-form :model="ruleForm" ref="formRef" :rules="rules" size="default" label-width="90px">
+        <el-form-item label="事件定义标识" prop="key">
+          <el-input v-model="ruleForm.key" placeholder="请输入事件定义标识" />
+        </el-form-item>
+        <el-form-item label="事件定义名称" prop="name">
+          <el-input v-model="ruleForm.name" placeholder="请输入事件定义名称" />
+        </el-form-item>
+    
+    
+
+
+           
+         <el-form-item label="数据类型" prop="valueType">
+
+             <!--    <el-select v-model="ruleForm.valueType" placeholder="请选择数据类型">
+              <el-option
+                v-for="item in typeData"
+                :key="item.key"
+                :label="item.name"
+                :value="item.key"
+              />
+            </el-select> -->
+
+             <el-select v-model="ruleForm.valueType" placeholder="请选择数据类型">
+              <el-option-group
+                v-for="group in typeData"
+                :key="group"
+                :label="group"
+              >
+                <el-option
+                  v-for="item in group.options"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-option-group>
+            </el-select>
+            </el-form-item> 
+
+          
+
+      
+        <el-form-item label="是否只读" prop="accessMode">
+          <el-radio-group v-model="ruleForm.accessMode" model-value="0">
+            <el-radio label="0">读写</el-radio>
+
+            <el-radio label="1">只读</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="事件定义描述	" prop="desc">
+          <el-input v-model="ruleForm.desc" type="textarea" placeholder="请输入事件定义描述"></el-input>
+        </el-form-item>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="onCancel" size="default">取 消</el-button>
+					<el-button type="primary" @click="onSubmit" size="default">{{ruleForm.id!==0?'修 改':'添 加'}}</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, defineComponent,ref, unref } from 'vue';
+import api from '/@/api/device';
+import uploadVue from '/@/components/upload/index.vue';
+import {ElMessage,UploadProps} from "element-plus";
+
+interface RuleFormState {
+  id:number;
+  name:string;
+  dictType:string;
+  status:number;
+  desc:string;
+}
+interface DicState {
+	isShowDialog: boolean;
+	ruleForm: RuleFormState;
+  typeData: RuleFormState[];
+  rules:{}
+}
+
+export default defineComponent({
+	name: 'deviceEditPro',
+  components: { uploadVue },
+	setup(prop,{emit}) {
+    const formRef = ref<HTMLElement | null>(null);
+    const baseURL:string|undefined|boolean = import.meta.env.VITE_API_URL
+
+		const state = reactive<DicState>({
+			isShowDialog: false,
+    	typeData: [], // 
+    	
+
+			ruleForm: {
+        id:0,
+        name:'',
+        key:'',
+        transportProtocol:'',
+        accessMode:'0',
+        status:1,
+        desc:''
+			},
+      rules: {
+        name: [
+          { required: true, message: "事件定义名称不能为空", trigger: "blur" }
+        ],
+         key: [
+          { required: true, message: "事件定义标识不能为空", trigger: "blur" }
+        ],
+        accessMode: [{ required: true, message: '事件定义分类不能为空', trigger: 'blur' }],
+        deptId: [{ required: true, message: '所属部门不能为空', trigger: 'blur' }],
+        deviceType: [{ required: true, message: '设备类型不能为空', trigger: 'blur' }],
+      }
+		});
+
+		// 打开弹窗
+		const openDialog = (row: RuleFormState|null) => {
+      resetForm();
+   
+        api.product.getDataType({ status: -1 }).then((res: any) => {
+        
+       
+            // const  datat=Object.values(res.dataType);
+            // datat.forEach((item, index) => {
+
+            // });
+          
+                state.typeData = res.dataType || [];
+           
+         
+        });
+       
+      if (row){
+        // api.dict.getType(row.dictId).then((res:any)=>{
+        //   state.ruleForm = res.data.dictType
+        // }
+        console.log(row);
+        state.ruleForm = row;
+      }
+			state.isShowDialog = true;
+		};
+    const resetForm = ()=>{
+      state.ruleForm = {
+        id:0, 
+        name:'',
+        dictType:'',
+        status:1,
+        desc:''
+      }
+    };
+		// 关闭弹窗
+		const closeDialog = () => {
+			state.isShowDialog = false;
+		};
+		// 取消
+		const onCancel = () => {
+			closeDialog();
+		};
+		// 新增
+		const onSubmit = () => {
+      const formWrap = unref(formRef) as any;
+      if (!formWrap) return;
+      formWrap.validate((valid: boolean) => {
+        if (valid) {
+          if(state.ruleForm.id!==0){
+            //修改
+            api.product.edit(state.ruleForm).then(()=>{
+              ElMessage.success('事件定义类型修改成功');
+              closeDialog(); // 关闭弹窗
+              emit('typeList')
+            })
+          }else{
+            //添加
+            console.log(state.ruleForm);
+            api.product.add(state.ruleForm).then(()=>{
+              ElMessage.success('事件定义类型添加成功');
+              closeDialog(); // 关闭弹窗
+              emit('typeList')
+            })
+          }
+        }
+      });
+		};
+
+
+		return {
+			openDialog,
+			closeDialog,
+			onCancel,
+			onSubmit,
+      formRef,
+			...toRefs(state),
+		};
+	},
+});
+</script>
+
+<style scoped>
+.avatar-uploader .avatar {
+  width: 178px;
+  height: 178px;
+  display: block;
+}
+</style>
+
+<style>
+.avatar-uploader .el-upload {
+  border: 1px dashed var(--el-border-color);
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  transition: var(--el-transition-duration-fast);
+}
+
+.avatar-uploader .el-upload:hover {
+  border-color: var(--el-color-primary);
+}
+
+.el-icon.avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 178px;
+  height: 178px;
+  text-align: center;
+}
+</style>

+ 232 - 0
src/views/device/product/component/editFun.vue

@@ -0,0 +1,232 @@
+<template>
+	<div class="system-edit-dic-container">
+		<el-dialog :title="(ruleForm.id!==0?'修改':'添加')+'功能定义'" v-model="isShowDialog" width="769px">
+			<el-form :model="ruleForm" ref="formRef" :rules="rules" size="default" label-width="90px">
+        <el-form-item label="功能定义标识" prop="key">
+          <el-input v-model="ruleForm.key" placeholder="请输入功能定义标识" />
+        </el-form-item>
+        <el-form-item label="功能定义名称" prop="name">
+          <el-input v-model="ruleForm.name" placeholder="请输入功能定义名称" />
+        </el-form-item>
+    
+    
+
+
+           
+         <el-form-item label="数据类型" prop="valueType">
+
+             <!--    <el-select v-model="ruleForm.valueType" placeholder="请选择数据类型">
+              <el-option
+                v-for="item in typeData"
+                :key="item.key"
+                :label="item.name"
+                :value="item.key"
+              />
+            </el-select> -->
+
+             <el-select v-model="ruleForm.valueType" placeholder="请选择数据类型">
+              <el-option-group
+                v-for="group in typeData"
+                :key="group"
+                :label="group"
+              >
+                <el-option
+                  v-for="item in group.options"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-option-group>
+            </el-select>
+            </el-form-item> 
+
+          
+
+      
+        <el-form-item label="是否只读" prop="accessMode">
+          <el-radio-group v-model="ruleForm.accessMode" model-value="0">
+            <el-radio label="0">读写</el-radio>
+
+            <el-radio label="1">只读</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="功能定义描述	" prop="desc">
+          <el-input v-model="ruleForm.desc" type="textarea" placeholder="请输入功能定义描述"></el-input>
+        </el-form-item>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="onCancel" size="default">取 消</el-button>
+					<el-button type="primary" @click="onSubmit" size="default">{{ruleForm.id!==0?'修 改':'添 加'}}</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, defineComponent,ref, unref } from 'vue';
+import api from '/@/api/device';
+import uploadVue from '/@/components/upload/index.vue';
+import {ElMessage,UploadProps} from "element-plus";
+
+interface RuleFormState {
+  id:number;
+  name:string;
+  dictType:string;
+  status:number;
+  desc:string;
+}
+interface DicState {
+	isShowDialog: boolean;
+	ruleForm: RuleFormState;
+  typeData: RuleFormState[];
+  rules:{}
+}
+
+export default defineComponent({
+	name: 'deviceEditPro',
+  components: { uploadVue },
+	setup(prop,{emit}) {
+    const formRef = ref<HTMLElement | null>(null);
+    const baseURL:string|undefined|boolean = import.meta.env.VITE_API_URL
+
+		const state = reactive<DicState>({
+			isShowDialog: false,
+    	typeData: [], // 
+    	
+
+			ruleForm: {
+        id:0,
+        name:'',
+        key:'',
+        transportProtocol:'',
+        accessMode:'0',
+        status:1,
+        desc:''
+			},
+      rules: {
+        name: [
+          { required: true, message: "功能定义名称不能为空", trigger: "blur" }
+        ],
+         key: [
+          { required: true, message: "功能定义标识不能为空", trigger: "blur" }
+        ],
+        accessMode: [{ required: true, message: '功能定义分类不能为空', trigger: 'blur' }],
+        deptId: [{ required: true, message: '所属部门不能为空', trigger: 'blur' }],
+        deviceType: [{ required: true, message: '设备类型不能为空', trigger: 'blur' }],
+      }
+		});
+
+		// 打开弹窗
+		const openDialog = (row: RuleFormState|null) => {
+      resetForm();
+   
+        api.product.getDataType({ status: -1 }).then((res: any) => {
+        
+       
+            // const  datat=Object.values(res.dataType);
+            // datat.forEach((item, index) => {
+
+            // });
+          
+                state.typeData = res.dataType || [];
+           
+         
+        });
+       
+      if (row){
+        // api.dict.getType(row.dictId).then((res:any)=>{
+        //   state.ruleForm = res.data.dictType
+        // }
+        console.log(row);
+        state.ruleForm = row;
+      }
+			state.isShowDialog = true;
+		};
+    const resetForm = ()=>{
+      state.ruleForm = {
+        id:0, 
+        name:'',
+        dictType:'',
+        status:1,
+        desc:''
+      }
+    };
+		// 关闭弹窗
+		const closeDialog = () => {
+			state.isShowDialog = false;
+		};
+		// 取消
+		const onCancel = () => {
+			closeDialog();
+		};
+		// 新增
+		const onSubmit = () => {
+      const formWrap = unref(formRef) as any;
+      if (!formWrap) return;
+      formWrap.validate((valid: boolean) => {
+        if (valid) {
+          if(state.ruleForm.id!==0){
+            //修改
+            api.product.edit(state.ruleForm).then(()=>{
+              ElMessage.success('功能定义类型修改成功');
+              closeDialog(); // 关闭弹窗
+              emit('typeList')
+            })
+          }else{
+            //添加
+            console.log(state.ruleForm);
+            api.product.add(state.ruleForm).then(()=>{
+              ElMessage.success('功能定义类型添加成功');
+              closeDialog(); // 关闭弹窗
+              emit('typeList')
+            })
+          }
+        }
+      });
+		};
+
+
+		return {
+			openDialog,
+			closeDialog,
+			onCancel,
+			onSubmit,
+      formRef,
+			...toRefs(state),
+		};
+	},
+});
+</script>
+
+<style scoped>
+.avatar-uploader .avatar {
+  width: 178px;
+  height: 178px;
+  display: block;
+}
+</style>
+
+<style>
+.avatar-uploader .el-upload {
+  border: 1px dashed var(--el-border-color);
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  transition: var(--el-transition-duration-fast);
+}
+
+.avatar-uploader .el-upload:hover {
+  border-color: var(--el-color-primary);
+}
+
+.el-icon.avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 178px;
+  height: 178px;
+  text-align: center;
+}
+</style>

+ 23 - 35
src/views/device/product/component/editPro.vue

@@ -2,25 +2,18 @@
 	<div class="system-edit-dic-container">
 		<el-dialog :title="(ruleForm.id!==0?'修改':'添加')+'产品'" v-model="isShowDialog" width="769px">
 			<el-form :model="ruleForm" ref="formRef" :rules="rules" size="default" label-width="90px">
+        <el-form-item label="产品标识" prop="key">
+          <el-input v-model="ruleForm.key" placeholder="请输入产品标识" />
+        </el-form-item>
         <el-form-item label="产品名称" prop="name">
           <el-input v-model="ruleForm.name" placeholder="请输入产品名称" />
         </el-form-item>
         <el-form-item label="产品图片" prop="imageUrl">
-        <el-upload
-            name="icon"
-            class="avatar-uploader"
-            :action="singleImg"
-            :show-file-list="false"
-            :on-success="handleAvatarSuccess"
-            :before-upload="beforeAvatarUpload"
-          >
-            <img v-if="imageUrl" :src="imageUrl" class="avatar" />
-            <el-icon v-else class="avatar-uploader-icon"><ele-Plus /></el-icon>
-          </el-upload>
-        </el-form-item>
-         <el-form-item label="产品标识" prop="key">
-          <el-input v-model="ruleForm.key" placeholder="请输入产品标识" />
+     
+                     <uploadVue @set-img="handleAvatarSuccess" ></uploadVue>
+
         </el-form-item>
+       
         <el-form-item label="产品分类" prop="categoryId">
               <el-cascader :options="cateData" :props="{ checkStrictly: true,emitPath: false, value: 'id', label: 'name' }" placeholder="请选择分类" clearable class="w100" v-model="ruleForm.categoryId">
                 <template #default="{ node, data }">
@@ -68,9 +61,10 @@
 
       
         <el-form-item label="设备类型" prop="deviceType">
-          <el-radio-group v-model="ruleForm.deviceType">
-            <el-radio label="网关" >网关</el-radio>
-            <el-radio label="设备" >设备</el-radio>
+          <el-radio-group v-model="ruleForm.deviceType" model-value="设备">
+            <el-radio label="设备">设备</el-radio>
+
+            <el-radio label="网关">网关</el-radio>
           </el-radio-group>
         </el-form-item>
         <el-form-item label="产品描述	" prop="desc">
@@ -90,13 +84,13 @@
 <script lang="ts">
 import { reactive, toRefs, defineComponent,ref, unref } from 'vue';
 import api from '/@/api/device';
+import uploadVue from '/@/components/upload/index.vue';
 import {ElMessage,UploadProps} from "element-plus";
 
 interface RuleFormState {
   id:number;
   name:string;
   dictType:string;
-  deviceType:string;
   status:number;
   desc:string;
 }
@@ -112,6 +106,7 @@ interface DicState {
 
 export default defineComponent({
 	name: 'deviceEditPro',
+  components: { uploadVue },
 	setup(prop,{emit}) {
     const formRef = ref<HTMLElement | null>(null);
     const baseURL:string|undefined|boolean = import.meta.env.VITE_API_URL
@@ -132,7 +127,7 @@ export default defineComponent({
         deptId:'',
         messageProtocol:'',
         transportProtocol:'',
-        deviceType:'网关',
+        deviceType:'设备',
         status:1,
         desc:''
 			},
@@ -151,25 +146,19 @@ export default defineComponent({
       }
 		});
 
+
+
+
     const handleAvatarSuccess: UploadProps['onSuccess'] = (
-      response,
-      uploadFile
-    ) => {
+      response    ) => {
 
-      state.imageUrl = response.data.name
-        state.ruleForm.imageUrl=response.data.name
-    }
+	console.log( response);
 
-    const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
-      if (rawFile.type !== 'image/jpeg') {
-        ElMessage.error('Avatar picture must be JPG format!')
-        return false
-      } else if (rawFile.size / 1024 / 1024 > 2) {
-        ElMessage.error('Avatar picture size can not exceed 2MB!')
-        return false
-      }
-      return true
+         state.imageUrl = response
+        state.ruleForm.imageUrl=response
     }
+
+
 		// 打开弹窗
 		const openDialog = (row: RuleFormState|null) => {
       resetForm();
@@ -241,7 +230,6 @@ export default defineComponent({
 		return {
 			openDialog,
       handleAvatarSuccess,
-      beforeAvatarUpload,
 			closeDialog,
 			onCancel,
 			onSubmit,

+ 232 - 0
src/views/device/product/component/editTab.vue

@@ -0,0 +1,232 @@
+<template>
+	<div class="system-edit-dic-container">
+		<el-dialog :title="(ruleForm.id!==0?'修改':'添加')+'标签定义'" v-model="isShowDialog" width="769px">
+			<el-form :model="ruleForm" ref="formRef" :rules="rules" size="default" label-width="90px">
+        <el-form-item label="标签定义标识" prop="key">
+          <el-input v-model="ruleForm.key" placeholder="请输入标签定义标识" />
+        </el-form-item>
+        <el-form-item label="标签定义名称" prop="name">
+          <el-input v-model="ruleForm.name" placeholder="请输入标签定义名称" />
+        </el-form-item>
+    
+    
+
+
+           
+         <el-form-item label="数据类型" prop="valueType">
+
+             <!--    <el-select v-model="ruleForm.valueType" placeholder="请选择数据类型">
+              <el-option
+                v-for="item in typeData"
+                :key="item.key"
+                :label="item.name"
+                :value="item.key"
+              />
+            </el-select> -->
+
+             <el-select v-model="ruleForm.valueType" placeholder="请选择数据类型">
+              <el-option-group
+                v-for="group in typeData"
+                :key="group"
+                :label="group"
+              >
+                <el-option
+                  v-for="item in group.options"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                />
+              </el-option-group>
+            </el-select>
+            </el-form-item> 
+
+          
+
+      
+        <el-form-item label="是否只读" prop="accessMode">
+          <el-radio-group v-model="ruleForm.accessMode" model-value="0">
+            <el-radio label="0">读写</el-radio>
+
+            <el-radio label="1">只读</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="标签定义描述	" prop="desc">
+          <el-input v-model="ruleForm.desc" type="textarea" placeholder="请输入标签定义描述"></el-input>
+        </el-form-item>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="onCancel" size="default">取 消</el-button>
+					<el-button type="primary" @click="onSubmit" size="default">{{ruleForm.id!==0?'修 改':'添 加'}}</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, defineComponent,ref, unref } from 'vue';
+import api from '/@/api/device';
+import uploadVue from '/@/components/upload/index.vue';
+import {ElMessage,UploadProps} from "element-plus";
+
+interface RuleFormState {
+  id:number;
+  name:string;
+  dictType:string;
+  status:number;
+  desc:string;
+}
+interface DicState {
+	isShowDialog: boolean;
+	ruleForm: RuleFormState;
+  typeData: RuleFormState[];
+  rules:{}
+}
+
+export default defineComponent({
+	name: 'deviceEditPro',
+  components: { uploadVue },
+	setup(prop,{emit}) {
+    const formRef = ref<HTMLElement | null>(null);
+    const baseURL:string|undefined|boolean = import.meta.env.VITE_API_URL
+
+		const state = reactive<DicState>({
+			isShowDialog: false,
+    	typeData: [], // 
+    	
+
+			ruleForm: {
+        id:0,
+        name:'',
+        key:'',
+        transportProtocol:'',
+        accessMode:'0',
+        status:1,
+        desc:''
+			},
+      rules: {
+        name: [
+          { required: true, message: "标签定义名称不能为空", trigger: "blur" }
+        ],
+         key: [
+          { required: true, message: "标签定义标识不能为空", trigger: "blur" }
+        ],
+        accessMode: [{ required: true, message: '标签定义分类不能为空', trigger: 'blur' }],
+        deptId: [{ required: true, message: '所属部门不能为空', trigger: 'blur' }],
+        deviceType: [{ required: true, message: '设备类型不能为空', trigger: 'blur' }],
+      }
+		});
+
+		// 打开弹窗
+		const openDialog = (row: RuleFormState|null) => {
+      resetForm();
+   
+        api.product.getDataType({ status: -1 }).then((res: any) => {
+        
+       
+            // const  datat=Object.values(res.dataType);
+            // datat.forEach((item, index) => {
+
+            // });
+          
+                state.typeData = res.dataType || [];
+           
+         
+        });
+       
+      if (row){
+        // api.dict.getType(row.dictId).then((res:any)=>{
+        //   state.ruleForm = res.data.dictType
+        // }
+        console.log(row);
+        state.ruleForm = row;
+      }
+			state.isShowDialog = true;
+		};
+    const resetForm = ()=>{
+      state.ruleForm = {
+        id:0, 
+        name:'',
+        dictType:'',
+        status:1,
+        desc:''
+      }
+    };
+		// 关闭弹窗
+		const closeDialog = () => {
+			state.isShowDialog = false;
+		};
+		// 取消
+		const onCancel = () => {
+			closeDialog();
+		};
+		// 新增
+		const onSubmit = () => {
+      const formWrap = unref(formRef) as any;
+      if (!formWrap) return;
+      formWrap.validate((valid: boolean) => {
+        if (valid) {
+          if(state.ruleForm.id!==0){
+            //修改
+            api.product.edit(state.ruleForm).then(()=>{
+              ElMessage.success('标签定义类型修改成功');
+              closeDialog(); // 关闭弹窗
+              emit('typeList')
+            })
+          }else{
+            //添加
+            console.log(state.ruleForm);
+            api.product.add(state.ruleForm).then(()=>{
+              ElMessage.success('标签定义类型添加成功');
+              closeDialog(); // 关闭弹窗
+              emit('typeList')
+            })
+          }
+        }
+      });
+		};
+
+
+		return {
+			openDialog,
+			closeDialog,
+			onCancel,
+			onSubmit,
+      formRef,
+			...toRefs(state),
+		};
+	},
+});
+</script>
+
+<style scoped>
+.avatar-uploader .avatar {
+  width: 178px;
+  height: 178px;
+  display: block;
+}
+</style>
+
+<style>
+.avatar-uploader .el-upload {
+  border: 1px dashed var(--el-border-color);
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  transition: var(--el-transition-duration-fast);
+}
+
+.avatar-uploader .el-upload:hover {
+  border-color: var(--el-color-primary);
+}
+
+.el-icon.avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 178px;
+  height: 178px;
+  text-align: center;
+}
+</style>

+ 356 - 0
src/views/device/product/detail.vue

@@ -0,0 +1,356 @@
+<template>
+	<div class="system-dic-container">
+		<div class="content">
+			<div class="cont_box">
+				<div class="title">产品:{{ detail.name }}</div>
+				<div class="pro-status"><span class="on"></span>已发布</div>
+				<div class="pro-option">停用</div>
+			</div>
+		</div>
+
+		<div class="content-box">
+			<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+				<el-tab-pane label="产品信息" name="1">
+					<div class="pro-box">
+						<div class="protitle">产品信息</div>
+						<el-button type="" :icon="Edit" class="buttonedit" @click="onOpenEditDic(detail)">编辑</el-button>
+					</div>
+
+					<div class="ant-descriptions-view">
+						<table>
+							<tbody>
+								<tr class="ant-descriptions-row">
+									<th class="ant-descriptions-item-label ant-descriptions-item-colon">产品名称</th>
+									<td class="ant-descriptions-item-content" colspan="1">{{ detail.name }}</td>
+									<th class="ant-descriptions-item-label ant-descriptions-item-colon">所属品类</th>
+									<td class="ant-descriptions-item-content" colspan="1">{{ detail.categoryName }}</td>
+									<th class="ant-descriptions-item-label ant-descriptions-item-colon">所属部门</th>
+									<td class="ant-descriptions-item-content" colspan="1">{{ detail.deptName }}</td>
+								</tr>
+								<tr class="ant-descriptions-row">
+									<th class="ant-descriptions-item-label ant-descriptions-item-colon">消息协议</th>
+									<td class="ant-descriptions-item-content" colspan="1">{{ detail.messageProtocol }}</td>
+									<th class="ant-descriptions-item-label ant-descriptions-item-colon">链接协议</th>
+									<td class="ant-descriptions-item-content" colspan="1">{{ detail.transportProtocol }}</td>
+									<th class="ant-descriptions-item-label ant-descriptions-item-colon">设备类型</th>
+									<td class="ant-descriptions-item-content" colspan="1">{{ detail.deviceType }}</td>
+								</tr>
+								<tr class="ant-descriptions-row">
+									<th class="ant-descriptions-item-label ant-descriptions-item-colon">描述</th>
+									<td class="ant-descriptions-item-content" colspan="5">{{ detail.desc }}</td>
+								</tr>
+							</tbody>
+						</table>
+					</div>
+				</el-tab-pane>
+				<el-tab-pane label="物模型" name="2">
+					<div class="wu-box">
+						<el-tabs type="border-card">
+							<el-tab-pane label="属性定义">
+								<div class="wu-title">
+									<div class="title">属性定义</div>
+									<div><el-button type="primary" @click="onOpenEditAttr()">添加</el-button></div>
+								</div>
+
+								<el-table style="width: 100%">
+									<el-table-column label="属性标识" align="center" prop="id" />
+									<el-table-column label="属性名称" prop="name" :show-overflow-tooltip="true" />
+									<el-table-column label="数据类型" prop="key" :show-overflow-tooltip="true" />
+									<el-table-column label="属性值来源" prop="categoryName" :show-overflow-tooltip="true" />
+									<el-table-column label="是否只读" prop="deptName" :show-overflow-tooltip="true" />
+									<el-table-column label="说明" prop="messageProtocol" :show-overflow-tooltip="true" />
+									<el-table-column label="操作" width="300" align="center">
+										<template #default="scope">
+											<el-button size="small" text type="warning">修改</el-button>
+											<el-button size="small" text type="danger">删除</el-button>
+										</template>
+									</el-table-column>
+								</el-table>
+							</el-tab-pane>
+							<el-tab-pane label="功能定义">
+								<div class="wu-title">
+									<div class="title">功能定义</div>
+									<div><el-button type="primary" @click="onOpenEditFun()">添加</el-button></div>
+								</div>
+
+								<el-table style="width: 100%">
+									<el-table-column label="功能标识" align="center" prop="id" />
+									<el-table-column label="名称" prop="name" :show-overflow-tooltip="true" />
+									<el-table-column label="是否异步" prop="key" :show-overflow-tooltip="true" />
+									<el-table-column label="描述" prop="categoryName" :show-overflow-tooltip="true" />
+									<el-table-column label="操作" width="300" align="center">
+										<template #default="scope">
+											<el-button size="small" text type="warning">修改</el-button>
+											<el-button size="small" text type="danger">删除</el-button>
+										</template>
+									</el-table-column>
+								</el-table>
+							</el-tab-pane>
+							<el-tab-pane label="事件定义">
+								<div class="wu-title">
+									<div class="title">事件定义</div>
+									<div><el-button type="primary" @click="onOpenEditEvent()">添加</el-button></div>
+								</div>
+
+								<el-table style="width: 100%">
+									<el-table-column label="事件标识" align="center" prop="id" />
+									<el-table-column label="名称" prop="name" :show-overflow-tooltip="true" />
+									<el-table-column label="事件级别" prop="key" :show-overflow-tooltip="true" />
+									<el-table-column label="描述" prop="categoryName" :show-overflow-tooltip="true" />
+									
+									<el-table-column label="操作" width="300" align="center">
+										<template #default="scope">
+											<el-button size="small" text type="warning">修改</el-button>
+											<el-button size="small" text type="danger">删除</el-button>
+										</template>
+									</el-table-column>
+								</el-table></el-tab-pane
+							>
+							<el-tab-pane label="标签定义"
+								><div class="wu-title">
+									<div class="title">标签定义</div>
+									<div><el-button type="primary" @click="onOpenEditTab()">添加</el-button></div>
+								</div>
+
+								<el-table style="width: 100%">
+									<el-table-column label="属性标识" align="center" prop="id" />
+									<el-table-column label="属性名称" prop="name" :show-overflow-tooltip="true" />
+									<el-table-column label="数据类型" prop="key" :show-overflow-tooltip="true" />
+									<el-table-column label="属性值来源" prop="categoryName" :show-overflow-tooltip="true" />
+									<el-table-column label="是否只读" prop="deptName" :show-overflow-tooltip="true" />
+									<el-table-column label="说明" prop="messageProtocol" :show-overflow-tooltip="true" />
+									<el-table-column label="操作" width="300" align="center">
+										<template #default="scope">
+											<el-button size="small" text type="warning">修改</el-button>
+											<el-button size="small" text type="danger">删除</el-button>
+										</template>
+									</el-table-column>
+								</el-table></el-tab-pane
+							>
+						</el-tabs>
+					</div>
+				</el-tab-pane>
+			</el-tabs>
+		</div>
+		<EditDic ref="editDicRef" @typeList="typeList" />
+		<EditAttr ref="editAttrRef" @typeList="typeList" />
+		<EditFun ref="editFunRef" @typeList="typeList" />
+		<EditEvent ref="editEventRef" @typeList="typeList" />
+		<EditTab ref="editTabRef" @typeList="typeList" />
+	</div>
+</template>
+<script lang="ts">
+import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
+import { Delete, Edit, Search, Share, Upload } from '@element-plus/icons-vue';
+import EditDic from './component/editPro.vue';
+import EditAttr from './component/editAttr.vue';
+import EditFun from './component/editFun.vue';
+import EditEvent from './component/editEvent.vue';
+import EditTab from './component/editTab.vue';
+
+import { useRoute } from 'vue-router';
+
+import api from '/@/api/device';
+
+export default defineComponent({
+	name: 'deviceEditPro',
+	components: { EditDic,EditAttr,EditFun,EditEvent,EditTab },
+
+	setup(prop, context) {
+		const route = useRoute();
+		const editDicRef = ref();
+		const editAttrRef = ref();
+		const editFunRef = ref();
+		const editEventRef = ref();
+		const editTabRef = ref();
+		const state = reactive<DicState>({
+			isShowDialog: false,
+			activeName: '2', // 分类数据
+			detail: [],
+		});
+
+		onMounted(() => {
+			const ids = route.params && route.params.id;
+			api.product.detail(ids).then((res: any) => {
+				state.detail = res.data;
+			});
+		});
+
+		//打开添加属性弹窗
+		const onOpenEditAttr = () => {
+			editAttrRef.value.openDialog({product_id:route.params.id,id:0});
+		};
+
+		//打开添加功能弹窗
+		const onOpenEditFun = () => {
+			editFunRef.value.openDialog({product_id:route.params.id,id:0});
+		};
+		//打开添加事件弹窗
+		const onOpenEditEvent = () => {
+			editEventRef.value.openDialog({product_id:route.params.id,id:0});
+		};
+
+		//打开添加事件弹窗
+		const onOpenEditTab = () => {
+			editTabRef.value.openDialog({product_id:route.params.id,id:0});
+		};
+
+
+
+		// 打开修改产品弹窗
+		const onOpenEditDic = (row: TableDataRow) => {
+			editDicRef.value.openDialog(row);
+		};
+
+		const handleClick = (tab: TabsPaneContext, event: Event) => {
+			console.log(tab, event);
+		};
+
+		return {
+			Edit,
+			editDicRef,
+			editAttrRef,
+			editFunRef,
+			editEventRef,
+			editTabRef,
+			onOpenEditTab,
+			onOpenEditEvent,
+			onOpenEditAttr,
+			onOpenEditFun,
+			onOpenEditDic,
+			handleClick,
+			...toRefs(state),
+		};
+	},
+});
+</script>
+  <style>
+.content {
+	background: #fff;
+	width: 100%;
+	padding: 20px;
+}
+.content-box {
+	background: #fff;
+	width: 100%;
+	padding: 20px;
+	margin-top: 20px;
+}
+.cont_box {
+	display: flex;
+}
+.cont_box .title {
+	font-size: 24px;
+}
+.cont_box .pro-status {
+	line-height: 40px;
+	margin-left: 30px;
+}
+.cont_box .pro-status .on {
+	background: #52c41a;
+}
+.cont_box .pro-status .off {
+	background: #c41a1a;
+}
+.cont_box .pro-status span {
+	position: relative;
+	top: -1px;
+	display: inline-block;
+	width: 6px;
+	height: 6px;
+	vertical-align: middle;
+	border-radius: 50%;
+	margin-right: 5px;
+}
+.cont_box .pro-option {
+	line-height: 40px;
+	margin-left: 10px;
+	color: #1890ff;
+}
+.content-box .pro-box {
+	display: flex;
+	padding: 10px;
+}
+.content-box .pro-box .protitle {
+	font-size: 18px;
+	font-weight: bold;
+	line-height: 35px;
+}
+.content-box .pro-box .buttonedit {
+	border: 0px;
+	color: #1890ff;
+}
+table {
+	border-collapse: collapse;
+	text-indent: initial;
+	border-spacing: 2px;
+}
+tbody {
+	box-sizing: border-box;
+	display: table-row-group;
+	vertical-align: middle;
+	border-color: inherit;
+}
+
+tr {
+	display: table-row;
+	vertical-align: inherit;
+	border-color: inherit;
+}
+.ant-descriptions-view {
+	width: 100%;
+	overflow: hidden;
+	border-radius: 4px;
+}
+.ant-descriptions-view {
+	border: 1px solid #e8e8e8;
+}
+.ant-descriptions-view table {
+	width: 100%;
+	table-layout: fixed;
+}
+.ant-descriptions-view > table {
+	table-layout: auto;
+}
+.ant-descriptions-row {
+	border-bottom: 1px solid #e8e8e8;
+}
+.ant-descriptions-item-label {
+	color: rgba(0, 0, 0, 0.85);
+	font-weight: 400;
+	font-size: 14px;
+	line-height: 1.5;
+}
+.ant-descriptions-item-label {
+	padding: 16px 24px;
+	border-right: 1px solid #e8e8e8;
+}
+.ant-descriptions-item-label {
+	background-color: #fafafa;
+}
+.ant-descriptions-item-content {
+	padding: 16px 24px;
+	border-right: 1px solid #e8e8e8;
+	display: table-cell;
+	color: rgba(0, 0, 0, 0.65);
+	font-size: 14px;
+	line-height: 1.5;
+}
+.wu-box {
+	border: #e8e8e8 solid 1px;
+	padding: 20px;
+	width: 100%;
+}
+.wu-box .wu-title {
+	display: flex;
+	flex-direction: row;
+	justify-content: space-between;
+	padding: 20px;
+	border-bottom: #e8e8e8 1px solid;
+}
+.wu-box .wu-title .title {
+	font-size: 18px;
+}
+</style>
+
+

+ 4 - 1
src/views/device/product/index.vue

@@ -64,8 +64,11 @@
           </template>
         </el-table-column>
         <!-- <el-table-column prop="createdAt" label="创建时间" align="center" width="180"></el-table-column> -->
-        <el-table-column label="操作" width="100" align="center">
+        <el-table-column label="操作" width="300" align="center">
           <template #default="scope">
+		     <router-link :to="'/device/product/detail/' + scope.row.id" class="link-type" style="padding-right: 10px;color: #409eff;">
+              <span>详情</span>
+            </router-link>
             <el-button size="small" text type="warning" @click="onOpenEditDic(scope.row)">修改</el-button>
             <el-button size="small" text type="danger" @click="onRowDel(scope.row)">删除</el-button>
           </template>