import { IPSAppCodeList, IPSAppCounterRef, IPSAppDataEntity, IPSAppDEField, IPSAppDEMultiDataView, IPSAppView, IPSCodeItem, IPSControlNavigatable, IPSDECalendar, IPSDETBUIActionItem, IPSDEToolbar, IPSDEToolbarItem, IPSDETree, IPSDEUIAction, IPSExpBar, IPSSysImage, IPSLanguageRes, IPSSysMap, IPSDEChart, IPSNavigateContext, IPSNavigateParam, } from '@ibizstudio/runtime'; import { CodeListServiceBase, throttle, ExpBarControlInterface, LogUtil, ModelTool, Util, ViewTool } from '@ibizstudio/runtime'; import { AppViewLogicService } from '../app-service'; import { MainControlBase } from './main-control-base'; import elementResizeDetectorMaker from 'element-resize-detector'; /** * 导航栏部件基类 * * @export * @class ExpBarControlBase * @extends {MainControlBase} */ export class ExpBarControlBase extends MainControlBase implements ExpBarControlInterface { /** * 导航栏部件模型对象 * * @memberof ExpBarControlBase */ declare controlInstance: IPSExpBar; /** * 数据部件 * * @memberof ExpBarControlBase */ protected declare $xDataControl: IPSDECalendar | IPSControlNavigatable | IPSDETree | IPSSysMap | IPSDEChart; /** * 父导航视图模型对象 * * @memberof ExpBarControlBase */ protected parentModel!: IPSAppDEMultiDataView; /** * 数据部件名称 * * @memberof ExpBarControlBase */ xDataControlName!: string; /** * 视图唯一标识 * * @type {boolean} * @memberof ExpBarControlBase */ viewUID: string = ''; /** * 导航边栏位置 * * @memberof ExpBarControlBase */ sideBarlayout: any; /** * 搜素值 * * @type {(string)} * @memberof ExpBarControlBase */ searchText: string = ''; /** * 呈现模式,可选值:horizontal或者vertical * * @public * @type {(string)} * @memberof ExpBarControlBase */ showMode: string = ''; /** * 控件宽度 * * @type {number} * @memberof ExpBarControlBase */ ctrlWidth: number = 0; /** * 控件高度 * * @type {number} * @memberof ExpBarControlBase */ ctrlHeight: number = 0; /** * 分割宽度 * * @type {number} * @memberof ExpBarControlBase */ split: number = 0.3; /** * 导航视图名称 * * @type {*} * @memberof ExpBarControlBase */ navViewName: any = {}; /** * 导航参数 * * @type {*} * @memberof ExpBarControlBase */ navParam: any = {}; /** * 导航上下文参数 * * @type {*} * @memberof ExpBarControlBase */ navigateContext: any = {}; /** * 导航视图参数 * * @type {*} * @memberof ExpBarControlBase */ navigateParams: any = {}; /** * 导航过滤项 * * @type {string} * @memberof ExpBarControlBase */ navFilter: string = ''; /** * 导航关系 * * @type {string} * @memberof ExpBarControlBase */ navPSDer: string = ''; /** * 选中数据 * * @type {*} * @memberof ExpBarControlBase */ selection: any = {}; /** * 工具栏模型数据 * * @protected * @type {*} * @memberof ExpBarControlBase */ protected toolbarModels: any; /** * 快速分组数据对象 * * @memberof ExpBarControlBase */ quickGroupData: any; /** * 快速分组是否有抛值 * * @memberof ExpBarControlBase */ isEmitQuickGroupValue: boolean = false; /** * 快速分组模型 * * @memberof ExpBarControlBase */ quickGroupModel: Array = []; /** * 备份当前分割宽度 * * @memberof ExpBarControlBase */ copySplit: number = 0; /** * 导航dom节点 * * @memberof ExpBarControlBase */ expDom: any; /** * 缓存UUID * (导航部件抛出值时,renderNavView创建视图容器需要UUID来创建一个新的,才能重绘刷新右侧) * * * @type {*} * @memberof ExpBarControlBase */ cacheUUID: any; /** * 监听静态参数变化 * * @param {*} newVal * @param {*} oldVal * @memberof ExpBarControlBase */ onStaticPropsChange(newVal: any, oldVal: any) { this.viewUID = newVal.viewUID; this.sideBarlayout = newVal.sideBarLayout ? newVal.sideBarLayout : 'LEFT'; super.onStaticPropsChange(newVal, oldVal); } /** * 部件模型数据初始化实例 * * @memberof ExpBarControlBase */ async ctrlModelInit(args?: any) { await super.ctrlModelInit(); this.xDataControlName = this.controlInstance.xDataControlName; this.$xDataControl = ModelTool.findPSControlByName(this.xDataControlName, this.controlInstance.getPSControls()); this.showMode = this.sideBarlayout && this.sideBarlayout == 'LEFT' ? 'horizontal' : 'vertical'; this.showBusyIndicator = this.controlInstance?.showBusyIndicator; this.ctrlWidth = this.controlInstance?.width; if ((this.$xDataControl as any)?.getPSNavigateContexts?.() && ((this.$xDataControl as any)?.getPSNavigateContexts?.() as IPSNavigateContext[])?.length > 0) { this.navigateContext = Util.formatNavParam((this.$xDataControl as any).getPSNavigateContexts()); } if ((this.$xDataControl as any)?.getPSNavigateParams?.() && ((this.$xDataControl as any).getPSNavigateParams?.() as IPSNavigateParam[])?.length > 0) { this.navigateParams = Util.formatNavParam((this.$xDataControl as any).getPSNavigateParams()); } await this.handleXDataCtrlOptions(); } /** * 处理数据部件参数 * * @memberof ExpBarControlBase */ async handleXDataCtrlOptions() { this.parentModel = this.controlInstance.getParentPSModelObject() as IPSAppDEMultiDataView; if (this.parentModel && this.parentModel.enableQuickGroup) { await this.loadQuickGroupModel(); } } /** * 部件初始化 * * @param {*} [args] * @memberof ExpBarControlBase */ ctrlInit(args?: any) { super.ctrlInit(args); this.initCtrlToolBar(); } viewStateAction(tag: string, action: string, data: any) { if (!Object.is(tag, this.name)) { return; } super.viewStateAction(tag, action, data); if (this.$xDataControl) { this.viewState.next({ tag: this.xDataControlName, action: action, data: data }); } } /** * 设置导航区工具栏禁用状态 * * @param {boolean} state * @return {*} * @memberof ExpBarControlBase */ calcToolbarItemState(state: boolean) { let _this: any = this; const models: any = _this.toolbarModels; if (models && models.length > 0) { for (const key in models) { if (!models.hasOwnProperty(key)) { return; } const _item = models[key]; if (_item.uiaction && (Object.is(_item.uiaction.actionTarget, 'SINGLEKEY') || Object.is(_item.uiaction.actionTarget, 'MULTIKEY'))) { _item.disabled = state; } _item.visabled = true; if (_item.noprivdisplaymode && _item.noprivdisplaymode === 6) { _item.visabled = false; } } this.calcNavigationToolbarState(); } } /** * 加载快速分组模型 * * @memberof ExpBarControlBase */ async loadQuickGroupModel() { let quickGroupCodeList: IPSAppCodeList = this.parentModel.getQuickGroupPSCodeList() as IPSAppCodeList; await quickGroupCodeList?.fill?.(); let codeListService = new CodeListServiceBase({ $store: this.$store }); if (!(quickGroupCodeList && quickGroupCodeList.codeName)) { return; } try { let res: any = await codeListService.getDataItems({ tag: quickGroupCodeList.codeName, type: quickGroupCodeList.codeListType, codeList: quickGroupCodeList, context: this.context }); this.quickGroupModel = [...this.handleDynamicData(Util.deepCopy(res))]; } catch (error) { LogUtil.log(`----${quickGroupCodeList.codeName}----${this.$t('app.commonwords.codenotexist')}`); } } /** * 处理快速分组模型动态数据部分(%xxx%) * * @param {Array} inputArray 代码表数组 * @return {*} * @memberof ExpBarControlBase */ handleDynamicData(inputArray: Array) { if (inputArray.length > 0) { const defaultSelect: any = this.getQuickGroupDefaultSelect(); if (defaultSelect) { let select = inputArray.find((item: any) => { return item.value === defaultSelect.value; }); if (select) select.default = true; } inputArray.forEach((item: any) => { if (item.data && Object.keys(item.data).length > 0) { Object.keys(item.data).forEach((name: any) => { let value: any = item.data[name]; if (value && typeof value == 'string' && value.startsWith('%') && value.endsWith('%')) { const key = value.substring(1, value.length - 1).toLowerCase(); if (this.context[key]) { value = this.context[key]; } else if (this.viewparams[key]) { value = this.viewparams[key]; } } item.data[name] = value; }); } }); } return inputArray; } /** * 获取快速分组默认选中项 * * @memberof ExpBarControlBase */ getQuickGroupDefaultSelect() { const codeListItems: Array = (this.parentModel?.getQuickGroupPSCodeList() as IPSAppCodeList)?.getPSCodeItems() || []; let defaultSelect: any = null; if (codeListItems.length > 0) { for (const item of codeListItems) { const childItems: Array = item.getPSCodeItems() || []; if (childItems.length > 0) { defaultSelect = childItems.find((_item: any) => { return _item.default; }); } if (item.default || defaultSelect) { defaultSelect = item; break; } } } return defaultSelect; } /** * 初始化工具栏数据 * * @memberof ExpBarControlBase */ initCtrlToolBar() { let targetViewToolbarItems: any[] = []; const toolbar: IPSDEToolbar = ModelTool.findPSControlByType('TOOLBAR', this.controlInstance.getPSControls() || []) as IPSDEToolbar; if (toolbar) { const toolbarItems: Array = toolbar.getPSDEToolbarItems() || []; toolbarItems.forEach((item: IPSDEToolbarItem) => { const img = item.getPSSysImage(); const css = item.getPSSysCss(); let itemModel: any = { name: item.name, showCaption: item.showCaption, showIcon: item.showIcon, tooltip: this.$tl((item.getTooltipPSLanguageRes() as IPSLanguageRes)?.lanResTag, item.tooltip), iconcls: (item.getPSSysImage() as IPSSysImage)?.cssClass, icon: (item.getPSSysImage() as IPSSysImage)?.glyph, caption: this.$tl((item.getCapPSLanguageRes() as IPSLanguageRes)?.lanResTag, item.caption), disabled: false, itemType: item.itemType, visabled: true, getPSSysImage: img ? { cssClass: img.cssClass, imagePath: img.imagePath } : '', }; if (item.itemType && item.itemType == 'DEUIACTION') { const uiAction: IPSDEUIAction = (item as IPSDETBUIActionItem).getPSUIAction() as IPSDEUIAction; Object.assign(itemModel, { actiontarget: (item as IPSDETBUIActionItem).uIActionTarget, noprivdisplaymode: (item as IPSDETBUIActionItem).data, dataaccaction: uiAction?.dataAccessAction, uiaction: { tag: uiAction?.uIActionTag, target: uiAction?.actionTarget, }, }); //TODO YY 表格工具栏 } targetViewToolbarItems.push(itemModel); }); } this.toolbarModels = targetViewToolbarItems; } /** * split值变化事件 * * @memberof ExpBarControlBase */ onSplitChange() { if (this.split) { this.$store.commit('setViewSplit', { viewUID: `${this.parentModel?.codeName}_${this.controlInstance?.codeName}`, viewSplit: this.split }); } } /** * 初始化导航参数 * * @param params 初始化参数 * @memberof ExpBarControlBase */ initNavParam(params: any) { if (params && params.length > 0) { let navParams: any = {}; params.forEach((param: any) => { const navParam = { [param.key]: param.rawValue ? param.value : '%' + param.value + '%', }; Object.assign(navParams, navParam); }); return navParams; } else { return null; } } /** * 部件挂载 * * @param args 额外参数 * @memberof ExpBarControlBase */ ctrlMounted(args?: any) { super.ctrlMounted(args); const tempSplit = this.$store.getters.getViewSplit(`${this.parentModel?.codeName}_${this.controlInstance?.codeName}`); let expBarContainer = this.$refs['exp-bar-container']; if (expBarContainer) { const erd = elementResizeDetectorMaker(); this.resizeSplit = this.resizeSplit.bind(this); erd.listenTo(expBarContainer, this.resizeSplit); } if (tempSplit) { this.split = Number(tempSplit); } else { this.calcSplit(); } } /** * @description 计算split值 * @memberof ExpBarControlBase */ calcSplit() { let splitDom: any = this.$refs[`${this.appDeCodeName}-${this.controlInstance?.codeName?.toLowerCase()}`]; let containerWidth: number = splitDom?.$el?.offsetWidth; let containerHeight: number = splitDom?.$el?.offsetHeight; if (Object.is(this.showMode, 'horizontal')) { if (this.ctrlWidth && containerWidth) { this.split = this.ctrlWidth / containerWidth; } } else { if (this.ctrlHeight && containerHeight) { this.split = this.ctrlHeight / containerHeight; } } this.$store.commit('setViewSplit', { viewUID: `${this.parentModel?.codeName}_${this.controlInstance?.codeName}`, viewSplit: this.split }); } /** * @description 重新计算split值 * @memberof ExpBarControlBase */ resizeSplit() { this.calcSplit(); this.$forceUpdate(); } /** * 绘制数据部件 * * @memberof ExpBarControlBase */ renderXDataControl() { let { targetCtrlName, targetCtrlParam, targetCtrlEvent } = this.computeTargetCtrlData(this.$xDataControl); return this.$createElement(targetCtrlName, { props: targetCtrlParam, ref: this.xDataControlName, on: targetCtrlEvent }); } /** * 计算目标部件所需参数 * * @param {*} controlInstance 数据部件 * @return {*} * @memberof ExpBarControlBase */ computeTargetCtrlData(controlInstance: any) { const { targetCtrlName, targetCtrlParam, targetCtrlEvent } = super.computeTargetCtrlData(controlInstance); Object.assign(targetCtrlParam.staticProps, { isSelectFirstDefault: true, isSingleSelect: true, }); return { targetCtrlName: targetCtrlName, targetCtrlParam: targetCtrlParam, targetCtrlEvent: targetCtrlEvent }; } /** * 执行搜索 * * @memberof ExpBarControlBase */ onSearch() {} /** * 绘制快速搜索 * * @memberof ExpBarControlBase */ renderSearch() { const appDataEntity: IPSAppDataEntity = this.controlInstance.getPSAppDataEntity() as IPSAppDataEntity; const getQuickSearchPlaceholader = (entity: IPSAppDataEntity) => { let placeholder: any = ''; const fields: Array = entity.getQuickSearchPSAppDEFields() || []; fields.forEach((field: IPSAppDEField, index: number) => { const _field = entity.findPSAppDEField(field.codeName); if (_field) { placeholder += this.$tl(_field.getLNPSLanguageRes()?.lanResTag, _field.logicName) + (index === fields.length - 1 ? '' : ', '); } }); return placeholder; }; return (
{ this.searchText = $event.target.value; }} placeholder={getQuickSearchPlaceholader(appDataEntity)} on-on-search={($event: any) => this.onSearch()} >
); } /** * 绘制快速分组 * * @memberof ExpBarControlBase */ renderQuickGroup() { const enableCounter = this.controlInstance.enableCounter; if (enableCounter) { let counterService: any; let sysCounter: IPSAppCounterRef | null = this.parentModel?.getPSAppCounterRef(); if (sysCounter?.id) { counterService = Util.findElementByField(this.counterServiceArray, 'id', sysCounter.id)?.service; } return this.quickGroupValueChange(value)}>; } else { return this.quickGroupValueChange(value)}>; } } /** * 绘制工具栏 * * @memberof ExpBarControlBase */ renderToolbar() { return ( { throttle(this.handleItemClick, [data, $event], this); }} > ); } /** * 工具栏点击 * * @param {*} data 事件数据 * @param {*} $event 事件对象 * @return {*} * @memberof ExpBarControlBase */ handleItemClick(data: any, $event: any) { if (this.Environment && this.Environment.isPreviewMode) { return; } AppViewLogicService.getInstance().executeViewLogic( `${this.controlInstance.name?.toLowerCase()}_toolbar_${data.tag}_click`, $event, this, undefined, this.controlInstance.getPSAppViewLogics() || [], ); } /** * 快速分组值变化 * * @param {*} $event 分组事件源 * @return {*} * @memberof ExpBarControlBase */ quickGroupValueChange($event: any) { if (this.Environment && this.Environment.isPreviewMode) { return; } if ($event && $event.data) { if (this.quickGroupData) { for (let key in this.quickGroupData) { delete this.viewparams[key]; } } this.quickGroupData = $event.data; Object.assign(this.viewparams, $event.data); } else { if (this.quickGroupData) { for (let key in this.quickGroupData) { delete this.viewparams[key]; } } } if (this.isEmitQuickGroupValue) { this.onSearch(); } this.isEmitQuickGroupValue = true; } /** * 计算导航工具栏权限状态 * * @memberof ExpBarControlBase */ calcNavigationToolbarState() { let _this: any = this; if (_this.toolbarModels) { ViewTool.calcActionItemAuthState({}, this.toolbarModels, this.appUIService); } } /** * 刷新 * * @memberof ExpBarControlBase */ refresh(): void { if (this.$xDataControl) { const xDataControl: any = (this.$refs[`${this.xDataControlName?.toLowerCase()}`] as any).ctrl; if (xDataControl && xDataControl.refresh && xDataControl.refresh instanceof Function) { xDataControl.refresh(); } } } /** * 选中数据事件 * * * @param {any[]} args 选中数据 * @return {*} {void} * @memberof ExpBarControlBase */ onSelectionChange(args: any[]): void { let tempContext: any = {}; let tempViewParam: any = {}; if (args.length === 0) { this.calcToolbarItemState(true); return; } const arg: any = args[0]; if (this.context) { Object.assign(tempContext, Util.deepCopy(this.context)); } if (this.$xDataControl) { const appDataEntity: IPSAppDataEntity | null = this.$xDataControl?.getPSAppDataEntity(); if (appDataEntity) { Object.assign(tempContext, { [`${appDataEntity.codeName?.toLowerCase()}`]: arg[appDataEntity.codeName?.toLowerCase()] }); Object.assign(tempContext, { srfparentdename: appDataEntity.codeName, srfparentdemapname: (appDataEntity as any)?.getPSDEName(), srfparentkey: arg[appDataEntity.codeName?.toLowerCase()] }); if (this.navFilter && !Object.is(this.navFilter, '')) { Object.assign(tempViewParam, { [this.navFilter]: arg[appDataEntity.codeName?.toLowerCase()] }); } if (this.navPSDer && !Object.is(this.navPSDer, '')) { Object.assign(tempViewParam, { [this.navPSDer]: arg[appDataEntity.codeName?.toLowerCase()] }); } } if (this.navigateContext && Object.keys(this.navigateContext).length > 0) { let _context: any = this.$util.computedNavData(arg, tempContext, tempViewParam, this.navigateContext); Object.assign(tempContext, _context); } if (this.navigateParams && Object.keys(this.navigateParams).length > 0) { let _params: any = this.$util.computedNavData(arg, tempContext, tempViewParam, this.navigateParams); Object.assign(tempViewParam, _params); } this.selection = {}; Object.assign(tempContext, { viewpath: this.navViewName }); Object.assign(this.selection, { view: { viewname: 'app-view-shell' }, context: tempContext, viewparam: tempViewParam }); this.calcToolbarItemState(false); if (this.expDom && this.selection) { this.expDom.className = 'ivu-split-horizontal openedit'; this.split = this.copySplit; } this.$forceUpdate(); this.$emit('ctrl-event', { controlname: this.controlInstance.name, action: 'selectionchange', data: args }); } } /** * load完成事件 * * @param {*} args 加载数据 * @param {string} [tag] * @param {*} [$event2] * @memberof ExpBarControlBase */ onLoad(args: any, tag?: string, $event2?: any) { this.calcToolbarItemState(true); if (this.$xDataControl) { this.$emit('ctrl-event', { controlname: this.xDataControlName, action: 'load', data: args }); } } /** * 部件事件 * @param ctrl 部件 * @param action 行为 * @param data 数据 * * @memberof ExpBarControlBase */ onCtrlEvent(controlname: any, action: any, data: any) { if (controlname && Object.is(controlname, this.xDataControlName)) { switch (action) { case 'selectionchange': this.onSelectionChange(data); return; case 'load': this.onLoad(data, action); return; } } super.onCtrlEvent(controlname, action, data); } /** * 关闭编辑视图 * * @memberof ExpBarControlBase */ close() { this.expDom = document.getElementsByClassName('ivu-split-horizontal')[1]; if (this.expDom) { this.expDom.className = 'ivu-split-horizontal closeedit'; } this.selection = {}; this.copySplit = this.split; this.split = 1; } /** * 绘制导航标题栏 * * @memberof ExpBarControlBase */ renderTitleBar() { const classStr: string = `${this.$xDataControl.controlType?.toLowerCase()}-exp-bar`; const title = this.$tl(this.controlInstance.getTitlePSLanguageRes()?.lanResTag, this.controlInstance?.title); return (
{title}
); } /** * 绘制右侧导航组件 * * @memberof ExpBarControlBase */ renderNavView() { if (this.selection?.view && !Object.is(this.selection.view.viewname, '')) { if (!this.cacheUUID || this.cacheUUID.indexOf(this.selection.context.viewpath) == -1) { this.cacheUUID = this.selection.context.viewpath + Util.createUUID(); } let targetCtrlParam: any = { staticProps: { viewDefaultUsage: false, }, dynamicProps: { viewparam: JSON.stringify(this.selection.viewparam), viewdata: JSON.stringify(this.selection.context), }, }; return this.$createElement('app-view-shell', { key: this.cacheUUID, class: 'viewcontainer2', props: targetCtrlParam, on: { close: (data: any) => { this.close(); }, }, }); } } /** * 绘制内容 * * @param {*} [otherClassNames] 额外类名 * @return {*} * @memberof ExpBarControlBase */ renderContent(otherClassNames?: any) { const { showTitleBar, enableSearch } = this.controlInstance; let enableQuickGroup = this.parentModel?.enableQuickGroup; const controlType = this.$xDataControl?.controlType; let classNames: any = { [`${controlType?.toLowerCase()}-exp-bar-content`]: showTitleBar ? true : false, [`${controlType?.toLowerCase()}-exp-bar-content2`]: !showTitleBar ? true : false, 'has-search': enableSearch ? true : false, }; if (otherClassNames) { Object.assign(classNames, otherClassNames); } let viewStyle = (this.controlInstance?.getParentPSModelObject?.() as IPSAppView)?.viewStyle; return [ viewStyle == 'DEFAULT' && this.sideBarlayout == 'LEFT' ? (
) : null,
{showTitleBar ? this.renderTitleBar() : null}
{enableQuickGroup && this.quickGroupModel?.length > 0 ? this.renderQuickGroup() : null} {enableSearch ? this.renderSearch() : null} {ModelTool.findPSControlByType('TOOLBAR', this.controlInstance.getPSControls() || []) ? this.renderToolbar() : null}
{this.$xDataControl ? this.renderXDataControl() : null}
,
{this.renderNavView()}
, ]; } /** * 绘制导航栏主体内容 * * @memberof ExpBarControlBase */ renderMainContent() { if (!this.controlIsLoaded) { return null; } return (
{this.renderContent()}
); } /** * 绘制导航栏主内容 * @returns {*} * @memberof ExpBarControlBase */ render() { if (!this.controlIsLoaded) { return null; } return this.renderMainContent(); } }