Browse Source

Merge branch 'master' of http://git.mydig.net/Sagoo-Cloud/sagoo-admin-ui

vera_min 3 years ago
parent
commit
a359e586d5

+ 15 - 6
src/api/datahub/index.ts

@@ -3,11 +3,20 @@ import { get, post, del, put } from '/@/utils/request';
 export default {
 
   common: {
-    getList: (params: object) => get('/common/base/db/list', params),
-    add: (data: object) => post('/common/base/db/add', data),
-    delete: (id: number) => del('/common/base/db/del', { id }),
-    edit: (data: object) => put('/common/base/db/edit', data),
-    detail: (id: number) => get('/common/base/db/detail', { id }),
-  },
+    getList: (params: object) => get('/source/search', params),
+    add: (data: object) => post('/source/api/add', data),
+    delete: (ids: number) => del('/source/del', { ids }),
+    edit: (data: object) => put('/source/api/edit', data),
+    detail: (sourceId: number) => get('/source/detail', { sourceId }),
+    deploy: (data: object) => post('/source/deploy', data),
+    undeploy: (data: object) => post('/source/undeploy', data),  
+    },
+   
+   node:{
+      getList: (params: object) => get('/source/node/list', params),
+      add: (data: object) => post('/source/node/add', data),
+      delete: (nodeId: number) => del('/source/node/del', { nodeId }),
+      edit: (data: object) => put('/source/node/edit', data),
+   } 
   
 }

+ 16 - 0
src/api/heatingDistrict/index.ts

@@ -16,5 +16,21 @@ export default {
     edit: (data: object) => put('/region/floor/edit', data),
     del: (id: number) => del('/region/floor/del', { id }),
     detail: (id: number) => get('/region/floor/detail', { id }),
+  },
+  unit: {
+    getListByFloorId: (params: object) => get('/region/unit/getInfoByFloorId', params),
+    getList: (params: object) => get('/region/unit/list', params),
+    add: (data: object) => post('/region/unit/add', data),
+    edit: (data: object) => put('/region/unit/edit', data),
+    del: (id: number) => del('/region/unit/del', { id }),
+    detail: (id: number) => get('/region/unit/getInfoById', { id }),
+  },
+  resident: {
+    allList: (params: object) => get('/region/resident/all', params),
+    getList: (params: object) => get('/region/resident/list', params),
+    add: (data: object) => post('/region/resident/add', data),
+    edit: (data: object) => put('/region/resident/edit', data),
+    del: (id: number) => del('/region/resident/del', { id }),
+    detail: (id: number) => get('/region/resident/detail', { id }),
   }
 }

+ 367 - 0
src/views/datahub/modeling/component/edit.vue

@@ -0,0 +1,367 @@
+<template>
+	<div class="system-edit-dic-container">
+		<el-dialog :title="(ruleForm.sourceId !== 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="description">
+					<el-input v-model="ruleForm.description" type="textarea" placeholder="请输入内容"></el-input>
+				</el-form-item>
+
+				<el-form-item label="数据来源" prop="from">
+					<el-radio-group v-model="ruleForm.from">
+						<el-radio :label="1">api导入</el-radio>
+						<el-radio :label="2">数据库</el-radio>
+						<el-radio :label="3">文件</el-radio>
+					</el-radio-group>
+				</el-form-item>
+
+				<el-divider content-position="left">规则表达式</el-divider>
+
+				<div v-for="(item, index) in rule" :key="index">
+					<el-form-item label="表达式">
+						<el-input v-model="item.expression" placeholder="请输入规则表达式" />
+					</el-form-item>
+
+					<el-form-item label="参数" >
+						<el-input v-model="item.params.name" placeholder="请输入键值" class="w-35" />
+						<el-input v-model="item.params.value" placeholder="请输入值" class="w-35" />
+						<div class="conicon">
+							<el-icon @click="delRule(index)" v-if="index > 0"><Delete /></el-icon>
+						</div>
+					</el-form-item>
+				</div>
+				<div style="padding: 10px">
+					<el-button type="primary" class="addbutton" @click="addRule">增加</el-button>
+				</div>
+				<el-divider content-position="left">数据源配置</el-divider>
+
+				<el-form-item label="请求方法" >
+					<el-select v-model="config.method" placeholder="请选择请求方法">
+						<el-option v-for="item in methodData" :key="item.value" :label="item.label" :value="item.value" />
+					</el-select>
+				</el-form-item>
+
+				<el-form-item label="请求地址" >
+					<el-input v-model="config.url" placeholder="请输入请求地址" />
+				</el-form-item>
+
+				<el-form-item label="更新时间" >
+					<el-input v-model="config.interval" placeholder="请输入更新时间" class="w-35" />
+					<el-select v-model="config.intervalUnit" placeholder="请选择单位">
+						<el-option v-for="item in unitData" :key="item.value" :label="item.label" :value="item.value" />
+					</el-select>
+				</el-form-item>
+
+				<div class="box-content">
+					<el-divider content-position="left">请求参数</el-divider>
+					<div class="content-f" v-for="(item, index) in requestParams" :key="index">
+						<el-select v-model="item.type" placeholder="参数类型" style="width: 320px">
+							<el-option v-for="item in paramData" :key="item.value" :label="item.label" :value="item.value" />
+						</el-select>
+						<el-input v-model="item.name" placeholder="请输入参数标题" style="width: 320px" />
+						<el-input v-model="item.key" placeholder="请输入参数名" style="width: 320px" />
+						<el-input v-model="item.value" placeholder="请输入参数值" style="width: 320px" />
+						<div class="conicon">
+							<el-icon @click="delParams(index)" v-if="index > 0"><Delete /></el-icon>
+						</div>
+					</div>
+					<el-button type="primary" class="addbutton" @click="addParams">增加</el-button>
+				</div>
+			</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.sourceId !== 0 ? '修 改' : '添 加' }}</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, defineComponent, ref, unref } from 'vue';
+import api from '/@/api/datahub';
+import { ElMessage } from 'element-plus';
+import { Delete, Minus, Right } from '@element-plus/icons-vue';
+
+interface RuleFormState {
+	sourceId: number;
+	name: string;
+	from: number;
+	key: string;
+	userName: string;
+	password: string;
+	description: string;
+	status: number;
+}
+interface DicState {
+	isShowDialog: boolean;
+	ruleForm: RuleFormState;
+	rules: {};
+}
+
+export default defineComponent({
+	name: 'Edit',
+	components: { Delete, Minus, Right },
+
+	setup(prop, { emit }) {
+		const formRef = ref<HTMLElement | null>(null);
+		const state = reactive<DicState>({
+			
+			isShowDialog: false,
+			config: {},
+			ruledata: [
+				{
+					expression: '',
+					params: {},
+				},
+			],
+			rule: [
+				{
+					expression: '',
+					params: {
+						name: '',
+						value: '',
+					},
+				},
+			],
+			requestParams: [
+				{
+					type: '',
+					key: '',
+					name: '',
+					value: '',
+				},
+			],
+			methodData: [
+				{
+					label: 'GET',
+					value: 'get',
+				},
+				{
+					label: 'POST',
+					value: 'post',
+				},
+				{
+					label: 'PUT',
+					value: 'put',
+				},
+			],
+
+			unitData: [
+				{
+					label: '秒',
+					value: 'second',
+				},
+				{
+					label: '分',
+					value: 'minute',
+				},
+				{
+					label: '时',
+					value: 'hour',
+				},
+				{
+					label: '天',
+					value: 'day',
+				},
+			],
+
+			paramData: [
+				{
+					lable: 'header',
+					value: 'header',
+				},
+				{
+					lable: 'body',
+					value: 'body',
+				},
+				{
+					lable: 'param',
+					value: 'param',
+				},
+			],
+
+			ruleForm: {
+				sourceId: 0,
+				name: '',
+				from: 1,
+				key: '',
+				rule: [],
+				config: {
+					method: '',
+					url: '',
+					interval: '',
+					intervalUnit: '',
+					requestParams: [],
+				},
+				description: '',
+			},
+			rules: {
+				key: [{ required: true, message: '数据源标识不能为空', trigger: 'blur' }],
+				name: [{ required: true, message: '数据源名称不能为空', trigger: 'blur' }],
+				from: [{ required: true, message: '数据源类型不能为空', trigger: 'blur' }],
+			
+			},
+		});
+		const delParams = (index) => {
+			state.requestParams.splice(index, 1);
+		};
+
+		const addParams = () => {
+			state.requestParams.push({
+				type: '',
+				key: '',
+				name: '',
+				value: '',
+			});
+		};
+
+		const delRule = (index) => {
+			state.rule.splice(index, 1);
+		};
+
+		const addRule = () => {
+			state.rule.push({
+				expression: '',
+				params: {
+					name: '',
+					value: '',
+				},
+			});
+		};
+		// 打开弹窗
+		const openDialog = (row: RuleFormState | null) => {
+			resetForm();
+
+			if (row) {
+				 api.common.detail(row.sourceId).then((res:any)=>{
+				    state.ruleForm = res.data
+					state.config=res.data.apiConfig
+					state.requestParams=res.data.apiConfig.requestParams
+
+           			res.data.sourceRule.forEach((item, index) => {
+						state.rule[index].expression = item.expression;
+						state.rule[index].params.name =Object.keys(item.params) ;
+						state.rule[index].params.value = item.params[Object.keys(item.params)];
+					});
+
+
+				 })
+			}
+			state.isShowDialog = true;
+		};
+		const resetForm = () => {
+			state.ruleForm = {
+						sourceId: 0,
+				name: '',
+				from: 1,
+				key: '',
+				rule: [],
+				config: {
+					method: '',
+					url: '',
+					interval: '',
+					intervalUnit: '',
+					requestParams: [],
+				},
+				description: '',
+			};
+		};
+		// 关闭弹窗
+		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) {
+					//修改rule数据
+					state.rule.forEach((item, index) => {
+						item.params[item.params.name] = item.params.value;
+						delete item.params.name;
+						delete item.params.value;
+					});
+
+					state.ruleForm.rule = state.rule;
+					state.config.requestParams = state.requestParams;
+					state.ruleForm.config = state.config;
+
+					if (state.ruleForm.sourceId !== 0) {
+						//修改
+						api.common.edit(state.ruleForm).then(() => {
+							ElMessage.success('数据源类型修改成功');
+							closeDialog(); // 关闭弹窗
+							emit('typeList');
+						});
+					} else {
+						//添加
+
+						api.common.add(state.ruleForm).then(() => {
+							ElMessage.success('数据源类型添加成功');
+							closeDialog(); // 关闭弹窗
+							emit('typeList');
+						});
+					}
+				}
+			});
+		};
+
+		return {
+			addRule,
+			delRule,
+			addParams,
+			delParams,
+			openDialog,
+			closeDialog,
+			onCancel,
+			onSubmit,
+			formRef,
+			...toRefs(state),
+		};
+	},
+});
+</script>
+<style>
+.el-input__wrapper {
+	width: 98%;
+}
+
+.box-content {
+	border: 1px solid #e8e8e8;
+	margin: 10px;
+	padding: 10px;
+}
+
+.content-f {
+	display: flex;
+	margin-bottom: 10px;
+}
+.content-f .el-input__wrapper {
+	margin-right: 5px;
+}
+.addbutton {
+	width: 100%;
+	margin-top: 10px;
+}
+.conicon {
+	width: 55px;
+	height: 25px;
+
+	font-size: 28px;
+	line-height: 28px;
+	cursor: pointer;
+}
+</style>

+ 304 - 0
src/views/datahub/modeling/component/editNode.vue

@@ -0,0 +1,304 @@
+<template>
+	<div class="system-edit-dic-container">
+		<el-dialog :title="(ruleForm.nodeId !== 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="dataType">
+					<el-select v-model="ruleForm.dataType" filterable placeholder="请选择数据类型" >
+						<el-option
+						v-for="item in tabData"
+						:key="item.value"
+						:label="item.label"
+						:value="item.value"
+						/>
+					</el-select>
+				</el-form-item>
+
+				<el-form-item label="取值项" prop="value">
+					<el-input v-model="ruleForm.value" placeholder="请输入取值项" />
+				</el-form-item>
+
+		
+
+				<el-divider content-position="left">规则表达式</el-divider>
+
+				<div v-for="(item, index) in rule" :key="index">
+					<el-form-item label="表达式" >
+						<el-input v-model="item.expression" placeholder="请输入规则表达式" />
+					</el-form-item>
+
+					<el-form-item label="参数" >
+						<el-input v-model="rule[index].params.name" placeholder="请输入键值" class="w-35" />
+						<el-input v-model="rule[index].params.value" placeholder="请输入值" class="w-35" />
+						<div class="conicon">
+							<el-icon @click="delRule(index)" v-if="index > 0"><Delete /></el-icon>
+						</div>
+					</el-form-item>
+				</div>
+				<div style="padding: 10px">
+					<el-button type="primary" class="addbutton" @click="addRule">增加</el-button>
+				</div>
+
+	
+
+			
+			
+
+			
+			</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.nodeId !== 0 ? '修 改' : '添 加' }}</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, defineComponent, ref, unref } from 'vue';
+import api from '/@/api/datahub';
+import { ElMessage } from 'element-plus';
+import { Delete, Minus, Right } from '@element-plus/icons-vue';
+
+interface RuleFormState {
+	nodeId: number;
+	name: string;
+	from: number;
+	key: string;
+	dataType: string;
+	value: string;
+	description: string;
+	status: number;
+}
+interface DicState {
+	isShowDialog: boolean;
+	ruleForm: RuleFormState;
+	rules: {};
+}
+
+export default defineComponent({
+	name: 'Edit',
+	components: { Delete, Minus, Right },
+
+	setup(prop, { emit }) {
+		const editDicRef = ref();
+		const formRef = ref<HTMLElement | null>(null);
+		const state = reactive<DicState>({
+			
+			isShowDialog: false,
+			config: {},
+			tabData:[{
+				label: 'varchar',
+				value: 'varchar',
+			},{
+				label: 'string',
+				value: 'string',
+			},{
+				label: 'int',
+				value: 'int',
+			},{
+				label: 'bigint',
+				value: 'bigint',
+			},{
+				label: 'tinyint',
+				value: 'tinyint',
+			},{
+				label: 'float',
+				value: 'float',
+			},{
+				label: 'double',
+				value: 'double',
+			},{
+				label: 'text',
+				value: 'text',
+			},{
+				label: 'datetime',
+				value: 'datetime',
+			},{
+				label: 'timestamp',
+				value: 'timestamp',
+			}],
+			ruledata:  [
+				{
+					expression: '',
+					params: {
+						name: '',
+						value: '',
+					},
+				},
+			],
+			rule: [
+				{
+					expression: '',
+					params: {
+						name: '',
+						value: '',
+					},
+				},
+			],
+			
+		
+
+		
+			ruleForm: {
+				nodeId: 0,
+				name: '',
+				key: '',
+				dataType:'',
+				value:'',
+				rule: [],
+				
+				description: '',
+			},
+			rules: {
+				key: [{ required: true, message: '数据节点标识不能为空', trigger: 'blur' }],
+				name: [{ required: true, message: '数据节点名称不能为空', trigger: 'blur' }],
+				dataType: [{ required: true, message: '数据节点类型不能为空', trigger: 'blur' }],
+				value: [{ required: true, message: '数据节点取值项不能为空', trigger: 'blur' }],
+			
+			},
+		});
+		
+
+		const delRule = (index) => {
+			state.rule.splice(index, 1);
+		};
+
+		const addRule = () => {
+			state.rule.push({
+				expression: '',
+				params: {
+					name: '',
+					value: '',
+				},
+			});
+		};
+		// 打开弹窗
+		const openDialog = (row: RuleFormState | null) => {
+			resetForm();
+
+			if (row?.nodeId) {
+
+				  state.ruleForm = row
+
+				 var data=JSON.parse(row.rule)
+           			 console.log(data);
+
+					data.forEach((item, index) => {
+						state.rule[index].expression = item.expression;
+						state.rule[index].params.name =Object.keys(item.params) ;
+						state.rule[index].params.value = item.params[Object.keys(item.params)];
+					});
+			}
+
+			state.ruleForm = row;
+			state.isShowDialog = true;
+		};
+		const resetForm = () => {
+			state.ruleForm = {
+				nodeId: 0,
+				name: '',
+				from: 1,
+				key: '',
+				rule: [],
+				
+				description: '',
+			};
+		};
+		// 关闭弹窗
+		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) {
+					//修改rule数据
+					state.rule.forEach((item, index) => {
+						item.params[item.params.name] = item.params.value;
+						delete item.params.name;
+						delete item.params.value;
+					});
+
+					state.ruleForm.rule = state.rule;
+
+					if (state.ruleForm.nodeId !== 0) {
+						//修改
+						api.node.edit(state.ruleForm).then(() => {
+							ElMessage.success('数据节点类型修改成功');
+							closeDialog(); // 关闭弹窗
+							emit('typeList');
+						});
+					} else {
+						//添加
+
+						api.node.add(state.ruleForm).then(() => {
+							ElMessage.success('数据节点类型添加成功');
+							closeDialog(); // 关闭弹窗
+							emit('typeList');
+						});
+					}
+				}
+			});
+		};
+
+		return {
+			addRule,
+			delRule,
+			openDialog,
+			closeDialog,
+			onCancel,
+			onSubmit,
+			formRef,
+			...toRefs(state),
+		};
+	},
+});
+</script>
+<style>
+.el-input__wrapper {
+	width: 98%;
+}
+
+.box-content {
+	border: 1px solid #e8e8e8;
+	margin: 10px;
+	padding: 10px;
+}
+
+.content-f {
+	display: flex;
+	margin-bottom: 10px;
+}
+.content-f .el-input__wrapper {
+	margin-right: 5px;
+}
+.addbutton {
+	width: 100%;
+	margin-top: 10px;
+}
+.conicon {
+	width: 55px;
+	height: 25px;
+
+	font-size: 28px;
+	line-height: 28px;
+	cursor: pointer;
+}
+</style>

