import { IAbility, IActionModel, IContext, IMDCtrlAbility, IParam, IRedirectInput, IRedirectResult, IUIActionResult, IUIService, IViewAbility, } from '@/core/interface'; import { deepCopy, formatActionData, hasFunction } from '../../utils/util'; /** * 界面服务基类 * * @export * @class UIService */ export abstract class UIServiceBase implements IUIService { /** * 是否启用主状态 * * @protected * @type {boolean} * @memberof UIService */ public isEnableDEMainState = false; /** * 流程状态数组 * * @protected * @type {Array} * @memberof UIServiceBase */ public InWorkflowArray: Array = ['todo', 'toread']; /** * 执行界面行为 * @param tag 界面行为标识 * @param context 应用上下文 * @param viewParams 视图参数 * @param data 业务数据 * @param event 事件对象 * @param ability 当前环境能力 */ public executeUIAction( tag: string, context: IContext, viewParams: IParam, data: IParam[], event: MouseEvent, ability: T ): Promise { const _this: any = this; if (hasFunction(_this, tag)) { return _this[tag](context, viewParams, data, event, ability); } console.error(`${tag} 行为不存在`); return Promise.reject({ ok: false, data: {} }); } /** * 执行界面逻辑 * @param tag 界面逻辑标识 * @param context 应用上下文 * @param viewParams 视图参数 * @param data 业务数据 * @param event 事件对象 * @param ability 当前环境能力 */ public executeUILogic( tag: string, context: IContext, viewParams: IParam, data: IParam[], event: MouseEvent, ability: T ): Promise { throw new Error('Method not implemented.'); } /** * 获取指定操作标识权限 * * @param tag 操作标识tag * @param data 业务数据 */ public abstract getOPPrivsAuth(tag: string, data: IParam): number; /** * 获取重定向视图 * @param context 应用上下文 * @param viewParams 视图参数 * @param data 当前业务数据 * @param redirectParam 重定向视图输入参数 */ public getAppRDView( context: IContext, viewParams: IParam, data: IParam, redirectParam: IRedirectInput ): Promise { throw new Error('Method not implemented.'); } /** * 处理界面行为参数 * */ protected async handleUIActionParam( context: IContext, viewParams: IParam, data: IParam[], actionModel: IActionModel ): Promise<{ context: IContext; viewParams: IParam; data: IParam[] }> { // 处理数据目标参数 const targetParams = await this.handleTargetParams( context, data, actionModel ); // 根据数据目标参数,合并导航参数 return this.handleNavParams( context, viewParams, data, targetParams, actionModel ); } /** * 根据数据目标处理行为参数 * * @param {string} action * @param { IUIActionParams } params * @memberof AppFrontAction */ protected async handleTargetParams( context: IContext, data: IParam[], actionModel: IActionModel ): Promise<{ targetContext: IParam; targetViewParams: IParam; targetData: IParam[]; }> { const { actionTarget, entityCodeName, keyFieldCodeName, majorFieldCodeName, } = actionModel; // 数据目标值 const targetContext: IParam = {}; const targetViewParams: IParam = {}; const targetData: IParam[] = []; if (actionTarget == 'SINGLEKEY' || actionTarget == 'MULTIKEY') { // 多数据主键和单数据主键,合并实体的主键参数和主信息参数 到上下文 后续统一合并进数据目标值 if (!entityCodeName || !keyFieldCodeName || !majorFieldCodeName) { throw new Error('实体级界面行为参数不足'); } const entityName = entityCodeName.toLowerCase(); const keyField = keyFieldCodeName.toLowerCase(); const majorField = majorFieldCodeName.toLowerCase(); if (data && data.length > 0 && data[0][keyField]) { Object.assign(targetContext, { [entityName]: `%${keyField}%`, }); } else { Object.assign(targetContext, { [entityName]: `%${entityName}%`, }); } Object.assign(targetViewParams, { [keyField]: `%${keyField}%`, }); Object.assign(targetViewParams, { [majorField]: `%${majorField}%`, }); } else if (actionTarget == 'SINGLEDATA') { if (data && data.length > 0) { targetData.push(data[0]); } } return { targetContext, targetViewParams, targetData }; } /** * 处理行为参数 导航参数 * * @ * @param {IParam} uiAction * @param IUIActionParams params * @memberof AppFrontAction */ protected handleNavParams( context: IContext, viewParams: IParam, data: IParam[], { targetContext, targetViewParams, targetData }: IParam, actionModel: IActionModel ): { context: IParam; viewParams: IParam; data: IParam[] } { const { navContexts, navParams, actionTarget } = actionModel; // 合并导航参数和导航上下文至数据目标处理后的参数 const _targetContext = deepCopy(targetContext); const _targetViewParams = deepCopy(targetViewParams); if (navContexts) { Object.assign(_targetContext, navContexts); } if (navParams) { Object.assign(_targetViewParams, navParams); } // 根据上下文和导航参数,解析参数 const _context = formatActionData( actionTarget, data, context, viewParams, _targetContext ); const _viewParams = formatActionData( actionTarget, data, context, viewParams, _targetViewParams ); // 单项数据并且目标数据中存在值时合并 if ( Object.is(actionTarget, 'SINGLEDATA') && targetData && targetData.length > 0 ) { Object.assign(targetData[0], _viewParams); } else { targetData = [_viewParams]; } Object.assign(context, _context); const tempViewParams = targetData && targetData.length > 0 ? targetData[0] : {}; if (viewParams && viewParams.srfactivatedtime) { Object.assign(tempViewParams, { srfactivatedtime: viewParams.srfactivatedtime }); } // 多项数据主键转换数据 // if (Object.is(actionTarget, 'MULTIKEY')) { // const tempDataArray: Array = []; // if (data.length > 1 && Object.keys(data).length > 0) { // for (let i = 0; i < data.length; i++) { // const tempObject: any = {}; // Object.keys(targetData).forEach((key: string) => { // Object.assign(tempObject, { [key]: targetData[key].split(',')[i] }); // }); // tempDataArray.push(tempObject); // } // } else { // tempDataArray.push(data); // } // targetData = tempDataArray; // } // return { context, viewParams: tempViewParams, data }; } /** * 行为附加操作 刷新引用视图 & 关闭编辑或弹出视图 & 后续界面行为 * * @param {IContext} context * @param {IParam} viewParams * @param {IParam[]} data * @param {MouseEvent} event * @param {IAbility} ability * @memberof UIServiceBase */ protected afterAction( context: IContext, viewParams: IParam, data: IParam[], event: MouseEvent, ability: IAbility, actionModel: IActionModel ): Promise { const { refreshMode, reloadData, closeEditView, nextAction, uILogicAttachMode, deUILogicTag, entityCodeName, } = actionModel; // 刷新引用视图(节点) if (reloadData && refreshMode === 1 && hasFunction(ability, 'refresh')) { (ability as IMDCtrlAbility).refresh(); } // 当刷新模式为刷新引用视图,且当前能力部件是表单时,全局刷新 if ( reloadData && refreshMode === 1 && ability.getModel().controlType === 'FORM' ) { App.getGlobalNotificationHelper().notice(entityCodeName, 'refresh'); } if (reloadData && (refreshMode === 2 || refreshMode === 3)) { const view = ability?.viewCtx.view; if (view) { // 刷新引用节点父节点 if (refreshMode === 2 && hasFunction(view, 'refreshParentView')) { view.refreshParentView(); } // 刷新引用节点根节点 if (refreshMode === 3 && hasFunction(view, 'refreshRootView')) { view.refreshRootView(); } } } // 关闭视图 if (closeEditView) { (ability as IViewAbility).closeView(); } // 后续界面行为 if (!nextAction) { // 后续界面逻辑 if (uILogicAttachMode === 'AFTER' && deUILogicTag) { return this.executeUILogic( deUILogicTag, context, viewParams, data, event, ability ); } return Promise.resolve({ ok: true, data: data }); } if (nextAction.predefinedType) { return App.getGlobalActionHelper().executeUIAction( nextAction.name, context, viewParams, data, event, ability ); } if (nextAction.actionDeCodeName) { return new Promise((resolve: Function) => { App.getUIService(nextAction.actionDeCodeName as string).then( (service: IUIService) => { resolve( service.executeUIAction( nextAction.name, context, viewParams, data, event, ability ) ); } ); }); } return Promise.resolve({ ok: true, data: data }); } /** * 获取工作流视图 * * @return {*} * @memberof UIServiceBase */ public getWFView(): any { throw new Error('Method not implemented.'); } }