更新时间:2023-04-23 GMT+08:00
分享

开发应用

创建目录

在应用的开发页面,根据规划创建目录Model、Logic和Page,分别用于存放数据对象,服务编排、脚本等,前端页面。

  1. 在应用的开发页面,如图1所示,单击应用右侧的,选择“目录”。

    图1 创建目录

  2. 在弹出的“添加目录”页面,如图2所示,输入目录名称(Model),单击“保存”。

    图2 添加目录

  3. 参见12,继续参见目录Logic和Page,目录创建完成后如图3所示。

    图3 创建的目录

创建对象

对象是AppCube的核心功能之一,对象相当于传统数据库里的一张表,用于持久化业务数据。AppCube中有内置的标准对象,也有租户开发者创建的自定义对象。

一个由租户开发者创建的自定义对象,在创建之后,就会有各种操作方式:前端页面可以使用页面模型绑定此对象,并使用表格组件,直接展现对象数据;使用脚本、自定义JS代码、服务编排等,对该对象中的信息进行增删改查。

本示例规划的自定义字段如表1所示。

表1 规划的自定义字段

字段标签

字段名称

字段类型

取值

字段描述

读取权限

编辑权限

添加到页面布局

ProjectCode

ProjectCode

文本

数据长度:255

项目编码

全选

全不选

选择

ProjectName

ProjectName

数据长度:255

项目名称

ProjectStatusCode

ProjectStatusCode

数据长度:255

项目状态

description

description

数据长度:255

描述

startDate

startDate

数据长度:255

开始时间

endDate

endDate

数据长度:255

结束时间

  1. 在“demo”应用中,如图4所示,单击规划存放对象目录Model右侧的,选择“对象”。

    图4 创建对象

  2. 在弹出的“添加对象”页面,如图5所示,选择创建新对象,输入对象的“标签”为“projectinfo”,单击“名称”的输入框后,系统将自动生成名称为“projectinfo”,输入描述信息,具体参数说明请参见表2,单击“添加”。

    图5 添加对象
    表2 添加对象参数说明

    参数

    配置说明

    示例

    创建新对象/导入已有对象

    添加对象的方式。

    创建新对象

    标签

    对象展示的名称,为了区分不同对象的描述信息。

    对象创建完后,“标签”可以在对象的“基本信息”中修改。

    projectinfo

    名称

    对象在系统内的唯一标识。

    • 对象创建后,系统会自动在“名称”增加租户命名空间前缀,以及增加“__CST”后缀,“__CST”是AppCube中对象的后缀标识。
    • 对象创建完后,“名称”不可以修改。

    projectinfo

    说明:

    对象创建后,系统自动为对象名称添加前后缀,实际创建的对象名为:ISDP__projectinfo__CST。

    描述

    对象的描述信息。

    项目信息

    对象创建完成后,自动进入对象详情页面,如图6所示。

    图6 对象详情页面

  3. 创建规划的自定义字段(ProjectCode)。

    1. 图7所示,单击“自定义字段”页签,单击“新增”,进入新建字段页面。
      图7 新增自定义字段
    2. 图8所示,选择字段类型为“文本”,单击“下一步”。
      图8 选择字段类型
    3. 图9所示,输入新字段详细信息:设置字段“标签”为“ProjectCode”、“名称”为“ProjectCode”、“描述”为“项目编码”、“数据长度”为“255”,单击“下一步”。
      图9 输入详情
    4. 图10所示,设置字段级的访问权限:选中“读取”复选框,为所有预置profile配置能读取本字段的权限,单击“下一步”。
      图10 建立字段级安全性
    5. 图11所示,将字段添加到对象的页面布局:选中“添加本字段到该页面布局”,单击“保存”。
      图11 添加到页面布局

  4. 参见3,继续添加规划的自定义字段,添加后的字段如图12所示。

    图12 自定义字段

创建脚本