+ 273 - 0
src/views/datahub/modeling/detail.vue

@@ -0,0 +1,273 @@
+<template>
+	<div class="system-dic-container">
+		<div class="content">
+			<div class="cont_box">
+				<div class="title">数据表名称:{{ detail.name }}</div>
+				<div class="title">数据表表名:{{ detail.name }}</div>
+		
+			</div>
+		</div>
+
+		<div class="content-box">
+
+
+                        <div class="wu-box">
+						 <div class="system-user-search mb15">
+        <el-form :model="tableData.param" ref="queryRef" :inline="true" label-width="68px">
+          <el-form-item label="字段标题" prop="name">
+            <el-input v-model="tableData.param.name" placeholder="请输入产品名称" clearable size="default" style="width: 240px" @keyup.enter.native="typeList" />
+          </el-form-item>
+          <el-form-item label="字段名称" prop="deviceType">
+            <el-input v-model="tableData.param.deviceType" placeholder="请输入设备类型" clearable size="default" style="width: 240px" @keyup.enter.native="typeList" />
+          </el-form-item>
+        
+          <el-form-item>
+            <el-button size="default" type="primary" class="ml10" @click="typeList">
+              <el-icon>
+                <ele-Search />
+              </el-icon>
+              查询
+            </el-button>
+            <el-button size="default" @click="resetQuery(queryRef)">
+              <el-icon>
+                <ele-Refresh />
+              </el-icon>
+              重置
+            </el-button>
+            <el-button size="default" type="success" class="ml10" @click="onOpenAddDic">
+              <el-icon>
+                <ele-FolderAdd />
+              </el-icon>
+              新增字段
+            </el-button>
+            <el-button size="default" type="danger" class="ml10" @click="onRowDel(null)">
+              <el-icon>
+                <ele-Delete />
+              </el-icon>
+              删除
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+                       
+
+                         <el-table :data="tableData.data" style="width: 100%" >
+        <el-table-column label="ID" align="center" prop="nodeId" width="80" />
+        <el-table-column label="字段标题" prop="key" :show-overflow-tooltip="true" />
+        <el-table-column label="字段名称" prop="name" :show-overflow-tooltip="true" />
+        <el-table-column label="字段类型" prop="dataType" :show-overflow-tooltip="true" />
+        <el-table-column label="字段长度" prop="value" :show-overflow-tooltip="true" />
+        <el-table-column label="默认值" prop="value" :show-overflow-tooltip="true" />
+        <el-table-column label="备注说明" prop="value" :show-overflow-tooltip="true" />
+		  <el-table-column prop="createdAt" label="创建时间" align="center" width="180"></el-table-column> 
+
+        <el-table-column label="操作" width="200" align="center">
+          <template #default="scope">
+	
+
+            <el-button size="small" text type="warning" @click="onOpenEdit1(scope.row)">修改</el-button>
+            <el-button size="small" text type="danger" @click="onRowDel(scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination v-show="tableData.total>0" :total="tableData.total" v-model:page="tableData.param.pageNum" v-model:limit="tableData.param.pageSize" @pagination="typeList" />
+           </div>         
+                  
+
+
+
+
+        </div>
+ <EditDic ref="editDicRef" @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 { ElMessageBox, ElMessage, FormInstance } from 'element-plus';
+import { useRoute } from 'vue-router';
+import EditDic from './component/editNode.vue';
+import api from '/@/api/datahub';
+
+interface TableDataState {
+	ids: number[];
+	tableData: {
+		data: [];
+		total: number;
+		loading: boolean;
+		param: {
+			pageNum: number;
+			pageSize: number;
+			name: string;
+			deviceType: string;
+			status: string;
+			dateRange: string[];
+		};
+	};
+}
+export default defineComponent({
+    name: 'dataDetail',
+    components: { EditDic },
+    setup(prop, context) {
+        		const editDicRef = ref();
+
+		const route = useRoute();
+        const state = reactive<TableDataState>({
+            config: {},
+		
+			isShowDialog: false,
+			detail: [],
+            
+			tableData: {
+				data: [],
+				total: 0,
+				loading: false,
+				param: {
+					pageNum: 1,
+					pageSize: 10,
+                    sourceId: route.params && route.params.sourceId,
+					status: '',
+					dateRange: [],
+				},
+			},
+		});
+
+
+
+        onMounted(() => {
+			
+
+                typeList();
+		});
+
+        const typeList = () => {
+			api.node.getList(state.tableData.param).then((res: any) => {
+				state.tableData.data = res.list;
+				state.tableData.total = res.Total;
+			});
+		};
+
+
+        const CkOption=()=>{
+                if(state.developer_status==1){
+                    api.common.undeploy({sourceId:route.params.sourceId}).then((res: any) => {
+                        ElMessage.success('操作成功');
+                        state.developer_status=0;
+                    });
+                }else{
+                    api.common.deploy({sourceId:route.params.sourceId}).then((res: any) => {
+                        ElMessage.success('操作成功');
+                        state.developer_status=1;
+                    });
+                }
+		}
+        const handleClick = (tab: TabsPaneContext, event: Event) => {
+			console.log(tab, event);
+		};
+
+        	const onRowDel = (row: TableDataRow) => {
+			let msg = '你确定要删除所选数据?';
+			let ids: number[] = [];
+			if (row) {
+				msg = `此操作将永久删除数据节点:“${row.name}”,是否继续?`;
+				ids = row.nodeId;
+			} else {
+				ids = state.ids;
+			}
+			if (ids.length === 0) {
+				ElMessage.error('请选择要删除的数据。');
+				return;
+			}
+			ElMessageBox.confirm(msg, '提示', {
+				confirmButtonText: '确认',
+				cancelButtonText: '取消',
+				type: 'warning',
+			})
+				.then(() => {
+					api.node.delete(ids).then(() => {
+						ElMessage.success('删除成功');
+						typeList();
+					});
+				})
+				.catch(() => {});
+		};
+
+        	// 打开修改数据源弹窗
+        const onOpenEdit = (row: TableDataRow) => {
+			editDicRef.value.openDialog(row);
+		};
+
+        	return {
+			Edit,
+            editDicRef,
+            typeList,
+            onRowDel,
+            onOpenEdit,
+            handleClick,
+			CkOption,
+			...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;
+	cursor: pointer;
+}
+.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;
+}
+
+
+</style>

+ 215 - 0
src/views/datahub/modeling/index.vue

@@ -0,0 +1,215 @@
+<template>
+  <div class="system-dic-container">
+    <el-card shadow="hover">
+      <div class="system-user-search mb15">
+        <el-form :model="tableData.param" ref="queryRef" :inline="true" >
+
+		 
+          <el-form-item label="自建表名称" prop="name">
+            <el-input v-model="tableData.param.name" placeholder="请输入自建表名称" clearable size="default" style="width: 240px" @keyup.enter.native="typeList" />
+          </el-form-item>
+		 
+         
+      
+        
+         
+          <el-form-item>
+            <el-button size="default" type="primary" class="ml10" @click="typeList">
+              <el-icon>
+                <ele-Search />
+              </el-icon>
+              查询
+            </el-button>
+            <el-button size="default" @click="resetQuery(queryRef)">
+              <el-icon>
+                <ele-Refresh />
+              </el-icon>
+              重置
+            </el-button>
+            <el-button size="default" type="success" class="ml10" @click="onOpenAdd">
+              <el-icon>
+                <ele-FolderAdd />
+              </el-icon>
+              新增自建表
+            </el-button>
+       <el-button size="default" type="danger" class="ml10" @click="onRowDel(null)">
+              <el-icon>
+                <ele-Delete />
+              </el-icon>
+              删除
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+      <el-table :data="tableData.data" style="width: 100%" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="ID" align="center" prop="sourceId" width="80" />
+        <el-table-column label="自建表名称" prop="name" :show-overflow-tooltip="true" />
+        <el-table-column label="自建表表名" prop="name" :show-overflow-tooltip="true" />
+        
+      
+
+		  <el-table-column prop="createdAt" label="创建时间" align="center" width="180"></el-table-column> 
+
+        <el-table-column label="操作" width="200" align="center">
+          <template #default="scope">
+		   	<router-link :to="'/datahub/modeling/detail/' + scope.row.sourceId" class="link-type" style="padding-right: 12px;
+    font-size: 12px;color: #409eff;">
+              <span>字段管理</span>
+            </router-link>
+
+            <el-button size="small" text type="warning" @click="onOpenEdit(scope.row)">修改</el-button>
+            <el-button size="small" text type="danger" @click="onRowDel(scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination v-show="tableData.total>0" :total="tableData.total" v-model:page="tableData.param.pageNum" v-model:limit="tableData.param.pageSize" @pagination="typeList" />
+    </el-card>
+    <EditDic ref="editDicRef" @typeList="typeList" />
+	    <Detail ref="detailRef"  />
+
+  </div>
+</template>
+
+<script lang="ts">
+import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
+import { ElMessageBox, ElMessage, FormInstance } from 'element-plus';
+import EditDic from './component/edit.vue';
+import api from '/@/api/datahub';
+
+// 定义接口来定义对象的类型
+interface TableDataRow {
+	sourceId: number;
+	name: string;
+	key: string;
+	status: number;
+	from: string;
+	createBy: string;
+}
+interface TableDataState {
+	ids: number[];
+	tableData: {
+		data: Array<TableDataRow>;
+		total: number;
+		loading: boolean;
+		param: {
+			pageNum: number;
+			pageSize: number;
+			name: string;
+			key: string;
+			from: string;
+			
+		};
+	};
+}
+
+export default defineComponent({
+	name: 'sourcelist',
+	components: { EditDic },
+	setup() {
+		const addDicRef = ref();
+		const editDicRef = ref();
+		const queryRef = ref();
+		const state = reactive<TableDataState>({
+			typeData: [
+				{
+					label: 'api导入',
+					value: '1',
+				},
+				{
+					label: '数据库',
+					value: '2',
+				},
+				{
+					label: '文件',
+					value: '3',
+				},
+			],
+			ids: [],
+			tableData: {
+				data: [],
+				total: 0,
+				loading: false,
+				param: {
+					pageNum: 1,
+					pageSize: 10,
+					name: '',
+					types: '',
+					status:'',
+				},
+			},
+		});
+		// 初始化表格数据
+		const initTableData = () => {
+			typeList();
+		};
+		const typeList = () => {
+			api.common.getList(state.tableData.param).then((res: any) => {
+				state.tableData.data = res.list;
+				state.tableData.total = res.Total;
+			});
+		};
+		// 打开新增自建表弹窗
+		const onOpenAdd = () => {
+			editDicRef.value.openDialog();
+		};
+		// 打开修改自建表弹窗
+		const onOpenEdit = (row: TableDataRow) => {
+			editDicRef.value.openDialog(row);
+		};
+		const onRowDel = (row: TableDataRow) => {
+			let msg = '你确定要删除所选数据?';
+			let ids: number[] = [];
+			if (row) {
+				msg = `此操作将永久删除自建表:“${row.name}”,是否继续?`;
+				ids = [row.sourceId];
+			} else {
+				ids = state.ids;
+			}
+			if (ids.length === 0) {
+				ElMessage.error('请选择要删除的数据。');
+				return;
+			}
+			ElMessageBox.confirm(msg, '提示', {
+				confirmButtonText: '确认',
+				cancelButtonText: '取消',
+				type: 'warning',
+			})
+				.then(() => {
+					api.common.delete(ids).then(() => {
+						ElMessage.success('删除成功');
+						typeList();
+					});
+				})
+				.catch(() => {});
+		};
+		// 页面加载时
+		onMounted(() => {
+			initTableData();
+		});
+		/** 重置按钮操作 */
+		const resetQuery = (formEl: FormInstance | undefined) => {
+			if (!formEl) return;
+			formEl.resetFields();
+			typeList();
+		};
+		// 多选框选中数据
+		const handleSelectionChange = (selection: TableDataRow[]) => {
+			state.ids = selection.map((item) => item.sourceId);
+		};
+	
+		return {
+			addDicRef,
+			editDicRef,
+			queryRef,
+			onOpenAdd,
+			onOpenEdit,
+			onRowDel,
+			typeList,
+			resetQuery,
+			handleSelectionChange,
+			...toRefs(state),
+		};
+	},
+});
+</script>

+ 0 - 150
src/views/datahub/source/component/detail.vue

@@ -1,150 +0,0 @@
-<template>
-	<div class="system-edit-dic-container">
-		<el-dialog title="查看数据源" v-model="isShowDialog" width="769px">
-			<el-form :model="ruleForm" ref="formRef" :rules="rules" size="default" label-width="110px">
-       
-        <el-form-item label="数据源名称" prop="name">
-          {{ruleForm.name}}
-        </el-form-item>
-
-        <el-form-item label="数据类型" prop="types">
-           {{ruleForm.types}}
-        </el-form-item>
-
-        <el-form-item label="地址" prop="host">
-          {{ruleForm.host}}
-        </el-form-item>
-
-         <el-form-item label="端口" prop="port">
-          {{ruleForm.port}}
-        </el-form-item>
-        <el-form-item label="用户名" prop="userName">
-          {{ruleForm.userName}}
-        </el-form-item>
-        <el-form-item label="密码" prop="password">
-           {{ruleForm.password}}
-        </el-form-item>
-  	
-        <el-form-item label="备注" prop="description">
-        {{ruleForm.description}}
-        </el-form-item>
-			</el-form>
-		
-		</el-dialog>
-	</div>
-</template>
-
-<script lang="ts">
-import { reactive, toRefs, defineComponent,ref, unref } from 'vue';
-import api from '/@/api/datahub';
-import {ElMessage} from "element-plus";
-interface RuleFormState {
-  id:number;
-  name:string;
-  types:string;
-  host:string;
-  port:string;
-  userName:string;
-  password:string;
-  description:string;
-  status:number;
-}
-interface DicState {
-	isShowDialog: boolean;
-	ruleForm: RuleFormState;
-  rules:{}
-}
-
-export default defineComponent({
-	name: 'deviceEditPro',
-	setup(prop,{emit}) {
-    const formRef = ref<HTMLElement | null>(null);
-		const state = reactive<DicState>({
-			isShowDialog: false,
-			ruleForm: {
-        id:0,
-        name:'',
-        types:'',
-        host:'',
-        port:'',
-        userName:'',
-        password:'',
-        description:'',
-        status:1,
-
-			},
-      rules: {
-       
-      }
-		});
-		// 打开弹窗
-		const openDialog = (row: RuleFormState|null) => {
-      resetForm();
-
-
-      if (row){
-        // api.dict.getType(row.id).then((res:any)=>{
-        //   state.ruleForm = res.data.dictType
-        // })
-        state.ruleForm = row;
-      }
-			state.isShowDialog = true;
-		};
-    const resetForm = ()=>{
-      state.ruleForm = {
-       id:0,
-        name:'',
-        types:'',
-        host:'',
-        port:'',
-        userName:'',
-        password:'',
-        description:'',
-        status:1
-      }
-    };
-		// 关闭弹窗
-		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.common.edit(state.ruleForm).then(()=>{
-              ElMessage.success('数据源类型修改成功');
-              closeDialog(); // 关闭弹窗
-              emit('typeList')
-            })
-          }else{
-            //添加
-            api.common.add(state.ruleForm).then(()=>{
-              ElMessage.success('数据源类型添加成功');
-              closeDialog(); // 关闭弹窗
-              emit('typeList')
-            })
-          }
-        }
-      });
-		};
-
-
-		return {
-			openDialog,
-			closeDialog,
-			onCancel,
-			onSubmit,
-      formRef,
-			...toRefs(state),
-		};
-	},
-});
-</script>

