فهرست منبع

更改目录 资产管理,完善档案属性

yukai 1 سال پیش
والد
کامیت
989845739b

+ 130 - 0
src/views/iot/property/attribute/edit.vue

@@ -0,0 +1,130 @@
+<template>
+	<el-dialog
+		class="api-edit"
+		v-model="showDialog"
+		:title="`${formData.id ? '编辑设备档案属性' : '新增设备档案属性'}`"
+		width="800px"
+		:close-on-click-modal="false"
+		:close-on-press-escape="false"
+	>
+		<el-form class="inline-form" ref="formRef" :model="formData" :rules="ruleForm" label-width="120px">
+			<el-form-item label="所属产品" prop="productKey">
+				<el-select v-model="formData.productKey" placeholder="请选择产品" class="w100" clearable>
+					<el-option v-for="item in productData" :key="item.key" :label="item.name" :value="item.key">
+						<span style="float: left">{{ item.name }}</span>
+						<span style="float: right; font-size: 13px">{{ item.key }}</span>
+					</el-option>
+				</el-select>
+			</el-form-item>
+			<el-form-item label="字段名称" prop="name">
+				<el-input v-model.trim="formData.name" placeholder="请输入字段名称" />
+			</el-form-item>
+			<el-form-item label="字段标题" prop="title">
+				<el-input v-model.trim="formData.title" placeholder="请输入字段标题" />
+			</el-form-item>
+			<el-form-item label="字段类型" prop="types">
+						<el-select v-model="formData.types" placeholder="请字段类型" class="w100" clearable>
+							<el-option v-for="item in typesData" :key="item.value" :label="item.name" :value="item.value">
+						</el-option>
+						</el-select>
+					</el-form-item>
+
+			<el-form-item label="字段描述" prop="desc">
+				<el-input v-model.trim="formData.desc" placeholder="请输入字段描述" />
+			</el-form-item>
+		</el-form>
+
+		<template #footer>
+			<div class="dialog-footer">
+				<el-button @click="showDialog = false">取消</el-button>
+				<el-button type="primary" @click="onSubmit">确定</el-button>
+			</div>
+		</template>
+	</el-dialog>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, nextTick } from 'vue'
+import api from '/@/api/device'
+import { ruleRequired } from '/@/utils/validator'
+import { ElMessage } from 'element-plus'
+
+const emit = defineEmits(['getList'])
+
+const showDialog = ref(false)
+const formRef = ref()
+const productData=ref();
+const typesData = ref([{
+	value:'input',
+	name:'输入框',
+},{
+	value:'textarea',
+	name:'文本框',
+},{
+	value:'date',
+	name:'日期',
+},{
+	value:'file',
+	name:'上传文件',
+}])
+const baseForm = {
+	id: undefined,
+	name: '',
+	productKey: '',
+	title: '',
+	types: '',
+	desc: '',
+}
+
+const formData = reactive({
+	...baseForm,
+})
+
+const ruleForm = {
+	name: [ruleRequired('字段名称不能为空')],
+	title: [ruleRequired('字段标题不能为空')],
+	productKey: [ruleRequired('所属产品不能为空')],
+	types: [ruleRequired('字段类型不能为空')],
+}
+
+
+const onSubmit = async () => {
+	await formRef.value.validate()
+
+	const theApi = formData.id ? api.dev_asset_metadata.edit : api.dev_asset_metadata.add
+
+	await theApi(formData)
+
+	ElMessage.success('操作成功')
+	resetForm()
+	showDialog.value = false
+	emit('getList')
+}
+
+const resetForm = async () => {
+	Object.assign(formData, { ...baseForm })
+	formRef.value && formRef.value.resetFields()
+}
+
+const open = async (row: any, productInfo: any) => {
+	resetForm()
+	showDialog.value = true
+	nextTick(() => {
+		Object.assign(formData, { ...row })
+
+		//获取 所有的产品
+		api.product.getLists({}).then((res: any) => {
+			productData.value = res.product
+		})
+	
+		formData.productKey = productInfo.key
+	})
+}
+
+defineExpose({ open })
+</script>
+<style scoped lang="scss">
+.demo-form-inline .el-input {
+	--el-input-width: 320px;
+}
+</style>

+ 193 - 0
src/views/iot/property/attribute/index.vue

