逻辑

逻辑主要作用是构建应用的交互操作,从事件触发,到数据请求、页面展示,都属于逻辑的一部分。

IBizSys 模型预置逻辑丰富了应用的交互操作,通过配置化导向,解析业务模型,发布业务处理过程。

本部分使用界面行为前台调用(类别文件)作为说明对象,解释逻辑的构成单位以及构成内容。

构成单位

前台调用的构成单位分为以下 2 个部分

  • 前台调用逻辑内容 LOGIC.tsx.ftl
  • 前台调用逻辑标识 template.properties

前台调用逻辑内容

前台调用逻辑内容如下:

其中默认内容使用 ------内容区------- 替换掉。

<#--  前台界面行为  -->
<#if front_block??>
${front_block}
<#else>
    ------内容区-------
</#if>

由于默认内容过多,此不做展开,查看详情,点击 LOGIC.tsx.ftl 访问

此处将选取部分要点做讲解。

  • 扩展变量说明
  • 支持界面行为数据类型和处理模式
  • 预置参数处理
  • 其他关联逻辑
扩展变量说明

front_block 是界面行为内容扩展,用于绘制内容。

发开人员使用界面行为扩展时,只需要在界面行为内定义如下,即可完成的替换默认内容。

<#assign front_block>
public ${item.getFullCodeName()}{
    return (
        <div>这是扩展内容</div>
    );
}
</#assign>

<#ibizinclude>
../前台调用/LOGIC.tsx.ftl
</#ibizinclude>

完整的扩展,还有很多其他的内容支持,此处只做 front_block 简单说明。

支持界面行为数据类型和处理模式

前台界面行为支持单项数据主键、多项数据主键和无数据,其他数据类型不支持,开发人员选择其他数据类型后,触发界面行为会有报错提示。

<#if item.getActionTarget() == 'SINGLEDATA'>
        return new Promise((resolve: any, reject: any) => {
            this.$Notice.error({ title: '错误', desc: '不支持单项数据' });
        });
<#elseif item.getActionTarget() == 'MULTIDATA'>
        return new Promise((resolve: any, reject: any) => {
            this.$Notice.error({ title: '错误', desc: '不支持多项数据' });
        });
<#else>

其中 SINGLEDATA 是单项数据,MULTIDATA 是多项数据。

处理模式支持以下模式

  • 打开视图或向导(模态)
  • 打开顶级视图
  • 打开html页面
  • 用户自定义

打开html页面 item.getFrontProcessType() == 'OPENHTMLPAGE'

<#--  打开独立程序弹出  -->
return new Promise((resolve, reject) => {
    const openPopupApp = (url: string) => {
        window.open(url, '_blank');
        resolve();
    }
    const localdata: any = this.$store.getters.getLocalData();
    const url = `${item.getHtmlPageUrl()}`;
    openPopupApp(url);
});

用户自定义 item.getFrontProcessType() == 'OTHER'

// 自定义实体界面行为
this.$Notice.warning({ title: '错误', desc: '${item.getCaption()} 未实现' });
return new Promise((resolve: any, reject: any) => {

});