+ 310 - 113
src/views/datahub/source/component/edit.vue

@@ -1,44 +1,83 @@
 <template>
 	<div class="system-edit-dic-container">
-		<el-dialog :title="(ruleForm.id!==0?'修改':'添加')+'数据源'" v-model="isShowDialog" width="769px">
+		<el-dialog :title="(ruleForm.sourceId !== 0 ? '修改' : '添加') + '数据源'" v-model="isShowDialog" width="769px">
 			<el-form :model="ruleForm" ref="formRef" :rules="rules" size="default" label-width="110px">
-       
-        <el-form-item label="数据源名称" prop="name">
-          <el-input v-model="ruleForm.name" placeholder="请输入数据源名称" />
-        </el-form-item>
-
-        <el-form-item label="数据类型" prop="types">
-          <el-input v-model="ruleForm.types" placeholder="请输入数据类型" />
-        </el-form-item>
-
-        <el-form-item label="地址" prop="host">
-          <el-input v-model="ruleForm.host" placeholder="请输入地址" />
-        </el-form-item>
-
-         <el-form-item label="端口" prop="port">
-          <el-input v-model="ruleForm.port" placeholder="请输入端口" />
-        </el-form-item>
-        <el-form-item label="用户名" prop="userName">
-          <el-input v-model="ruleForm.userName" placeholder="请输入用户名" />
-        </el-form-item>
-        <el-form-item label="密码" prop="password">
-          <el-input v-model="ruleForm.password" placeholder="请输入密码" />
-        </el-form-item>
-  	<el-form-item label="状态" prop="status">
-					<el-radio-group v-model="ruleForm.status"  >
-						<el-radio label="0">未启用</el-radio>
-
-						<el-radio label="1">启用</el-radio>
+				<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="description">
+					<el-input v-model="ruleForm.description" type="textarea" placeholder="请输入内容"></el-input>
+				</el-form-item>
+
+				<el-form-item label="数据来源" prop="from">
+					<el-radio-group v-model="ruleForm.from">
+						<el-radio :label="1">api导入</el-radio>
+						<el-radio :label="2">数据库</el-radio>
+						<el-radio :label="3">文件</el-radio>
 					</el-radio-group>
 				</el-form-item>
-        <el-form-item label="备注" prop="description">
-          <el-input v-model="ruleForm.description" type="textarea" placeholder="请输入内容"></el-input>
-        </el-form-item>
+
+				<el-divider content-position="left">规则表达式</el-divider>
+
+				<div v-for="(item, index) in rule" :key="index">
+					<el-form-item label="表达式">
+						<el-input v-model="item.expression" placeholder="请输入规则表达式" />
+					</el-form-item>
+
+					<el-form-item label="参数" >
+						<el-input v-model="item.params.name" placeholder="请输入键值" class="w-35" />
+						<el-input v-model="item.params.value" placeholder="请输入值" class="w-35" />
+						<div class="conicon">
+							<el-icon @click="delRule(index)" v-if="index > 0"><Delete /></el-icon>
+						</div>
+					</el-form-item>
+				</div>
+				<div style="padding: 10px">
+					<el-button type="primary" class="addbutton" @click="addRule">增加</el-button>
+				</div>
+				<el-divider content-position="left">数据源配置</el-divider>
+
+				<el-form-item label="请求方法" >
+					<el-select v-model="config.method" placeholder="请选择请求方法">
+						<el-option v-for="item in methodData" :key="item.value" :label="item.label" :value="item.value" />
+					</el-select>
+				</el-form-item>
+
+				<el-form-item label="请求地址" >
+					<el-input v-model="config.url" placeholder="请输入请求地址" />
+				</el-form-item>
+
+				<el-form-item label="更新时间" >
+					<el-input v-model="config.interval" placeholder="请输入更新时间" class="w-35" />
+					<el-select v-model="config.intervalUnit" placeholder="请选择单位">
+						<el-option v-for="item in unitData" :key="item.value" :label="item.label" :value="item.value" />
+					</el-select>
+				</el-form-item>
+
+				<div class="box-content">
+					<el-divider content-position="left">请求参数</el-divider>
+					<div class="content-f" v-for="(item, index) in requestParams" :key="index">
+						<el-select v-model="item.type" placeholder="参数类型" style="width: 320px">
+							<el-option v-for="item in paramData" :key="item.value" :label="item.label" :value="item.value" />
+						</el-select>
+						<el-input v-model="item.name" placeholder="请输入参数标题" style="width: 320px" />
+						<el-input v-model="item.key" placeholder="请输入参数名" style="width: 320px" />
+						<el-input v-model="item.value" placeholder="请输入参数值" style="width: 320px" />
+						<div class="conicon">
+							<el-icon @click="delParams(index)" v-if="index > 0"><Delete /></el-icon>
+						</div>
+					</div>
+					<el-button type="primary" class="addbutton" @click="addParams">增加</el-button>
+				</div>
 			</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>
+					<el-button type="primary" @click="onSubmit" size="default">{{ ruleForm.sourceId !== 0 ? '修 改' : '添 加' }}</el-button>
 				</span>
 			</template>
 		</el-dialog>
@@ -46,83 +85,195 @@
 </template>
 
 <script lang="ts">
-import { reactive, toRefs, defineComponent,ref, unref } from 'vue';
+import { reactive, toRefs, defineComponent, ref, unref } from 'vue';
 import api from '/@/api/datahub';