@@ -0,0 +1,193 @@
+<template>
+	<el-card shadow="hover">
+		<div class="search">
+			<el-form :inline="true" ref="queryRef" @keyup.enter="getList(1)">
+				<el-form-item label="名称:" prop="keyWord">
+					<el-input v-model="params.keyWord" placeholder="请输入名称" clearable size="default" style="width: 240px" />
+				</el-form-item>
+
+				<el-form-item>
+					<el-button size="default" type="primary" class="ml10" @click="getList(1)">
+						<el-icon>
+							<ele-Search />
+						</el-icon>
+						查询
+					</el-button>
+				</el-form-item>
+				<el-form-item>
+					<el-button type="success" @click="addOrEdit()" v-if="productIno">
+						<el-icon>
+							<ele-FolderAdd />
+						</el-icon>
+						新增属性
+					</el-button>
+
+				
+
+					<!-- <el-button type="danger" @click="addOrEdit()">
+						<el-icon>
+							<ele-FolderAdd />
+						</el-icon>
+						删除
+					</el-button> -->
+				</el-form-item>
+			</el-form>
+		</div>
+		<el-row>
+			<el-col :span="6">
+				<el-tree :data="mergedData" :props="defaultProps" accordion default-expand-all	 @node-click="handleNodeClick" style="border: 1px solid #eee;padding: 10px;margin-right: 10px;">
+					<template #default="{ node, data }">
+						<span :style="data.is_type === '2' ? { color: '#409eff' } : {}">
+							<el-icon  v-if="data.is_type == '2'"><Expand /></el-icon>
+						{{ node.label }}
+						</span>
+					</template>
+					</el-tree>
+			</el-col>
+			<el-col :span="18"><el-table :data="tableData" style="width: 100%" row-key="id" v-loading="loading">
+					<el-table-column prop="id" label="ID" min-width="100" show-overflow-tooltip></el-table-column>
+					<el-table-column prop="name" label="字段名称" show-overflow-tooltip></el-table-column>
+					<el-table-column prop="title" label="字段标题" show-overflow-tooltip></el-table-column>
+					<el-table-column prop="types" label="字段类型" show-overflow-tooltip></el-table-column>
+					
+
+					<el-table-column prop="createdAt" label="创建时间" width="160" align="center"></el-table-column>
+					<el-table-column label="操作" width="200" align="center">
+						<template #default="scope">
+						
+							<el-button size="small" text type="warning" 
+								@click="addOrEdit(scope.row)">编辑</el-button>
+
+							<el-button size="small" text type="info"  @click="del(scope.row)">删除</el-button>
+						</template>
+					</el-table-column>
+				</el-table>
+				<pagination v-if="params.total" :total="params.total" v-model:page="params.pageNum"
+					v-model:limit="params.pageSize" @pagination="getList()" />
+			</el-col>
+		</el-row>
+
+		<EditForm ref="editFormRef" @getList="getList(1)"></EditForm>
+	</el-card>
+</template>
+
+<script lang="ts" setup>
+import device from '/@/api/device'
+import { useSearch } from '/@/hooks/useCommon'
+import {  Expand } from '@element-plus/icons-vue';
+
+import { ElMessageBox, ElMessage } from 'element-plus'
+import EditForm from './edit.vue'
+interface Tree {
+  label: string
+  children?: Tree[]
+}
+import { ref,onMounted} from 'vue'
+import { useRouter } from 'vue-router'
+const defaultProps = {
+  children: 'children',
+  label: 'label',
+}
+
+const queryRef = ref()
+const router = useRouter()
+const productData = ref([])
+const mergedData = ref()
+const cateData = ref()
+const editFormRef = ref()
+const productIno=ref();
+
+
+const { params, tableData, getList, loading } = useSearch<any[]>(device.dev_asset_metadata.getList, 'Data', { keyWord: '' })
+getList()
+const toDetail = (id: number) => {
+	router.push(`/device/dossier/manage/${id}`)
+}
+onMounted(() => {
+	getCateList()
+
+});
+const addOrEdit = async (row?: any) => {
+	if (row) {
+		editFormRef.value.open(row,productIno.value)
+		return
+	} else {
+		editFormRef.value.open({},productIno.value)
+	}
+}
+
+
+const getCateList = () => {
+	device.category.getList({}).then((res: any) => {
+		cateData.value = res.category;
+
+		device.product.getLists({}).then((res: any) => {
+			productData.value = res.product;
+			mergedData.value = matchProductsToCategories(productData.value, cateData.value);
+		})
+
+	})
+}
+
+const handleNodeClick = (data: any) => {
+	if(data.is_type==='2'){
+		productIno.value=data;
+	}else{
+		productIno.value='';
+
+	}
+}
+
+const matchProductsToCategories = (productData:any, cateData:any) => {
+  const treeData = []
+  for (let category of cateData) {
+    const treeNode = buildTree(category, productData)
+    treeData.push(treeNode)
+  }
+  return treeData
+}
+
+const buildTree = (category:any, productData:any) => {
+  const treeNode = {
+    id: category.id,
+    label: category.name,
+	key: category.key,
+    is_type: '1', // 1是分类
+    children: [],
+  }
+
+  if (category.children && category.children.length > 0) {
+    for (let child of category.children) {
+      const childNode = buildTree(child, productData)
+      treeNode.children.push(childNode)
+    }
+  } else {
+    const products = productData.filter((product:any) => product.categoryId === category.id)
+    for (let product of products) {
+      const productNode = {
+        id: product.id,
+        label: product.name,
+        key: product.key,
+        is_type: '2', // 2是产品
+      }
+      treeNode.children.push(productNode)
+    }
+  }
+
+  return treeNode
+}
+
+const del = (row: any) => {
+	ElMessageBox.confirm('是否确认删除名称为:"' + row.name + '"的数据项?', '提示', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+	}).then(async () => {
+		await device.dev_asset_metadata.delete(row.id)
+		ElMessage.success('删除成功')
+		getList()
+	})
+}
+getCateList()
+
+</script>