打开视图或向导(模态)和打开顶级视图 item.getFrontProcessType() == 'TOP' || item.getFrontProcessType() == 'WIZARD'
两者打开视图,是根据视图的打开方式来支持不同的打开逻辑处理。

  1. 打开顶级分页视图

    <#elseif frontview.getOpenMode() =='INDEXVIEWTAB' || frontview.getOpenMode() == ''>
    <#--  打开顶级分页视图  -->
    // 所有数据保持在同一级
    if (data.srfparentdata) {
     Object.assign(data, data.srfparentdata);
     delete data.srfparentdata;
    }
    const openIndexViewTab = (viewpath: string, data: any) => {
     const _params = this.$util.prepareRouteParmas({
         route: this.$route,
         sourceNode: this.$route.name,
         targetNode: viewpath,
         data: data,
     });
     this.$router.push({ name: viewpath, params: _params });
     resolve();
    }
    openIndexViewTab('${frontview.getPSAppModule().codeName?lower_case}_${frontview.codeName?lower_case}', data);
    
  2. 打开模态

    <#elseif frontview.getOpenMode() = 'POPUPMODAL'>
    <#--  打开模态  -->
    const openPopupModal = (view: any, data: any) => {
     let container: Subject<any> = this.$appmodal.openModal(view, data);
     container.subscribe((result: any) => {
         if (!result || !Object.is(result.ret, 'OK')) {
             return;
         }
         const _this: any = this;
         <#--  是否重新加载数据  -->
         <#if item.isReloadData?? && item.isReloadData()>
         if (xData && xData.refresh && xData.refresh instanceof Function) {
             xData.refresh(args);
         } else if (_this.refresh && _this.refresh instanceof Function) {
             _this.refresh(args);
         }
         </#if>
         <#--  后续界面行为  -->
         <#if item.getNextPSUIAction?? && item.getNextPSUIAction()??>
         <#assign nextPSUIAction = item.getNextPSUIAction()/>
         if (_this.${nextPSUIAction.getFullCodeName()} && _this.${nextPSUIAction.getFullCodeName()} instanceof Function) {
             _this.${nextPSUIAction.getFullCodeName()}(result.datas, params, $event, xData);
         }
         </#if>
         resolve(result.datas);
     });
    }
    const view: any = {
     viewname: '${srffilepath2(frontview.getCodeName())}', 
     height: ${frontview.getHeight()?c}, 
     width: ${frontview.getWidth()?c},  
     title: '${frontview.title}', 
    };
    openPopupModal(view, data);
    
  3. 打开抽屉

    <#elseif frontview.getOpenMode()?index_of('DRAWER') == 0>
    <#--  打开抽屉  -->
    const openDrawer = (view: any, data: any) => {
     let container: Subject<any> = this.$appdrawer.openDrawer(view, data);
     container.subscribe((result: any) => {
         if (!result || !Object.is(result.ret, 'OK')) {
             return;
         }
         const _this: any = this;
         <#--  是否重新加载数据  -->
         <#if item.isReloadData?? && item.isReloadData()>
         if (xData && xData.refresh && xData.refresh instanceof Function) {
             xData.refresh(args);
         } else if (_this.refresh && _this.refresh instanceof Function) {
             _this.refresh(args);
         }
         </#if>
         <#--  后续界面行为  -->
         <#if item.getNextPSUIAction?? && item.getNextPSUIAction()??>
         <#assign nextPSUIAction = item.getNextPSUIAction()/>
         if (_this.${nextPSUIAction.getFullCodeName()} && _this.${nextPSUIAction.getFullCodeName()} instanceof Function) {
             _this.${nextPSUIAction.getFullCodeName()}(result.datas, params, $event, xData);
         }
         </#if>
         resolve(result.datas);
     });
    }
    const view: any = {
     viewname: '${srffilepath2(frontview.getCodeName())}', 
     height: ${frontview.getHeight()?c}, 
     width: ${frontview.getWidth()?c},  
     title: '${frontview.title}', 
     placement: '${frontview.getOpenMode()}',
    };
    openDrawer(view, data);
    
  4. 打开气泡卡片

    <#elseif frontview.getOpenMode() == 'POPOVER'>
    <#--  打开气泡卡片  -->
    const openPopOver = (view: any, data: any) => {
     let container: Subject<any> = this.$apppopover.openPop($event, view, data);
     container.subscribe((result: any) => {
         if (!result || !Object.is(result.ret, 'OK')) {
             return;
         }
         const _this: any = this;
         <#--  是否重新加载数据  -->
         <#if item.isReloadData?? && item.isReloadData()>
         if (xData && xData.refresh && xData.refresh instanceof Function) {
             xData.refresh(args);
         } else if (_this.refresh && _this.refresh instanceof Function) {
             _this.refresh(args);
         }
         </#if>
         <#--  后续界面行为  -->
         <#if item.getNextPSUIAction?? && item.getNextPSUIAction()??>
         <#assign nextPSUIAction = item.getNextPSUIAction()/>
         if (_this.${nextPSUIAction.getFullCodeName()} && _this.${nextPSUIAction.getFullCodeName()} instanceof Function) {
             _this.${nextPSUIAction.getFullCodeName()}(result.datas, params, $event, xData);
         }
         </#if>
         resolve(result.datas);
     });
    }
    const view: any = {
     viewname: '${srffilepath2(frontview.getCodeName())}', 
     height: ${frontview.getHeight()?c}, 
     width: ${frontview.getWidth()?c},  
     title: '${frontview.title}', 
     placement: '${frontview.getOpenMode()}',
    };
    openPopOver(view, data);
    
预置参数处理

界面行为数据变量声明

const data: any = { srfparentdata: {} };

预置参数处理,主要包括

  • 父数据处理
  • 单项数据主键处理
  • 多项数据主键处理
  • 界面行为附加参数处理

父数据处理

