<#ibizinclude> ./CONTROL-BASE.template.ftl </#ibizinclude> <#assign import_block> import { Util } from '@ibiz-core/utils' </#assign> <#ibizinclude> ../@MACRO/CONTROL/CONTROL_HEADER-BASE.vue.ftl </#ibizinclude> /** * 树视图导航数组名称 * * @type {string[]} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public treeNav :any= [{id:"#",text:"<#if ctrl.getLogicName?? && ctrl.getLogicName()??>${ctrl.getLogicName()}</#if>"}]; /** * 获取多项数据 * * @returns {any[]} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public getDatas(): any[] { return [this.currentselectedNode]; } /** * 获取单项树 * * @returns {*} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public getData(): any { return this.currentselectedNode; } /** * 是否单选 * * @type {boolean} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Prop({ default: true }) public isSingleSelect!: boolean; /** * 是否默认选中第一条数据 * * @type {boolean} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Prop({ default: false }) public isSelectFirstDefault!: boolean; /** * 枝干节点是否可用(具有数据能力,可抛出) * * @type {string} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Prop({default:true}) public isBranchAvailable!: boolean; /** * 显示处理提示 * * @type {boolean} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Prop({ default: true }) public showBusyIndicator?: boolean; /** * 初始化完成 * * @type {boolean} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public inited: boolean = false; /** * 已选中数据集合 * * @type {*} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public selectedNodes: any = []; /** * 当前选中数据项 * * @type {*} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public currentselectedNode: any = {}; /** * 选中数据字符串 * * @type {string} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Prop() public selectedData?: string; /** * 节点点击加载 * * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public click_node(data:any){ this.treeNav.push(data); this.load({data:data}); } /** * 选中值变化 * * @param {*} newVal * @param {*} oldVal * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Watch('selectedData') public onValueChange(newVal: any, oldVal: any) { this.echoselectedNodes = newVal ? this.isSingleSelect ? JSON.parse(newVal)[0] : JSON.parse(newVal) : []; this.selectedNodes = []; if(this.echoselectedNodes.length > 0){ let AllnodesObj = (this.$refs.treeexpbar_tree as any).store.nodesMap; let AllnodesArray : any[] = []; for (const key in AllnodesObj) { if (AllnodesObj.hasOwnProperty(key)) { AllnodesArray.push(AllnodesObj[key].data); } } this.setDefaultSelection(AllnodesArray); } } /** * 导航点击行为 * * @param {*} newVal * @param {*} oldVal * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public nav_click(item:any) { if(item.id == this.treeNav[this.treeNav.length-1].id){ return } const count = this.treeNav.findIndex((i:any) => item.id === i.id) + 1; this.treeNav.splice(count,this.treeNav.length- count); this.load({data:item}); } /** * 节点数组 * * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public rootNodes :any= []; /** * 节点值数组 * * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public valueNodes :any= []; /** * 解析节点数据 * * @param {*} nodes * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public parsNodes(nodes:any) { let rootNodes :any= []; let valueNodes :any= []; nodes.forEach((item:any) => { if(item.isNode){ rootNodes.push(item); }else{ valueNodes.push(item); } }); this.rootNodes = rootNodes; this.valueNodes = valueNodes; } /** * 回显选中数据集合 * * @type {*} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public echoselectedNodes:any[] = this.selectedData ? ( this.isSingleSelect ? [JSON.parse(this.selectedData)[0]] : JSON.parse(this.selectedData)) : []; /** * 部件行为--update * * @type {string} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Prop() public updateAction!: string; /** * 部件行为--fetch * * @type {string} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Prop() public fetchAction!: string; /** * 部件行为--remove * * @type {string} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Prop() public removeAction!: string; /** * 部件行为--load * * @type {string} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Prop() public loadAction!: string; /** * 部件行为--create * * @type {string} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Prop() public createAction!: string; /** * 过滤属性 * * @type {string} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public srfnodefilter: string = ''; /** * 默认输出图标 * * @type {boolean} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public isOutputIconDefault: boolean = ${ctrl.isOutputIconDefault()?c}; /** * 树数据 * * @type {any[]} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Provide() public nodes: any[] = []; /** * 数据展开主键 * * @type {string[]} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ @Provide() public expandedKeys: string[] = []; /** * 应用状态事件 * * @public * @type {(Subscription | undefined)} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public appStateEvent: Subscription | undefined; /** * 选中数据变更事件 * * @public * @param {*} data * @param {*} data 当前节点对应传入对象 * @param {*} checkedState 树目前选中状态对象 * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public onCheck(data: any, checkedState: any) { // 处理多选数据 if(!this.isSingleSelect){ let leafNodes = checkedState.checkedNodes.filter((item:any) => item.leaf); this.selectedNodes = JSON.parse(JSON.stringify(leafNodes)); this.$emit('selectionchange', this.selectedNodes); } } /** * 选中数据变更事件 * * @public * @param {*} data 节点对应传入对象 * @param {*} node 节点对应node对象 * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public selectionChange(data: any, node: any) { // 禁用项处理 if (data.disabled){ node.isCurrent = false; return; } // 只处理最底层子节点 if(this.isBranchAvailable || data.leaf){ this.currentselectedNode = JSON.parse(JSON.stringify(data)); // 单选直接替换 if(this.isSingleSelect){ this.selectedNodes = [this.currentselectedNode]; this.$emit('selectionchange', this.selectedNodes); } // 多选用check方法 } } /** * Vue声明周期(处理组件的输入属性) * * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public created() { this.afterCreated(); } /** * 执行created后的逻辑 * * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public afterCreated(){ if (this.viewState) { this.viewStateEvent = this.viewState.subscribe(({ tag, action, data }) => { if (!Object.is(tag, this.name)) { return; } if (Object.is('load', action)) { this.inited = false; this.$nextTick(() => { this.inited = true; }); this.load(); } if (Object.is('filter', action)) { this.srfnodefilter = data.srfnodefilter; this.refresh_all(); } if (Object.is('refresh_parent', action)) { this.refresh_parent(); } }); } } /** * 对树节点进行筛选操作 * @memberof OrderTree */ public filterNode(value:any, data:any) { if (!value) return true; return data.text.indexOf(value) !== -1; } /** * vue 生命周期 * * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public destroyed() { this.afterDestroy(); } /** * 执行destroyed后的逻辑 * * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public afterDestroy() { if (this.viewStateEvent) { this.viewStateEvent.unsubscribe(); } if(this.appStateEvent){ this.appStateEvent.unsubscribe(); } <#if destroyed_block??> ${destroyed_block} </#if> } /** * 刷新数据 * * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public refresh_all(): void { this.inited = false; this.$nextTick(() => { this.inited = true; }); } /** * 刷新父节点 * * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public refresh_parent(): void { if (Object.keys(this.currentselectedNode).length === 0) { return; } const tree: any = this.$refs.${ctrl.name}; const node: any = tree.getNode(this.currentselectedNode.id); if (!node || !node.parent) { return; } let curNode:any = {}; const { parent: _parent } = node; curNode = Util.deepObjectMerge(curNode,_parent); let tempContext:any = {}; if(curNode.data && curNode.data.srfappctx){ Object.assign(tempContext,curNode.data.srfappctx); }else{ Object.assign(tempContext,this.context); } const id: string = _parent.key ? _parent.key : '#'; const param: any = { srfnodeid: id }; this.refresh_node(tempContext,param, true); } /** * 数据加载 * * @param {*} node * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public load(node: any = {}) { if (node.data && node.data.children) { return; } const params: any = { srfnodeid: node.data && node.data.id ? node.data.id : "#", srfnodefilter: this.srfnodefilter }; let tempViewParams:any = JSON.parse(JSON.stringify(this.viewparams)); let curNode:any = {}; curNode = Util.deepObjectMerge(curNode,node); let tempContext:any = this.computecurNodeContext(curNode); if(curNode.data && curNode.data.srfparentdename){ Object.assign(tempContext,{srfparentdename:curNode.data.srfparentdename}); Object.assign(tempViewParams,{srfparentdename:curNode.data.srfparentdename}); } if(curNode.data && curNode.data.srfparentkey){ Object.assign(tempContext,{srfparentkey:curNode.data.srfparentkey}); Object.assign(tempViewParams,{srfparentkey:curNode.data.srfparentkey}); } Object.assign(params,{viewparams:tempViewParams}); this.service.getNodes(tempContext,params).then((response: any) => { if (!response || response.status !== 200) { this.$notice.error(response.info); return; } const _items = response.data; this.formatExpanded(_items); <#-- if (!node.level || node.level === 0) { this.nodes = [..._items]; } this.nodes = response.data; --> this.nodes = [..._items]; this.parsNodes(this.nodes); let isRoot = Object.is(node.level,0); let isSelectedAll = node.checked; this.setDefaultSelection(_items, isRoot, isSelectedAll); this.$emit("load", _items); }).catch((response: any) => { if (response && response.status === 401) { return; } this.$notice.error(response.info); }); } /** * 计算当前节点的上下文 * * @param {*} curNode 当前节点 * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public computecurNodeContext(curNode:any){ let tempContext:any = {}; if(curNode && curNode.data && curNode.data.srfappctx){ tempContext = JSON.parse(JSON.stringify(curNode.data.srfappctx)); }else{ tempContext = JSON.parse(JSON.stringify(this.context)); } return tempContext; } /** * 刷新功能 * * @param {any[]} args * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public refresh(args: any[]): void { this.refresh_all(); <#-- if (Object.keys(this.currentselectedNode).length === 0) { return; } const id: string = this.currentselectedNode.id; const param: any = { srfnodeid: id }; const tree: any = this.$refs.${ctrl.name}; const node: any = tree.getNode(id); if (!node) { return; } let curNode:any = {}; curNode = Util.deepObjectMerge(curNode,node); let tempContext:any = {}; if(curNode.data && curNode.data.srfappctx){ Object.assign(tempContext,curNode.data.srfappctx); }else{ Object.assign(tempContext,this.context); } this.refresh_node(tempContext,param, false); --> } /** * 刷新节点 * * @public * @param {*} [curContext] 当前节点上下文 * @param {*} [arg={}] 当前节点附加参数 * @param {boolean} parentnode 是否是刷新父节点 * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public refresh_node(curContext:any,arg: any = {}, parentnode: boolean): void { const { srfnodeid: id } = arg; Object.assign(arg,{viewparams:this.viewparams}); const get: Promise<any> = this.service.getNodes(JSON.parse(JSON.stringify(this.context)),arg); get.then((response: any) => { if (!response || response.status !== 200) { this.$notice.error(response.info); return; } const _items = [...response.data]; this.formatExpanded(_items); const tree: any = this.$refs.${ctrl.name}; tree.updateKeyChildren(id, _items); if (parentnode) { this.currentselectedNode = {}; } this.setDefaultSelection(_items); }).catch((response: any) => { if (response && response.status === 401) { return; } this.$notice.error(response.info); }); } /** * 默认展开节点 * * @public * @param {any[]} items * @returns {any[]} * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public formatExpanded(items: any[]): any[] { const data: any[] = []; items.forEach((item) => { if (item.expanded || (item.children && item.children.length > 0)) { this.expandedKeys.push(item.id); } }); return data; } /** * 设置默认选中,回显数项,选中所有子节点 * * @param {any[]} items 当前节点所有子节点集合 * @param {boolean} isRoot 是否是加载根节点 * @param {boolean} isSelectedAll 是否选中所有子节点 * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public setDefaultSelection(items: any[], isRoot: boolean = false, isSelectedAll: boolean = false): void { if(items.length == 0){ return; } let defaultData: any; // 导航中选中第一条配置的默认选中,没有选中第一条 if(this.isSelectFirstDefault){ if(this.isSingleSelect){ let index = items.findIndex((item: any) => item.selected); if(index === -1) { if(isRoot){ index = 0; }else{ return; } } defaultData = items[index]; this.setTreeNodeHighLight(defaultData); this.currentselectedNode = JSON.parse(JSON.stringify(defaultData)); if(this.isBranchAvailable || defaultData.leaf){ this.selectedNodes = [this.currentselectedNode]; this.$emit('selectionchange', this.selectedNodes); } } } // 已选数据的回显 if(this.echoselectedNodes && this.echoselectedNodes.length > 0){ let checkedNodes = items.filter((item:any)=>{ return this.echoselectedNodes.some((val:any)=> { if(Object.is(item.srfkey,val.srfkey) && Object.is(item.srfmajortext,val.srfmajortext)){ val.used = true; return true; } }); }); if(checkedNodes.length > 0){ this.echoselectedNodes = this.echoselectedNodes.filter((item:any)=> !item.used); // 父节点选中时,不需要执行这段,会选中所有子节点 if(!isSelectedAll){ if(this.isSingleSelect){ this.setTreeNodeHighLight(checkedNodes[0]); this.currentselectedNode = JSON.parse(JSON.stringify(checkedNodes[0])); this.selectedNodes = [this.currentselectedNode]; }else{ this.selectedNodes = this.selectedNodes.concat(checkedNodes); const tree: any = this.$refs.treeexpbar_tree; tree.setCheckedNodes(this.selectedNodes); } } } } // 父节点选中时,选中所有子节点 if(isSelectedAll){ let leafNodes = items.filter((item:any) => item.leaf); this.selectedNodes = this.selectedNodes.concat(leafNodes); this.$emit('selectionchange', this.selectedNodes); } } /** * 绘制右击菜单 * * @param {*} node * @returns * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public renderContextMenu(node: any) { let content; if (node && node.data) { const data: any = JSON.parse(JSON.stringify(node.data)); this.currentselectedNode = { ...data }; const tags: string[] = data.id.split(';'); <#if ctrl.getPSControls()??> <#list ctrl.getPSControls() as childCtrl> <#if childCtrl.getControlType() == "CONTEXTMENU"> if (tags[0] === "${childCtrl.getOwner().getNodeType()}") { content = this.renderContextMenu${srfclassname(childCtrl.getOwner().getNodeType()?lower_case)}(); } </#if> </#list> </#if> } return content; } <#if ctrl.getPSControls()??> <#list ctrl.getPSControls() as childCtrl> <#if childCtrl.getControlType() == "CONTEXTMENU"> /** * 绘制${childCtrl.getOwner().getNodeType()}类型右键菜单 * * @param {*} node * @returns * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public renderContextMenu${srfclassname(childCtrl.getOwner().getNodeType()?lower_case)}() { return ( <@ibizindent blank=12> ${P.getCtrlCode(childCtrl, 'CONTROL.html').code} </@ibizindent> ); } </#if> </#list> </#if> /** * 设置选中高亮 * * @param {*} data * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public setTreeNodeHighLight(data: any): void { const tree: any = this.$refs.${ctrl.name}; tree.setCurrentKey(data.id); } /** * 执行默认界面行为 * * @param {*} node * @memberof ${srfclassname('${ctrl.codeName}')}Base */ public doDefaultAction(node: any) { if (node && node.data) { const data: any = node.data; const tags: string[] = data.id.split(';'); <#if ctrl.getPSDETreeNodes()??> <#list ctrl.getPSDETreeNodes() as node> <#if node.getPSDEContextMenu()?? && node.getDefaultPSUIAction()??> <#assign contextMenu = node.getPSDEContextMenu()/> if (tags[0] === "${contextMenu.getOwner().getNodeType()}") { this.${contextMenu.name}_click({tag: '${node.getDefaultPSUIAction().name}'}); } </#if> </#list> </#if> } this.$emit('nodedblclick', this.selectedNodes); } <#ibizinclude> ../@MACRO/CONTROL/CONTROL_BOTTOM-BASE.vue.ftl </#ibizinclude> <#ibizinclude> ../@MACRO/CONTROL/CONTROL-BASE.style.ftl </#ibizinclude>