# 总体概述

版本: 1.1 | 发布日期: 07/12/2020

# 警告

  1. 不允许重写任何M18的存储过程。
  2. 不允许修改或移除已经存在的M18表格栏位。
  3. 所有的SQL栏位名和存储过程名称应该使用App编号作为前缀。
  4. 在表格名称和栏位名称中不允许使用_

# 注意事项

  1. M18平台仅授权给Multiable的客户和经过认证的第三方开发人员。开发应用程序的前提是你要有一套经过授权的M18平台软件。

  2. 如果你有任何疑问,请联系我们的实施人员或者在我们的论坛 (opens new window) 上进行提问。

# M18 架构

M18平台基于J2EE技术架构进行开发,部署于Wildfly(Java EE Server)上面。前端使用JSF,后端应用使用EJB进行编写。数据库使用MySql。

Wildfly(原Jboss)是应用程序服务器,属于企业级Java中间件。请熟悉Wildfly的相关配置和功能,由于M18运行的环境主要受到中间件的控制,了解对于开发/测试将有很大的帮助。

EJB是用于应用程序业务逻辑的服务器组件。你可以理解为一个个搭建业务功能实现的小模块。它给企业及开发人员提供了一个标准方式,从而解决一些之前总是作业操作总是重复发生的问题。M18之中,EJB会接收JSF发出的请求,并且在有需要的情况下和数据库继续必要的交互。

mssst

# M18 应用程序概念

M18是一个预置了若干应用程序的低代码快速开发平台,第三方开发者可以通过开发自己的应用程序来达到扩展/修改/已有功能或者添加新功能的目的。

在M18中,我们将特定的功能的集合称为应用程序,并要求每一个应用程序的代码是独立管理和维护的,我们使用app.xml来描述一个应用程序是怎样的。

在M18里面,应将应用程序理解为最小的程序可分割的单元。

applist

# M18 应用程序开发指南

为了开发M18应用程序,你需要一整套的M18运行环境,包括WildFly、MySQL数据库和M18程序包。

如果有多名开发人员在同一套M18平台上进行开发,数据库通常是可以共用的,但WildFly通常是每一位开发者都有自己的一份拷贝。

如果你有开发应用程序的需求,可以使用UAT(用户测试环境)或者额外再独立一个开发环境进行开发,切忌在生产环境上直接进行开发。

你最好先读一下设置开发环境 再继续往下阅读,这样子你对下面的内容会有更好的理解。

# 关于 app.xml

每一个应用程序使用一个名为app.xml的文件对它的各个属性进行定义。 你可以看一下 Github上的例子 (opens new window)

名字 必填 说明
name App的名字,是App的唯一标识符
version 格式为d.d.d_*** d部分必须要为数字,而且我们要求版本是单向递增的
description 当前App的描述
mess 用于界面显示的MessCode
ear 用于描述App存在的ear名称,目前一定是caw_ear
ejb 当前App使用的ejb jar的名字
appLogoName App在界面显示的logo的名字
appLogoLib App在界面显示的logo的的位置
developer App在界面显示的开发者名称
developerLogoName App在界面显示的开发者Logo的名字
developerLogoLib App在界面显示的开发者Logo的位置
dependences 用于描述当前的App依赖的App
*** 其他内容将在之后的章节具体介绍

例子:

<?xml version="1.0"?>
<app xmlns="http://www.multiable.com/app">
	<name>m18 test</name>
	<version>1.0</version>
	<description>test</description>
	<ear>caw_ear</ear>
	<ejb>core_ejb</ejb>

	<dependences>
		<dependence id="caw" version="1.0">
	</dependences>

</app>

# 词汇表

名字 描述
Module M18 Module 类似于 领域驱动设计 中领域模型的概念, 在M18 中用于表示一个逻辑实体, 请看下面的详细描述
Menu ViewModule的界面视图, Module可以有多个不同界面布局和权限控制的视图. 在M18中,用户可以通过拖拉的方式定义自己的界面视图
SqlEntity 有时也简称为Entity, 是Module数据的装载实体,通常,Module中的一张单据与一个Entity 对应.
SqlTable Module的一张单据,后台通常对应的是多张表,每张表对应一个SqlTable. 所以多个SqlTable组成一个SqlEntity
Lookup M18中定义查询的地方, 包括查询的条件、显示的栏位、关键字查询的范围等等
Mess Message的简写, 定义多语言界面的文件,请参照多语言实现

# M18 Module

Module 类似于 领域驱动设计 中领域模型的概念, 在M18 中用于表示一个逻辑实体.

例如,“客户”,“销售订单”,“员工”,“仓库”,“部门”

M18用一个名为module.xml的XML文件去描述Module, 详细格式请参照module.xml.

