diff --git a/packages/core/src/environment/environment.ts b/packages/core/src/environment/environment.ts index 9f0a6f85ebbb32868460b1ff77bf0b2d8606ac77..1b591adfd7bde9644987b2076a176de5ac7971ce 100644 --- a/packages/core/src/environment/environment.ts +++ b/packages/core/src/environment/environment.ts @@ -36,4 +36,5 @@ export const Environment: IEnvironment = { fileUploadWhiteList: '', fileUploadMaxSize: 10, fileUploadDescription: '', + enableAutoCompletePassword: false, }; diff --git a/packages/core/src/interface/i-environment/i-environment.ts b/packages/core/src/interface/i-environment/i-environment.ts index 2aebb82bf817b84019dfbca4c15f27642f4d8a6a..d6d9c9eee323ba40e9e3a73e532d6ed0f257db8d 100644 --- a/packages/core/src/interface/i-environment/i-environment.ts +++ b/packages/core/src/interface/i-environment/i-environment.ts @@ -278,4 +278,11 @@ export interface IEnvironment { * @memberof IEnvironment */ fileUploadDescription: string; + + /** + * @description 是否允许自动填充密码 + * @type {boolean} + * @memberof IEnvironment + */ + enableAutoCompletePassword: boolean; } diff --git a/packages/model/src/app/app-entity-model/app-entity-model.ts b/packages/model/src/app/app-entity-model/app-entity-model.ts index af9767e15839538bda2c72c4a1760c971d93429e..9f6b5177a348b26a5a69fd42f12729eb280a0c63 100644 --- a/packages/model/src/app/app-entity-model/app-entity-model.ts +++ b/packages/model/src/app/app-entity-model/app-entity-model.ts @@ -1,5 +1,6 @@ import { IPSAppDataEntity, + IPSAppDEDataExport, IPSAppDEField, IPSAppDEMethod, IPSAppDERS, @@ -152,6 +153,16 @@ export class AppEntityModel extends ModelObject { return this._majorDERss; } + /** + * @description 实体数据导出集合 + * @readonly + * @type {IPSAppDEDataExport[]} + * @memberof AppEntityModel + */ + get appDEDataExports(): IPSAppDEDataExport[] { + return this.source.getAllPSAppDEDataExports() || []; + } + protected _deMethodMap: Map = new Map(); protected get deMethodMap(): Map { diff --git a/packages/runtime/src/utils/app-de-ui-action-util/handler/front-ui-action-handler.ts b/packages/runtime/src/utils/app-de-ui-action-util/handler/front-ui-action-handler.ts index 34e426d1cc8f222564ec317eb516bdb802511e0a..51657596bd40022579c9de741ae8d903dc696dc7 100644 --- a/packages/runtime/src/utils/app-de-ui-action-util/handler/front-ui-action-handler.ts +++ b/packages/runtime/src/utils/app-de-ui-action-util/handler/front-ui-action-handler.ts @@ -1,12 +1,11 @@ -/* eslint-disable no-new-func */ /* eslint-disable @typescript-eslint/ban-types */ -/* eslint-disable no-case-declarations */ +/* eslint-disable no-new-func */ import { AppEntityModel, IPSAppDEUIAction, UnsupportedModelError, } from '@ibiz-template/model'; -import { StringUtil } from '@ibiz-template/core'; +import { RuntimeError, StringUtil } from '@ibiz-template/core'; import { calcResPath } from '@ibiz-template/service'; import { OpenAppViewCommand } from '../../../command'; import { IModalData, IUIActionResult } from '../../../interface'; @@ -84,6 +83,10 @@ export class FrontUIActionHandler extends UIActionHandler { }; } } + if (frontProcessType === 'DATAEXP') { + await this.executeDataExport(action, context, data, params); + return actionResult; + } if (['TOP', 'WIZARD'].includes(frontProcessType)) { const frontPSAppView = action.getFrontPSAppView(); if (!frontPSAppView) { @@ -147,4 +150,96 @@ export class FrontUIActionHandler extends UIActionHandler { } throw new UnsupportedModelError(action, '自定义类型缺少配置脚本代码'); } + + /** + * 执行导出行为 + * @protected + * @param {IPSAppDEUIAction} action + * @param {IUILogicParams} args + * @return {*} + */ + protected async executeDataExport( + action: IPSAppDEUIAction, + context: IContext, + data: IData[] | null, + params: IParams, + ): Promise { + // 处理参数 + const { resultContext, resultParams, presetParams } = + await this.handleParams(action, context, data, params); + + const appDataEntity = action.getPSAppDataEntity(); + if (!appDataEntity) { + return; + } + const appEntity = new AppEntityModel(appDataEntity); + await appEntity.init(); + const dataExportModel = action.getPSAppDEDataExport(); + const appDEDataExport = appEntity.appDEDataExports?.find(dataExport => { + return dataExport.id === dataExportModel?.id; + }); + if (appDEDataExport) { + let exportDatasetCodeName: string = presetParams.srfexportdataset; + if (!exportDatasetCodeName) { + // 未指定导出数据集时拿取默认数据集 + exportDatasetCodeName = 'fetchdefault'; + } + + // 异步导出 + const isAsyncAction: boolean = presetParams.srfasyncaction === 'true'; + const paths = ibiz.resourcePathUtil.calcPaths( + resultContext, + appEntity.codeName, + ); + const resPath = calcResPath(resultContext, paths); + const url: string = `${resPath}/${appEntity.deNamePlural}/${ + isAsyncAction ? 'asyncexportdata' : 'exportdata' + }/fetchdefault`; + // 查询参数 + const queryParam: IParams = { srfexporttag: appDEDataExport.codeName }; + if (resultContext?.srfdatatype) { + Object.assign(queryParam, { srfdatatype: resultContext.srfdatatype }); + } + + // 参数 + const tempParams: IData = { + page: 0, + size: appDEDataExport.maxRowCount ? appDEDataExport.maxRowCount : 1000, + ...params, + ...resultParams, + }; + const res = await ibiz.net.request(url, { + method: 'post', + responseType: 'blob', + params: queryParam, + data: tempParams, + }); + if (isAsyncAction) return; + if (res.status === 200) { + // 获取文件 + const disposition = res.headers['content-disposition']; + let fileName = + disposition + .split(';') + .find((str: string) => str.indexOf('filename=') !== -1) + ?.slice(9) || ''; + fileName = decodeURIComponent(fileName); + const blob = new Blob([res.data as Blob], { + type: 'application/vnd.ms-excel', + }); + const elink = document.createElement('a'); + elink.download = fileName; + elink.style.display = 'none'; + elink.href = URL.createObjectURL(blob); + document.body.appendChild(elink); + elink.click(); + URL.revokeObjectURL(elink.href); // 释放URL 对象 + document.body.removeChild(elink); + } else { + throw new RuntimeError('导出请求失败'); + } + } else { + throw new RuntimeError('没有找到实体导出项'); + } + } } diff --git a/packages/runtime/src/utils/app-de-ui-action-util/handler/ui-action-handler.ts b/packages/runtime/src/utils/app-de-ui-action-util/handler/ui-action-handler.ts index 369ea2ddc908dd01156c6caedd50ae99e92ae232..8bc36b11d6280dd0574f44533b16a7afa20b4e80 100644 --- a/packages/runtime/src/utils/app-de-ui-action-util/handler/ui-action-handler.ts +++ b/packages/runtime/src/utils/app-de-ui-action-util/handler/ui-action-handler.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-prototype-builtins */ import { getPSUIActionByModelObject, IPSAppDEUIAction, @@ -161,6 +162,7 @@ export abstract class UIActionHandler implements IUIActionHandler { resultContext: IContext; resultData: IData[]; resultParams: IParams; + presetParams: IParams; }> { let resultData: IData[] = []; data = data || []; @@ -260,6 +262,20 @@ export abstract class UIActionHandler implements IUIActionHandler { isMultiData ? formatMultiData(navParams, data) : data[0] || {}, ); } - return { resultContext, resultData, resultParams }; + + // 预置属性处理 + const presetParams: IParams = {}; + // srfexportdataset(指定数据导出数据集标识) + if (resultParams.hasOwnProperty('srfexportdataset')) { + presetParams.srfexportdataset = resultParams.srfexportdataset; + delete resultParams.srfexportdataset; + } + + // srfasyncaction(指定当前界面行为是否异步(目前仅数据导出使用)) + if (resultParams.hasOwnProperty('srfasyncaction')) { + presetParams.srfasyncaction = resultParams.srfasyncaction; + delete resultParams.srfasyncaction; + } + return { resultContext, resultData, resultParams, presetParams }; } }