针对业务逻辑比较复杂的场景,AppCube平台提供了脚本(Script)能力,支持用户在线开发TypeScript脚本,完成灵活复杂的业务逻辑。

  1. 添加规划的系统参数如表3所示,供脚本使用。

    表3 规划的系统参数

    参数名称

    值类型

    描述

    是否加密

    是否默认

    权限

    ISDP__demo_token_url

    文本

    https://ISDP+的域名/oauth2/oauth/rest_toke

    粗斜体请根据实际情况填写。

    获取ISDP+ token的URL

    保持默认

    ISDP__demo_client_id

    sdcpxYGmj65aLxR3Qu34kBa3A6lwIyQK

    对应ISDP+租户下订阅API的应用ID

    ISDP__demo_client_secret

    ********************************

    对应ISDP+租户下订阅API的应用令牌

    说明:

    当值类型为“文本”时,该参数才会有用,且加密后无法转为非加密。

    ISDP__demo_getProjectlist_url

    https://ISDP+的域名/openapi/v1/project/findPagedProjectList

    查询项目信息URL

    1. 在“demo”应用中,图13所示,单击“配置”,选择“系统参数”页签。
      图13 系统参数
    2. 在“系统参数”页面,单击“新增”。
    3. 图14所示,输入参数信息。
      图14 创建新的系统参数
    4. 单击“创建”,完成系统参数的创建。
    5. 继续新建系统参数,完成规划的系统参数的创建,如图15所示。
      图15 规划的系统参数

  1. 创建脚本getAccesstoken,用户获取ISDP+ token。

    1. 在“demo”应用中,如图16所示,单击规划存放脚本目录Logic右侧的,选择“脚本”。
      图16 创建脚本
    2. 在弹出的“新增脚本”页面,如图17所示,选择创建一个新脚本,输入脚本“名称”为“getAccesstoken”,“模板”选择“空脚本”,输入描述信息,具体参数说明请参见表4,单击“添加”。
      图17 新增脚本
      表4 新增脚本参数说明

      参数

      配置说明

      示例

      创建一个新脚本/使用已有脚本

      创建脚本的方式。

      • 创建一个新脚本:选择后,创建空白脚本。
      • 使用已有脚本:选择后,复制一个已有的脚本。

      创建一个新脚本

      名称

      脚本在系统内的唯一标识。

      • 脚本创建后,系统会自动在“名称”增加租户命名空间前缀。
      • 脚本创建完后,“名称”不可以修改。

      getAccesstoken

      说明:

      脚本创建后,系统自动为脚本名称添加前缀,实际创建的脚本名为:ISDP__getISDPProjectList

      模板

      脚本模板,用于生成不同类型的脚本。

      目前支持以下几种类型。

      • 空脚本:表示不用模板。
      • 示例服务脚本:对外提供服务的脚本,可通过restful直接调用。
      • 示例内部脚本:是内部库代码,只能被其它脚本import使用。
      • 示例安装脚本:在安装或升级App/BO包时,在导入实例化配置数据之前或者之后执行的脚本。一般用于预清理数据,删除、更新数据等。
      • 示例权限脚本:在开放AppCube的服务编排、脚本或者操作对象数据接口给第三方系统调用时,通过该示例脚本可实现在第三方系统配置这些接口的访问权限。

      空脚本

      描述

      脚本的描述信息。

      获取ISDP+ token

      脚本创建完成后,自动进入脚本编辑页面,如图18所示。

      图18 脚本编辑页面
    3. 编辑获取ISDP+ token脚本。
      代码示例:
      import { Error } from 'error';
      import * as sys from 'sys';
      import * as iconv from 'iconv';
      import * as http from 'http';
      import { Encoding } from 'buffer';
       
      export class Input {
       
      }
       
      export class Output {
          @action.param({ type: "String", required: true })
          result: string;
      }
       
      const client_secret = sys.getParameter("ISDP__demo_client_secret");
      const client_id = sys.getParameter("ISDP__demo_client_id");
      const tokenURL = sys.getParameter("ISDP__demo_token_url");
      export class GetAccesstoken {
       
          @action.method({ input: "Input", output: "Output", description: "获取ISDP+的Token" })
          run(): Output {
              let output = new Output();
              let url = tokenURL;
              let clientId = client_id;
              let clientSecret = client_secret;
       
              let client = http.newClient();
              let resp = client.post(url, {
                  headers: {
                      "Content-Type": "application/json"
                  },
                  data: {
                      "client_id": "isdp-saas-openapi",
                      "grant_type": "password",
                      "client_secret": "isdp-saas-openapi",
                      "username": clientId,
                      "password": clientSecret
                  }
              });
       
              let data = iconv.decode(resp.data, Encoding.Utf8);
              let result = JSON.parse(data);
              if (!result.access_token) {
                  throw new Error(result.errorCode, result.errorMsg)
              }
              output.result = result["access_token"];
       
              return output;
          }
       
      }
    4. 图19所示,单击页面上方的,保存脚本。
      图19 保存脚本
    5. 图20所示,单击页面上方的,在页面底部显示测试窗口,如图21所示。
      图20 运行测试脚本
      图21 测试窗口

      本示例脚本,无需输入参数,直接单击测试窗口的,执行脚本。

      查看输出参数和日志,确认没有问题,符合预期结果。

      图22 输出参数
    6. 图23所示,单击页面上方的,启用脚本。
      图23 启用脚本

  2. 参见2,创建脚本getProjectListdemo,获取项目信息,写入到创建的对象ISDP__projectinfo__CST中。

    代码示例:

    import { Error } from 'error';
    import * as iconv from 'iconv';
    import * as http from 'http';
    import { Encoding } from 'buffer';
    import * as sys from 'sys';
    import { GetAccesstoken } from './ISDP__getAccesstoken';
    import * as db from 'db';
     
    const queryProjectURL = sys.getParameter("ISDP__demo_getProjectlist_url");
     
    export class projectListInfos {
        @action.param({ type: "String", required: true, description: "结束日期" })
        endDate: string;
        @action.param({ type: "String", required: false, description: "起始日期" })
        startDate: string;
        @action.param({ type: "String", required: false, description: "描述" })
        description: string;
        @action.param({ type: "String", required: false, description: "项目状态代码" })
        ProjectStatusCode: string;
        @action.param({ type: "String", required: false, description: "项目名称" })
        ProjectName: string;
        @action.param({ type: "String", required: false, description: "项目代码" })
        ProjectCode: string;
    }
     
    export class Input {
        @action.param({ type: "Number", required: true, min: 0, description: "当前页码:,从0开始" })
        start: number;
        @action.param({ type: "Number", required: true, min: 0, max: 100, description: "每页数量" })
        count: number;
        @action.param({ type: "String", required: false, description: "项目编码" })
        projectCode: string;
    }
     
    @action.object({ type: 'param' })
    export class Output {
        @action.param({ type: 'Any' })
        data: string[];
    }
     
    let result = this.result
    @useObject(['ISDP__projectinfo__CST'])
    @action.object({ type: 'method' })
     
    export class FindProject {
        @action.method({ input: "Input", output: "Output", description: "查询项目" })
        run(input: Input): Output {
            let output = new Output();
            let responses = new Output();
            const tokenResult = new GetAccesstoken().run().result;
            let result = this.queryProject(input, tokenResult).data;
            let project = this.projectinfos(result);
            output.data = project;
            return output;
     
        }
     
        private queryProject(input, tokenResult) {
            let url = queryProjectURL;
     
            //调用接口查询项目
            let client = http.newClient();
            let resp = client.post(url, {
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": "Bearer " + tokenResult
                },
                data: input
            });
     
            let data = iconv.decode(resp.data, Encoding.Utf8);
            let result = JSON.parse(data)
            if (result.status && result.status != 0) {
                throw new Error("500", result.message)
            }
            return result;
        }
     
        private projectinfos(result) {
     
            let projectinfos = db.object('ISDP__projectinfo__CST');
            let records = [];
            for (let i = 0; i < result.length; i++) {
     
                let data1 = {
                    "ISDP__ProjectCode__CST": result[i].projectCode,
                    "ISDP__ProjectName__CST": result[i].projectName,
                    "ISDP__ProjectStatusCode__CST": result[i].projectStatusCode,
                    "ISDP__description__CST": result[i].description,
                    "ISDP__startDate__CST": result[i].startDate,
                    "ISDP__endDate__CST": result[i].endDate
                };
     
                records.push(data1);
            }
            let project = projectinfos.batchInsert(records);
     
            return project
        }
    }

  3. 配置定时任务,定时执行脚本getProjectListdemo。

    1. 在“demo”应用中,图24所示,单击“配置”,选择“定时任务”页签。
      图24 定时任务
    2. 在“定时任务”页面,单击“新建”。
    3. 图25所示,设置相关参数,参数配置说明请参见表5
      图25 创建定时任务
      表5 参数配置说明

      参数

      说明

      示例

      名称

      定时任务名称。

      getProjectListdemo

      类型

      选择定时任务执行的类型,支持脚本或服务编排。

      脚本

      服务编排/脚本

      选择定时任务执行的脚本或服务编排。

      ISDP__getProjectListdemo

      输入参数

      执行的脚本或服务编排的入参。

      {

      "start": 0,

      "count": 15

      }

      任务首次执行时间

      首次执行脚本或服务编排的时间。

      2022-06-08 00:00:00

      执行次数

      定时任务执行次数。

      • 仅执行一次
      • 按设置的频率执行多次

      按设置的频率执行多次

      执行周期

      “执行次数”配置为“按设置的频率执行多次”时,需要设置。

      1

      执行周期单位

      “执行次数”配置为“按设置的频率执行多次”时,您需要设置执行任务时间间隔。

      • 小时
      • 分钟

      描述

      定时任务的描述信息,建议描述其用途。

      获取项目信息脚本

    4. 单击“保存”,在弹出的“警告”提示框中单击“确认无风险,继续保存”,完成定时任务的新建。

