# App 例子

版本: 1.0 | 发布日期: 30/6/2019

# 须知

我们的App例子是一个简单的图书借阅程序,它包含了两个重要的Module: Book(图书) and Member(会员)

  1. 会员的主页会显示该会员的借阅历史记录
  2. 图书的Available属性用于标识它是否可以被借阅
  3. 每本图书都有一个ISBN码,每次保存的时候都会检查该码的有效性
  4. 用户可以手动检查ISBN码是否有效
  5. 为会员添加了一个打印报告的功能
  6. 为会员添加了一个EBI(Multiable的商业智能报告)的功能

你可以在 github (opens new window) 下载到整个App的可运行代码

# 在App.xml中定义App的各项属性

p-share\src\main\resources\META-INF\app.xml

<?xml version="1.0"?>
<app xmlns="http://www.multiable.com/app">
	<name>opcq</name>
	<version>1.0</version>
	<description>Opcq App</description>
	<dependences>
		<dependence id="caw" versions="1.0" />
	</dependences>	
	<ear>caw_ear</ear>
	<ejb>p-ejb</ejb>	
</app>

更多可设置的参数请参见 App.xml .

# 在datadict.xml中定义表结构

p-share\src\main\resources\META-INF\datadict.xml

<?xml version="1.0"?>
<dd xmlns="http://www.multiable.com/datadict">
	
	<table name="opcqbookcat" mess="opcq.bookCat" pk="id">
		<inherit name="module_fm" />
		<column name="code" type="varchar" mess="core.code" length="20" defPattern="fmCode" required="true" batchUpdate="false"/>
		<column name="desc" type="varchar" mess="core.description" length="100" defPattern="charDesc" i18nField="true" batchUpdate="true"/>
		
		<index name="module_code" columns="code" />
	</table>
	
	<table name="opcqbook" mess="opcq.book" pk="id" >
		<inherit name="module_fm" />
		<column name="code" type="varchar" mess="opcq.bookCode" length="40" defPattern="fmCode" required="true" batchUpdate="false"/>
		<column name="isbn" type="varchar" mess="opcq.isbn" length="40" defPattern="char20" required="true" batchUpdate="false"/>
		<column name="desc" type="varchar" mess="opcq.title" length="200" defPattern="charDesc" i18nField="true" batchUpdate="true"/>
		<column name="author" type="varchar" mess="opcq.author" length="100" defPattern="char60" i18nField="true" batchUpdate="true"/>
		<column name="publisher" type="varchar" mess="opcq.publisher" length="100" defPattern="char100" i18nField="true" batchUpdate="true"/>
		<column name="pDate" type="datetime" mess="opcq.pDate" defValue="NOW()" defPattern="date"/>
		<column name="photoCode" type="varchar" mess="opcq.coverImg" length="60" defPattern="imgCode" />
		<column name="bookCatId" type="int_unsigned" mess="opcq.bookCat" defValue="0" defPattern="opcqBookCat" batchUpdate="false"/>
		<column name="avail" type="bit" mess="opcq.avail" defValue="0" defPattern="check"/>
		
		<index name="module_isbn" columns="isbn" unique="true"/>
	</table>
	
	<table name="opcqmem" mess="opcq.mem" pk="id" >
		<inherit name="module_fm" />
		<column name="code" type="varchar" mess="opcq.memNo" length="60" defPattern="fmCode" required="true" batchUpdate="false"/>
		<column name="desc" type="varchar" mess="opcq.name" length="200" defPattern="char50" i18nField="true" required="true" batchUpdate="true"/>
		<column name="card" type="varchar" mess="opcq.cardNum" length="60" defPattern="char30" required="true" batchUpdate="false"/>
		<column name="email" type="varchar" mess="opcq.email" length="200" defPattern="char100" batchUpdate="true"/>
		<column name="addr" type="varchar" mess="opcq.address" length="-1" defPattern="char2000" i18nField="true"/>
		
		<index name="module_code" columns="code"/>
	</table>
	
	<table name="opcqmemt" mess="opcq.memt" pk="id">
		<inherit name="id_irev" />
		<column name="hId" type="int_unsigned" mess="opcq.mem" defValue="0" defPattern="opcqMem" dataImport="false" dataExport="false" buildin="true"/>
		<column name="itemNo" type="varchar" mess="core.itemNo" length="12" defPattern="char6" dataEasy="true" dataImport="false" dataExport="false"/>
		<column name="bookId" type="int_unsigned" mess="opcq.bookCode" defValue="0" defPattern="opcqBook" required="true"/>
		<column name="bDate" type="datetime" mess="opcq.bDate" defValue="NOW()" defPattern="date"/>
		<column name="rDate" type="datetime" mess="opcq.rDate" defValue="NOW()" defPattern="date"/>
		
		<fk name="book" columns="bookId" refTable="opcqbook" refColumns="id" />		
	</table>