<?xml version="1.0"?>
<module name="virDept" mess="virDept" extend="false" mainTable="virdept" useChangenote="true"  genCode_Type="VO" recType="" useAccess="true" useAttach="true" useApv="true">
	<table name="virdept" key="code" initRow="1" hpk="" fKey="" hfName="" hfKey="" order=""/>
	<table name="virdeptpic" key="id" initRow="0" hpk="hId" fKey="picTypeId;userId;startDate" hfName="" hfKey="" order="" cpnType="table"/>
    <table name="virdeptmember" key="id" initRow="0" hpk="hId" fKey="" hfName="" hfKey="" order="" cpnType="table"/>
		
	<checker class="com.multiable.core.ejb.checker.VirDeptChecker"/>
</module>

# M18 Menu

M18用一个名为navmenu.xml的XML文件去描述Menu, 详细格式请参照navmenu.xml.

<folder code="language" messCode="core.lang">
	<menu code="langSetting" messCode="langSetting" src="view/module/langSetting" mType="SETTING">
		<function name="Save" />
	</menu>
			
	<menu code="udfMess" messCode="udfMess" src="view/module/udfMess">
		<function name="Save" />
		<function name="DataImport;DataExport" />
	</menu>
			
	<menu code="i18nFieldSetting" messCode="i18nFieldSetting" src="view/module/i18nFieldSetting" module="i18nFieldSetting" mType="SETTING">
		<function name="Save" />
	</menu>
</folder>

# M18 SqlTable

SqlTable是M18通用的数据存储结构。这个结构的生成的主要原因在于M18整个设计都是基于可扩展的方式的。

他包括以下几个部分:table名字(注:不是数据库table的名字,这里是一个虚拟的名字一般情况下可以不进行赋值),栏位信息(说明有哪些栏位,栏位的属性是什么 方便开发者进行遍历栏位的操作),数据。

M18用一个名为datadict.xml的XML文件去描述SqlTable,详细格式请参照datadict.xml.

<table name="useremailsender" mess="emailSender" pk="id">
		<inherit name="id_irev" />
	
		<column name="hId" type="int_unsigned" mess="user" defValue="0" defPattern="user" />
		<column name="mailUser" type="varchar" mess="core.mailUser" length="100" defPattern="char100" />
		<column name="mailPwd" type="varchar" mess="core.mailPwd" length="2000" defPattern="char2000" skipLookup="true" dataExport="false"/>
		<column name="mailAccount" type="varchar" mess="core.mailAccount" length="100" defPattern="char100" />
</table>

注意事项:

1. 由于系统会将数据转换为json,请确保存放到SqlTable的数据均可以转换为JSON。

2. 虽然支持SqlTable里面存放SqlTable,但是系统不推荐这样处理,甚至系统不推荐将非基本类型存入SqlTable。

# M18 SqlEntity

SqlEntity是M18模块最常见的模块数据存储结构,他由系统表module.xml 进行定义和描述。

在SqlEntity里面会说明: 当前Entity属于那个Module,当前Entity的所有信息。通常来说一个SqlEntity会包含若干个SqlTable

注意事项:

1. 请注意SqlEntity里面一定是有一个主表的,而且系统认为主表的id栏位就是entity的id属性。

SqlTable的常用操作

从数据库读取数据

SqlTable data = CawDs.getSqlResult("select * from test where code like 'B%';");

新建table

SqlTable data = new SqlTable();
data.setName("test");
data.addField(new SqlTableField("info", String.class));
data.addField(new SqlTableField("check", Boolean.class));
// or
SqlTable data_new = data.genEmptyTable();

增加行,并赋值

int row = data.addRow();
data.setString(row,"info","test");

表循环

for(int row : data){
  String info = data.getString(row,"info");
}

两个表数据合并

SqlTableLib.append(src, inc);

创建表索引

Integer[] indexs = SqlTableLib.getIndex(sortFields, data);
  • 对于SqlTable的绝大部分操作均存在SqlTable和SqlTableLib里面,请使用前仔细进行阅读。

# M18 Lookup

每一个ModuleMenu默认会有一个Lookup,用户可以定义自己的Lookup

lookup1

当你在一个Module的界面引用另外一个Module的数据时,所用到的查询也是由Lookup定义的

lookup2

关于Lookup的实现,请看stInfo.xmlstSearch.xml.

CheckMsg

系统绝大部分的错误提示使用CheckMsg进行反馈。

这里说明一下主要一些重要的点。

info_desc:用于界面显示的信息,不应该包含messcode

trace:用于定位checkmsg生成的位置

子元素MsgLocator用于定位错误信息发生在Entity那些相关的栏位上面。推荐需要填写。

  • 请参考CheckMsgLib获取关于Msg操作的更新信息。