01_功能遷移指引

前言

zyj工作的本質就是將Hec4.0項目邏輯全部搬到zyj項目,整個過程中的工作內容如下:

  • 遷表:將Hec4.0的Oracle表遷到 zyj 的mysql表
  • 遷移後端代碼
  • 遷移前端代碼

代碼部分需針對原有邏輯做相應的調整。

一、遷表

整個遷表過程如下:

1.修改Oracle表

  • 表名
    • 將複數表名改爲單數
  • Number字段
    • 將Oracle數據庫中整型含義的Number都改爲Number(38),這樣生成groovy時就會生成爲bigint
    • 浮點型含義的Number不用改,生成groovy時會生成爲 Decimal

2.生成groovy

2.1 生成groovy

  • 訪問 groovy 文件生成器地址:http://192.168.12.107:16060

  • 填寫 author、fileName,檢索表,勾選表名,然後點擊 `生成Groovy

在這裏插入圖片描述

  • 將生成的 groovy 文件 放入到 hap-core-db 工程下
    在這裏插入圖片描述

2.2 修改groovy

  • 描述ID

    • 將生成的groovy文件中的comment中的id去掉
  • 索引名

3.導入mysql

  • 將項目重新 clean install

先將hap-core-db模塊clean install 一下,然後再將hap-db模塊clean install一下(沒有測過)

  • 在parent下執行 process-resources 命令
mvn process-resources -D skipLiquibaseRun=false -D db.driver=com.mysql.jdbc.Driver -D db.url=jdbc:mysql://192.168.12.68:3306/hap_dev -D db.user=root -D db.password=h@ndhec

二、遷移後端代碼

1.生成後端代碼

啓動zyj 項目,訪問代碼生成器頁面

http://host:{host}:{port}/${context}/generator/generator.html

com.hand.hec

2.後端調整

2.1 DTO

  • 字段需要與表結構嚴格對應
  • DTO名稱與表名嚴格對應
  • 多表關聯字段儘量使用JoinTable方式實現

2.2 Mapper遷移指引

  • Mapper接口應當與DTO命名嚴格對應
  • 沒有特殊要寫的SQL邏輯,無需單獨編寫mapper文件
  • SQL語句需要確保未使用數據庫方言,能夠在多數據庫之間兼容

2.3 Service遷移指引

  • 基表類Service應當與DTO命名嚴格對應,複雜邏輯類Service命名應當與原PKG相對應
  • 沒有特殊驗證邏輯,無需編寫Service方法體
  • 業務邏輯型驗證應當寫在Service中

2.4 Controller

  • 一個頁面應當對應一個Controller
  • 一個頁面內的同模塊內的操作應當儘量在當前頁面的Controller內完成
  • 如果當前頁面沒有初始化查詢,無需特殊設置ModelAndView,在Controller類上設置RequestMapping
  • RequestMapping格式爲:/模塊名/A (A中單詞用中劃線分割)

三、遷移前端頁面

新增的頁面請遵循開發規範

若是遷移表,則screen頁面中需要做如下修改:

  • 動態取值

    • 頁面的所有{}動態取值需要切換爲[]
  • 字段名

    • 頁面內的字段名(filed、column等)需要改成駝峯形式,以匹配DTO字段
  • prompt

    • 字段級別的prompt在dataSet的field上進行定義
    • 格式爲小寫
    • 所有的prompt都需要在hap內註冊
      • 字段級prompt的命名規則爲:基表名.字段名
      • 校驗級prompt的命名規則爲:基表名.校驗結果
  • baseUrlqueryUrlsubmitUrl

    • 頁面內的DataSet的model切換成baseUrlqueryUrlsubmitUrl也切換成相關地址
    • baseUrl無需加添加 context
  • model-queryloadData

    • 頁面的所有的初始化查詢:model-queryloadData ,都需要改爲由Controller中返回值爲ModelAndView的方法中轉

四、常見問題彙總

1.日期選擇

日期格式要精確到時分秒,否則後臺無法接收

使用 renderer="Aurora.formatDateTime"<a:dateTimePicker id="GLD2030_grid_dp"/>

示例如下:

        <a:grid id="GLD2030_responsibility_centers_grid" bindTarget="GLD2030_responsibility_centers_result_ds" marginHeight="115" marginWidth="3" navBar="true">
            <a:columns>
                <a:column name="responsibilityCenterCode" align="center" editor="GLD2030_grid_tf" editorFunction="GLD2030_responsibilityCenterEditFun" sortable="true" width="80"/>
                <a:column name="responsibilityCenterName" align="left" editor="GLD2030_grid_tf" width="200"/>
                <a:column name="respCenterTypeCodeDisplay" align="center" editor="GLD2030_grid_cb" width="80"/>
                <a:column name="startDateActive" align="center" editor="GLD2030_grid_dp" renderer="Aurora.formatDateTime" width="80"/>
                <a:column name="endDateActive" align="center" editor="GLD2030_grid_dp" renderer="Aurora.formatDateTime" width="80"/>
                <a:column name="summaryFlag" align="center" editor="GLD2030_grid_cx" editorFunction="GLD2030_responsibilityCenterEditFun" width="80"/>
                <a:column name="assignBgtEntity" align="center" renderer="GLD2030_AssignBgtEntityRender" width="80"/>
                <a:column name="childResponsibilityCenter" align="center" renderer="GLD2030_setSubResbonsibilitys" width="80"/>
            </a:columns>
            <a:editors>
                <a:textField id="GLD2030_grid_tf" typeCase="upper"/>
                <a:checkBox id="GLD2030_grid_cx"/>
                <a:comboBox id="GLD2030_grid_cb"/>
                <a:dateTimePicker id="GLD2030_grid_dp"/>
            </a:editors>
        </a:grid>

2.lov

2.1 lov實現

(1)field中使用lovCode

<a:field name="bgtEntityName" lovCode="LOV.BGT_ENTITY.BGT_ENTITY_NAME"  required="true" prompt="BGT_ENTITY.DESCRIPTION" title="BGT_ENTITY.BGT_ENTITY_NAME">
    <a:mapping>
        <a:map from="entityId" to="bgtEntityId"/>
        <a:map from="entityName" to="bgtEntityName"/>
    </a:mapping>
</a:field>

(2)grid中使用lov編輯器

 <a:grid id="GLD2030_respCenterRefBeGrid" bindTarget="GLD2030_respCenterRefBeDs" marginHeight="200" navBar="true" width="1000">
                <a:columns>
                    <a:column name="bgtEntityName" align="center" editor="GLD2030_accEntityRefLov" width="200"/>
                    <a:column name="bgtCenterName" align="center" editorFunction="GLD2030_BgtCenterEditorFun" width="120"/>
                    <a:column name="defaultFlag" editor="GLD2030_accEntityRefCk" prompt="TRAVEL_PLAN_TYPE.DEFAULT_FLAG"/>
                    <a:column name="enabledFlag" editor="GLD2030_accEntityRefCk" prompt="FND_COMPANY_GROUP.ENABLED_FLAG"/>
                </a:columns>
                <a:editors>
                    <a:lov id="GLD2030_accEntityRefLov"/>
                    <a:checkBox id="GLD2030_accEntityRefCk"/>
                </a:editors>
                <a:events>
                    <a:event name="cellclick" handler="GLD2030_GridCellClick"/>
                </a:events>
</a:grid>

(3)然後頁面上去定義lov

2.1 lov字段帶出

需求說明:實現頁面一加載時就自動帶出關聯的lov字段的值,如下圖

在這裏插入圖片描述

(1)通過給實體類添加 JoinTableJoinColumn 註解

	/**
	 * 預算中心ID
	 */
	@JoinTable(name = "bgtCenterJoin", joinMultiLanguageTable = false, target = com.hand.hec.zyj.bgt.dto.BgtCenter.class,
			type = JoinType.LEFT, on = {@JoinOn(joinField = com.hand.hec.zyj.bgt.dto.BgtCenter.FIELD_CENTER_ID)})
	@NotNull
	private Long bgtCenterId;


	/**
	 * 預算中心名稱
	 */
	@Transient
	@Length(max = 500)
	@JoinColumn(joinName = "bgtCenterJoin", field = com.hand.hec.zyj.bgt.dto.BgtCenter.FIELD_DESCRIPTION)
	private String bgtCenterName;


(2)使用 Criteria 和 selectOptions

@RequestMapping("/query")
	@ResponseBody
	public ResponseData query(RespCenterRefBe dto, @RequestParam(defaultValue = DEFAULT_PAGE) int page,
			@RequestParam(defaultValue = DEFAULT_PAGE_SIZE) int pageSize, HttpServletRequest request) {
		IRequest requestContext = createRequestContext(request);
		Criteria criteria = new Criteria(dto);
		criteria.where(new WhereField(RespCenterRefBe.FIELD_BGT_ENTITY_NAME),
				new WhereField(RespCenterRefBe.FIELD_BGT_CENTER_NAME));
		return new ResponseData(service.selectOptions(requestContext,dto,criteria));
	}

(3)同時mapper.xml注意要添加 transient字段

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.hand.hec.gld.mapper.RespCenterRefBeMapper">
    <resultMap id="BaseResultMap" type="com.hand.hec.gld.dto.RespCenterRefBe">
        <result column="REF_ID" property="refId" jdbcType="DECIMAL" />
        <result column="RESP_CENTER_ID" property="respCenterId" jdbcType="DECIMAL" />
        <result column="BGT_ENTITY_ID" property="bgtEntityId" jdbcType="DECIMAL" />
        <result column="BGT_CENTER_ID" property="bgtCenterId" jdbcType="DECIMAL" />
        <result column="DEFAULT_FLAG" property="defaultFlag" jdbcType="VARCHAR" />
        <result column="ENABLED_FLAG" property="enabledFlag" jdbcType="VARCHAR" />
        <result column="BGT_ENTITY_NAME" property="bgtEntityName" jdbcType="VARCHAR" />
        <result column="BGT_CENTER_NAME" property="bgtCenterName" jdbcType="VARCHAR" />
    </resultMap>


</mapper>

2.3 lov傳參

(1)、lovCode傳參
field的lovCode屬性參數用?連接

<a:field name="unitCode" autoComplete="true" autoCompleteField="unitName" lovGridHeight="320" lovHeight="450" lovCode="LOV_EXP_UNIT_ASSIGN?companyId=$[/parameter/@companyId]?magOrgId=$[/parameter/@magOrgId]"  lovWidth="500" required="true" prompt="exp_org_units.unit_code" title="acp_invoice_lines.unit_id">
      <a:mapping>
            <a:map from="unitId" to="unitId"/>
            <a:map from="unitCode" to="unitCode"/>
            <a:map from="unitName" to="unitName"/>
            <a:map from="companyCode" to="companyCode"/>
            <a:map from="companyShortName" to="companyName"/>
      </a:mapping>
</a:field>

(2)、js傳參

   record.getField('unitCode').setLovPara('companyId', '$[/parameter/@companyId]');

2.4 lov定義自定義sql示例

   <if test="pageId != null">
   <bind name="pageIdNum" value="@java.lang.Long@parseLong(pageId)"/>
   </if>
   SELECT
       layout_id,
       layout_code,
       layout_desc
   FROM
       bpm_page_layout_basic b
   where
          b.page_id = #{pageIdNum}
      <if test="layoutCode!=null">
          and b.layout_code LIKE concat('%',
          concat(#{layoutCode,jdbcType=VARCHAR}, '%'))
      </if>
      <if test="layoutDesc!=null">
          and b.layout_desc LIKE concat('%',
          concat(#{layoutDesc,jdbcType=VARCHAR}, '%'))
      </if>
   ORDER BY
       layout_sequence

3.多語言

  • 類上加 @MultiLanguage
  • 多語言字段上加 @MultiLanguageField
  • 頁面上多語言field添加 dtodtoId
<a:field name="responsibilityCenterName" required="true" prompt="GLD_RESPONSIBILITY_CENTER.RESPONSIBILITY_CENTER_NAME" dto="com.hand.hec.gld.dto.ResponsibilityCenter" dtoId="responsibilityCenterId"/>
  • 頁面上多語言選擇框如下

     <a:tledit id="GLD2030_responsibilityCenterNameTld"/>
    

4.comboBox

4.1 普通dataset型

  • 獲取數據

此步驟也可採取設置默認值的方式,由Controller中轉

            <a:dataSet id="FND2140_gldCoaStructureDs" autoQuery="true" fetchAll="true" baseUrl="/gld-coa-structure" queryUrl="$[/request/@context_path]/gld-coa-structure/query">
                <a:fields>
                    <a:field name="coaStructureCode"/>
                    <a:field name="coaStructureId"/>
                    <a:field name="structureFormat"/>
                    <a:field name="description"/>
                </a:fields>
            </a:dataSet>
  • 映射數據到字段上
<a:field name="coaStructureCode" displayField="coaStructureCode" options="FND2140_gldCoaStructureDs" required="true"   valueField="coaStructureId" returnField="coaStructureId" prompt="GLD_COA_STRUCTURE.COA_STRUCTURE_CODE">
       <a:mapping>
           <a:map from="coaStructureId" to="coaStructureId"/>
           <a:map from="coaStructureCode" to="coaStructureCode"/>
           <a:map from="description" to="coaDescription"/>
           <a:map from="structureFormat" to="coaStructureFormat"/>
       </a:mapping>
 </a:field>

4.2 SysCode型

  • 取數據,注意queryUrl後面有個/
<a:dataSet id="GLD2030_respCenterTypeCodeDs" autoQuery="true" fetchAll="true"  queryUrl="$[/request/@context_path]/common/auroraCode/GLD.RESP_CENTER_TYPE/"/>
  • 映射數據到comboBox上
<a:field name="respCenterTypeCode"/>
<a:field name="respCenterTypeCodeDisplay" displayField="meaning" options="GLD2030_respCenterTypeCodeDs" prompt="GLD_RESPONSIBILITY_CENTER.RESP_CENTER_TYPE_CODE_DISPLAY" required="false" valueField="value" returnField="respCenterTypeCode" />
  • comboBox編輯器
  <a:comboBox id="GLD2030_gridCb"/>

5.條件查詢和模糊查詢

hap對查詢參數進行了限制,所有的條件查詢,均需用 @WhereCriteria 手動聲明

  • 條件查詢:Comparison.EQUAL
  • 模糊查詢:Comparison.LIKE
  • 其他匹配條件請參見 Comparison 枚舉類
  • 實體類添加 @Where
	/**
	 * 責任中心名稱
	 */
	@Length(max = 500)
	@MultiLanguageField
	@Where
	private String responsibilityCenterName;
  • 查詢時結合 Criteria 進行查詢
    @RequestMapping("/query")
    @ResponseBody
    public ResponseData query(ResponsibilityCenter dto, @RequestParam(defaultValue = DEFAULT_PAGE) int page,
        @RequestParam(defaultValue = DEFAULT_PAGE_SIZE) int pageSize, HttpServletRequest request) {
        IRequest requestContext = createRequestContext(request);
		Criteria criteria = new Criteria(dto);
		if(dto.getResponsibilityCenterCode()!=null){
			criteria.where(new WhereField(ResponsibilityCenter.FIELD_RESPONSIBILITY_CENTER_CODE, Comparison.LIKE));
		}
		if(dto.getResponsibilityCenterName()!=null){
			criteria.where(new WhereField(ResponsibilityCenter.FIELD_RESPONSIBILITY_CENTER_NAME, Comparison.LIKE));
		}
        return new ResponseData(service.selectOptions(requestContext,dto,criteria));
    }

6.設置默認值

Screen頁面上的mode-query是爲了準備默認值的,因此遷移時,針對默認值,可以做如下操作以實現相同的功能。

參見部門類型定義ExpOrgUnitTypeController

6.1 中轉站

首先跳轉到頁面之前先經過Controller的方法中轉一下。在此Controller方法,將頁面上需要的參數(也就是默認值)準備好。

  • 功能維護:

解讀:

將部門類型定義這個功能的入口頁面配置成 exp/org-unit-type/index ,這樣在點擊功能時,會先跳轉到 exp/org-unit-type/index,這樣我們可以在這個controller方法中準備好頁面上需要的參數,然後再跳轉到頁面上。

  • Controller方法:
	@RequestMapping(value = "/index")
	public ModelAndView index(HttpServletRequest request, Long accountSetId, Long accountId) {
		IRequest requestContext = createRequestContext(request);
		List<FndManagingOrganization> fndManagingOrganizationList = fndManagingOrganizationService.magOrgOption(requestContext);

		ModelAndView view = new ModelAndView("exp/EXP1012/exp_org_unit_type");
		view.addObject("fndManagingOrganizationList", fndManagingOrganizationList);
		return view;
	}

6.2 頁面取值

要想取值,就得先弄懂 AuroraContext,因爲值都在AuroraContext中。

(1)AuroraContext的結構

通過在頁面上加入xmlns:p="uncertain.proc"命名空間和<p:echo/>節點,可以頁面加載時,在tomcat控制檯輸出上下文的內容。

可以看到AuroraContext結構如下:

  • context
    • cookie
    • parameter
    • session
    • model
      • 具體model(在此示例中爲 fndManagingOrganizationList)
        • records
          • record
          • record

(2)取值

取值就按照AuroraContext的結構取,根節點爲/,取到節點中的值時使用@符號。於是取值示例如下:

'$[/model/fndManagingOrganizationList/records/record/@magOrgCodeName]'

(3)設置默認值

7.批量分配

以部門類型定義頁面 批量分配公司爲例:

[外鏈圖片轉存失敗(img-DmptGygU-1562294483758)(images/1548397772141.png)]

主要步驟:

  • 獲取所有被選中的記錄
  • 發送Ajax請求
// 見 exp_org_unit_type_batch_assign_com_all.screen

var datas = $au('EXP1012_batch_assign_all_result_ds').getJsonData(true);  //獲取所有選中的記錄
Aurora.request({                                                          //發送ajax請求
    lockMessage: '$[l:hap_waiting]',
    url: $au('EXP1110_org_unit_type_asgn_com_batch_assign_all_link').getUrl(),
    para: datas,
    success: EXP1012_batchAssignAllBackFun,
    scope: this
});

//另外可參見:exp_mo_unit_group_relations_bath_assign.screen

8.附件相關

// 1.隱藏 上傳附件 按鈕
//var url = $au('upload_image_cannotUpload_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId;
// 2.顯示 上傳附件 按鈕
// var url = $au('upload_image_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId;
// 3.隱藏 上傳附件與附件刪除 按鈕
var url = $au('upload_image_cannotUpload_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId + '&showDelete=false';

8.1 使用附件實現上傳、下載、刪除功能

可參見

管理組織定義(fnd_managing_organizations.screen) -> 附件上傳

目前已實現附件上傳、下載、刪除功能

要使用附件相關功能,需完成以下3個步驟:

(1)在 screen(fnd_managing_organizations.screen)頁面上定義附件上傳頁面的地址:

<a:link id="upload_image_link" url="$[/request/@context_path]/app/APP2030/app_uploadFile.screen"/>

(2)渲染附件上傳按鈕

function upload_file_link(value, record, name) {
            var magOrgId = record.get('magOrgId');

            return '<a href="javascript:uploadFile(' + magOrgId + ')">$[l:prompt.upload_attachment]</a>';

}


<a:column name="uploadFile" align="center" renderer="upload_file_link" width="80"/>
 

(3)跳轉附件上傳頁面時需要帶上兩個參數:

  • tableName: 本條記錄所在表名
  • tablePkValue: 本條記錄對應的主鍵值
  • showDelete:是否顯示刪除按鈕,默認爲false,不顯示刪除按鈕
function uploadFile(magOrgId) {
            var url = $au('upload_image_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId+ '&showDelete=true';
            new Aurora.Window({
                url: url,
                title: '$[l:prompt.upload_attachment]',
                id: 'upload_image_screen',
                width: 600,
                height: 400
            });
}

8.2 隱藏附件上傳按鈕

附件上傳按鈕的隱藏與顯示是通過使用兩個頁面來實現的:

  • app_uploadFile.screen:顯示附件上傳按鈕的頁面
  • app_uploadFile_cannotUpload.screen:不顯示附件上傳按鈕的頁面

因此若要隱藏附件上傳按鈕:

(1)定義附件上傳頁面的地址:

 <a:link id="upload_image_cannotUpload_link" url="$[/request/@context_path]/app/APP2030/app_uploadFile_cannotUpload.screen"/>

(2)構造跳轉附件上傳頁面的url

 var url = $au('upload_image_cannotUpload_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId;

因此若要顯示附件上傳按鈕:

(1)定義附件上傳頁面的地址:

<a:link id="upload_image_link" url="$[/request/@context_path]/app/APP2030/app_uploadFile.screen"/>

(2)構造跳轉附件上傳頁面的url

 var url = $au('upload_image_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId;

8.3 隱藏刪除按鈕

刪除按鈕的顯示與隱藏是通過傳參來控制的

showDelete:

  • true: 顯示刪除按鈕
  • false或其他值:隱藏刪除按鈕。
  • 默認值爲false

因此附件上傳按鈕、刪除按鈕的顯示隱藏組合如下:

(1)隱藏附件上傳按鈕,隱藏刪除按鈕

var url = $au('upload_image_cannotUpload_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId;

(2)隱藏 上傳附件按鈕,顯示 附件刪除 按鈕

var url = $au('upload_image_cannotUpload_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId + '&showDelete=true';

(3)顯示 上傳附件按鈕 並 顯示 附件刪除 按鈕

 var url = $au('upload_image_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId + '&showDelete=true';

(4)顯示 上傳附件按鈕 並 隱藏 附件刪除 按鈕

var url = $au('upload_image_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId ;

默認值爲false

因此附件上傳按鈕、刪除按鈕的顯示隱藏組合如下:

(1)隱藏附件上傳按鈕,隱藏刪除按鈕

var url = $au('upload_image_cannotUpload_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId;

(2)隱藏 上傳附件按鈕,顯示 附件刪除 按鈕

var url = $au('upload_image_cannotUpload_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId + '&showDelete=true';

(3)顯示 上傳附件按鈕 並 顯示 附件刪除 按鈕

 var url = $au('upload_image_link').getUrl() + '?tableName=FND_MANAGING_ORGANIZATIONS&tablePkValue=' + magOrgId + '&showDelete=true';
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章