</dd>

更多可设置的参数请参见 Datadict.xml.

出于重用和统一修改的目的,栏位的属性可以在 Pattern.xml 中统一进行定义.

<?xml version="1.0"?>
<pattern xmlns="http://www.multiable.com/pattern">

	<record code="opcqBookCat" type="lookup">
		<lookup searchType="opcqBookCat"/>
	</record>
	
	<record code="opcqBook" type="lookup">
		<lookup searchType="opcqBook"/>
	</record>			
	
	<record code="opcqMem" type="lookup">
		<lookup searchType="opcqMem"/>
	</record>
</pattern>

# 在module.xml中定义Module

这个App总共有三个Module,它们分别是:

  1. Book Category
  2. Book
  3. Member

p-share\src\main\resources\META-INF\module.xml

<?xml version="1.0"?>
<md xmlns="http://www.multiable.com/module" app="opcq">

	<module name="opcqBookCat" mess="opcq.bookCat" extend="false" mainTable="opcqbookcat" recType="" useAccess="true" useAttach="true" useBeShare="true" useApv="true" useChangenote="true" fmShare="Y" genCode_Type="BC">
		<table name="opcqbookcat" key="id" c="true" r="true" d="true" u="true" initRow="1" hpk="" fKey="" order=""/>
	</module>		
	
	<module name="opcqBook" mess="opcq.book" extend="false" mainTable="opcqbook" recType="" useAccess="true" useAttach="true" useBeShare="true" useApv="true" useChangenote="true" fmShare="Y" genCode_Type="BK">
		<table name="opcqbook" key="id" c="true" r="true" d="true" u="true" initRow="1" hpk="" fKey="" order=""/>
		
		<checker class="com.multiable.opcq.ejb.checker.OpcqBookChecker"/>
	</module>
	
	<module name="opcqMem" mess="opcq.mem" extend="false" mainTable="opcqmem" recType="" useAccess="true" useAttach="true" useBeShare="true" useApv="true" useChangenote="true" fmShare="Y" importThreadMode="false" genCode_Type="MEM">
		<table name="opcqmem" key="id" c="true" r="true" d="true" u="true" initRow="1" hpk="" fKey="" order=""/>
		<table name="opcqmemt" key="id" c="true" r="true" d="true" u="true" initRow="0" hpk="hId" fKey="" order="" cpnType="table"/>
	</module>
</md>

更多可设置的参数请参见 Module.xml.

# 在navmenu.xml中定义Menu(视图)

这个App总共有四个视图,它们分别是:

  1. Book Category
  2. Book
  3. Member
  4. EBI for Member

p-share\src\main\resources\META-INF\navmenu.xml

<?xml version="1.0"?>
<nm xmlns="http://www.multiable.com/navmenu" app="opcq">
	
	<folder code="m18Opcq" messCode="opcq.opcqApp">
		<menu code="opcqBookCat" messCode="opcq.bookCat" src="view/opcq/module/opcqBookCat" module="opcqBookCat" mType="FM" order="1000">			
			<inherit name ="module_fc" />
		</menu>	
		<menu code="opcqBook" messCode="opcq.book" src="view/opcq/module/opcqBook" module="opcqBook" mType="FM" order="2000">			
			<inherit name ="module_fc" />
		</menu>	
		<menu code="opcqMem" messCode="opcq.mem" src="view/opcq/module/opcqMem" module="opcqMem" mType="FM" order="3000">			
			<inherit name ="module_fc" />
		</menu>		
		<folder code="biOpcq" messCode="opcq.ebi" order="4000">
			<icon name="cicon-ebi" library="font/cawIcon"/>
			<menu code="M18_EBI_OPCQMEM" messCode="opcq.memRep" src="view/module/ebi/ebi" mType="EBI" order="1000">
				<icon name="cicon-ebi-report" library="font/cawIcon"/>
				<inherit name="module_ebi"/>
			</menu>
		</folder>
	</folder>	
</nm>

更多可设置的参数请参见 NavMenu.xml.

# i18N 支持

为了避免与其它的App冲突,每一项翻译项的Key请以App名字作为前缀。

p-share\src\main\resources\META-INF\lang\Message_en.properties

p-share\src\main\resources\META-INF\lang\Message_zh-CN.properties

p-share\src\main\resources\META-INF\lang\Message_zh-TW.properties

c6

# App 截图

Book Category

c2

Book

c3

Add books to Member

c4

c5