+ 43 - 19
src/views/iot/device/dossier/edit.vue → src/views/iot/property/dossier/edit.vue

@@ -5,28 +5,32 @@
 
 			<el-row>
 				<el-col :span="12">
-					<el-form-item label="选择产品" prop="name">
-						<el-select v-model="formData.name" placeholder="请选择产品" class="w100" clearable>
-							<el-option label="Zone one" value="shanghai" />
-							<el-option label="Zone two" value="beijing" />
+					<el-form-item label="选择产品" prop="productKey">
+						<el-select v-model="formData.productKey" placeholder="请选择产品" class="w100" clearable>
+							<el-option v-for="item in productData" :key="item.key" :label="item.name" :value="item.key">
+							<span style="float: left">{{ item.name }}</span>
+							<span style="float: right; font-size: 13px">{{ item.key }}</span>
+						</el-option>
 						</el-select>
 					</el-form-item>
 				</el-col>
 
 				<el-col :span="12">
-					<el-form-item label="选择设备" prop="name">
-						<el-select v-model="formData.name" placeholder="请选择设备" class="w100" clearable>
-							<el-option label="Zone one" value="shanghai" />
-							<el-option label="Zone two" value="beijing" />
-						</el-select>
+					<el-form-item label="选择设备" prop="deviceKey">
+						<el-select v-model="formData.deviceKey" placeholder="请选择设备" class="w100" clearable @change="handleSelectionChange">
+							<el-option v-for="item in deviceList" :key="item.key" :label="item.name" :value="item.key">
+							<span style="float: left">{{ item.name }}</span>
+							<span style="float: right; font-size: 13px">{{ item.key }}</span>
+						</el-option>
+					</el-select>
 					</el-form-item>
 				</el-col>
 			</el-row>
 
 			<el-row>
 				<el-col :span="12">
-					<el-form-item label="设备ID" prop="name">
-						<el-input v-model.trim="formData.name" placeholder="请输入场景名称" />
+					<el-form-item label="设备名称" prop="deviceName">
+						<el-input v-model.trim="formData.deviceName" placeholder="请输入设备名称" />
 					</el-form-item>
 				</el-col>
 
@@ -43,7 +47,7 @@
 					<el-form-item label="所属区域" prop="area">
 						<el-cascader :options="orgData"
 							:props="{ checkStrictly: true, emitPath: false, value: 'id', label: 'name' }"
-							placeholder="请选择区域" clearable class="w100" v-model="ruleForm.area">
+							placeholder="请选择区域" clearable class="w100" v-model="formData.area">
 							<template #default="{ node, data }">
 								<span>{{ data.name }}</span>
 								<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
@@ -174,7 +178,7 @@
 
 <script lang="ts" setup>
 import { ref, reactive, nextTick } from 'vue';
-import api from '/@/api/scene';
+import api from '/@/api/device'
 import system from '/@/api/system';
 
 import { ruleRequired } from '/@/utils/validator';
@@ -185,11 +189,14 @@ const emit = defineEmits(['getList']);
 const showDialog = ref(false);
 const formRef = ref();
 const orgData = ref();
-
+const deviceList=ref();
+const productData=ref();
 const baseForm = {
 	id: undefined,
-	name: '',
-	sceneType: "device",
+	productKey: '',
+	deviceKey:'',
+	deviceName:'',
+	area: "",
 	description: '',
 
 };