创建页面

  1. 在“demo”应用中,如图26所示,单击规划存放页面目录Page右侧的,选择“标准页面”。

    图26 创建标准页面

  2. 在弹出的“添加标准页面”页面,如图27所示,选择“空白”模板,输入页面的“标签”为“projectInfo”,“名称”为“projectInfo”,单击“添加”。

    图27 添加标准页面

    页面创建完成后,自动进入编辑页面,如图28所示。

    图28 编辑页面

  3. 单击页面右上角的,进入移动端页面开发。
  4. 进行页面的开发,开发方式和应用PC端类似,请参见创建页面

预览验证

在页面开发时,单击,可进入开发环境的预览页面,跟实际效果稍有差距。本节将介绍如何在应用的预览环境中,预览应用效果。这里预览效果跟实际在运行环境中基本一致。在应用配置下,还可以更改应用框架的样式和颜色。

  1. 在应用中(demo),如图29所示,单击应用左侧导航下部的“配置”,单击“导航条”页签。

    图29 进入导航条

  2. 图30所示,单击“菜单树”右侧的“+”,选择“添加页签”。

    图30 添加页签

    在导航条上的页面较多时,您可以添加目录。添加目录可以更方便区分页面类型,方便导航使用。目录添加之后,会在应用导航中直接显示,目录下可以添加页签。

  3. 图31所示,设置页签信息,页签参数配置说明请参见表6,单击“保存”。

    图31 设置页签信息
    表6 页签参数说明

    参数

    配置说明

    示例

    页签类型

    当前要添加的页签的类型:

    • 主页页签:用于展示个人任务相关的信息。
    • 对象页签:关联一个对象的布局,将展示指定对象的某个布局页面。
    • 标准页面页签:用于关联并展示一个标准页面。
    • 高级页面页签:用于关联并展示一个高级页面。
    • BPM页签:用于关联并展示一个BPM。
    • Web页签:用于关联一个URL,将展示URL对应的网页或页面。
    • 状态机页签:用于关联并展示一个状态机。
    • 报表页签:用于关联并展示一个报表。

    标准页面页签

    显示区域

    导航页签的显示区域,有以下两种:

    • 主页菜单:会按照布局样式进行显示,例如显示顶栏区域或者右上角。
    • 自定义菜单栏:选择该方式后,在App的运行态Portal中,单击右上角用户名,会在下拉选项中显示导航页签。

    主页菜单

    打开方式

    导航页签的打开方法,有以下两种:

    • 当前窗口:选择该导航页签后,在当前窗口打开页面。
    • 新窗口:选择该导航页签后,在新窗口打开页面。

    当前窗口

    标签

    显示在应用导航的名称。

    项目列表

    名称

    用于唯一标识页签的名称。

    项目列表

    图标

    导航页签的展示图标。

    这里可以不设置,如果有,可以选择一个图标直接上传。

    页面

    需要添加的页面。

    projectInfo

    描述

    当前页面的描述信息,用于了解当前页面的主要内容。

    -

  4. 图32所示,单击,在弹出的警告框中单击“确定”,删除Home页签

    图32 删除Home页签

  5. 图33所示,设置布局为手机菜单。

    图33 布局和颜色

  6. 图34所示,在应用左侧导航下,单击,进入应用预览页面。

    图34 预览

  7. 图35所示,在预览页面,查看页面展示字段,数据等。

    图35 项目列表页面

