Переглянути джерело

关系过滤;干管关联容器

zhaoyk 3 роки тому
батько
коміт
b490679aac

+ 123 - 24
adm_comp/src/components/FilterPanel.vue

@@ -31,9 +31,32 @@
 				 
 				<el-button size="mini" @click.prevent="removeFilterItem(item)">删除</el-button>
 			</el-row>
+			<br>
+			<el-row v-for="(item, index) in relFilterItems" :key="item.key">
+				<el-form-item label="关联对象">
+					<el-select v-model="item.relObj">
+						<el-option
+							v-for="op in releatedObjOptions"
+							:key="op.value"
+							:label="op.label"
+							:value="op.value">
+						</el-option>
+					</el-select>
+				</el-form-item>
+				<el-form-item label="关系类型">
+					<el-cascader
+					  placeholder="搜索"
+					  :options="dicRels" :props="{expandTrigger: 'hover', multiple: true, label: 'name', value: 'code'}"
+					  v-model="item.relTypes" filterable collapse-tags clearable style="width: 300px;"></el-cascader>
+				</el-form-item>
+				&nbsp;
+				<el-button size="mini" @click.prevent="removeFilterItem(item)">删除</el-button>
+			</el-row>
 		</el-form>
 		<br>
+		
 		<el-button size="mini" @click="addFilterItem()">添加条件(and)</el-button>
+		<el-button size="mini" @click="addRelationItem()" v-if="releatedObjs && releatedObjs.length > 0">添加关系过滤(and)</el-button>
 	</div>
 </template>
 
@@ -51,35 +74,67 @@
 		@Prop()
 		dataFilter: any;
 		
+		@Prop()
+		releatedObjs: any[];
+		
+		@Prop()
+		dicRels: any[];
+		
 		filterItems: any[] = [];