@@ -201,11 +208,19 @@ const formData = reactive({
 const ruleForm = {
 	name: [ruleRequired('场景名称不能为空')],
 };
+const handleSelectionChange=(value:any)=> {
+      const selectedOption = deviceList.value.find(option => option.key === value);
+      if (selectedOption) {
+        formData.deviceName = selectedOption.name;
+      } else {
+        formData.deviceName = '';
+      }
+ }
 
 const onSubmit = async () => {
 	await formRef.value.validate();
 
-	const theApi = formData.id ? api.manage.edit : api.manage.add;
+	const theApi = formData.id ? api.dev_asset.edit : api.dev_asset.add;
 
 	await theApi(formData);
 
@@ -220,14 +235,23 @@ const resetForm = async () => {
 	formRef.value && formRef.value.resetFields();
 };
 
-const open = async (row: any) => {
+const open = async (row: any,productInfo:any) => {
 	resetForm();
-	showDialog.value = true;
+	showDialog.value = true;		
 	nextTick(() => {
 		Object.assign(formData, { ...row });
 		system.org.getList({ status: 1 }).then((res: any) => {
 			orgData.value = res || [];
 		});
+		//获取 所有的产品
+		api.product.getLists({}).then((res: any) => {
+			productData.value = res.product;
+		})
+		//根据产品ID获取设备列表
+		api.device.allList({ productId: productInfo.id }).then((res: any) => {
+			deviceList.value = res.device || [];
+		});
+		formData.productKey=productInfo.key
 	});
 };
 

+ 18 - 12
src/views/iot/device/dossier/index.vue → src/views/iot/property/dossier/index.vue

@@ -15,14 +15,14 @@
 					</el-button>
 				</el-form-item>
 				<el-form-item>
-					<el-button type="success" @click="addOrEdit()">
+					<el-button type="success" @click="addOrEdit()" v-if="productIno">
 						<el-icon>
 							<ele-FolderAdd />
 						</el-icon>
 						新增档案
 					</el-button>
 
-					<el-button type="primary" @click="addOrEdit()">
+					<el-button type="primary" @click="addOrEdit()" v-if="productIno">
 						<el-icon>
 							<ele-FolderAdd />
 						</el-icon>
@@ -96,11 +96,10 @@
 
 <script lang="ts" setup>
 import device from '/@/api/device'
-import api from '/@/api/scene'
 import { useSearch } from '/@/hooks/useCommon'
 import {  Expand } from '@element-plus/icons-vue';
 
-import { ElMessageBox, ElMessage, FormInstance } from 'element-plus'
+import { ElMessageBox, ElMessage } from 'element-plus'
 import EditForm from './edit.vue'
 interface Tree {
   label: string
@@ -112,15 +111,17 @@ const defaultProps = {
   children: 'children',
   label: 'label',
 }
+
 const queryRef = ref()
 const router = useRouter()
 const productData = ref([])
 const mergedData = ref()
 const cateData = ref()
 const editFormRef = ref()
+const productIno=ref();
 
 
-const { params, tableData, getList, loading } = useSearch<any[]>(api.manage.getList, 'Data', { keyWord: '' })
+const { params, tableData, getList, loading } = useSearch<any[]>(device.dev_asset.getList, 'Data', { keyWord: '' })
 getList()
 const toDetail = (id: number) => {
 	router.push(`/device/dossier/manage/${id}`)
@@ -131,10 +132,10 @@ onMounted(() => {
 });
 const addOrEdit = async (row?: any) => {
 	if (row) {
-		editFormRef.value.open(row)
+		editFormRef.value.open(row,productIno.value)
 		return
 	} else {
-		editFormRef.value.open()
+		editFormRef.value.open({},productIno.value)
 	}
 }
 
@@ -146,15 +147,18 @@ const getCateList = () => {
 		device.product.getLists({}).then((res: any) => {
 			productData.value = res.product;
 			mergedData.value = matchProductsToCategories(productData.value, cateData.value);
-			console.log(mergedData.value); // 打印生成的树形数据
-			// 将treeData绑定到el-tree的data属性上
 		})
 
 	})
 }
 
-const handleNodeClick = (data: Tree) => {
-  console.log(data)
+const handleNodeClick = (data: any) => {
+	if(data.is_type==='2'){
+		productIno.value=data;
+	}else{
+		productIno.value='';
+
+	}
 }
 
 const matchProductsToCategories = (productData:any, cateData:any) => {
@@ -170,6 +174,7 @@ const buildTree = (category:any, productData:any) => {
   const treeNode = {
     id: category.id,
     label: category.name,
+	key: category.key,
     is_type: '1', // 1是分类
     children: [],
   }
@@ -185,6 +190,7 @@ const buildTree = (category:any, productData:any) => {
       const productNode = {
         id: product.id,
         label: product.name,
+        key: product.key,
         is_type: '2', // 2是产品
       }
       treeNode.children.push(productNode)
@@ -200,7 +206,7 @@ const del = (row: any) => {
 		cancelButtonText: '取消',
 		type: 'warning',
 	}).then(async () => {
-		await api.manage.del(row.id)
+		await device.dev_asset.delete(row.id)
 		ElMessage.success('删除成功')
 		getList()
 	})