编译发布应用

应用开发完成后,需要将应用进行编译打包发布操作,打包后该应用才能发布使用。

  1. 在应用中(demo),如图36所示,单击,选择“设置”

    图36 属性设置

  2. 设置软件包,参数配置说明请参见表7,单击“保存”。

    表7 参数说明

    参数

    配置说明

    示例

    包类型

    应用包的类型:

    • 选择“资产包”发布的应用包,包中组件可设置是否受保护。

      选择该项后,您需要配置版权信息(可选)、描述(可选)、每个组件的保护设置(必选。配置为未受保护或者只读保护)。

      若后续其他用户在开发环境安装后,会显示在开发环境首页的“库”页签下。

    • 选择“源码包”发布的应用包,包中的所有组件不受保护和限制。在其他环境安装后可编辑包中组件,即在原有基础上进行再开发。

      若后续其他用户在开发环境安装后,会显示在开发环境首页的“项目”页签下。

    资产包

    是否全量包

    打包时是否打全量包:

    • 全量包:表示对整个应用(包括应用中的各个组件)作为一个整体进行设置打包。
    • 增量包:对应用中部分组件进行设置打包。单击“添加应用组件”,在“类别”中选择相应的类别,勾选需要打包的组件。

    全量包

    产权设置 > 加密保护

    当选择“资产包”打包时,才会显示该参数。表示是否对打包的组件中敏感内容(例如脚本内容)进行加密。

    勾选表示加密。在其他环境安装前,包中敏感数据是经过加密的。

    产权设置 > 版权信息

    当选择“资产包”打包时,才会显示该参数。表示该包的版权信息。

    选填项。

    -

    产权设置 > 描述信息

    当选择“资产包”打包时,才会显示该参数。表示该包的描述信息。

    选填项,建议描述该App提供的功能。

    项目列表

    产权设置 > 联系邮件

    您可以在此留下当前软件包的问题联系邮箱,若安装过程中出现问题会将联系邮件提示给使用者。

    -

    产权设置 > 联系链接

    您可以在此留下当前软件包的文档链接,若安装过程中出现问题会将联系链接提示给使用者。

    -

    产权设置 > 资产保护 > 保护模式

    当选择“资产包”打包时,才会显示该参数。表示打包数据的保护模式。

    • 未受保护
    • 只读保护
    • 不可见保护

    未受保护的资产包在开发环境中安装后,可进行二次编辑;在运行环境安装资产包后,不论保护模式是“未受保护”还是“只读保护”,都不可编辑。

    只读保护

    部署策略 > 安装前置脚本

    当选择“资产包”打包且打全量包时,该配置页才会显示。表示在安装应用包时,在导入实例化配置数据之前执行的脚本。一般用于预清理数据,避免数据冲突的情况。

    您可以选择已有脚本,也可以单击“创建”新建脚本。

    -

    部署策略 > 安装后置脚本

    当选择“资产包”打包且打全量包时,该配置页才会显示。表示在安装应用包时,在导入实例化配置数据之后执行的脚本。一般用于删除、更新数据等。

    您可以选择已有脚本,也可以单击“创建”新建脚本。

    -

    部署策略 > 安装时组件的更新策略

    当打包的组件中包含系统参数、连接器、Rest操作、数据接入或事件流时,才会显示该参数。例如可设置系统参数随包打包发布后,在升级时遇到新旧数据冲突(唯一索引相同的数据)的数据更新策略。

    • 覆盖:当相关组件数据在打包升级到其他环境,发生数据冲突时,会进行覆盖。
    • 不覆盖:当相关组件数据在打包升级到其他环境,发生数据冲突时,不会进行覆盖。

    默认“不覆盖”。在配置为“不覆盖”的情况下,例如在开发环境修改数据接入的任意配置数据(包括所有图元的配置信息),打包升级到测试或者运行环境,不会覆盖同名的数据接入配置,即在开发环境修改的数据在测试或者运行环境不会生效。

    覆盖

    预置数据

    当选择“资产包”打包时,该配置页才会显示。

    您可以在该页面选择您在应用打包时一起发布的数据。支持按照对象名称打包。单击“添加对象”可设置数据导出条件,选择对象后,在应用打包时,会将该对象的满足条件的数据都打包出来。打包后,在资产包中“refdata”文件夹下可查看到导出的数据文件。

    使用该方式前,您需要先清理不需要发布的数据,且导出对象的“基本信息”页必须勾选上“允许API批量访问”。

    -

  3. 图37所示,单击,选择“编译”,编译完成如图38所示。

    图37 编译
    图38 编译完成

  4. 图39所示,单击

    图39 发布

  5. 图40所示,在弹出的页面中选择“我的仓库”。

    图40 发布应用

  6. 图41所示,填写版本信息,单击“发布”。

    图41 发布到我的仓库

    如果勾选“压缩高级页面”,表示会对包中所有高级页面涉及的css和js文件进行合并及压缩,这样可以有效降低运行时服务器压力,但从终端浏览器首次访问该站点页面时,访问时间会稍微增加。

    发布成功后,页面显示“程序包已经被成功上传到我的仓库。”

    图42所示,可以查看并下载发布的包,也可以在“管理 > 应用管理 > 我的仓库”中查看到发布的包,如图43所示。

    图42 发布的包
    图43 我的仓库

相关文档