import { IAppViewMsgHelper, IContext, IDEDataSetViewMsg, IParam, isExistAndNotEmpty, IViewMsg, IViewMsgGroup, IViewMsgGroupDetail, } from '@/core'; import { AppViewMsgHelperBase } from '@/core/modules/view-msg'; import { ascSort, descSort } from 'qx-util'; export class AppViewMsgHelper extends AppViewMsgHelperBase implements IAppViewMsgHelper { /** * 单例服务 * * @protected * @static * @type {IAppViewMsgHelper} * @memberof AppViewMsgHelperBase */ private static service: IAppViewMsgHelper; /** * 获取实例 * * @static * @return {*} {IAppViewMsgHelper} * @memberof AppViewMsgHelperBase */ static getInstance(): IAppViewMsgHelper { if (!this.service) { this.service = new AppViewMsgHelper(); } return this.service; } /** * 视图消息缓存(加载中) * * @type {Map} * @memberof AppViewMsgHelper */ public static messageCache: Map = new Map(); /** * 视图消息缓存(已完成) * * @type {Map} * @memberof AppViewMsgHelper */ public static messageCached: Map< string, { result: any[]; expirationTime?: number } > = new Map(); /** * 获取视图消息集合 * * @memberof AppViewMsgHelper */ public async getViewMsgDetails( tag: string, context?: IContext, viewParams?: IParam ): Promise { // 根据tag 获取视图消息 const viewMessageGroup = App.getAppViewMsgConfig()[tag] as IViewMsgGroup; if (!viewMessageGroup) return []; const viewMsgGroupDetails: Array = viewMessageGroup?.viewMsgGroupDetails || []; if (viewMsgGroupDetails.length == 0) { return []; } const viewMsgs: any[] = []; for (let i = 0; i < viewMsgGroupDetails.length; i++) { const viewMsg = viewMsgGroupDetails[i].viewMsg; let items: any[] = []; if (viewMsg?.dynamicMode == 0) { // 动态模式为 静态 items = await this.getStaticViewMessage(viewMsg, context, viewParams); } else if (viewMsg?.dynamicMode == 1) { // 动态模式为 实体数据集 items = await this.getDynamicViewMessage( viewMsg as IDEDataSetViewMsg, context, viewParams ); } viewMsgs.push(...items); } return viewMsgs; } /** * 获取动态模式(静态)类型视图消息 * * @param {IViewMsg} 动态模式(静态)类型视图消息实例 * @memberof AppViewMsgHelper */ public async getStaticViewMessage( detail: IViewMsg, context?: IContext, viewParams?: IParam ): Promise { const _this: any = this; return new Promise((resolve: any, reject: any) => { const viewMessage: any = { position: detail.position || 'TOP', name: detail.name, codeName: detail.codeName?.toLowerCase(), type: detail.messageType, title: detail.title, titleLanResTag: detail.titleLanResTag || detail.titlePSLanguageRes?.lanResTag, content: detail.message, removeMode: detail.removeMode, enableRemove: detail.enableRemove, }; _this.translateMessageTemp(viewMessage, detail, context, viewParams); resolve([viewMessage]); }); } /** * 获取动态模式(静态)类型视图消息模板标题和内容 * * @target {*} target 返回目标数据 * @param {IViewMsg} 动态模式(静态)视图消息实例 * * @memberof AppViewMsgHelper */ public translateMessageTemp( target: any, detail: IViewMsg, context?: IContext, viewParams?: IParam, item?: any ) { const format = (content: any) => { if (!isExistAndNotEmpty(content)) { return content; } const params: any[] = content.match(/\${(.+?)\}/g) || []; if (params.length > 0) { params.forEach((param: any) => { const _param: any = param .substring(2, param.length - 1) .toLowerCase(); const arr: string[] = _param.split('.'); if (arr.length == 2) { switch (arr[0]) { case 'context': content = context ? content.replace(param, context[arr[1]]) : content; break; case 'viewparams': content = viewParams ? content.replace(param, viewParams[arr[1]]) : content; break; case 'item': case 'data': content = item ? content.replace(param, item[arr[1]]) : content; break; } } }); } return content; }; const appMsgTempl = detail.msgTempl; if (!appMsgTempl) { return; } Object.assign(target, { messageType: appMsgTempl.contentType == 'HTML' ? 'HTML' : 'TEXT', title: format(appMsgTempl.subject), titleLanResTag: appMsgTempl.subPSLanguageRes?.lanResTag, content: format(appMsgTempl.content), }); } /** * 初始化动态模式(实体数据集合)类型视图消息 * * @param {any} tag 视图消息标识 * @param {any} messageService 消息服务 * @param {string} context * @returns {Promise} * @memberof AppViewMsgHelper */ public async getDynamicViewMessage( detail: IDEDataSetViewMsg, context: any = {}, viewParams: any = {}, isloading?: boolean ): Promise { if (context && context.srfsessionid) { delete context.srfsessionid; } // 动态模式(实体数据集合)类型视图消息服务 return new Promise((resolve: any, reject: any) => { const isEnableCache: boolean = (detail as any).enableCache; const cacheTimeout: any = (detail as any).cacheTimeout; const tag: any = detail.codeName; // 启用缓存 if (isEnableCache) { const callback: Function = ( context: any = {}, data: any = {}, tag: string, promise: Promise ) => { promise .then((result: any) => { if (result.length > 0) { AppViewMsgHelper.messageCached.set(tag, { result, expirationTime: new Date().getTime() + cacheTimeout, }); AppViewMsgHelper.messageCache.delete(tag); return resolve(result); } else { return resolve([]); } }) .catch((result: any) => { return reject(result); }); }; // 加载完成,从本地缓存获取 const activeViewMsg = AppViewMsgHelper.messageCached.get(tag); if (activeViewMsg) { const items: any = activeViewMsg.result; if (items.length > 0 && activeViewMsg?.expirationTime) { if (new Date().getTime() <= activeViewMsg.expirationTime) { return resolve(items); } } } // 加载中,UI又需要数据,解决连续加载同一消息服务问题 if (AppViewMsgHelper.messageCache.get(tag)) { callback( context, viewParams, tag, AppViewMsgHelper.messageCache.get(tag) ); } else { const result: Promise = this.getItems( detail, context, viewParams ); AppViewMsgHelper.messageCache.set(tag, result); callback(context, viewParams, tag, result); } } else { this.getItems(detail, context, viewParams) .then((result: any) => { resolve(result); }) .catch((error: any) => { Promise.reject([]); }); } }); } /** * 获取远程数据 * * @param {*} context 应用上下文 * @param {*} data 视图参数 * @param {boolean} [isloading] 加载状态 * @returns {Promise} * * @memberof AppViewMsgHelper */ public getItems( detail: IDEDataSetViewMsg, context: any = {}, viewParams: any = {} ): Promise { const _this = this; const appDataEntityCodeName = detail.psAppDataEntity?.codeName; const appDataSetCodeName = detail.psAppDEDataSet?.codeName; const tempContext: any = context ? context : {}; const tempData: any = viewParams ? viewParams : {}; return new Promise((resolve, reject) => { if (appDataEntityCodeName && appDataSetCodeName) { App.getDataService(appDataEntityCodeName, context).then( (service: any) => { if (service && service[appDataSetCodeName] instanceof Function) { const promise: Promise = service[appDataSetCodeName]( tempContext, tempData ); promise .then((response: any) => { if (response.success) { const data = response.data; resolve(_this.doItems(detail, data, tempContext, tempData)); } else { resolve([]); } }) .catch((response: any) => { console.error(response); reject(response); }); } } ); } else { resolve([]); } }); } /** * 处理数据 * * @param {any[]} items 源数据 * @param {*} context 应用上下文 * @param {*} data 视图参数 * @returns {any[]} * * @memberof AppViewMsgHelper */ public doItems( detail: IDEDataSetViewMsg, items: any[], context: any = {}, data: any = {} ): any[] { const _this = this; const tempItems: any[] = []; const { name, codeName, title, position, titleLanResTag, message, messageType, removeMode, enableRemove, } = detail; if (items.length > 0) { // 排序 if (detail.orderValuePSAppDEField?.codeName) { _this.sortItems(detail, items); } items.forEach((item: any) => { const tempData: any = { position: position || 'TOP', name: name, codeName: codeName?.toLowerCase(), type: messageType, title: title, titleLanResTag: titleLanResTag || detail.titlePSLanguageRes?.lanResTag, content: message, removeMode: removeMode, enableRemove: enableRemove, }; _this.formatDynamicViewMsg(detail, tempData, context, data, item); _this.translateMessageTemp(tempData, detail, context, data, item); tempItems.push(tempData); }); } return tempItems; } /** * 根据属性配置翻译视图消息 * * @target {*} target 返回目标数据 * @param {*} context 应用上下文 * @param {*} viewParams 视图参数 * * @memberof AppViewMsgHelper */ public formatDynamicViewMsg( detail: IDEDataSetViewMsg, target: any, context: any = {}, viewParams: any = {}, item?: any ) { if (!item) { return; } // 标题 const titleField = detail.titlePSAppDEField?.codeName?.toLowerCase(); if (titleField && item[titleField]) { Object.assign(target, { title: item[titleField] }); } // 内容 const contentField = detail.contentPSAppDEField?.codeName?.toLowerCase(); if (contentField && item[contentField]) { Object.assign(target, { content: item[contentField] }); } // 消息类型 const msgTypeField = detail.msgTypePSAppDEField?.codeName?.toLowerCase(); if (msgTypeField) { const type = item[msgTypeField]; if ( type == 'INFO' || item[msgTypeField] == 'WARN' || type == 'ERROR' || type == 'CUSTOM' ) { Object.assign(target, { type: type }); } else { console.warn( "视图消息类型值异常,应为['INFO', 'WARN', 'ERROR', 'CUSTOM']中的类型" ); } } // 消息位置 const msgPosField = detail.msgPosPSAppDEField?.codeName?.toLowerCase(); if (msgPosField) { const position = item[msgPosField]; if ( position == 'TOP' || position == 'BODY' || position == 'BOTTOM' || position == 'POPUP' || position == 'CUSTOM' ) { Object.assign(target, { position: position }); } else { console.warn( "视图消息位置值异常,应为['TOP', 'BODY', 'BOTTOM', 'POPUP', 'CUSTOM']中的位置" ); } } // 删除模式 const removeFlagField = detail.removeFlagPSAppDEField?.codeName?.toLowerCase(); if (removeFlagField) { const removeMode = item[removeFlagField]; if (removeMode == 0 || removeMode == 1 || removeMode == 2) { Object.assign(target, { removeMode: removeMode }); } else { console.warn( "视图消息删除模式值异常,应为[0, 1, 2]中的值,分别表示['无关闭', '默认关闭', '本次关闭']" ); } } // 排序标识 const orderValueField = detail.orderValuePSAppDEField?.codeName?.toLowerCase(); if (orderValueField && item[orderValueField]) { Object.assign(target, { orderKey: item[orderValueField] }); } // 标题多语言 const titleLanResTagField = detail.titleLanResTagPSAppDEField?.codeName?.toLowerCase(); if (titleLanResTagField && item[titleLanResTagField]) { Object.assign(target, { titleLanResTag: item[titleLanResTagField] }); } } /** * 排序(默认升序) * * @param items */ public sortItems(detail: IDEDataSetViewMsg, items: any[], mode = 'ASC') { const orderValue = detail.orderValuePSAppDEField?.codeName.toLowerCase(); if (mode == 'ASC') { items = ascSort(items, orderValue); } else { items = descSort(items, orderValue); } } }