+		relFilterItems: any[] = [];
+		
+		releatedObjOptions: any[] = [];
 		
 		mounted(){
 			this.buildFilterItems();
+			this.buildReleatedObjOptions();
 		}
 		
 		@Watch("dataFilter")
 		buildFilterItems(){
-			this.filterItems = this.buildItems(this.dataFilter);
+			this.buildItems(this.dataFilter);
+		}
+		
+		@Watch("releatedObjs")
+		buildReleatedObjOptions(){
+			this.releatedObjOptions = [];
+			if(this.releatedObjs) {
+				for(const obj of this.releatedObjs) {
+					if(obj.compType == 'mainPipe'){
+						this.releatedObjOptions.push({value: 'mainPipe:' + obj.id, label: '干管:' + (obj.name != null ? obj.name : obj.id)});
+					} else if(obj.compType == 'container') {
+						//TODO
+					}
+				}
+			}
 		}
 		
 		buildItems(filter){
 			const items:any[] = [];
+			const rels:any[] = [];
 			if(filter && filter.type) {
 				if(filter.type == 1) { // match
 					items.push(this.buildItem4Edit(filter));
+				} else if(filter.type == 9) { // match
+					rels.push(this.buildRelItem4Edit(filter));
 				} else if (filter.type == 2) { // and
 					for(const i of filter.items){
-						items.push(this.buildItem4Edit(i));	
+						if(i.type == 1)
+							items.push(this.buildItem4Edit(i));	
+						else if(i.type == 9)
+							rels.push(this.buildRelItem4Edit(i));
 					}
 				}
 			} else {
-				items.push({});
+				items.push({type: 1});
 			}
-			return items;
+			
+			this.filterItems = items;
+			this.relFilterItems = rels;
 		}
 		
 		buildItem4Edit(filterItem){
-			const item:any = {};
+			const item:any = {type: filterItem.type};
 			const obj:string = filterItem.object;
 			const infosPre = 'infos.';
 			if(obj.indexOf(infosPre) == 0){
@@ -94,38 +149,70 @@
 			return item;
 		}
 		
+		buildRelItem4Edit(filterItem){
+			const item:any = {type: filterItem.type};
+			item.relObj = filterItem.relObjType + ':' + filterItem.relObjId;
+			if(filterItem.relTypes){
+				item.relTypes = [];
+				for(const r of filterItem.relTypes) {
+					item.relTypes.push(r.split("/"));
+				}
+			}
+			return item;
+		}
+		
 		//添加过滤条件条目
 		addFilterItem(){
-			this.filterItems.push({});
+			this.filterItems.push({type: 1});
+		}
+		
+		addRelationItem(){
+			this.relFilterItems.push({type: 9});
 		}
 		
 		//删除过滤条件条目
 		removeFilterItem(item){
-			const idx = this.filterItems.indexOf(item);
-			this.filterItems.splice(idx, 1);
+			var idx = this.filterItems.indexOf(item);
+			if(idx >= 0){
+				this.filterItems.splice(idx, 1);
+				return;
+			}
+			idx = this.relFilterItems.indexOf(item);
+			if(idx >= 0) {
+				this.relFilterItems.splice(idx, 1);
+			}
 		}
 		
 		//创建设备过滤条件
 		buildFilter(){
 			var filter: any;
-			if(this.filterItems.length == 0)
+			const allItems = [];
+			allItems.push(...this.filterItems);
+			allItems.push(...this.relFilterItems);
+			if(allItems.length == 0)
 				filter = null;
 			else {
-				for(const item of this.filterItems) {
-					var flag = !this['$common'].isEmpty(item.filterObj) && !this['$common'].isEmpty(item.filterOper) && !this['$common'].isEmpty(item.filterVal);
-					if(flag) {
-						if(item.filterObj == 'infos.')
-							flag = !this['$common'].isEmpty(item.infoCode);
+				for(const item of allItems) {
+					var flag = true;
+					if(item.type == 1) {
+						flag = !this['$common'].isEmpty(item.filterObj) && !this['$common'].isEmpty(item.filterOper) && !this['$common'].isEmpty(item.filterVal);
+						if(flag) {
+							if(item.filterObj == 'infos.')
+								flag = !this['$common'].isEmpty(item.infoCode);
+						}	
+					} else if(item.type == 9) {
+						flag = !this['$common'].isEmpty(item.relObj);
 					}
+
 					if(!flag)
 						return {errMsg: '缺少必要的信息'};
 				}
 				
-				if(this.filterItems.length == 1)
-					filter = this.buildItem4Commit(this.filterItems[0]);
+				if(allItems.length == 1)
+					filter = this.buildItem4Commit(allItems[0]);
 				else {
 					filter = {type: 2, items: []}; //and
-					for(const item of this.filterItems) {
+					for(const item of allItems) {
 						filter.items.push(this.buildItem4Commit(item));
 					}
 				}
@@ -134,13 +221,25 @@
 		}
 		
 		buildItem4Commit(item){
-			const filterItem:any = {type: 1};
-			filterItem.object = item.filterObj;
-			if(filterItem.object == 'infos.')
-				filterItem.object += item.infoCode;
-			filterItem.operation = item.filterOper;
-			filterItem.value = item.filterVal;	
-			filterItem.not = item.not;	
+			const filterItem:any = {type: item.type};
+			if(item.type == 1) {
+				filterItem.object = item.filterObj;
+				if(filterItem.object == 'infos.')
+					filterItem.object += item.infoCode;
+				filterItem.operation = item.filterOper;
+				filterItem.value = item.filterVal;	
+				filterItem.not = item.not;	
+			} else if (item.type == 9) {
+				const arr = item.relObj.split(":");
+				filterItem.relObjType = arr[0];
+				filterItem.relObjId = arr[1];
+				if(item.relTypes) {
+					filterItem.relTypes = [];
+					for(const arr of item.relTypes) {
+						filterItem.relTypes.push(arr.join("/"));
+					}	
+				}				
+			}
 			return filterItem;
 		}
 		

+ 33 - 0
adm_comp/src/lib/DiagramModel.ts

@@ -20,6 +20,25 @@ export class Template {
 	
 	scatteredContainers: Array<Container>;
 	
+	static findRelatedMainPipes(con: Container, template: Template): Array<MainPipe> {
+		const mps = new Array<MainPipe>();
+		while(true) {
+			if(con == null)
+				break;
+			
+			for(const mp of template.mainPipes) {
+				if(mp.relatedContainers && mp.relatedContainers.indexOf(con.id) >= 0){
+					if(mps.indexOf(mp) < 0) {
+						mps.push(mp);	
+					}
+				}
+			}
+			
+			con = con.parent;
+		}
+		return mps;
+	}
+	
 }
 
 export class Comp {
@@ -69,6 +88,18 @@ export class Container extends Comp {
 		return arr;
 	}
 	
+	static findSubCons(con: Container, arr?: Array<Container>) {
+		if(!arr)
+			arr = new Array<Container>();
+		if(con.children && con.children.length > 0) {
+			for(const item of con.children) {
+				arr.push(<Container>item);
+				Container.findSubCons(<Container>item, arr);
+			}
+		}
+		return arr;
+	}
+	
 }
 
 export class DataFilter {
@@ -119,6 +150,8 @@ export class MainPipe {
 	
 	path: any[];
 	
+	relatedContainers: Array<string>;
+	
 	locationPath: Array<Array<Point>>;
 			
 }

+ 7 - 1
adm_comp/src/lib/TemplateEditor.ts

@@ -163,9 +163,15 @@ export class TemplateEditor extends Editor {
 		this.ctx.rect(location.x, location.y, con.size.x, con.size.y);	
 		this.ctx.stroke();
 		
-		if(this.getSelComp() == con) {
+		const selComp = this.getSelComp();
+		if(selComp == con) {
 			this.ctx.fillStyle = "rgba(0, 127, 255, 0.1)";
 			this.ctx.fill();
+		} else if(selComp && selComp.compType == 'mainPipe') {
+			if(selComp.relatedContainers && selComp.relatedContainers.indexOf(con.id) >= 0){
+				this.ctx.fillStyle = "rgba(127, 127, 0, 0.1)";
+				this.ctx.fill();	
+			}
 		}
 
 		if(con.dynGroup && con.parent){

+ 2 - 0
adm_comp/src/lib/UIUtils.ts

@@ -133,6 +133,8 @@ export class ViewTool {
 				info += '!';
 			if(filter.type == 1)
 				info += filter.value;
+			else if(filter.type == 9)
+				info += '关系过滤';
 			else {
 				info += '组合过滤';
 			}

+ 32 - 6
adm_comp/src/views/DiagramTemplate.vue

@@ -259,6 +259,17 @@
 					</el-select>
 				</el-form-item>
 				
+				<el-form-item label="关联的容器">
+					<el-select v-model="propsData.relatedContainers" multiple>
+						<el-option
+							v-for="item in allCons"
+							:key="item.value"
+							:label="item.label"
+							:value="item.value">
+						</el-option>
+					</el-select>
+				</el-form-item>
+				
 			</el-form>
 			
 			<div slot="footer" class="dialog-footer">
@@ -269,7 +280,7 @@
 		
 		<!-- 设备过滤对话框 -->
 		<el-dialog title="设备过滤" :visible.sync="dlgFilterVisible">
-			<FilterPanel ref="filterPanel" :dataFilter="dataFilter"></FilterPanel>
+			<FilterPanel ref="filterPanel" :dataFilter="dataFilter" :releatedObjs="filterReleatedObjs" :dicRels="dicRels"></FilterPanel>
 			
 			<div slot="footer" class="dialog-footer">
 				<el-button @click="dlgFilterVisible = false">取 消</el-button>
@@ -362,7 +373,7 @@
 	} from "vue-property-decorator";
 	import FilterPanel from '@/components/FilterPanel.vue';
 	import {TemplateEditor} from '@/lib/TemplateEditor';
-	import {Container} from '@/lib/DiagramModel';
+	import {Template, Container} from '@/lib/DiagramModel';
 
 	@Component({components:{FilterPanel}})
 	export default class DiagramTemplate extends Vue {
@@ -387,6 +398,7 @@
 		
 		propsData: any = {};
 		dataFilter: any = {};
+		filterReleatedObjs: any[] = [];
 		selectionInfo = '~';
 		dynInfo = '';
 		
@@ -394,6 +406,7 @@
 		equipOptions:any[] = []; //属性设定时,下拉框中的设备类型列表(动态)
 		dicRels:any[] = [];
 		dicEquips:any[] = [];
+		allCons:any[] = [];
 		dynSourceOptions:any[] = [];
 				
 		mounted() {
@@ -668,6 +681,13 @@
 				}
 				
 				props.connectEquips = sel.connectEquips;
+				props.relatedContainers = sel.relatedContainers;
+				
+				this.allCons = [];
+				const conObjs: any[] = Container.findSubCons(this.currentTemplate.frame);
+				for(const con of conObjs) {
+					this.allCons.push({value: con.id, label: con.name != null ? con.name : con.id});
+				}
 				
 				this.propsData = props;
 				this.dlgLineVisible = true;
@@ -713,7 +733,7 @@
 				});
 				return;
 			}
-			
+						
 			if(this.propsData.passbyRels) {
 				const rels = [];
 				for(const arr of this.propsData.passbyRels) {
@@ -721,6 +741,7 @@
 				}
 				this.propsData.passbyRels = rels;
 			}
+			
 			const params:any = {templatePropsData: this.propsData, currentCompId: this.propsData.id0, templateId: this.currentTemplate.id};
 			this.callAction('modifyMainPipe', params);
 		}
@@ -729,6 +750,11 @@
 		editFilter(){
 			const sel = this.editor.getSelComp();
 			this.dataFilter = sel.dataFilter != null ? sel.dataFilter : {};//为null时赋一个新对象,触发子组件watch
+			if(sel.compType == 'container') {
+				this.filterReleatedObjs = Template.findRelatedMainPipes(sel, this.currentTemplate);
+			} else {
+				this.filterReleatedObjs = [];
+			}
 			
 			this.dlgFilterVisible = true;
 		}
@@ -803,8 +829,8 @@
 			this.dynSourceOptions = [{value:'floor', label: '楼层'}, {value:'building', label: '建筑'}];
 			if(this.currentTemplate.mainPipes){
 				for(const mp of this.currentTemplate.mainPipes) {
-					if(mp.bindEquipment){
-						this.dynSourceOptions.push({value: 'mainPipe:' + mp.id, label: '干管:' + mp.name});
+					if(mp.bindEquipment && mp.relatedContainers && mp.relatedContainers.indexOf(sel.id) >= 0){
+						this.dynSourceOptions.push({value: 'mainPipe:' + mp.id, label: '干管:' + (mp.name != null ? mp.name : mp.id)});
 					}
 				}
 			}
@@ -928,7 +954,7 @@
 			});
 
 			const params:any = {lines: lines, templateId: this.currentTemplate.id};
-			this.callAction('addMainPipe', params);
+			this.callAction('drawMainPipe', params);
 		}
 		
 		//切换编辑状态