-import {ElMessage} from "element-plus";
+import { ElMessage } from 'element-plus';
+import { Delete, Minus, Right } from '@element-plus/icons-vue';
+
 interface RuleFormState {
-  id:number;
-  name:string;
-  types:string;
-  host:string;
-  port:string;
-  userName:string;
-  password:string;
-  description:string;
-  status:number;
+	sourceId: number;
+	name: string;
+	from: number;
+	key: string;
+	userName: string;
+	password: string;
+	description: string;
+	status: number;
 }
 interface DicState {
 	isShowDialog: boolean;
 	ruleForm: RuleFormState;
-  rules:{}
+	rules: {};
 }
 
 export default defineComponent({
-	name: 'deviceEditPro',
-	setup(prop,{emit}) {
-    const formRef = ref<HTMLElement | null>(null);
+	name: 'Edit',
+	components: { Delete, Minus, Right },
+
+	setup(prop, { emit }) {
+		const formRef = ref<HTMLElement | null>(null);
 		const state = reactive<DicState>({
+			
 			isShowDialog: false,
-			ruleForm: {
-        id:0,
-        name:'',
-        types:'',
-        host:'',
-        port:'',
-        userName:'',
-        password:'',
-        description:'',
-        status:1,
+			config: {},
+			ruledata: [
+				{
+					expression: '',
+					params: {},
+				},
+			],
+			rule: [
+				{
+					expression: '',
+					params: {
+						name: '',
+						value: '',
+					},
+				},
+			],
+			requestParams: [
+				{
+					type: '',
+					key: '',
+					name: '',
+					value: '',
+				},
+			],
+			methodData: [
+				{
+					label: 'GET',
+					value: 'get',
+				},
+				{
+					label: 'POST',
+					value: 'post',
+				},
+				{
+					label: 'PUT',
+					value: 'put',
+				},
+			],
 
+			unitData: [
+				{
+					label: '秒',
+					value: 'second',
+				},
+				{
+					label: '分',
+					value: 'minute',
+				},
+				{
+					label: '时',
+					value: 'hour',
+				},
+				{
+					label: '天',
+					value: 'day',
+				},
+			],
+
+			paramData: [
+				{
+					lable: 'header',
+					value: 'header',
+				},
+				{
+					lable: 'body',
+					value: 'body',
+				},
+				{
+					lable: 'param',
+					value: 'param',
+				},
+			],
+
+			ruleForm: {
+				sourceId: 0,
+				name: '',
+				from: 1,
+				key: '',
+				rule: [],
+				config: {
+					method: '',
+					url: '',
+					interval: '',
+					intervalUnit: '',
+					requestParams: [],
+				},
+				description: '',
+			},
+			rules: {
+				key: [{ required: true, message: '数据源标识不能为空', trigger: 'blur' }],
+				name: [{ required: true, message: '数据源名称不能为空', trigger: 'blur' }],
+				from: [{ required: true, message: '数据源类型不能为空', trigger: 'blur' }],
+			
 			},
-      rules: {
-        name: [
-          { required: true, message: "数据源名称不能为空", trigger: "blur" }
-        ],
-        types: [
-          { required: true, message: "数据源类型不能为空", trigger: "blur" }
-        ],
-        host: [{ required: true, message: '地址不能为空', trigger: 'blur' }],
-        port: [{ required: true, message: '端口不能为空', trigger: 'blur' }],
-        userName: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
-        password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
-      }
 		});
+		const delParams = (index) => {
+			state.requestParams.splice(index, 1);
+		};
+
+		const addParams = () => {
+			state.requestParams.push({
+				type: '',
+				key: '',
+				name: '',
+				value: '',
+			});
+		};
+
+		const delRule = (index) => {
+			state.rule.splice(index, 1);
+		};
+
+		const addRule = () => {
+			state.rule.push({
+				expression: '',
+				params: {
+					name: '',
+					value: '',
+				},
+			});
+		};
 		// 打开弹窗
-		const openDialog = (row: RuleFormState|null) => {
-      resetForm();
+		const openDialog = (row: RuleFormState | null) => {
+			resetForm();
 
+			if (row) {
+				 api.common.detail(row.sourceId).then((res:any)=>{
+				    state.ruleForm = res.data
+					state.config=res.data.apiConfig
+					state.requestParams=res.data.apiConfig.requestParams
 
-      if (row){
-        // api.dict.getType(row.id).then((res:any)=>{
-        //   state.ruleForm = res.data.dictType
-        // })
-        state.ruleForm = row;
-      }
+           			res.data.sourceRule.forEach((item, index) => {
+						state.rule[index].expression = item.expression;
+						state.rule[index].params.name =Object.keys(item.params) ;
+						state.rule[index].params.value = item.params[Object.keys(item.params)];
+					});
+
+
+				 })
+			}
 			state.isShowDialog = true;
 		};
-    const resetForm = ()=>{
-      state.ruleForm = {
-       id:0,
-        name:'',
-        types:'',
-        host:'',
-        port:'',
-        userName:'',
-        password:'',
-        description:'',
-        status:1
-      }
-    };
+		const resetForm = () => {
+			state.ruleForm = {
+						sourceId: 0,
+				name: '',
+				from: 1,
+				key: '',
+				rule: [],
+				config: {
+					method: '',
+					url: '',
+					interval: '',
+					intervalUnit: '',
+					requestParams: [],
+				},
+				description: '',
+			};
+		};
 		// 关闭弹窗
 		const closeDialog = () => {
 			state.isShowDialog = false;
@@ -133,38 +284,84 @@ export default defineComponent({
 		};
 		// 新增
 		const onSubmit = () => {
-      const formWrap = unref(formRef) as any;
-      if (!formWrap) return;
-      formWrap.validate((valid: boolean) => {
-        if (valid) {
-          if(state.ruleForm.id!==0){
-            //修改
-            api.common.edit(state.ruleForm).then(()=>{
-              ElMessage.success('数据源类型修改成功');
-              closeDialog(); // 关闭弹窗
-              emit('typeList')
-            })
-          }else{
-            //添加
-            api.common.add(state.ruleForm).then(()=>{
-              ElMessage.success('数据源类型添加成功');
-              closeDialog(); // 关闭弹窗
-              emit('typeList')
-            })
-          }
-        }
-      });
-		};
+			const formWrap = unref(formRef) as any;
+			if (!formWrap) return;
+			formWrap.validate((valid: boolean) => {
+				if (valid) {
+					//修改rule数据
+					state.rule.forEach((item, index) => {
+						item.params[item.params.name] = item.params.value;
+						delete item.params.name;
+						delete item.params.value;
+					});
+
+					state.ruleForm.rule = state.rule;
+					state.config.requestParams = state.requestParams;
+					state.ruleForm.config = state.config;
 
+					if (state.ruleForm.sourceId !== 0) {
+						//修改
+						api.common.edit(state.ruleForm).then(() => {
+							ElMessage.success('数据源类型修改成功');
+							closeDialog(); // 关闭弹窗
+							emit('typeList');
+						});
+					} else {
+						//添加
+
+						api.common.add(state.ruleForm).then(() => {
+							ElMessage.success('数据源类型添加成功');
+							closeDialog(); // 关闭弹窗
+							emit('typeList');
+						});
+					}
+				}
+			});
+		};
 
 		return {
+			addRule,
+			delRule,
+			addParams,
+			delParams,
 			openDialog,
 			closeDialog,
 			onCancel,
 			onSubmit,
-      formRef,
+			formRef,
 			...toRefs(state),
 		};
 	},
 });
 </script>
+<style>
+.el-input__wrapper {
+	width: 98%;
+}
+
+.box-content {
+	border: 1px solid #e8e8e8;
+	margin: 10px;
+	padding: 10px;
+}
+
+.content-f {
+	display: flex;
+	margin-bottom: 10px;
+}
+.content-f .el-input__wrapper {
+	margin-right: 5px;
+}
+.addbutton {
+	width: 100%;
+	margin-top: 10px;
+}
+.conicon {
+	width: 55px;
+	height: 25px;
+
+	font-size: 28px;
+	line-height: 28px;
+	cursor: pointer;
+}
+</style>

+ 304 - 0
src/views/datahub/source/component/editNode.vue

@@ -0,0 +1,304 @@
+<template>
+	<div class="system-edit-dic-container">
+		<el-dialog :title="(ruleForm.nodeId !== 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="dataType">
+					<el-select v-model="ruleForm.dataType" filterable placeholder="请选择数据类型" >
+						<el-option
+						v-for="item in tabData"
+						:key="item.value"
+						:label="item.label"
+						:value="item.value"
+						/>
+					</el-select>
+				</el-form-item>
+
+				<el-form-item label="取值项" prop="value">
+					<el-input v-model="ruleForm.value" placeholder="请输入取值项" />
+				</el-form-item>
+
+		
+
+				<el-divider content-position="left">规则表达式</el-divider>
+
+				<div v-for="(item, index) in rule" :key="index">
+					<el-form-item label="表达式" >
+						<el-input v-model="item.expression" placeholder="请输入规则表达式" />
+					</el-form-item>
+
+					<el-form-item label="参数" >
+						<el-input v-model="rule[index].params.name" placeholder="请输入键值" class="w-35" />
+						<el-input v-model="rule[index].params.value" placeholder="请输入值" class="w-35" />
+						<div class="conicon">
+							<el-icon @click="delRule(index)" v-if="index > 0"><Delete /></el-icon>
+						</div>
+					</el-form-item>
+				</div>
+				<div style="padding: 10px">
+					<el-button type="primary" class="addbutton" @click="addRule">增加</el-button>
+				</div>
+
+	
+
+			
+			
+
+			
+			</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.nodeId !== 0 ? '修 改' : '添 加' }}</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, defineComponent, ref, unref } from 'vue';
+import api from '/@/api/datahub';
+import { ElMessage } from 'element-plus';
+import { Delete, Minus, Right } from '@element-plus/icons-vue';
+
+interface RuleFormState {
+	nodeId: number;
+	name: string;
+	from: number;
+	key: string;
+	dataType: string;
+	value: string;
+	description: string;
+	status: number;
+}
+interface DicState {
+	isShowDialog: boolean;
+	ruleForm: RuleFormState;
+	rules: {};
+}
+
+export default defineComponent({
+	name: 'Edit',
+	components: { Delete, Minus, Right },
+
+	setup(prop, { emit }) {
+		const editDicRef = ref();
+		const formRef = ref<HTMLElement | null>(null);
+		const state = reactive<DicState>({
+			
+			isShowDialog: false,
+			config: {},
+			tabData:[{
+				label: 'varchar',
+				value: 'varchar',
+			},{
+				label: 'string',
+				value: 'string',
+			},{
+				label: 'int',
+				value: 'int',
+			},{
+				label: 'bigint',
+				value: 'bigint',
+			},{
+				label: 'tinyint',
+				value: 'tinyint',
+			},{
+				label: 'float',
+				value: 'float',
+			},{
+				label: 'double',
+				value: 'double',
+			},{
+				label: 'text',
+				value: 'text',
+			},{
+				label: 'datetime',
+				value: 'datetime',
+			},{
+				label: 'timestamp',
+				value: 'timestamp',
+			}],
+			ruledata:  [
+				{
+					expression: '',
+					params: {
+						name: '',
+						value: '',
+					},
+				},
+			],
+			rule: [
+				{
+					expression: '',
+					params: {
+						name: '',
+						value: '',
+					},
+				},
+			],
+			
+		
+
+		
+			ruleForm: {
+				nodeId: 0,
+				name: '',
+				key: '',
+				dataType:'',
+				value:'',
+				rule: [],
+				
+				description: '',
+			},
+			rules: {
+				key: [{ required: true, message: '数据节点标识不能为空', trigger: 'blur' }],
+				name: [{ required: true, message: '数据节点名称不能为空', trigger: 'blur' }],
+				dataType: [{ required: true, message: '数据节点类型不能为空', trigger: 'blur' }],
+				value: [{ required: true, message: '数据节点取值项不能为空', trigger: 'blur' }],
+			
+			},
+		});
+		
+
+		const delRule = (index) => {
+			state.rule.splice(index, 1);
+		};
+
+		const addRule = () => {
+			state.rule.push({
+				expression: '',
+				params: {
+					name: '',
+					value: '',
+				},
+			});
+		};
+		// 打开弹窗
+		const openDialog = (row: RuleFormState | null) => {
+			resetForm();
+
+			if (row?.nodeId) {
+
+				  state.ruleForm = row
+
+				 var data=JSON.parse(row.rule)
+           			 console.log(data);
+
+					data.forEach((item, index) => {
+						state.rule[index].expression = item.expression;
+						state.rule[index].params.name =Object.keys(item.params) ;
+						state.rule[index].params.value = item.params[Object.keys(item.params)];
+					});
+			}
+
+			state.ruleForm = row;
+			state.isShowDialog = true;
+		};
+		const resetForm = () => {
+			state.ruleForm = {
+				nodeId: 0,
+				name: '',
+				from: 1,
+				key: '',
+				rule: [],
+				
+				description: '',
+			};
+		};
+		// 关闭弹窗
+		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) {
+					//修改rule数据
+					state.rule.forEach((item, index) => {
+						item.params[item.params.name] = item.params.value;
+						delete item.params.name;
+						delete item.params.value;
+					});
+
+					state.ruleForm.rule = state.rule;
+
+					if (state.ruleForm.nodeId !== 0) {
+						//修改
+						api.node.edit(state.ruleForm).then(() => {
+							ElMessage.success('数据节点类型修改成功');
+							closeDialog(); // 关闭弹窗
+							emit('typeList');
+						});
+					} else {
+						//添加
+
+						api.node.add(state.ruleForm).then(() => {
+							ElMessage.success('数据节点类型添加成功');
+							closeDialog(); // 关闭弹窗
+							emit('typeList');
+						});
+					}
+				}
+			});
+		};
+
+		return {
+			addRule,
+			delRule,
+			openDialog,
+			closeDialog,
+			onCancel,
+			onSubmit,
+			formRef,
+			...toRefs(state),
+		};
+	},
+});
+</script>
+<style>
+.el-input__wrapper {
+	width: 98%;
+}
+
+.box-content {
+	border: 1px solid #e8e8e8;
+	margin: 10px;
+	padding: 10px;
+}
+
+.content-f {
+	display: flex;
+	margin-bottom: 10px;
+}
+.content-f .el-input__wrapper {
+	margin-right: 5px;
+}
+.addbutton {
+	width: 100%;
+	margin-top: 10px;
+}
+.conicon {
+	width: 55px;
+	height: 25px;
+
+	font-size: 28px;
+	line-height: 28px;
+	cursor: pointer;
+}
+</style>

+ 428 - 0
src/views/datahub/source/detail.vue

