import { MobTreeControlInterface, Util, ViewTool } from 'ibiz-core'; import { MDControlBase } from './md-control-base'; import { AppMobTreeService } from '../ctrl-service'; import { AppViewLogicService } from "../app-service"; import { DataServiceHelp, UIServiceHelp } from "ibiz-core"; import { IPSDETree, IPSDETreeNode, IPSDEToolbarItem, IPSDECMUIActionItem, IPSDEUIAction, IPSDETBUIActionItem, IPSAppDataEntity } from '@ibiz/dynamic-model-api'; /** * 移动端树视图部件基类 * * @export * @class MobTreeControlBase * @extends {MDControlBase} */ export class MobTreeControlBase extends MDControlBase implements MobTreeControlInterface { /** * 树视图部件的模型对象 * * @type {*} * @memberof MobTreeControlBase */ public declare controlInstance: IPSDETree; /** * 树视图导航数组名称 * * @type {string[]} * @memberof MobTreeControlBase */ public treeNav: any = []; /** * 已选中数据集合 * * @type {*} * @memberof MobTreeControlBase */ public selectedNodes: any = []; /** * 当前选中数据项 * * @type {*} * @memberof MobTreeControlBase */ public currentselectedNode: any = {}; /** * 选中数据字符串 * * @type {string} * @memberof MobTreeControlBase */ public selectedData?: string; /** * 回显选中数据集合 * * @type {*} * @memberof MobTreeControlBase */ public echoselectedNodes: any[] = []; /** * 过滤属性 * * @type {string} * @memberof MobTreeControlBase */ public srfnodefilter: string = ''; /** * 树数据 * * @type {any[]} * @memberof MobTreeControlBase */ public nodes: any[] = []; /** * 激活节点 * * @memberof MobTreeControlBase */ public activeNode = ""; /** * 节点数组 * * @memberof MobTreeControlBase */ public rootNodes: any = []; /** * 节点值数组 * * @memberof MobTreeControlBase */ public valueNodes: any = []; /** * 备份树节点上下文菜单 * * @type any * @memberof MainTreeBase */ public copyActionModel: any; /** * 单选选择值 * * @param {string} * @memberof MobTreeControlBase */ public selectedValue: string = ""; /** * 树缓存 * * @type {Map} * @memberof MobTreeControlBase */ public treeCache: Map = new Map(); /** * 获取多项数据 * * @returns {any[]} * @memberof MobTreeControlBase */ public getDatas(): any[] { return [this.currentselectedNode]; } /** * 获取单项树 * * @returns {*} * @memberof MobTreeControlBase */ public getData(): any { return this.currentselectedNode; } /** * 选中值变化 * * @param {*} newVal * @param {*} oldVal * @memberof MobTreeControlBase */ public async onSelectedDataValueChange(newVal: any) { if (!(await this.handleCtrlEvents('onselectionchange', { action: this.loadAction, data: newVal }))) { return; } 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); } } /** * 节点点击加载 * * @memberof MobTreeControlBase */ public click_node(data: any) { if (this.treeNav[this.treeNav.length - 1].id == data.id) { return } this.treeNav.push(data); this.load({ data: data }); } /** * 初始化树节点上下文菜单集合 * * @memberof CalendarControlBase */ public initCtrlActionModel() { const allTreeNodes = this.controlInstance.getPSDETreeNodes() || []; let tempModel: any = {}; if (allTreeNodes?.length > 0) { allTreeNodes.forEach((item: IPSDETreeNode) => { if (item?.getPSDEContextMenu()) { let toobarItems: any = item.getPSDEContextMenu()?.getPSDEToolbarItems(); if (toobarItems.length > 0) { toobarItems.forEach((toolbarItem: IPSDEToolbarItem) => { this.initActionModelItem(toolbarItem, item, tempModel) }) } } }) } this.actionModel = {}; Object.assign(this.actionModel, tempModel); } /** * 初始化上下菜单项 * * @param toolbarItem * @param item * @param tempModel * @memberof CalendarControlBase */ public initActionModelItem(toolbarItem: IPSDEToolbarItem, item: IPSDETreeNode, tempModel: any) { if (!toolbarItem) { return } let tempItem: any = { name: toolbarItem.name, ctrlname: item.getPSDEContextMenu()?.name, nodeOwner: item.nodeType } if (toolbarItem.itemType == 'DEUIACTION') { const uiAction: IPSDEUIAction = (toolbarItem as IPSDECMUIActionItem).getPSUIAction() as IPSDEUIAction; if (uiAction) { tempItem.type = uiAction.uIActionType; tempItem.tag = uiAction.uIActionTag; tempItem.visabled = true; tempItem.disabled = false; if (uiAction?.actionTarget && uiAction?.actionTarget != "") { tempItem.actiontarget = uiAction.actionTarget; } if (uiAction.noPrivDisplayMode) { tempItem.noprivdisplaymode = uiAction.noPrivDisplayMode; } if (uiAction.dataAccessAction) { tempItem.dataaccaction = uiAction.dataAccessAction; } } } tempItem.imgclass = toolbarItem.showIcon && toolbarItem.getPSSysImage() ? toolbarItem.getPSSysImage()?.cssClass : ''; tempItem.caption = toolbarItem.showCaption ? toolbarItem.caption : ''; tempItem.title = toolbarItem.tooltip; tempModel[`${item.nodeType}_${toolbarItem.name}`] = tempItem; const toolbarItems = (toolbarItem as IPSDETBUIActionItem)?.getPSDEToolbarItems?.() || []; if (toolbarItems?.length > 0) { for (let toolBarChild of toolbarItems) { this.initActionModelItem(toolBarChild, item, tempModel) } } } /** * 显示上下文菜单 * * @param data 节点数据 * @param event 事件源 * @memberof DocLibTreeProductMobBase */ public showContext(data: any, event: any) { let _this: any = this; this.copyActionModel = {}; const tags: string[] = data.id.split(';'); Object.values(this.actionModel).forEach((item: any) => { if (Object.is(item.nodeOwner, tags[0])) { this.copyActionModel[item.name] = item; } }) if (Object.keys(this.copyActionModel).length === 0) { return; } this.computeNodeState(data, data.nodeType, data.appEntity).then((result: any) => { let flag: boolean = false; if (Object.values(result).length > 0) { flag = Object.values(result).some((item: any) => { return item.visabled === true; }) } if (flag) { (_this.$refs.contextmenu as any).openContextMenu(); } }); } /** * 计算节点右键权限 * * @param {*} node 节点数据 * @param {*} nodeType 节点类型 * @param {*} appEntityName 应用实体名称 * @returns * @memberof MobTreeControlBase */ public async computeNodeState(node: any, nodeType: string, appEntity:IPSAppDataEntity) { if (Object.is(nodeType, 'STATIC')) { return this.copyActionModel; } try { let service: any = await DataServiceHelp.getInstance().getService(appEntity, { context: this.context }); if (this.copyActionModel && Object.keys(this.copyActionModel).length > 0) { if (service['Get'] && service['Get'] instanceof Function) { let tempContext: any = Util.deepCopy(this.context); tempContext[appEntity.codeName.toLowerCase()] = node.srfkey; let targetData = await service.Get(tempContext, {}, false); const uiService = await UIServiceHelp.getInstance().getService(appEntity,this.context); ViewTool.calcTreeActionItemAuthState(targetData.data, this.copyActionModel, uiService); } else { console.warn(this.$t('app.warn.getDataWarn')); } } } catch (error) { console.warn(error); } return this.copyActionModel; } /** * 导航点击行为 * * @param {*} newVal * @param {*} oldVal * @memberof MobTreeControlBase */ 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 }); } /** * 解析节点数据 * * @param {*} nodes * @memberof MobTreeControlBase */ public parseNodes(nodes: any) { this.rootNodes = []; this.valueNodes = []; for (let index = 0; index < nodes.length; index++) { const item = nodes[index]; if (!item.leaf) { this.rootNodes.push(item); } else { this.backfill(item); this.valueNodes.push(item); } } this.$forceUpdate(); } /** * 回填已选择树节点 * * @param {*} nodes * @memberof MobTreeControlBase */ public backfill(item: any) { let ele: any = this.$refs[item.srfkey + 'checkbox']; if (this.selectedNodes.findIndex((temp: any) => { return temp.srfkey == item.srfkey }) > -1) { item.selected = true; if (ele && ele[0]) { ele[0].ariaChecked = true; } } else { item.selected = false; if (ele && ele[0]) { ele[0].ariaChecked = false; } } } /** * 选中数据变更事件 * * @public * @param {*} data * @param {*} data 当前节点对应传入对象 * @param {*} checkedState 树目前选中状态对象 * @memberof MobTreeControlBase */ 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 MobTreeControlBase */ public selectionChange(data: any, node: any) { // 禁用项处理 if (data.disabled) { node.isCurrent = false; return; } // 只处理最底层子节点 if (data.leaf) { this.currentselectedNode = JSON.parse(JSON.stringify(data)); // 单选直接替换 if (this.isSingleSelect) { this.selectedNodes = [this.currentselectedNode]; this.$emit('selectionchange', this.selectedNodes); } // 多选用check方法 } } /** * 对树节点进行筛选操作 * @memberof OrderTree */ public filterNode(value: any, data: any) { if (!value) return true; return data.text.indexOf(value) !== -1; } /** * 刷新数据 * * @memberof MobTreeControlBase */ public refresh_all(): void { this.treeNav.splice(1, this.treeNav.length - 1); this.load(); } /** * 刷新父节点 * * @memberof MobTreeControlBase */ public refresh_parent(): void { this.load({ data: this.treeNav[this.treeNav.length - 1] }) } /** * 数据加载 * * @param {*} node * @memberof MobTreeControlBase */ public async load(node: any = {}, args: 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)); if (tempViewParams.selectedData) { delete tempViewParams.selectedData; } 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 }); } if (curNode.data && curNode.data.srfparentdemapname) { Object.assign(tempContext, { srfparentdemapname: curNode.data.srfparentdemapname }); Object.assign(tempViewParams, { srfparentdemapname: curNode.data.srfparentdemapname }); } Object.assign(params, { viewparams: tempViewParams }); if (args) { Object.assign(params, args); } if (!(await this.handleCtrlEvents('onbeforeload', { action: this.fetchAction, data: args }))) { return; } const cacheID = JSON.stringify(tempContext) + JSON.stringify(params); const cacheData = this.treeCache.get(cacheID); if (cacheData) { const _items = Util.deepCopy(cacheData); this.nodes = [..._items]; this.parseNodes(this.nodes); let isRoot = Object.is(node.level, 0); let isSelectedAll = node.checked; this.setDefaultSelection(_items, isRoot, isSelectedAll); return; } try { const response = await this.service.getNodes(tempContext, params); if (!response || response.status !== 200) { this.$Notice.error(response.info); return response; } if (!(await this.handleCtrlEvents('onloadsuccess', { action: this.fetchAction, data: response?.data }))) { return response; } const _items = response.data; this.nodes = [..._items]; this.treeCache.set(cacheID, [..._items]); this.parseNodes(this.nodes); let isRoot = Object.is(node.level, 0); let isSelectedAll = node.checked; this.setDefaultSelection(_items, isRoot, isSelectedAll); this.$emit("load", _items); return response; } catch (response: any) { if (!(await this.handleCtrlEvents('onloaderror', { action: this.fetchAction, data: response?.data }))) { return; } if (response && response.status === 401) { return; } this.$Notice.error(response.info); } } /** * 计算当前节点的上下文 * * @param {*} curNode 当前节点 * @memberof MobTreeControlBase */ 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 MobTreeControlBase */ public refresh(args: any[]): void { this.refresh_all(); } /** * 设置默认选中,回显数项,选中所有子节点 * * @param {any[]} items 当前节点所有子节点集合 * @param {boolean} isRoot 是否是加载根节点 * @param {boolean} isSelectedAll 是否选中所有子节点 * @memberof MobTreeControlBase */ 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: number = -1; if (this.selectedNodes && this.selectedNodes.length > 0) { this.selectedNodes.forEach((select: any) => { index = items.findIndex((item: any) => { if (Util.isEmpty(item.srfkey)) { return select.id == item.id; } else { return select.srfkey == item.srfkey; } }); }); } if (index === -1) { if (isRoot) { index = 0; } else { return; } } defaultData = items[index]; this.setTreeNodeHighLight(defaultData); this.currentselectedNode = JSON.parse(JSON.stringify(defaultData)); if (defaultData.leaf) { this.selectedNodes = [this.currentselectedNode]; this.ctrlEvent({ controlname: this.controlInstance.name, action: 'selectionchange', data: 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); } this.ctrlEvent({ controlname: this.controlInstance.name, action: 'selectionchange', data: this.selectedNodes, }); } } } // 父节点选中时,选中所有子节点 if (isSelectedAll) { let leafNodes = items.filter((item: any) => item.leaf); this.selectedNodes = this.selectedNodes.concat(leafNodes); this.ctrlEvent({ controlname: this.controlInstance.name, action: 'selectionchange', data: this.selectedNodes, }); } } /** * 设置选中高亮 * * @param {*} data * @memberof MobTreeControlBase */ public setTreeNodeHighLight(data: any): void { const tree: any = this.$refs[this.controlInstance.name]; tree?.setCurrentKey(data.id); } /** * 执行默认界面行为 * * @param {*} node * @memberof MobTreeControlBase */ public doDefaultAction(node: any) { if (node && node.data) { const data: any = node.data; const tags: string[] = data.id.split(';'); // todo 执行默认界面行为 } this.ctrlEvent({ controlname: this.controlInstance.name, action: 'nodedblclick', data: this.selectedNodes, }); } /** * 单选点击行为 * * @param {*} item * @memberof MobTreeControlBase */ public onSimpleSelChange(item: any) { if(item.appEntity){ delete item.appEntity; } this.ctrlEvent({ controlname: this.controlInstance.name, action: 'selectchange', data: [item], }); this.selectedValue = item.srfkey; } /** * 多选点击行为 * * @param {*} data * @memberof MobTreeControlBase */ public onChecked(data: any) { let { detail } = data; if (!detail) { return; } let { value } = detail; for (let index = 0; index < this.valueNodes.length; index++) { const item = this.valueNodes[index]; if(item.appEntity){ delete item.appEntity; } if (Object.is(item.srfkey, value)) { if (detail.checked) { this.selectedNodes.push(this.valueNodes[index]); } else { let i = this.selectedNodes.findIndex((i: any) => i.srfkey === item.srfkey) if (i > -1) { this.selectedNodes.splice(i, 1) } } } } this.ctrlEvent({ controlname: this.controlInstance.name, action: 'selectchange', data: this.selectedNodes, }); } /** * 节点长按 * * @memberof MobTreeControlBase */ public node_touch(item: any) { this.activeNode = item.id.split(';')[0]; this.currentselectedNode = Object.assign(JSON.parse(JSON.stringify(item.curData || {})), item); this.showContext(item, {}) } /** * 树前端搜索 * * @memberof MobTreeControlBase */ public webLoad(query: string) { let reNodes: any = []; for (let index = 0; index < this.nodes.length; index++) { const node = this.nodes[index]; if (node.srfmajortext.indexOf(query) != -1) { reNodes.push(node); } } this.parseNodes(reNodes); } /** * 上下文菜单点击 */ public context_menu_click() { (this.$refs.contextmenu as any).closeContextMenu(); } /** * 监听动态参数变化 * * @param {*} newVal * @param {*} oldVal * @memberof TreeControlBase */ public onDynamicPropsChange(newVal: any, oldVal: any) { super.onDynamicPropsChange(newVal, oldVal); if (newVal?.selectedData && newVal.selectedData != oldVal?.selectedData) { this.selectedData = newVal.selectedData; this.onSelectedDataValueChange(newVal.selectedData) } } /** * 监听静态参数变化 * * @param {*} newVal * @param {*} oldVal * @memberof TreeControlBase */ public onStaticPropsChange(newVal: any, oldVal: any) { this.isSingleSelect = newVal?.isSingleSelect !== false; super.onStaticPropsChange(newVal, oldVal); } /** * 部件模型数据初始化 * * @memberof AppDefaultMobForm */ public async ctrlModelInit(args?: any) { await super.ctrlModelInit(); this.service = new AppMobTreeService(this.controlInstance); this.treeNav = [{ id: "#", text: this.controlInstance.logicName }]; } /** * 树视图部件初始化 * * @memberof MobTreeControlBase */ public ctrlInit() { super.ctrlInit(); if (this.viewState) { this.viewStateEvent = this.viewState.subscribe(({ tag, action, data }: any) => { if (!Object.is(tag, this.name)) { return; } if (Object.is('load', action)) { this.load(); } if (Object.is('filter', action)) { this.srfnodefilter = data.srfnodefilter; this.refresh_all(); } if (Object.is('refresh_parent', action)) { this.refresh_parent(); } if (Object.is('quicksearch', action)) { this.load({ data: this.treeNav[this.treeNav.length - 1] }, { query: data }); } if (Object.is('refresh', action)) { this.selectedNodes = data; this.parseNodes(this.nodes); } if (Object.is('search', action)) { this.load({ data: this.treeNav[this.treeNav.length - 1] }, { query: data?.quickSearchValue }); } }); } } /** * 部件事件 * @param ctrl 部件 * @param action 行为 * @param data 数据 * * @memberof ViewBase */ public onCtrlEvent(controlname: string, action: string, data: any) { if (action == 'contextMenuItemClick') { AppViewLogicService.getInstance().executeViewLogic(`${controlname}_${data}_click`, undefined, this, undefined, this.controlInstance.getPSAppViewLogics()); // 关闭上下文菜单 this.context_menu_click(); } else { this.ctrlEvent({ controlname, action, data }); } } }