const _this: any = this;
if (_this.srfparentdata) {
    Object.assign(data.srfparentdata, _this.srfparentdata);
}

单项数据主键处理

<#if item.getActionTarget() == 'SINGLEKEY'>

    <#--  单项数据主键  -->
    if (args.length > 0) {
        Object.assign(data, { srfkey: args[0].srfkey });
    }

    // 值项名称 - 单项数据主键,默认为srfkey
    const valueItem: string = '<#if item.getValueItem?? && item.getValueItem() != ''>${item.getValueItem()}<#else>srfkey</#if>';
    // 数据项名称 - 单项数据主键,默认为srfkey
    const paramItem: string = '<#if item.getParamItem?? && item.getParamItem() != ''>${item.getParamItem()}<#else>srfkey</#if>';
    if (args.length > 0 && args[0].hasOwnProperty(valueItem)) {
        const _params2: any = {};
        Object.assign(_params2, { [paramItem]: args[0][valueItem] });
        // 参数层级处理
        if (Object.is(paramItem, 'srfkey')) {
            Object.assign(data, _params2);
        } else {
            Object.assign(data.srfparentdata, _params2);
        }
        // 非默认值转换 删除原始值
        if (Object.is(valueItem, 'srfkey') && !Object.is(paramItem, 'srfkey')) {
            delete data.srfkey;
        }
    }
</#if>

多项数据主键处理

<#if item.getActionTarget() == 'MULTIKEY'>

<#--  多项数据主键  -->
let keys: string[] = [];
args.forEach((arg: any) => {
    if (arg.srfkey) {
        keys.push(arg.srfkey);
    }
});
if (keys.length > 0) {
    Object.assign(data, { srfkeys: keys.join(';') });
}

// 值项名称 -  多项数据主键,默认为srfkey
const valueItem: string = '<#if item.getValueItem?? && item.getValueItem() != ''>${item.getValueItem()}<#else>srfkey</#if>';
// 数据项名称 - 多项数据主键,默认为srfkeys
const paramItem: string = '<#if item.getParamItem?? && item.getParamItem() != ''>${item.getParamItem()}<#else>srfkeys</#if>';
const _params2: any = {};
let _keys: string[] = [];
args.forEach((arg: any) => {
    if (arg.hasOwnProperty(valueItem)) {
        _keys.push(arg[valueItem]);
    }
});

Object.assign(_params2, { [paramItem]: _keys.join(';') });
// 参数层级处理
if (Object.is(paramItem, 'srfkeys')) {
    Object.assign(data, _params2);
} else {
    Object.assign(data.srfparentdata, _params2);
}
</#if>

界面行为附加参数处理

if (params && Object.keys(params).length > 0) {
    const _params: any = {};
    const arg: any = args[0];
    Object.keys(params).forEach((name: string) => {
        if (!name) {
            return;
        }
        let value: string | null = params[name];
        if (value && value.startsWith('%') && value.endsWith('%')) {
            const key = value.substring(1, value.length - 1);
            if (arg && arg.hasOwnProperty(key)) {
                value = (arg[key] !== null && arg[key] !== undefined) ? arg[key] : null;
            } else {
                value = null;
            }
        }
        Object.assign(_params, { [name]: value });
    });
    Object.assign(data.srfparentdata, _params);
}
其他关联逻辑

前台调用界面行为关联逻辑主要包含两个部:

  • 是否重新加载数据
  • 后续界面行为

是否重新加载数据

<#--  是否重新加载数据  -->
<#if item.isReloadData?? && item.isReloadData()>
if (xData && xData.refresh && xData.refresh instanceof Function) {
    xData.refresh(args);
} else if (_this.refresh && _this.refresh instanceof Function) {
    _this.refresh(args);
}

后续界面行为

<#--  后续界面行为  -->
<#if item.getNextPSUIAction?? && item.getNextPSUIAction()??>
<#assign nextPSUIAction = item.getNextPSUIAction()/>
if (_this.${nextPSUIAction.getFullCodeName()} && _this.${nextPSUIAction.getFullCodeName()} instanceof Function) {
    _this.${nextPSUIAction.getFullCodeName()}(result.datas, params, $event, xData);
}
</#if>

前台调用逻辑标识

LOGICTYPE=FRONT

LOGICTYPE 是逻辑类型,FRONT 是逻辑标识名称,属于 IBizSys 模型预置。

构成内容

解析业务逻辑通过 FreeMarker 引擎发布业务逻辑内容

results matching ""

    No results matching ""