@@ -0,0 +1,428 @@
+<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="developer_status==1?'on':'off'"></span>{{developer_status==1?'已发布':'未发布'}}</div>
+			
+				<div class="pro-option"  @click="CkOption"> {{developer_status==1?'停用':'发布'}}</div>
+			</div>
+		</div>
+
+		<div class="content-box">
+                <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+
+                    <el-tab-pane label="数据源信息" name="1">
+                        
+                        <el-form size="default" label-width="110px" :inline="true">
+
+                        <el-divider content-position="left">基本信息</el-divider>
+
+                            <el-form-item label="数据源标识:">
+                                  {{detail.key}}
+                                </el-form-item>
+
+                                 <el-form-item label="数据源名称:">
+                                  {{detail.name}}
+                                </el-form-item>
+                                 <el-form-item label="数据源描述:">
+                                  {{detail.description}}
+                                </el-form-item>
+                                 <el-form-item label="数据来源:">
+                                 
+                                  <span v-if="detail.from==1">api导入</span>
+                                  <span v-if="detail.from==2">数据库</span>
+                                  <span v-if="detail.from==3">文件</span>
+                                </el-form-item>
+
+                                	<el-divider content-position="left">规则表达式</el-divider>
+
+
+                                    <div v-for="(item, index) in rule" :key="index">
+                                <el-form-item label="表达式:">
+                                   {{item.expression}}
+                                </el-form-item>
+
+                                <el-form-item label="参数:" >
+                                     {{item.params.name}}~ {{item.params.value}}
+                                   
+                                </el-form-item>
+
+                                <el-divider content-position="left">数据源配置</el-divider>
+
+                                <el-form-item label="请求方法:" prop="method">
+                                        {{config.method}}
+                                </el-form-item>
+                                <el-form-item label="请求地址:" prop="method">
+                                        {{config.url}}
+                                </el-form-item>
+                                 <el-form-item label="更新时间:" prop="method">
+                                        {{config.interval}}
+                                        {{config.intervalUnit}}
+                                </el-form-item>
+
+                                <el-divider content-position="left">请求参数</el-divider>
+
+                                <div class="content-f" v-for="(item, index) in requestParams" :key="index">
+
+                                <el-form-item label="参数类型:">
+                                        {{item.type}}
+                                </el-form-item>
+                                <el-form-item label="参数标题:">
+                                        {{item.name}}
+                                </el-form-item>
+                                 <el-form-item label="参数名:">
+                                        {{item.key}}
+                                </el-form-item>
+                                 <el-form-item label="参数值:">
+                                        {{item.value}}
+                                </el-form-item>
+
+                                    
+                                       
+                                    </div>
+                            </div>
+                        </el-form>
+
+                    </el-tab-pane>
+
+                    <el-tab-pane label="数据节点" name="2">
+                        <div class="wu-box">
+                            <div class="wu-title">
+									<div class="title">数据节点</div>
+									<div><el-button type="primary" @click="onOpenEdit()">添加</el-button></div>
+								</div>
+
+                         <el-table :data="tableData.data" style="width: 100%" >
+        <el-table-column label="ID" align="center" prop="nodeId" width="80" />
+        <el-table-column label="数据标识" prop="key" :show-overflow-tooltip="true" />
+        <el-table-column label="数据名称" prop="name" :show-overflow-tooltip="true" />
+        <el-table-column label="数据类型" prop="dataType" :show-overflow-tooltip="true" />
+        <el-table-column label="数据取值项" prop="value" :show-overflow-tooltip="true" />
+        
+   
+
+		  <el-table-column prop="createdAt" label="创建时间" align="center" width="180"></el-table-column> 
+
+        <el-table-column label="操作" width="200" align="center">
+          <template #default="scope">
+	
+
+            <el-button size="small" text type="warning" @click="onOpenEdit1(scope.row)">修改</el-button>
+            <el-button size="small" text type="danger" @click="onRowDel(scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination v-show="tableData.total>0" :total="tableData.total" v-model:page="tableData.param.pageNum" v-model:limit="tableData.param.pageSize" @pagination="typeList" />
+           </div>         
+                    </el-tab-pane>
+
+                </el-tabs>
+
+
+
+
+        </div>
+ <EditDic ref="editDicRef" @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 { ElMessageBox, ElMessage, FormInstance } from 'element-plus';
+import { useRoute } from 'vue-router';
+import EditDic from './component/editNode.vue';
+import api from '/@/api/datahub';
+
+interface TableDataState {
+	ids: number[];
+	tableData: {
+		data: [];
+		total: number;
+		loading: boolean;
+		param: {
+			pageNum: number;
+			pageSize: number;
+			name: string;
+			deviceType: string;
+			status: string;
+			dateRange: string[];
+		};
+	};
+}
+export default defineComponent({
+    name: 'dataDetail',
+    components: { EditDic },
+    setup(prop, context) {
+        		const editDicRef = ref();
+
+		const route = useRoute();
+        const state = reactive<TableDataState>({
+            config: {},
+			ruledata: [
+				{
+					expression: '',
+					params: {},
+				},
+			],
+			rule: [
+				{
+					expression: '',
+					params: {
+						name: '',
+						value: '',
+					},
+				},
+			],
+			requestParams: [
+				{
+					type: '',
+					key: '',
+					name: '',
+					value: '',
+				},
+			],
+          
+			isShowDialog: false,
+			detail: [],
+            activeName: '1',
+			developer_status:0,
+			tableData: {
+				data: [],
+				total: 0,
+				loading: false,
+				param: {
+					pageNum: 1,
+					pageSize: 10,
+                    sourceId: route.params && route.params.sourceId,
+					status: '',
+					dateRange: [],
+				},
+			},
+		});
+
+
+
+        onMounted(() => {
+			const ids = route.params && route.params.sourceId;
+			api.common.detail(ids).then((res: any) => {
+				state.detail = res.data;
+				state.developer_status=res.data.status
+				state.config=res.data.apiConfig
+				state.requestParams=res.data.apiConfig.requestParams
+                res.data.sourceRule.forEach((item, index) => {
+						state.rule[index].expression = item.expression;
+						state.rule[index].params.name =Object.keys(item.params) ;
+						state.rule[index].params.value = item.params[Object.keys(item.params)];
+					});
+
+           	
+			});
+
+                typeList();
+		});
+
+        const typeList = () => {
+			api.node.getList(state.tableData.param).then((res: any) => {
+				state.tableData.data = res.list;
+				state.tableData.total = res.Total;
+			});
+		};
+
+
+        const CkOption=()=>{
+                if(state.developer_status==1){
+                    api.common.undeploy({sourceId:route.params.sourceId}).then((res: any) => {
+                        ElMessage.success('操作成功');
+                        state.developer_status=0;
+                    });
+                }else{
+                    api.common.deploy({sourceId:route.params.sourceId}).then((res: any) => {
+                        ElMessage.success('操作成功');
+                        state.developer_status=1;
+                    });
+                }
+		}
+        const handleClick = (tab: TabsPaneContext, event: Event) => {
+			console.log(tab, event);
+		};
+
+        	const onRowDel = (row: TableDataRow) => {
+			let msg = '你确定要删除所选数据?';
+			let ids: number[] = [];
+			if (row) {
+				msg = `此操作将永久删除数据节点:“${row.name}”,是否继续?`;
+				ids = row.nodeId;
+			} else {
+				ids = state.ids;
+			}
+			if (ids.length === 0) {
+				ElMessage.error('请选择要删除的数据。');
+				return;
+			}
+			ElMessageBox.confirm(msg, '提示', {
+				confirmButtonText: '确认',
+				cancelButtonText: '取消',
+				type: 'warning',
+			})
+				.then(() => {
+					api.node.delete(ids).then(() => {
+						ElMessage.success('删除成功');
+						typeList();
+					});
+				})
+				.catch(() => {});
+		};
+
+        	// 打开修改数据源弹窗
+		const onOpenEdit = () => {
+			editDicRef.value.openDialog({ sourceId: route.params.sourceId, nodeId: 0 });
+		};
+        const onOpenEdit1 = (row: TableDataRow) => {
+			editDicRef.value.openDialog(row);
+		};
+
+        	return {
+			Edit,
+            editDicRef,
+            typeList,
+            onRowDel,
+            onOpenEdit,
+            onOpenEdit1,
+            handleClick,
+			CkOption,
+			...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;
+	cursor: pointer;
+}
+.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>

+ 73 - 43
src/views/datahub/source/index.vue

@@ -3,20 +3,22 @@
     <el-card shadow="hover">
       <div class="system-user-search mb15">
         <el-form :model="tableData.param" ref="queryRef" :inline="true" >
+
+		 <el-form-item label="数据源标识" prop="key">
+            <el-input v-model="tableData.param.key" placeholder="数据源标识" clearable size="default" style="width: 240px" @keyup.enter.native="typeList" />
+          </el-form-item>
           <el-form-item label="数据源名称" prop="name">
             <el-input v-model="tableData.param.name" placeholder="请输入数据源名称" clearable size="default" style="width: 240px" @keyup.enter.native="typeList" />
           </el-form-item>
-		  <el-form-item label="数据源类型" prop="types">
-            <el-input v-model="tableData.param.types" placeholder="请输入数据源类型" clearable size="default" style="width: 240px" @keyup.enter.native="typeList" />
-          </el-form-item>
-          <el-form-item label="数据源地址" prop="host">
-            <el-input v-model="tableData.param.host" placeholder="请输入数据源地址" clearable size="default" style="width: 240px" @keyup.enter.native="typeList" />
+		 
+          <el-form-item label="数据源类型" prop="host">
+				<el-select v-model="tableData.param.from" placeholder="请选择数据源类型" @keyup.enter.native="typeList">
+						<el-option v-for="item in typeData" :key="item.value" :label="item.label" :value="item.value" />
+					</el-select>
           </el-form-item>
       
         
-          <el-form-item label="创建时间" prop="dateRange">
-            <el-date-picker v-model="tableData.param.dateRange" size="default" style="width: 240px" value-format="YYYY-MM-DD" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
-          </el-form-item>
+         
           <el-form-item>
             <el-button size="default" type="primary" class="ml10" @click="typeList">
               <el-icon>
@@ -36,28 +38,42 @@
               </el-icon>
               新增数据源
             </el-button>
-      
+       <el-button size="default" type="danger" class="ml10" @click="onRowDel(null)">
+              <el-icon>
+                <ele-Delete />
+              </el-icon>
+              删除
+            </el-button>
           </el-form-item>
         </el-form>
       </div>
       <el-table :data="tableData.data" style="width: 100%" @selection-change="handleSelectionChange">
         <el-table-column type="selection" width="55" align="center" />
-        <el-table-column label="ID" align="center" prop="id" width="80" />
+        <el-table-column label="ID" align="center" prop="sourceId" width="80" />
+        <el-table-column label="数据源标识" prop="key" :show-overflow-tooltip="true" />
         <el-table-column label="数据源名称" prop="name" :show-overflow-tooltip="true" />
-        <el-table-column label="类型" prop="types" :show-overflow-tooltip="true" />
-        <el-table-column label="地址" prop="host" :show-overflow-tooltip="true" />
-        <el-table-column label="端口" prop="port" :show-overflow-tooltip="true" />
-       
-        
+         <el-table-column prop="from" label="数据源类型"  align="center">
+          <template #default="scope">
+		  	<span v-if="scope.row.from==1">api导入</span>
+		  	<span v-if="scope.row.from==2">数据库</span>
+		  	<span v-if="scope.row.from==3">文件</span>
+          </template>
+        </el-table-column>
         <el-table-column prop="status" label="状态" width="120" align="center">
           <template #default="scope">
-            <el-tag type="success" size="small" v-if="scope.row.status==1">启用</el-tag>
-            <el-tag type="info" size="small" v-if="scope.row.status==0">未启用</el-tag>
+            <el-tag type="success" size="small" v-if="scope.row.status==1">已发布</el-tag>
+            <el-tag type="info" size="small" v-if="scope.row.status==0">未发布</el-tag>
           </template>
         </el-table-column>
+
+		  <el-table-column prop="createdAt" label="创建时间" align="center" width="180"></el-table-column> 
+
         <el-table-column label="操作" width="200" align="center">
           <template #default="scope">
-		   			 <el-button size="small" text type="primary" @click="onOpenDetail(scope.row)">详情</el-button>
+		   	<router-link :to="'/datahub/source/detail/' + scope.row.sourceId" class="link-type" style="padding-right: 12px;
+    font-size: 12px;color: #409eff;">
+              <span>详情</span>
+            </router-link>
 
             <el-button size="small" text type="warning" @click="onOpenEdit(scope.row)">修改</el-button>
             <el-button size="small" text type="danger" @click="onRowDel(scope.row)">删除</el-button>
@@ -77,15 +93,14 @@ import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
 import { ElMessageBox, ElMessage, FormInstance } from 'element-plus';
 import EditDic from './component/edit.vue';
 import api from '/@/api/datahub';
-import Detail from './component/detail.vue';
 
 // 定义接口来定义对象的类型
 interface TableDataRow {
-	id: number;
+	sourceId: number;
 	name: string;
 	key: string;
 	status: number;
-	desc: string;
+	from: string;
 	createBy: string;
 }
 interface TableDataState {
@@ -99,21 +114,34 @@ interface TableDataState {
 			pageSize: number;
 			name: string;
 			key: string;
-			status: string;
-			dateRange: string[];
+			from: string;
+			
 		};
 	};
 }
 
 export default defineComponent({
-	name: 'deviceInstance',
-	components: { EditDic,Detail },
+	name: 'sourcelist',
+	components: { EditDic },
 	setup() {
 		const addDicRef = ref();
 		const editDicRef = ref();
 		const queryRef = ref();
-		const detailRef=ref();
 		const state = reactive<TableDataState>({
+			typeData: [
+				{
+					label: 'api导入',
+					value: '1',
+				},
+				{
+					label: '数据库',
+					value: '2',
+				},
+				{
+					label: '文件',
+					value: '3',
+				},
+			],
 			ids: [],
 			tableData: {
 				data: [],
@@ -124,7 +152,7 @@ export default defineComponent({
 					pageSize: 10,
 					name: '',
 					types: '',
-					status:'-1',
+					status:'',
 				},
 			},
 		});
@@ -134,31 +162,38 @@ export default defineComponent({
 		};
 		const typeList = () => {
 			api.common.getList(state.tableData.param).then((res: any) => {
-				state.tableData.data = res.Data;
-				state.tableData.total = res.total;
+				state.tableData.data = res.list;
+				state.tableData.total = res.Total;
 			});
 		};
-		// 打开新增产品弹窗
+		// 打开新增数据源弹窗
 		const onOpenAdd = () => {
 			editDicRef.value.openDialog();
 		};
-		// 打开修改产品弹窗
+		// 打开修改数据源弹窗
 		const onOpenEdit = (row: TableDataRow) => {
 			editDicRef.value.openDialog(row);
 		};
-		// 删除产品
 		const onRowDel = (row: TableDataRow) => {
-
 			let msg = '你确定要删除所选数据?';
-			msg = `此操作将永久删除数据源:“${row.name}”,是否继续?`;
-			
+			let ids: number[] = [];
+			if (row) {
+				msg = `此操作将永久删除数据源:“${row.name}”,是否继续?`;
+				ids = [row.sourceId];
+			} else {
+				ids = state.ids;
+			}
+			if (ids.length === 0) {
+				ElMessage.error('请选择要删除的数据。');
+				return;
+			}
 			ElMessageBox.confirm(msg, '提示', {
 				confirmButtonText: '确认',
 				cancelButtonText: '取消',
 				type: 'warning',
 			})
 				.then(() => {
-					api.common.delete(row.id).then(() => {
+					api.common.delete(ids).then(() => {
 						ElMessage.success('删除成功');
 						typeList();
 					});
@@ -177,19 +212,14 @@ export default defineComponent({
 		};
 		// 多选框选中数据
 		const handleSelectionChange = (selection: TableDataRow[]) => {
-			state.ids = selection.map((item) => item.id);
+			state.ids = selection.map((item) => item.sourceId);
 		};
-		//查看详情
-		const onOpenDetail=(row: TableDataRow)=>{
-			detailRef.value.openDialog(row);
-		}
+	
 		return {
 			addDicRef,
 			editDicRef,
 			queryRef,
-			detailRef,
 			onOpenAdd,
-			onOpenDetail,
 			onOpenEdit,
 			onRowDel,
 			typeList,

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

@@ -9,7 +9,7 @@
 		  <el-form-item label="设备标识" prop="key">
             <el-input v-model="tableData.param.key" placeholder="请输入产品名称" clearable size="default" style="width: 240px" @keyup.enter.native="typeList" />
           </el-form-item>
-          
+
           <el-form-item label="状态" prop="status" style="width: 200px;">
             <el-select v-model="tableData.param.status" placeholder="状态" clearable size="default" style="width: 240px">
               <el-option label="在线" :value="2" />
@@ -17,7 +17,7 @@
               <el-option label="未启用" :value="0" />
             </el-select>
           </el-form-item>
-        
+
           <el-form-item label="创建时间" prop="dateRange">
             <el-date-picker v-model="tableData.param.dateRange" size="default" style="width: 240px" value-format="YYYY-MM-DD" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
           </el-form-item>
@@ -44,32 +44,32 @@
               <el-icon>
                 <ele-Delete />
               </el-icon>
-              删除删除
+              删除
             </el-button>
           </el-form-item>
         </el-form>
       </div>
       <el-table :data="tableData.data" style="width: 100%" @selection-change="handleSelectionChange">
         <el-table-column type="selection" width="55" align="center" />
-        <el-table-column label="ID" align="center" prop="id" width="80" />
-	    <el-table-column label="设备标识" prop="key" :show-overflow-tooltip="true" />
-        <el-table-column label="设备名称" prop="name" :show-overflow-tooltip="true" />
+        <el-table-column label="ID" align="center" prop="id" width="60" />
+	    <el-table-column label="标识" prop="key" :show-overflow-tooltip="true" />
+        <el-table-column label="名称" prop="name" :show-overflow-tooltip="true" />
         <el-table-column label="产品名称" prop="productName" :show-overflow-tooltip="true" />
-        <el-table-column label="部门名称" prop="deptName" :show-overflow-tooltip="true" />
-       
-        
-        <el-table-column prop="status" label="状态" width="120" align="center">
+        <el-table-column label="部门" prop="deptName" :show-overflow-tooltip="true" />
+
+
+        <el-table-column prop="status" label="状态" width="100" align="center">
           <template #default="scope">
             <el-tag type="info" size="small" v-if="scope.row.status==1">离线</el-tag>
             <el-tag type="success" size="small" v-if="scope.row.status==2">在线</el-tag>
             <el-tag type="info" size="small" v-if="scope.row.status==0">未启用</el-tag>
           </template>
         </el-table-column>
-         <el-table-column prop="registryTime" label="激活时间" align="center" width="180"></el-table-column> 
-         <el-table-column prop="lastOnlineTime" label="最后上线时间" align="center" width="180"></el-table-column> 
+         <el-table-column prop="registryTime" label="激活时间" align="center" width="150"></el-table-column>
+         <el-table-column prop="lastOnlineTime" label="最后上线时间" align="center" width="150"></el-table-column>
         <el-table-column label="操作" width="200" align="center">
           <template #default="scope">
-	
+
 			 <el-button size="small" text type="primary" @click="onOpenDetail(scope.row)">详情</el-button>
             <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>

+ 8 - 8
src/views/heatStation/loop/index.vue

@@ -52,10 +52,10 @@
       <el-table :data="tableData.data" style="width: 100%" @selection-change="handleSelectionChange">
         <!-- <el-table-column type="selection" width="55" align="center" /> -->
         <el-table-column label="ID" align="center" prop="id" width="60" />
-	    	<el-table-column label="环路名称" prop="name" :show-overflow-tooltip="true" />
-	    	<el-table-column label="环路编号" prop="code" :show-overflow-tooltip="true" />
-	    	<el-table-column label="所属换热站" prop="stationId" :show-overflow-tooltip="true" />
-	    	<el-table-column label="环路类型" prop="loopTypes">
+        <el-table-column label="编号" prop="code" :show-overflow-tooltip="true" />
+        <el-table-column label="名称" prop="name" :show-overflow-tooltip="true" />
+	    	<el-table-column label="换热站" prop="stationId" :show-overflow-tooltip="true" />
+	    	<el-table-column label="类型" prop="loopTypes">
           <template #default="scope">
             <el-tag type="success" size="small" v-if="scope.row.loopTypes === 1">一网</el-tag>
             <el-tag type="info" size="small" v-else-if="scope.row.loopTypes === 2">二网</el-tag>
@@ -80,14 +80,14 @@
         </el-table-column>
 	    	<el-table-column label="供暖面积" prop="heatingArea" :show-overflow-tooltip="true" />
 	    	<el-table-column label="实际面积" prop="forRealArea" :show-overflow-tooltip="true" />
-	    	<el-table-column label="环路年代" prop="decade" :show-overflow-tooltip="true" />
+<!--	    	<el-table-column label="环路年代" prop="decade" :show-overflow-tooltip="true" />-->
         <el-table-column prop="status" label="状态" align="center">
           <template #default="scope">
-            <el-tag type="success" size="small" v-if="scope.row.status === 0">不在线</el-tag>
-            <el-tag type="info" size="small" v-else-if="scope.row.status === 1">在线</el-tag>
+            <el-tag type="info" size="small" v-if="scope.row.status === 0">不在线</el-tag>
+            <el-tag type="success" size="small" v-else-if="scope.row.status === 1">在线</el-tag>
           </template>
         </el-table-column>
-        <el-table-column label="操作" width="200" align="center">
+        <el-table-column label="操作" width="150" align="center">
           <template #default="scope">
 			 			<el-button size="small" text type="primary" @click="onOpenDetail(scope.row)">详情</el-button>
             <el-button size="small" text type="warning" @click="onOpenEditDic(scope.row)">修改</el-button>

+ 11 - 1
src/views/heatingDistrict/floorManage/component/edit.vue

@@ -48,6 +48,10 @@
 				<el-form-item label="楼号" prop="number">
 					<el-input v-model="ruleForm.number" placeholder="请输入楼号" />
 				</el-form-item>
+				<el-form-item label="状态" prop="status">
+					<el-radio v-model="ruleForm.status" :label="1">启用</el-radio>
+					<el-radio v-model="ruleForm.status" :label="0">禁用</el-radio>
+				</el-form-item>
 				<el-form-item label="备注" prop="remark">
 					<el-input type="textarea" :rows="8" v-model="ruleForm.remark" placeholder="请输入备注" />
 				</el-form-item>
@@ -87,6 +91,7 @@ export default defineComponent({
         heatId: '',
         number: '',
         remark: '',
+				status: 1
 			},
 			rules: {
 				name: [{ required: true, message: '楼宇名称不能为空', trigger: ['blur', 'change'] }],
@@ -113,7 +118,12 @@ export default defineComponent({
 			state.ruleForm = {
 				id: 0,
 				name: '',
-        organizationId: ''
+        organizationId: '',
+        plotId: '',
+        heatId: '',
+        number: '',
+        remark: '',
+				status: 1
 			}
 		}
 		// 关闭弹窗

+ 10 - 10
src/views/heatingDistrict/floorManage/index.vue

@@ -64,19 +64,19 @@
       <el-table :data="tableData.data" style="width: 100%" >
         <!-- <el-table-column type="selection" width="55" align="center" /> -->
         <el-table-column label="ID" align="center" prop="id" width="60" />
-	    	<el-table-column label="组织名称" prop="">
-					<template #default="{ row }">
-						{{ row.SysOrganization.name }}
-					</template>
-				</el-table-column>
-	    	<el-table-column label="小区名称" prop="">
-					<template #default="{ row }">
-						{{ row.ZhgyPlotInfo.name }}
-					</template>
-				</el-table-column>
 	    	<el-table-column label="楼宇名称" prop="name" />
 	    	<el-table-column label="楼号" prop="number" />
 	    	<!-- <el-table-column label="单元数" prop="name" /> -->
+        <el-table-column label="小区名称" prop="">
+          <template #default="{ row }">
+            {{ row.ZhgyPlotInfo ? row.ZhgyPlotInfo.name : '-' }}
+          </template>
+        </el-table-column>
+        <el-table-column label="组织名称" prop="">
+          <template #default="{ row }">
+            {{ row.SysOrganization ? row.SysOrganization.name : '-' }}
+          </template>
+        </el-table-column>
 	    	<el-table-column label="更新时间" prop="createdAt" />
         <el-table-column label="操作" width="200" align="center">
           <template #default="scope">

+ 7 - 1
src/views/heatingDistrict/regionalManage/component/edit.vue

@@ -20,6 +20,10 @@
 				<el-form-item label="小区名称" prop="name">
 					<el-input v-model="ruleForm.name" placeholder="请输入小区名称" />
 				</el-form-item>
+				<el-form-item label="状态" prop="status">
+					<el-radio v-model="ruleForm.status" :label="1">启用</el-radio>
+					<el-radio v-model="ruleForm.status" :label="0">禁用</el-radio>
+				</el-form-item>
 			</el-form>
 			<template #footer>
 				<span class="dialog-footer">
@@ -51,6 +55,7 @@ export default defineComponent({
 				id: 0,
 				name: '',
         organizationId: '',
+				status: 1
 			},
 			rules: {
 				name: [{ required: true, message: '小区名称不能为空', trigger: ['blur', 'change'] }],
@@ -71,7 +76,8 @@ export default defineComponent({
 			state.ruleForm = {
 				id: 0,
 				name: '',
-        organizationId: ''
+        organizationId: '',
+				status: 1
 			}
 		}
 		// 关闭弹窗

+ 2 - 2
src/views/heatingDistrict/regionalManage/index.vue

@@ -54,12 +54,12 @@
       <el-table :data="tableData.data" style="width: 100%" >
         <!-- <el-table-column type="selection" width="55" align="center" /> -->
         <el-table-column label="ID" align="center" prop="id" width="60" />
-	    	<el-table-column label="组织名称" prop="">
+        <el-table-column label="小区名称" prop="name" />
+        <el-table-column label="组织名称" prop="">
 					<template #default="{ row }">
 						{{ row.SysOrganization.name }}
 					</template>
 				</el-table-column>
-	    	<el-table-column label="小区名称" prop="name" />
 	    	<el-table-column label="更新时间" prop="createdAt" />
         <el-table-column label="操作" width="200" align="center">
           <template #default="scope">

+ 200 - 0
src/views/heatingDistrict/residentManage/component/detail.vue

@@ -0,0 +1,200 @@
+<template>
+	<div class="system-edit-dic-container">
+		<el-dialog :title="'环路详情'" v-model="dialogVisible" width="950px">
+			<el-form :model="ruleForm" ref="formRef" size="default" label-width="110px">
+				<el-form-item label="环路名称" prop="name">
+					{{ ruleForm.name }}
+				</el-form-item>
+				<el-form-item label="环路编号" prop="code">
+					{{ ruleForm.code }}
+				</el-form-item>
+				<el-form-item label="所属换热站" prop="stationId">
+          {{ ruleForm.stationId }}
+					<!-- <el-tree-select
+						v-model="ruleForm.stationId"
+						:data="treeData"
+						:props="{
+							label: 'name',
+							children: 'children'
+						}"
+						node-key="id"
+						:clearable="true"
+						check-strictly
+						style="width: 100%;"
+						:render-after-expand="true"
+					/> -->
+				</el-form-item>
+        <el-form-item label="环路类型" prop="loopTypes">
+          {{ ruleForm.loopTypes === 1 ? '一网' : '二网' }}
+        </el-form-item>
+        <el-form-item label="节能类型" prop="energyTypes">
+          {{ ruleForm.energyTypes === 1 ? '节能' : '' }}
+        </el-form-item>
+        <el-row :gutter="10">
+          <el-col :span="12">
+            <el-form-item label="供暖对象" prop="heatingObject">
+              {{ ruleForm.heatingObject === 1 ? '公建' : '居民' }}
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="供暖类型" prop="heatingTypes">
+              {{ ruleForm.heatingTypes === 1 ? '地暖' : '暖气片' }}
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="10">
+          <el-col :span="12">
+            <el-form-item label="供暖面积" prop="heatingArea">
+              {{ ruleForm.heatingArea }}
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="实际面积" prop="forRealArea">
+              {{ ruleForm.forRealArea }}
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="环路年代" prop="decade">
+          {{ ruleForm.decade }}
+        </el-form-item>
+				<el-form-item label="状态" prop="status">
+          {{ ruleForm.decade === 1 ? '在线' : '不在线' }}
+				</el-form-item>
+        <el-form-item label="路线信息" prop="">
+					<div class="mb10" style="width: 100%">
+						<div style="display: flex;" class="mb10" v-for="(item, index) in pointList" :key="index">
+							<el-input v-model="item.position" :disabled="!item.editFalg" @keydown="onLocalChange(item, index)" @change="onLocalChange(item, index)" placeholder="请输入关键字进行搜索" clearable style="flex: 1; margin-right: 10px"></el-input>
+							<span>排序:</span>
+							<el-input-number v-model="item.sort" :controls="false" :disabled="!item.editFalg" placeholder="排序" clearable style="width: 100px; margin-right: 10px"></el-input-number>
+						</div>
+					</div>
+        </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 } from 'vue';
+import api from '/@/api/heatStation';
+import { ElMessage } from 'element-plus';
+interface Point {
+	sort?: number;
+	lnt: number;
+	lat: number
+}
+interface RuleFormState {
+	id?: number;
+	name: string;
+	code: string;
+	stationId: string;
+	loopTypes: string;
+	energyTypes: string;
+	heatingObject: string;
+	heatingTypes: string;
+	heatingArea: string;
+	forRealArea: string;
+	viaPoint: Array<Point>;
+	decade: string;
+	status: number;
+}
+
+export default defineComponent({
+	name: 'headStationLoop',
+	setup(prop, { emit }) {
+		const formRef = ref<HTMLElement | null>(null);
+		const state = reactive({
+			dialogVisible: false,
+			ruleForm: {
+				id: 0,
+				name: '',
+        code: '',
+        stationId: '',
+        loopTypes: '',
+        energyTypes: '',
+        heatingObject: '',
+        heatingTypes: '',
+        heatingArea: '',
+        forRealArea: '',
+        decade: '',
+				viaPoint: [],
+        status: 1
+			},
+			treeData: [],
+      pointList: [] as any
+		})
+		// 打开弹窗
+		const openDialog = (row: RuleFormState | null) => {
+			resetForm()
+			queryTree()
+			if (row) {
+				(state.ruleForm as any).id = row.id
+				getDetail()
+			}
+			state.dialogVisible = true
+		}
+		const resetForm = () => {
+			state.ruleForm = {
+				id: 0,
+				name: '',
+        code: '',
+        stationId: '',
+        loopTypes: '',
+        energyTypes: '',
+        heatingObject: '',
+        heatingTypes: '',
+        heatingArea: '',
+        forRealArea: '',
+				viaPoint: [],
+        decade: '',
+        status: 1
+			}
+		}
+		// 关闭弹窗
+		const closeDialog = () => {
+			state.dialogVisible = false
+		}
+		// 取消
+		const onCancel = () => {
+			closeDialog()
+			state.pointList = []
+		}
+		const queryTree = () => {
+			api.heatStation.getList({
+					name: '',
+					code: '',
+					status: -1
+				})
+				.then((res: any) => {
+					state.treeData = res || [];
+				});
+		};
+		const getDetail = () => {
+			api.loop.detail(state.ruleForm.id)
+				.then((res: any) => {
+					state.ruleForm = {
+						...res
+					}
+					state.pointList = state.ruleForm.viaPoint.map((item: any) => ({
+						...item,
+						editFlag: false
+					}))
+				})
+		}
+
+		return {
+			openDialog,
+			closeDialog,
+			onCancel,
+			formRef,
+			...toRefs(state)
+		}
+	}
+})
+</script>

+ 277 - 0
src/views/heatingDistrict/residentManage/component/edit.vue

@@ -0,0 +1,277 @@
+<template>
+	<div class="system-edit-dic-container">
+		<el-dialog :title="(ruleForm.id !== 0 ? '修改' : '添加') + '住户'" v-model="dialogVisible" width="550px">
+			<el-form :model="ruleForm" ref="formRef" :rules="rules" size="default" label-width="110px">
+				<el-form-item label="所属组织" prop="organizationId">
+					<el-tree-select
+						v-model="ruleForm.organizationId"
+						:data="orgList"
+						:props="{
+							label: 'name',
+							children: 'children'
+						}"
+						node-key="id"
+						:clearable="true"
+						check-strictly
+						style="width: 100%;"
+						:render-after-expand="true"
+					/>
+				</el-form-item>
+				<el-form-item label="所属换热站" prop="">
+					<el-tree-select
+						v-model="ruleForm.heatId"
+						:data="heatList"
+						:props="{
+							label: 'name',
+							children: 'children'
+						}"
+						node-key="id"
+						:clearable="true"
+						check-strictly
+						style="width: 100%;"
+						:render-after-expand="true"
+					/>
+				</el-form-item>
+				<el-form-item label="小区名称" prop="plotId">
+					<el-select v-model="ruleForm.plotId" @change="onPlotChange" placeholder="选择小区名称" filterable clearable size="default" style="width: 100%">
+						<el-option
+							v-for="item in plotList"
+							:key="item.id"
+							:label="item.name"
+							:value="item.id">
+						</el-option>
+					</el-select>
+				</el-form-item>
+				<el-form-item label="楼宇名称" prop="floorId">
+					<el-select v-model="ruleForm.floorId" @change="onFloorChange" placeholder="选择楼宇名称" filterable clearable size="default" style="width: 100%">
+						<el-option
+							v-for="item in floorList"
+							:key="item.id"
+							:label="item.name"
+							:value="item.id">
+						</el-option>
+					</el-select>
+				</el-form-item>
+				<el-form-item label="单元名称" prop="unitId">
+					<el-select v-model="ruleForm.unitId" placeholder="选择单元名称" filterable clearable size="default" style="width: 100%">
+						<el-option
+							v-for="item in unitList"
+							:key="item.id"
+							:label="item.name"
+							:value="item.id">
+						</el-option>
+					</el-select>
+				</el-form-item>
+				<el-form-item label="住户姓名" prop="name">
+					<el-input v-model="ruleForm.name" placeholder="请输入住户姓名" />
+				</el-form-item>
+				<el-form-item label="楼层" prop="floorLevel">
+					<el-input v-model="ruleForm.floorLevel" placeholder="请输入楼层" />
+				</el-form-item>
+				<el-form-item label="房间号" prop="roomNumber">
+					<el-input v-model="ruleForm.roomNumber" placeholder="请输入房间号" />
+				</el-form-item>
+				<el-form-item label="电话号码" prop="phone">
+					<el-input v-model="ruleForm.phone" placeholder="请输入电话号码" />
+				</el-form-item>
+				<el-form-item label="建筑面积" prop="buildingArea">
+					<el-input v-model="ruleForm.buildingArea" placeholder="请输入建筑面积" />
+				</el-form-item>
+				<el-form-item label="实供面积" prop="forRealArea">
+					<el-input v-model="ruleForm.forRealArea" placeholder="请输入实供面积" />
+				</el-form-item>
+				<el-form-item label="状态" prop="status">
+					<el-radio v-model="ruleForm.status" :label="1">启用</el-radio>
+					<el-radio v-model="ruleForm.status" :label="0">禁用</el-radio>
+				</el-form-item>
+				<el-form-item label="备注" prop="remark">
+					<el-input type="textarea" :rows="8" v-model="ruleForm.remark" placeholder="请输入备注" />
+				</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, nextTick } from 'vue';
+import api from '/@/api/heatingDistrict';
+import heatApi from '/@/api/heatStation';
+import { ElMessage } from 'element-plus';
+interface RuleFormState {
+	id?: number;
+	name: string;
+	organizationId: string;
+}
+
+export default defineComponent({
+	name: 'edit',
+	setup(prop, { emit }) {
+		const formRef = ref<HTMLElement | null>(null);
+		const state = reactive({
+			dialogVisible: false,
+			ruleForm: {
+				id: 0,
+				organizationId: '',
+				heatId: '',
+				plotId: '',
+				floorId: '',
+				unitId: '',
+				name: '',
+				floorLevel: '',
+				roomNumber: '',
+				phone: '',
+				buildingArea: '',
+				forRealArea: '',
+				remark: '',
+				status: 1
+			},
+			rules: {
+				name: [{ required: true, message: '住户名称不能为空', trigger: ['blur', 'change'] }],
+				organizationId: [{ required: true, message: '所属组织不能为空', trigger: ['blur', 'change'] }],
+				plotId: [{ required: true, message: '小区名称不能为空', trigger: ['blur', 'change'] }],
+				floorId: [{ required: true, message: '楼宇名称不能为空', trigger: ['blur', 'change'] }],
+				unitId: [{ required: true, message: '单元名称不能为空', trigger: ['blur', 'change'] }],
+				heatId: [{ required: true, message: '所属换热站不能为空', trigger: ['blur', 'change'] }],
+				floorLevel: [{ required: true, message: '楼层不能为空', trigger: ['blur', 'change'] }],
+				roomNumber: [{ required: true, message: '房间号不能为空', trigger: ['blur', 'change'] }],
+				phone: [{ required: true, message: '手机号码不能为空', trigger: ['blur', 'change'] }],
+				forRealArea: [{ required: true, message: '实供面积不能为空', trigger: ['blur', 'change'] }],
+				buildingArea: [{ required: true, message: '建筑面积不能为空', trigger: ['blur', 'change'] }],
+			},
+			orgList: [],
+			plotList: [],
+			floorList: [],
+			unitList: [],
+			heatList: []
+		})
+		// 打开弹窗
+		const openDialog = (row: RuleFormState | null) => {
+			resetForm()
+			queryTree()
+			if (row) {
+				(state.ruleForm as any).id = row.id
+				getDetail()
+			}
+			state.dialogVisible = true
+		}
+		const resetForm = () => {
+			state.ruleForm = {
+				id: 0,
+				organizationId: '',
+				heatId: '',
+				plotId: '',
+				floorId: '',
+				unitId: '',
+				name: '',
+				floorLevel: '',
+				roomNumber: '',
+				phone: '',
+				buildingArea: '',
+				forRealArea: '',
+				remark: '',
+				status: 1
+			}
+		}
+		// 关闭弹窗
+		const closeDialog = () => {
+			state.dialogVisible = false;
+			(formRef.value as any).clearValidate()
+		}
+		// 取消
+		const onCancel = () => {
+			closeDialog()
+		}
+		const queryTree = () => {
+			heatApi.heatStation.getList({
+					name: '',
+					code: '',
+					status: -1
+				})
+				.then((res: any) => {
+					state.heatList = res || [];
+				});
+		};
+		const getDetail = () => {
+			api.floor.detail(state.ruleForm.id)
+				.then((res: any) => {
+					state.ruleForm = {
+						...res
+					}
+				})
+		}
+		// 获取楼宇
+		const getFloorList = () => {
+			api.floor.allList({})
+				.then((res: any) => {
+					state.floorList = res.Info || []
+				})
+		}
+		// 获取单元
+		const getUnitList = () => {
+			api.unit.getListByFloorId({ floorId: state.ruleForm.floorId })
+				.then((res: any) => {
+					(state.unitList as any) = res ? [res] : []
+				})
+		}
+		const onPlotChange = () => { 
+			state.floorList = []
+			state.unitList = []
+			state.ruleForm.floorId = ''
+			state.ruleForm.unitId = ''
+			if (state.ruleForm.plotId) {
+				getFloorList()
+			}
+		}
+		const onFloorChange = () => {
+			state.unitList = []
+			state.ruleForm.unitId = ''
+			if (state.ruleForm.floorId) {
+				getUnitList()
+			}
+		}
+		// 新增
+		const onSubmit = () => {
+			const formWrap = unref(formRef) as any
+			if (!formWrap) return;
+			formWrap.validate((valid: boolean) => {
+				if (valid) {
+					let params = { ...state.ruleForm }
+
+					if (params.id) {
+						//修改
+						api.resident.edit(params).then(() => {
+							ElMessage.success('单元修改成功')
+							closeDialog() // 关闭弹窗
+							emit('queryList')
+						})
+					} else {
+						//添加
+						api.resident.add(params).then(() => {
+							ElMessage.success('单元添加成功')
+							closeDialog() // 关闭弹窗
+							emit('queryList')
+						})
+					}
+				}
+			})
+		}
+
+		return {
+			openDialog,
+			closeDialog,
+			onCancel,
+			onSubmit,
+			formRef,
+			onPlotChange,
+			onFloorChange,
+			...toRefs(state)
+		}
+	}
+})
+</script>

+ 277 - 0
src/views/heatingDistrict/residentManage/index.vue

@@ -0,0 +1,277 @@
+<template>
+  <div class="system-dic-container">
+    <el-card shadow="hover">
+      <div class="system-user-search mb15">
+        <el-form :model="tableData.param" ref="queryRef" :inline="true" label-width="68px">
+          <el-form-item label="所属组织" prop="organizationId">
+						<el-tree-select
+							v-model="tableData.param.organizationId"
+							:data="orgList"
+							:props="{
+								label: 'name',
+								children: 'children'
+							}"
+							placeholder="请选择"
+							node-key="id"
+							:clearable="true"
+							check-strictly
+							style="width: 100%;"
+							:render-after-expand="true"
+							size="default"
+						/>
+          </el-form-item>
+          <el-form-item label="小区名称" prop="plotId">
+            <el-select v-model="tableData.param.plotId" @change="onPlotChange" placeholder="选择小区名称" filterable clearable size="default">
+							<el-option
+								v-for="item in plotList"
+								:key="item.id"
+								:label="item.name"
+								:value="item.id">
+							</el-option>
+						</el-select>
+          </el-form-item>
+          <el-form-item label="楼宇名称" prop="floorId">
+            <el-select v-model="tableData.param.floorId" @change="onFloorChange" placeholder="选择楼宇名称" filterable clearable size="default">
+							<el-option
+								v-for="item in floorList"
+								:key="item.id"
+								:label="item.name"
+								:value="item.id">
+							</el-option>
+						</el-select>
+          </el-form-item>
+          <el-form-item label="单元名称" prop="unitId">
+            <el-select v-model="tableData.param.unitId" placeholder="选择单元名称" filterable clearable size="default">
+							<el-option
+								v-for="item in unitList"
+								:key="item.id"
+								:label="item.name"
+								:value="item.id">
+							</el-option>
+						</el-select>
+          </el-form-item>
+          <el-form-item label="住户名称" prop="name">
+            <el-input v-model="tableData.param.name" placeholder="请输入住户名称" clearable size="default" style="width: 240px" @keyup.enter="queryList" />
+          </el-form-item>
+          <el-form-item>
+            <el-button size="default" type="primary" class="ml10" @click="queryList">
+              <el-icon>
+                <ele-Search />
+              </el-icon>
+              查询
+            </el-button>
+            <el-button size="default" @click="resetQuery(queryRef)">
+              <el-icon>
+                <ele-Refresh />
+              </el-icon>
+              重置
+            </el-button>
+            <el-button size="default" type="success" class="ml10" @click="onOpenDialog()">
+              <el-icon>
+                <ele-FolderAdd />
+              </el-icon>
+              新增
+            </el-button>
+            <!-- <el-button size="default" type="danger" class="ml10" @click="onRowDel(null)">
+              <el-icon>
+                <ele-Delete />
+              </el-icon>
+              删除
+            </el-button> -->
+          </el-form-item>
+        </el-form>
+      </div>
+      <el-table :data="tableData.data" style="width: 100%" >
+        <!-- <el-table-column type="selection" width="55" align="center" /> -->
+        <el-table-column label="ID" align="center" prop="id" width="60" />
+        <el-table-column label="组织名称" prop="">
+          <template #default="{ row }">
+            {{ row.SysOrganization.name }}
+          </template>
+        </el-table-column>
+        <el-table-column label="小区名称" prop="">
+          <template #default="{ row }">
+            {{ row.ZhgyPlotInfo.name }}
+          </template>
+        </el-table-column>
+        <el-table-column label="楼宇名称" prop="">
+          <template #default="{ row }">
+            {{ row.floorInfo.name }}
+          </template>
+        </el-table-column>
+	    	<el-table-column label="单元名称" prop="name" />
+	    	<el-table-column label="单元号" prop="number" />
+	    	<el-table-column label="住户姓名" prop="name" />
+	    	<el-table-column label="更新时间" prop="createdAt" />
+        <el-table-column label="操作" width="200" align="center">
+          <template #default="scope">
+            <el-button size="small" text type="warning" @click="onOpenDialog(scope.row)">修改</el-button>
+            <el-button size="small" text type="danger" @click="onRowDel(scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination v-show="tableData.total>0" :total="tableData.total" v-model:page="tableData.param.pageNum" v-model:limit="tableData.param.pageSize" @pagination="queryList" />
+    </el-card>
+    <EditDic ref="editDicRef" @queryList="queryList" />
+    <Detail ref="detailRef"  />
+  </div>
+</template>
+
+<script lang="ts">
+import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
+import { ElMessageBox, ElMessage, FormInstance } from 'element-plus';
+import EditDic from './component/edit.vue';
+import Detail from './component/detail.vue';
+import api from '/@/api/heatingDistrict';
+import systemApi from '/@/api/system';
+
+export default defineComponent({
+	name: 'loop',
+	components: { EditDic,Detail },
+	setup() {
+		const addDicRef = ref();
+		const editDicRef = ref();
+		const detailRef=ref();
+		const queryRef = ref();
+		const state = reactive({
+			ids: [],
+			tableData: {
+				data: [],
+				total: 0,
+				loading: false,
+				param: {
+					pageNum: 1,
+					pageSize: 10,
+					name: '',
+					plotId: '',
+					floorId: '',
+					unitId: '',
+					organizationId: '',
+					status: -1
+				},
+			},
+		});
+		// 组织
+		const orgList = ref([])
+		// 小区
+		const plotList = ref([])
+		// 楼宇
+		const floorList = ref([])
+		// 单元
+		const unitList = ref([])
+		// 初始化表格数据
+		const initTableData = () => {
+			queryList();
+		};
+		// 获取组织
+		const getOrgList = () => {
+			systemApi.org.getList({ name: '', status: -1 }).then((res: any) => {
+				orgList.value = res;
+			});
+		}
+		// 获取区域
+		const getPlotList = () => {
+			api.regionalManage.allList({})
+				.then((res: any) => {
+					plotList.value = res.Info || []
+				})
+		}
+		// 获取楼宇
+		const getFloorList = () => {
+			api.floor.allList({})
+				.then((res: any) => {
+					floorList.value = res.Info || []
+				})
+		}
+		// 获取单元
+		const getUnitList = () => {
+			api.unit.getListByFloorId({ floorId: state.tableData.param.floorId })
+				.then((res: any) => {
+					(unitList.value as any) = res ? [res] : []
+				})
+		}
+		const queryList = () => {
+			api.resident.getList(state.tableData.param).then((res: any) => {
+				console.log(res);
+				state.tableData.data = res.Info || [];
+				state.tableData.total = res.Total;
+			});
+		};
+		const onPlotChange = () => { 
+			floorList.value = []
+			unitList.value = []
+			state.tableData.param.floorId = ''
+			state.tableData.param.unitId = ''
+			if (state.tableData.param.plotId) {
+				getFloorList()
+			}
+		}
+		const onFloorChange = () => {
+			unitList.value = []
+			state.tableData.param.unitId = ''
+			if (state.tableData.param.floorId) {
+				getUnitList()
+			}
+		}
+		//查看详情
+		const onOpenDetail=(row: any)=>{
+			detailRef.value.openDialog(row);
+		}
+		// 打开新增修改弹窗
+		const onOpenDialog = (row: any) => {
+			editDicRef.value.orgList = orgList.value
+			editDicRef.value.plotList = plotList.value
+			editDicRef.value.openDialog(row);
+		};
+		// 删除产品
+		const onRowDel = (row: any) => {
+			let msg = `此操作将永久删除住户:“${row.name}”,是否继续?`;
+			ElMessageBox.confirm(msg, '提示', {
+				confirmButtonText: '确认',
+				cancelButtonText: '取消',
+				type: 'warning',
+			})
+				.then(() => {
+					api.resident.del(row.id).then(() => {
+						ElMessage.success('删除成功');
+						queryList();
+					});
+				})
+				.catch(() => {});
+		};
+		// 页面加载时
+		onMounted(() => {
+			initTableData();
+			getOrgList();
+			getPlotList()
+			// getFloorList()
+			// getUnitList()
+		});
+		/** 重置按钮操作 */
+		const resetQuery = (formEl: FormInstance | undefined) => {
+			if (!formEl) return;
+			formEl.resetFields();
+			queryList();
+		};
+
+		return {
+			addDicRef,
+			editDicRef,
+			detailRef,
+			queryRef,
+			onOpenDetail,
+			onOpenDialog,
+			onRowDel,
+			queryList,
+			resetQuery,
+			orgList,
+			plotList,
+			floorList,
+			unitList,
+			onPlotChange,
+			onFloorChange,
+			...toRefs(state),
+		};
+	},
+});
+</script>

+ 200 - 0
src/views/heatingDistrict/unitManage/component/detail.vue

@@ -0,0 +1,200 @@
+<template>
+	<div class="system-edit-dic-container">
+		<el-dialog :title="'环路详情'" v-model="dialogVisible" width="950px">
+			<el-form :model="ruleForm" ref="formRef" size="default" label-width="110px">
+				<el-form-item label="环路名称" prop="name">
+					{{ ruleForm.name }}
+				</el-form-item>
+				<el-form-item label="环路编号" prop="code">
+					{{ ruleForm.code }}
+				</el-form-item>
+				<el-form-item label="所属换热站" prop="stationId">
+          {{ ruleForm.stationId }}
+					<!-- <el-tree-select
+						v-model="ruleForm.stationId"
+						:data="treeData"
+						:props="{
+							label: 'name',
+							children: 'children'
+						}"
+						node-key="id"
+						:clearable="true"
+						check-strictly
+						style="width: 100%;"
+						:render-after-expand="true"
+					/> -->
+				</el-form-item>
+        <el-form-item label="环路类型" prop="loopTypes">
+          {{ ruleForm.loopTypes === 1 ? '一网' : '二网' }}
+        </el-form-item>
+        <el-form-item label="节能类型" prop="energyTypes">
+          {{ ruleForm.energyTypes === 1 ? '节能' : '' }}
+        </el-form-item>
+        <el-row :gutter="10">
+          <el-col :span="12">
+            <el-form-item label="供暖对象" prop="heatingObject">
+              {{ ruleForm.heatingObject === 1 ? '公建' : '居民' }}
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="供暖类型" prop="heatingTypes">
+              {{ ruleForm.heatingTypes === 1 ? '地暖' : '暖气片' }}
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="10">
+          <el-col :span="12">
+            <el-form-item label="供暖面积" prop="heatingArea">
+              {{ ruleForm.heatingArea }}
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="实际面积" prop="forRealArea">
+              {{ ruleForm.forRealArea }}
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="环路年代" prop="decade">
+          {{ ruleForm.decade }}
+        </el-form-item>
+				<el-form-item label="状态" prop="status">
+          {{ ruleForm.decade === 1 ? '在线' : '不在线' }}
+				</el-form-item>
+        <el-form-item label="路线信息" prop="">
+					<div class="mb10" style="width: 100%">
+						<div style="display: flex;" class="mb10" v-for="(item, index) in pointList" :key="index">
+							<el-input v-model="item.position" :disabled="!item.editFalg" @keydown="onLocalChange(item, index)" @change="onLocalChange(item, index)" placeholder="请输入关键字进行搜索" clearable style="flex: 1; margin-right: 10px"></el-input>
+							<span>排序:</span>
+							<el-input-number v-model="item.sort" :controls="false" :disabled="!item.editFalg" placeholder="排序" clearable style="width: 100px; margin-right: 10px"></el-input-number>
+						</div>
+					</div>
+        </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 } from 'vue';
+import api from '/@/api/heatStation';
+import { ElMessage } from 'element-plus';
+interface Point {
+	sort?: number;
+	lnt: number;
+	lat: number
+}
+interface RuleFormState {
+	id?: number;
+	name: string;
+	code: string;
+	stationId: string;
+	loopTypes: string;
+	energyTypes: string;
+	heatingObject: string;
+	heatingTypes: string;
+	heatingArea: string;
+	forRealArea: string;
+	viaPoint: Array<Point>;
+	decade: string;
+	status: number;
+}
+
+export default defineComponent({
+	name: 'headStationLoop',
+	setup(prop, { emit }) {
+		const formRef = ref<HTMLElement | null>(null);
+		const state = reactive({
+			dialogVisible: false,
+			ruleForm: {
+				id: 0,
+				name: '',
+        code: '',
+        stationId: '',
+        loopTypes: '',
+        energyTypes: '',
+        heatingObject: '',
+        heatingTypes: '',
+        heatingArea: '',
+        forRealArea: '',
+        decade: '',
+				viaPoint: [],
+        status: 1
+			},
+			treeData: [],
+      pointList: [] as any
+		})
+		// 打开弹窗
+		const openDialog = (row: RuleFormState | null) => {
+			resetForm()
+			queryTree()
+			if (row) {
+				(state.ruleForm as any).id = row.id
+				getDetail()
+			}
+			state.dialogVisible = true
+		}
+		const resetForm = () => {
+			state.ruleForm = {
+				id: 0,
+				name: '',
+        code: '',
+        stationId: '',
+        loopTypes: '',
+        energyTypes: '',
+        heatingObject: '',
+        heatingTypes: '',
+        heatingArea: '',
+        forRealArea: '',
+				viaPoint: [],
+        decade: '',
+        status: 1
+			}
+		}
+		// 关闭弹窗
+		const closeDialog = () => {
+			state.dialogVisible = false
+		}
+		// 取消
+		const onCancel = () => {
+			closeDialog()
+			state.pointList = []
+		}
+		const queryTree = () => {
+			api.heatStation.getList({
+					name: '',
+					code: '',
+					status: -1
+				})
+				.then((res: any) => {
+					state.treeData = res || [];
+				});
+		};
+		const getDetail = () => {
+			api.loop.detail(state.ruleForm.id)
+				.then((res: any) => {
+					state.ruleForm = {
+						...res
+					}
+					state.pointList = state.ruleForm.viaPoint.map((item: any) => ({
+						...item,
+						editFlag: false
+					}))
+				})
+		}
+
+		return {
+			openDialog,
+			closeDialog,
+			onCancel,
+			formRef,
+			...toRefs(state)
+		}
+	}
+})
+</script>

+ 220 - 0
src/views/heatingDistrict/unitManage/component/edit.vue

@@ -0,0 +1,220 @@
+<template>
+	<div class="system-edit-dic-container">
+		<el-dialog :title="(ruleForm.id !== 0 ? '修改' : '添加') + '单元'" v-model="dialogVisible" width="550px">
+			<el-form :model="ruleForm" ref="formRef" :rules="rules" size="default" label-width="110px">
+				<el-form-item label="所属组织" prop="organizationId">
+					<el-tree-select
+						v-model="ruleForm.organizationId"
+						:data="orgList"
+						:props="{
+							label: 'name',
+							children: 'children'
+						}"
+						node-key="id"
+						:clearable="true"
+						check-strictly
+						style="width: 100%;"
+						:render-after-expand="true"
+					/>
+				</el-form-item>
+				<!-- heatId -->
+				<el-form-item label="所属换热站" prop="">
+					<el-tree-select
+						v-model="ruleForm.heatId"
+						:data="heatList"
+						:props="{
+							label: 'name',
+							children: 'children'
+						}"
+						node-key="id"
+						:clearable="true"
+						check-strictly
+						style="width: 100%;"
+						:render-after-expand="true"
+					/>
+				</el-form-item>
+				<el-form-item label="小区名称" prop="plotId">
+					<el-select v-model="ruleForm.plotId" @change="onPlotChange" placeholder="选择小区名称" filterable clearable size="default" style="width: 100%">
+						<el-option
+							v-for="item in plotList"
+							:key="item.id"
+							:label="item.name"
+							:value="item.id">
+						</el-option>
+					</el-select>
+				</el-form-item>
+				<el-form-item label="楼宇名称" prop="floorId">
+					<el-select v-model="ruleForm.floorId" placeholder="选择楼宇名称" filterable clearable size="default" style="width: 100%">
+						<el-option
+							v-for="item in floorList"
+							:key="item.id"
+							:label="item.name"
+							:value="item.id">
+						</el-option>
+					</el-select>
+				</el-form-item>
+				<el-form-item label="单元名称" prop="name">
+					<el-input v-model="ruleForm.name" placeholder="请输入单元名称" />
+				</el-form-item>
+				<el-form-item label="单元号" prop="number">
+					<el-input v-model="ruleForm.number" placeholder="请输入单元号" />
+				</el-form-item>
+				<el-form-item label="状态" prop="status">
+					<el-radio v-model="ruleForm.status" :label="1">启用</el-radio>
+					<el-radio v-model="ruleForm.status" :label="0">禁用</el-radio>
+				</el-form-item>
+				<el-form-item label="备注" prop="remark">
+					<el-input type="textarea" :rows="8" v-model="ruleForm.remark" placeholder="请输入备注" />
+				</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, nextTick } from 'vue';
+import api from '/@/api/heatingDistrict';
+import heatApi from '/@/api/heatStation';
+import { ElMessage } from 'element-plus';
+
+export default defineComponent({
+	name: 'edit',
+	setup(prop, { emit }) {
+		const formRef = ref<HTMLElement | null>(null);
+		const state = reactive({
+			dialogVisible: false,
+			ruleForm: {
+				id: 0,
+				name: '',
+        organizationId: '',
+        plotId: '',
+        floorId: '',
+        heatId: '',
+        number: '',
+        remark: '',
+				status: 1
+			},
+			rules: {
+				name: [{ required: true, message: '单元名称不能为空', trigger: ['blur', 'change'] }],
+				organizationId: [{ required: true, message: '所属组织不能为空', trigger: ['blur', 'change'] }],
+				plotId: [{ required: true, message: '小区名称不能为空', trigger: ['blur', 'change'] }],
+				floorId: [{ required: true, message: '楼宇名称不能为空', trigger: ['blur', 'change'] }],
+				heatId: [{ required: true, message: '所属换热站不能为空', trigger: ['blur', 'change'] }],
+				number: [{ required: true, message: '楼号不能为空', trigger: ['blur', 'change'] }],
+			},
+			orgList: [],
+			plotList: [],
+			floorList: [],
+			heatList: []
+		})
+		// 打开弹窗
+		const openDialog = (row: any) => {
+			resetForm()
+			queryTree()
+			if (row) {
+				(state.ruleForm as any).id = row.id;
+				(state.ruleForm as any).plotId = row.plotId;
+				getDetail()
+				getFloorList()
+			}
+			state.dialogVisible = true
+		}
+		const resetForm = () => {
+			state.ruleForm = {
+				id: 0,
+				name: '',
+        organizationId: '',
+        plotId: '',
+        floorId: '',
+        heatId: '',
+        number: '',
+        remark: '',
+				status: 1
+			}
+		}
+		// 关闭弹窗
+		const closeDialog = () => {
+			state.dialogVisible = false;
+			(formRef.value as any).clearValidate()
+		}
+		// 取消
+		const onCancel = () => {
+			closeDialog()
+		}
+		const queryTree = () => {
+			heatApi.heatStation.getList({
+					name: '',
+					code: '',
+					status: -1
+				})
+				.then((res: any) => {
+					state.heatList = res || [];
+				});
+		};
+		const getDetail = () => {
+			api.unit.detail(state.ruleForm.id)
+				.then((res: any) => {
+					state.ruleForm = {
+						...res
+					}
+				})
+		}
+		const onPlotChange = () => {
+			state.floorList = []
+			state.ruleForm.floorId = ''
+			if (state.ruleForm.plotId) {
+				getFloorList()
+			}
+		}
+		// 获取楼宇
+		const getFloorList = () => {
+			api.floor.allList({ plotId: state.ruleForm.plotId })
+				.then((res: any) => {
+					state.floorList = res.Info || []
+				})
+		}
+		// 新增
+		const onSubmit = () => {
+			const formWrap = unref(formRef) as any
+			if (!formWrap) return;
+			formWrap.validate((valid: boolean) => {
+				if (valid) {
+					let params = { ...state.ruleForm }
+
+					if (params.id) {
+						//修改
+						api.unit.edit(params).then(() => {
+							ElMessage.success('单元修改成功')
+							closeDialog() // 关闭弹窗
+							emit('queryList')
+						})
+					} else {
+						//添加
+						api.unit.add(params).then(() => {
+							ElMessage.success('单元添加成功')
+							closeDialog() // 关闭弹窗
+							emit('queryList')
+						})
+					}
+				}
+			})
+		}
+
+		return {
+			openDialog,
+			closeDialog,
+			onCancel,
+			onSubmit,
+			formRef,
+			onPlotChange,
+			...toRefs(state)
+		}
+	}
+})
+</script>

+ 231 - 0
src/views/heatingDistrict/unitManage/index.vue

@@ -0,0 +1,231 @@
+<template>
+  <div class="system-dic-container">
+    <el-card shadow="hover">
+      <div class="system-user-search mb15">
+        <el-form :model="tableData.param" ref="queryRef" :inline="true" label-width="68px">
+          <el-form-item label="所属组织" prop="organizationId">
+						<el-tree-select
+							v-model="tableData.param.organizationId"
+							:data="orgList"
+							:props="{
+								label: 'name',
+								children: 'children'
+							}"
+							placeholder="请选择"
+							node-key="id"
+							:clearable="true"
+							check-strictly
+							style="width: 100%;"
+							:render-after-expand="true"
+							size="default"
+						/>
+          </el-form-item>
+          <el-form-item label="小区名称" prop="plotId">
+            <el-select v-model="tableData.param.plotId" @change="onPlotChange" placeholder="选择小区名称" filterable clearable size="default">
+							<el-option
+								v-for="item in plotList"
+								:key="item.id"
+								:label="item.name"
+								:value="item.id">
+							</el-option>
+						</el-select>
+          </el-form-item>
+          <el-form-item label="楼宇名称" prop="floorId">
+            <el-select v-model="tableData.param.floorId" placeholder="选择楼宇名称" filterable clearable size="default">
+							<el-option
+								v-for="item in floorList"
+								:key="item.id"
+								:label="item.name"
+								:value="item.id">
+							</el-option>
+						</el-select>
+          </el-form-item>
+          <el-form-item label="单元名称" prop="name">
+            <el-input v-model="tableData.param.name" placeholder="请输入单元名称" clearable size="default" style="width: 240px" @keyup.enter="queryList" />
+          </el-form-item>
+          <el-form-item>
+            <el-button size="default" type="primary" class="ml10" @click="queryList">
+              <el-icon>
+                <ele-Search />
+              </el-icon>
+              查询
+            </el-button>
+            <el-button size="default" @click="resetQuery(queryRef)">
+              <el-icon>
+                <ele-Refresh />
+              </el-icon>
+              重置
+            </el-button>
+            <el-button size="default" type="success" class="ml10" @click="onOpenDialog()">
+              <el-icon>
+                <ele-FolderAdd />
+              </el-icon>
+              新增
+            </el-button>
+            <!-- <el-button size="default" type="danger" class="ml10" @click="onRowDel(null)">
+              <el-icon>
+                <ele-Delete />
+              </el-icon>
+              删除
+            </el-button> -->
+          </el-form-item>
+        </el-form>
+      </div>
+      <el-table :data="tableData.data" style="width: 100%" >
+        <!-- <el-table-column type="selection" width="55" align="center" /> -->
+        <el-table-column label="ID" align="center" prop="id" width="60" />
+        <el-table-column label="组织名称" prop="organizationInfo.name" />
+        <el-table-column label="小区名称" prop="plotInfo.name" />
+        <el-table-column label="楼宇名称" prop="floorInfo.name" />
+	    	<el-table-column label="单元名称" prop="name" />
+	    	<el-table-column label="单元号" prop="number" />
+	    	<el-table-column label="更新时间" prop="updatedAt" />
+        <el-table-column label="操作" width="200" align="center">
+          <template #default="scope">
+            <el-button size="small" text type="warning" @click="onOpenDialog(scope.row)">修改</el-button>
+            <el-button size="small" text type="danger" @click="onRowDel(scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination v-show="tableData.total>0" :total="tableData.total" v-model:page="tableData.param.pageNum" v-model:limit="tableData.param.pageSize" @pagination="queryList" />
+    </el-card>
+    <EditDic ref="editDicRef" @queryList="queryList" />
+    <Detail ref="detailRef"  />
+  </div>
+</template>
+
+<script lang="ts">
+import { toRefs, reactive, onMounted, ref, defineComponent } from 'vue';
+import { ElMessageBox, ElMessage, FormInstance } from 'element-plus';
+import EditDic from './component/edit.vue';
+import Detail from './component/detail.vue';
+import api from '/@/api/heatingDistrict';
+import systemApi from '/@/api/system';
+
+export default defineComponent({
+	name: 'loop',
+	components: { EditDic,Detail },
+	setup() {
+		const addDicRef = ref();
+		const editDicRef = ref();
+		const detailRef=ref();
+		const queryRef = ref();
+		const state = reactive({
+			ids: [],
+			tableData: {
+				data: [],
+				total: 0,
+				loading: false,
+				param: {
+					pageNum: 1,
+					pageSize: 10,
+					name: '',
+					plotId: '',
+					floorId: '',
+					organizationId: '',
+					status: -1
+				},
+			},
+		});
+		// 组织
+		const orgList = ref([])
+		// 小区
+		const plotList = ref([])
+		// 楼宇
+		const floorList = ref([])
+		// 初始化表格数据
+		const initTableData = () => {
+			queryList();
+		};
+		// 获取组织
+		const getOrgList = () => {
+			systemApi.org.getList({ name: '', status: -1 }).then((res: any) => {
+				orgList.value = res;
+			});
+		}
+		// 获取区域
+		const getPlotList = () => {
+			api.regionalManage.allList({})
+				.then((res: any) => {
+					plotList.value = res.Info || []
+				})
+		}
+		// 获取楼宇
+		const getFloorList = () => {
+			api.floor.allList({ plotId: state.tableData.param.plotId })
+				.then((res: any) => {
+					floorList.value = res.Info || []
+				})
+		}
+		const queryList = () => {
+			api.unit.getList(state.tableData.param).then((res: any) => {
+				console.log(res);
+				state.tableData.data = res.Data || [];
+				state.tableData.total = res.Total;
+			});
+		};
+		const onPlotChange = () => {
+			floorList.value = []
+			state.tableData.param.floorId = ''
+			if (state.tableData.param.plotId) {
+				getFloorList()
+			}
+		}
+		//查看详情
+		const onOpenDetail=(row: any)=>{
+			detailRef.value.openDialog(row);
+		}
+		// 打开新增修改弹窗
+		const onOpenDialog = (row: any) => {
+			editDicRef.value.orgList = orgList.value
+			editDicRef.value.plotList = plotList.value
+			editDicRef.value.openDialog(row);
+		};
+		// 删除产品
+		const onRowDel = (row: any) => {
+			let msg = `此操作将永久删除单元:“${row.name}”,是否继续?`;
+			ElMessageBox.confirm(msg, '提示', {
+				confirmButtonText: '确认',
+				cancelButtonText: '取消',
+				type: 'warning',
+			})
+				.then(() => {
+					api.unit.del(row.id).then(() => {
+						ElMessage.success('删除成功');
+						queryList();
+					});
+				})
+				.catch(() => {});
+		};
+		// 页面加载时
+		onMounted(() => {
+			initTableData();
+			getOrgList();
+			getPlotList()
+		});
+		/** 重置按钮操作 */
+		const resetQuery = (formEl: FormInstance | undefined) => {
+			if (!formEl) return;
+			formEl.resetFields();
+			queryList();
+		};
+
+		return {
+			addDicRef,
+			editDicRef,
+			detailRef,
+			queryRef,
+			onOpenDetail,
+			onOpenDialog,
+			onRowDel,
+			queryList,
+			resetQuery,
+			orgList,
+			plotList,
+			floorList,
+			onPlotChange,
+			...toRefs(state),
+		};
+	},
+});
+</script>