Commit 8b2a91d5 authored by custom's avatar custom

Merge origin/master into master

parents ddfb3fe1 246390c5
...@@ -72,7 +72,7 @@ winId | String(必填) | html元素标签的id ...@@ -72,7 +72,7 @@ winId | String(必填) | html元素标签的id
functionCode | String(必填) | 抽屉的唯一标识,用以确定该抽屉的相关信息 functionCode | String(必填) | 抽屉的唯一标识,用以确定该抽屉的相关信息
params | Object | 需传递的参数,将自动拼到url上 params | Object | 需传递的参数,将自动拼到url上
closeFunction | function | 关闭抽屉调用的方法 closeFunction | function | 关闭抽屉调用的方法
width | Number | 自定义宽度 width | Number/字符串(100% , 100px) | 自定义宽度
```javascript ```javascript
......
...@@ -147,7 +147,7 @@ mvn clean install -Dmaven.test.skip=true ...@@ -147,7 +147,7 @@ mvn clean install -Dmaven.test.skip=true
在 HelParent 项目录下执行: 在 HelParent 项目录下执行:
- MySql - MySql
- `mvn process-resources -D skipLiquibaseRun=false -D db.driver=com.mysql.jdbc.Driver -D db.url=jdbc:mysql://127.0.0.1:3306/hel -Ddb.user=hel_dev -Ddb.password=hel_dev` - `mvn process-resources -D skipLiquibaseRun=false -D db.driver=com.mysql.jdbc.Driver -D db.url="jdbc:mysql:127.0.0.1:3306/hel?useUnicode=true&characterEncoding=utf8" -Ddb.user=hel_dev -Ddb.password=hel_dev`
- SqlServer - SqlServer
- `mvn process-resources -D skipLiquibaseRun=false -Ddb.user=hel_dev -Ddb.password=hel_dev-D db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver -D db.url="jdbc:sqlserver://127.0.0.1:1433; DatabaseName=hel"` - `mvn process-resources -D skipLiquibaseRun=false -Ddb.user=hel_dev -Ddb.password=hel_dev-D db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver -D db.url="jdbc:sqlserver://127.0.0.1:1433; DatabaseName=hel"`
- Oracle - Oracle
......
## HlsBarChart
```xml
<h:hlsChart chartType="BAR" style="margin-top:5px;margin-left:6px;" barSourceData="barSourceData" titleBgColor="red"
title="商业伙伴" modify="modifyFunc" add="addFunc" color="#ed4e2a"></h:hlsChart>
```
**常用的属性**
| 属性名 | 类型 | 作用 | 是否必输|
|:---: | :---: | :---: | :---: |
| id | string | 唯一标识 |
| chartType | string | 组件类型 | Y
| style | string | 组件box样式 |
| barSourceData | object | 组件数据源 | Y
| titleBgColor | string | 组件标题背景颜色 |
| title | string | 组件标题 |
| modify | function | 编辑icon触发的事件 |
| add | function | 新增icon触发的事件 |
|color|string |字体颜色|
**下面是一个例子**
```javascript
var datas = function (url) {
var odatas = [],
$.ajax({
type: 'GET',
url: "${base.contextPath}/hls/bp/master/home/secord/query",
async: false,
contentType: "application/json; charset=utf-8",
success: function (datas) {
odatas = datas.rows;
}
});
return odatas;
}();
var statisticalData = function () {
var o = {};
$.ajax({
type: 'GET',
url: "${base.contextPath}/hls/bp/master/count/query",
async: false,
contentType: "application/json; charset=utf-8",
success: function (datas) {
o.allCount = datas.rows[0].allCount;
o.monthAddCount = datas.rows[0].monthAddCount;
}
});
return o;
}();
//数据源
var barSourceData = {
barModel: {
xkey: 'description',
ykeys: 'count',
data: datas,
labels: '数值', //鼠标经过柱子图显示的描述
barColors: 'green',
barSizeRatio: 0.5,
},
statisticalModel: {
statisticalTitle: {
allCount: "总数",
monthAddCount: "本月新增"
},
statisticalData: statisticalData
}
};
function modifyFunc(e) {
alert("modifyFunc");
}
function addFunc(e) {
alert("addFunc");
}
```
#### 注意: 数据源中的属性名,需要固定,这样做是考虑到将不同的查询结果整合成统一的数据格式,方便组件渲染。
> - barModel:柱形图
| 属性名 | 类型 | 作用 |
|:---: | :---: | :---: | :---: |
| xkey | string | x轴标题对应的属性名
| ykeys | string | y轴数据对应的属性名 |
| data | Array | 数据集 |
| labels | string | 鼠标经过柱状图时ykeys对应的值的描述 |
| barColors | string | 柱子颜色 |
| barSizeRatio | Number | 柱子和数据的比例 |
> - statisticalModel:上方的统计框
| 属性名 | 类型 | 作用 |
|:---: | :---: | :---: |
| statisticalTitle | object | 统计框的属性名以及属性描述 |
| statisticalData | object | 数据源 (注意statisticalData的属性名和statisticalTitle中的属性名要对应上)
```xml
<h:hlsChart chartType="BAR" style="margin-top:5px;margin-left:6px;" barSourceData="barSourceData" titleBgColor="red"
title="商业伙伴" modify="modifyFunc" add="addFunc" color="#ed4e2a"></h:hlsChart>
```
\ No newline at end of file
## hlsChart 图表
### 实心饼状图(SOLID)
使用方法:
```xml
<h:hlsChart
chartType="SOLID"
style="position: relative;"
dataSource="data"
color="#FA6A4D,#2EC3E8,#A0D469,#FFCD55,#E75B8D"
labels="承租人变更,担保人变更,租赁物变更,租金计划变更,合同文本变更"
values="tenant,guarantor,item,mortgage,cashflow"
segmentShowStroke="true">
</h:hlsChart>
<script>
var data={
"cashflow": "0",
"guarantor": "2",
"item": "0",
"mortgage": "0",
"tenant": "6"
}
</script>
```
| 属性名 | 类型 | 描述 |
| --- | --- | --- |
| chartType | String | 图表类型 |
| style | String | 图表外层的style样式 |
| dataSource | object | 图表数据源 |
| color | String | 图表各数据块所对应的颜色,多个数据块之间使用“,”分隔 |
| labels | String | 图表中各数据块所对应的标签,多个数据块之间使用“,”分隔 |
| values | String | 图表中各数据块所对应响应数据中的字段,多个数据块之间使用“,”分隔 |
| segmentShowStroke | String | 饼图中的块是否分隔,默认为false即不分隔 |
### 环状图(CIRCULAR)
使用方法:
```xml
<h:hlsChart
chartType="CIRCULAR"
style="position: relative;"
url="${base.contextPath}/con/conHomepage/ApprovalQuantity/query"
color="#FFCD55,#2EC3E8,#FA6A4D,#A0D469"
labels="新建,审批中,审批拒绝,审批通过"
values="newCount,approvingCount,rejectedCount,approvedCount"
selectedChanged="select">
</h:hlsChart>
<script>
var select = function(arg,item){
console.log('label:'+item.label);
}
</script>
```
| 属性名 | 类型 | 描述 |
| --- | --- | --- |
| chartType | String | 图表类型 |
| style | String | 图表外层的style样式 |
| url | String | 图表数据源的获取地址 |
| color | String | 图表各数据块所对应的颜色,多个数据块之间使用“,”分隔 |
| labels | String | 图表中各数据块所对应的标签,多个数据块之间使用“,”分隔 |
| values | String | 图表中各数据块所对应响应数据中的字段,多个数据块之间使用“,”分隔 |
| selectedChanged | String | 图表中各数据块的点击回调事件 |
## HlsBarChart 图表
### 柱状图(BAR)
```xml
<h:hlsChart chartType="BAR" style="margin-top:5px;margin-left:6px;" barSourceData="barSourceData" titleBgColor="red"
title="商业伙伴" modify="modifyFunc" add="addFunc" color="#ed4e2a"></h:hlsChart>
```
**常用的属性**
| 属性名 | 类型 | 作用 | 是否必输|
|:---: | :---: | :---: | :---: |
| id | string | 唯一标识 |
| chartType | string | 组件类型 | Y
| style | string | 组件box样式 |
| barSourceData | object | 组件数据源 | Y
| titleBgColor | string | 组件标题背景颜色 |
| title | string | 组件标题 |
| modify | function | 编辑icon触发的事件 |
| add | function | 新增icon触发的事件 |
|color|string |字体颜色|
**下面是一个例子**
```javascript
var datas = function (url) {
var odatas = [],
$.ajax({
type: 'GET',
url: "${base.contextPath}/hls/bp/master/home/secord/query",
async: false,
contentType: "application/json; charset=utf-8",
success: function (datas) {
odatas = datas.rows;
}
});
return odatas;
}();
var statisticalData = function () {
var o = {};
$.ajax({
type: 'GET',
url: "${base.contextPath}/hls/bp/master/count/query",
async: false,
contentType: "application/json; charset=utf-8",
success: function (datas) {
o.allCount = datas.rows[0].allCount;
o.monthAddCount = datas.rows[0].monthAddCount;
}
});
return o;
}();
//数据源
var barSourceData = {
barModel: {
xkey: 'description',
ykeys: 'count',
data: datas,
labels: '数值', //鼠标经过柱子图显示的描述
barColors: 'green',
barSizeRatio: 0.5,
},
statisticalModel: {
statisticalTitle: {
allCount: "总数",
monthAddCount: "本月新增"
},
statisticalData: statisticalData
}
};
function modifyFunc(e) {
alert("modifyFunc");
}
function addFunc(e) {
alert("addFunc");
}
```
#### 注意: 数据源中的属性名,需要固定,这样做是考虑到将不同的查询结果整合成统一的数据格式,方便组件渲染。
> * barModel:柱形图
| 属性名 | 类型 | 作用 |
| --- | --- | --- |
| xkey | string | x轴标题对应的属性名 |
| ykeys | string | y轴数据对应的属性名 |
| data | Array | 数据集 |
| labels | string | 鼠标经过柱状图时ykeys对应的值的描述 |
| barColors | string | 柱子颜色 |
| barSizeRatio | Number | 柱子和数据的比例 |
> * statisticalModel:上方的统计框
| 属性名 | 类型 | 作用 |
| --- | --- | --- |
| statisticalTitle | object | 统计框的属性名以及属性描述 |
| statisticalData | object | 数据源 \(注意statisticalData的属性名和statisticalTitle中的属性名要对应上\) |
```xml
<h:hlsChart chartType="BAR" style="margin-top:5px;margin-left:6px;" barSourceData="barSourceData" titleBgColor="red"
title="商业伙伴" modify="modifyFunc" add="addFunc" color="#ed4e2a"></h:hlsChart>
```
## HlsBrokenChart 图表
### 折线图(BROKEN)
| 属性名 | 类型 | 作用 |
| --- | --- | --- |
| renderType | string | 渲染类型(one 或者 three) |
| url | string | 当渲染为three的时候url生效 |
| time | string | 当天时间(yyyy-mm-dd) |
| title | string | 折线图标题 |
| imageSrc | string | 折线图左角图片路径 |
```xml
<h:hlsChart renderType="three"
url="/con/conHomepage/putIn/query" chartType="BROKEN" time="${Session.sysDate!}"
title="合同逾期金额变动"
imageSrc="/resources/images/CONT/zhuzi.png"></h:hlsChart>
```
## HlsLineChart 图表
### 折线图(LINECHART)
| 属性名 | 类型 | 作用 |
| --- | --- | --- |
| id | string | 唯一标识 |
| url | string | 获取数据源的url |
| chartType | string | 图表类型 |
| title | string | 折线图标题 |
| style | string | 图表外层样式 |
| code | string | 选择放款/回款数据 |
```
<h:hlsChart chartType="LINECHART" id="A" code="PAYMENT" title="放款"
style="margin-top:15px;margin-left:60px;float:left;"
url="${base.contextPath}/csh/write/off/getEveryMonthPaymentAndReceiptAmount/query"> </h:hlsChart>
<h:hlsChart chartType="LINECHART" id="B" code="RECEIPT" title="回款"
style="margin-top:15px;margin-left:60px;float:left;"
url="${base.contextPath}/csh/write/off/getEveryMonthPaymentAndReceiptAmount/query"> </h:hlsChart>
<script>
InitiateSparklineCharts.init();
</script>
```
...@@ -415,7 +415,64 @@ function template(){ ...@@ -415,7 +415,64 @@ function template(){
> **提示**: > **提示**:
> >
> * 遇到**object**类型 就向下添加子标签,当遇到普通类型时,就添加到当前的标签上,就像处理一般属性那样。 > * 遇到**object**类型 就向下添加子标签,当遇到普通类型时,就添加到当前的标签上,就像处理一般属性那样。
### 任务通知栏(noticeTable)
```xml
<h:hlsGrid gridType="noticeTable" titleSearchId="titleSearchId" titleSearchInputId="titleSearchInputId"
hlsDataSource="taskListData" title="任务列表" inputPlaceHolder="搜索任务" titleIcon="fa fa-tasks"
inputImg="${base.contextPath}/resources/images/MAIN/hls-todo-search.png" locateEvent="af" maxPageSize="3"
id="noticeTable"></h:hlsGrid>
```
**常用属性**
| 属性名 | 类型 | 作用 | 是否必输|
|:---: | :---: | :---: | :---: |
| id | string | 唯一标识 | Y |
| gridType | string | 组件类型 | Y |
| titleSearchId | string | input查询框图标的id |
| titleSearchInputId | string | input框id |
| hlsDataSource | Array | 数据源 |
| title | string | 组件标题 |
| titleIcon | string | 组件标题icon(字体图标) |
| inputImg | string | 查询框图标 ||
| locateEvent | function | 行点击事件调用的函数|
| maxPageSize | Number | 记录最大的条数||
**提示:**
>- 每个noticeTable在window下面都会有以该ID命名的对象,该对象上有以下常用方法
| 方法名 | 参数 | 返回值 | 作用|
|:---: | :---: | :---: | :---: |
| renderUI | | | 重新渲染图表,(渲染之前改变传入的数据等信息)|
| selectCheckedItem | | 选中行的数据信息 | 获得选中行的数据信息|
>- locateEvent参数传递一个定义好的方法名字,locateEvent = "testFunc"
```javascript
function testFunc(e,rowdata){
}
```
该函数返回两个参数,参数1: 事件对象; 参数2: 该行数据信息
...@@ -23,46 +23,66 @@ ...@@ -23,46 +23,66 @@
| 1 | 1 | 篮球 |因为篮球好玩| | 1 | 1 | 篮球 |因为篮球好玩|
| 2 | 1| 游泳 | 因为游泳好玩| | 2 | 1| 游泳 | 因为游泳好玩|
| 3 | 1 |动画片 | 最爱看大头儿子| | 3 | 1 |动画片 | 最爱看大头儿子|
| 4 | 2 |画画| 梵高的画也不过如此| | 4 | 2 |画画| 因为画画好玩|
需求是新增一个人的信息以及它的爱好(向hls_person和hls_hobby表新增记录) 需求是新增一个人的信息以及它的爱好(向hls_person和hls_hobby表新增记录)
下面是一个头行保存的列子: 下面是一个头行保存的列子:
#### 准备工作
1. 建表,主键默认自增长
2. 搭建数据模型,根据表建立相应的DTO,即HlsPerson.java和HlsHobby.java,注意HlsPerson.java中应存在List \<HlsHobby\> hlsHobbyList属性。
3. 搭建控制层,建立controller
4. 搭建业务逻辑,建立service及其实现类。
5. 搭建数据持久化层,新建mapper.java和mapper.xml
>- 先建立结构,在具体实现功能,以免疏漏。
#### 前台
```javascript ```javascript
<script><![CDATA[ <script><![CDATA[
//提交数据用到的容器 //提交数据用到的容器
var viewModel = kendo.observable({ var viewModel = kendo.observable({
isEnabled: true, isEnabled: true,
data:{}, data: {},
mySubmit: function (e) {
mySubmit:function(e){ if (e) {
if(e){ e.preventDefault();
e.preventDefault(); }
} Hap.submitForm({
Hap.submitForm({ url: '${base.contextPath}/hls/test/hdLnSave',
url : '${base.contextPath}/hls/test/save', formModel: viewModel.data,
formModel : viewModel.data, asArray: false,
asArray:false, grid: {
grid: { "hobby": $("#grid") "hlsHobbyList": $("#grid")
}, },
success:function(){ success: function () {
showInfoDialog("保存成功!"); viewModel.showInfoDialog("保存成功!");
$('#grid').data('kendoGrid').dataSource.page(1);
},
error:function(){
viewModel.showInfoDialog("保存失败!");
} }
}); });
}, },
function:showInfoDialog(pMessage){ showInfoDialog: function(pMessage)
kendo.ui.showInfoDialog({ {
title: $l('提示'), kendo.ui.showInfoDialog({
message: pMessage title: $l('提示'),
}); message: pMessage
} });
}
});
});
//请求处理方法 //请求处理方法
function parameterMap(options, type){ function parameterMap(options, type){
...@@ -77,13 +97,9 @@ function parameterMap(options, type){ ...@@ -77,13 +97,9 @@ function parameterMap(options, type){
return kendo.stringify(datas); return kendo.stringify(datas);
} else if (type === "read") { } else if (type === "read") {
var map = {}; var map = {};
map.page = options.page; map.page = options.page || 1;
map.pagesize = options.pageSize; map.pagesize = options.pageSize|| 5;
for (var k in map) { return kendo.stringify(map);
if (map[k] === '' || map[k] === null || map[k] === undefined)
delete map[k]
}
return Hap.prepareQueryParameter(viewModel.model.toJSON(), options);
} }
} }
...@@ -99,8 +115,8 @@ function dsEditable(field){ ...@@ -99,8 +115,8 @@ function dsEditable(field){
<!--头--> <!--头-->
<h:hlsForm title="个人信息" width="100%"> <h:hlsForm title="个人信息" width="100%">
<h:hlsHBox> <h:hlsHBox>
<h:hlsMaskedTextBox name="name" id="name" bind="enabled: isEnabled, value:model.name" colspan="3" prompt="姓名:" required="true" style="width:100%;"/> <h:hlsMaskedTextBox name="name" id="name" bind="enabled: isEnabled, value:data.name" colspan="3" prompt="姓名:" required="true" style="width:100%;"/>
<h:hlsMaskedTextBox name="age" id="age" bind="enabled: isEnabled, value:model.age" colspan="3" prompt="年龄:" required="true" style="width:100%;"/> <h:hlsMaskedTextBox name="age" id="age" bind="enabled: isEnabled, value:data.age" colspan="3" prompt="年龄:" required="true" style="width:100%;"/>
</h:hlsHBox> </h:hlsHBox>
</h:hlsForm> </h:hlsForm>
...@@ -108,9 +124,8 @@ function dsEditable(field){ ...@@ -108,9 +124,8 @@ function dsEditable(field){
<!--行--> <!--行-->
<h:dataSource id="dataSource" batch="true" pageSize="10" serverPaging="true"> <h:dataSource id="dataSource" batch="true" pageSize="10" serverPaging="true">
<h:transport parameterMap="parameterMap"> <h:transport parameterMap="parameterMap">
<h:read url="${base.contextPath}/hls/test/query" type="GET" dataType="json"/> <h:read url="${base.contextPath}/hls/test/ln/query" type="GET" dataType="json"/>
<h:create url="${base.contextPath}/hls/test/create" type="POST" contentType="application/json" /> <h:destroy url="${base.contextPath}/hls/test/ln/remove" type="POST" contentType="application/json" />
<h:update url="${base.contextPath}/hls/test/save" type="POST" contentType="application/json" />
</h:transport> </h:transport>
<h:schema data="rows" total="total" errors="schemaError"> <h:schema data="rows" total="total" errors="schemaError">
<h:model id="pid" editable="dsEditable"> <h:model id="pid" editable="dsEditable">
...@@ -138,50 +153,116 @@ function dsEditable(field){ ...@@ -138,50 +153,116 @@ function dsEditable(field){
<!--按钮--> <!--按钮-->
<h:hlsToolBar> <h:hlsToolBar>
<h:hlsButton click="mySubmit" text="保存"></h:hlsButton> <h:hlsButton click="viewModel.mySubmit" text="保存"></h:hlsButton>
</h:hlsToolBar> </h:hlsToolBar>
``` ```
#### 后台
保存按钮注册了点了事件,点击保存将数据提交到'${base.contextPath}/hls/test/hdLnSave'
保存按钮注册了点了事件,点击保存将数据提交到'${base.contextPath}/hls/test/save' > 在后端controller通过定义 @RequestMapping("/hls/test/hdLnSave") 注解映射到对应的url,捕获到对应请求。
> 在后端controller通过定义 @RequestMapping("/hls/test/save") 注解映射到对应的url,捕获到对应请求。
后端收到前台传过来的数据,调用service层对数据进行持久化。 后端收到前台传过来的数据,调用service层对数据进行持久化。
controller HlsTESTController.java
```java ```java
@RequestMapping("/hls/test/save") @Controller
public class HlsTESTController extends BaseController {
@Autowired
private HlsPersonService hlsPersonService;
@Autowired
private HlsHobbyService hlsHobbyService;
@RequestMapping(value = "/hls/test/query")
@ResponseBody @ResponseBody
public ResponseData save(HttpServletRequest request,@RequestBody HlsPerson hlsPerson, @RequestParam(defaultValue = DEFAULT_PAGE) final int page, public ResponseData hdQuery(final HlsPerson hlsPerson, @RequestParam(defaultValue = DEFAULT_PAGE) final int page,
@RequestParam(defaultValue = DEFAULT_PAGE_SIZE) final int pagesize){ @RequestParam(defaultValue = DEFAULT_PAGE_SIZE) final int pagesize, final HttpServletRequest request) {
IRequest iRequest = createRequestContext(request); IRequest requestContext = createRequestContext(request);
testService.batchChildUpdate(iRequest, hlsPerson ,hlsPerson.getHlsHobby()); return new ResponseData(hlsPersonService.select(requestContext,hlsPerson,page,pagesize));
return new ResponseData(); }
}
```
testService的实现类testServiceImpl定义了batchChildUpdate方法: @RequestMapping(value="/hls/test/hdLnSave",method=RequestMethod.POST)
```java @ResponseBody
public ResponseData hdLnSave(HttpServletRequest request,@RequestBody HlsPerson hlsPerson, @RequestParam(defaultValue = DEFAULT_PAGE) final int page,
@RequestParam(defaultValue = DEFAULT_PAGE_SIZE) final int pagesize){
IRequest iRequest = createRequestContext(request);
hlsPersonService.batchChildUpdate(iRequest, hlsPerson);
return new ResponseData();
}
@RequestMapping(value = "/hls/test/ln/query")
@ResponseBody
public ResponseData lnQuery(final HlsHobby hlsHobby, @RequestParam(defaultValue = DEFAULT_PAGE) final int page,
@RequestParam(defaultValue = DEFAULT_PAGE_SIZE) final int pagesize, final HttpServletRequest request) {
IRequest requestContext = createRequestContext(request);
return new ResponseData(hlsHobbyService.select(requestContext,hlsHobby,page,pagesize));
}
@Override
public void batchChildUpdate(IRequest iRequest, HlsPerson hlsPerson, List<HlsHobby> hlsHobbyList) { @RequestMapping(value="/hls/test/ln/remove",method=RequestMethod.POST)
List<HlsPerson> tempHlsPerson = new ArrayList<HlsPerson>(); @ResponseBody
if(hlsPerson != null ){ public ResponseData delete(HttpServletRequest request, @RequestBody List<HlsHobby> hlsHobbyList) {
tempHlsPerson.add(hlsPerson); hlsHobbyService.batchDelete(hlsHobbyList);
hlsPersonService.batchUpdate(iRequest,tempHlsPerson); return new ResponseData();
Long pid = tempHlsPerson.get(0).getPid();
for(HlsHobby hh : hlsHobbyList){
hh.setPid(pid);
}
hlsHobbyService.batchUpdate(iRequest,hlsHobbyList);
}
} }
}
```
> **提示:**
>* 通常头行结构还会涉及对头行数据的删和查,根据需要在controller中加入入口。
>* bathUpdate会根据传入的List对象中单个对象的属性值__status判断,如为update即做更新操作,add为插入操作, __status的值由前端paramter函数决定。
>* 这里的select()、batchDelete()和batchUpdate()由相应的service继承自IBaseService,自己无需实现,类似方法还有许多,请自行练习使用。
HlsPersonService.java
```java
public interface HlsPersonService extends IBaseService<HlsPerson>,ProxySelf<HlsPersonService>{
void batchChildUpdate(IRequest iRequest, HlsPerson hlsPerson);
}
``` ```
> bathUpdate会根据传入的List对象中单个对象的属性值__status判断,如为update即做更新操作,add为插入操作, __status的值由前端paramter函数决定。
\ No newline at end of file
接口实现类HlsPersonServiceImpl定义了batchChildUpdate方法:
HlsPersonServiceImpl.java
```java
@Service
@Transactional
public class HlsPersonServiceImpl extends BaseServiceImpl<HlsPerson> implements HlsPersonService {
@Autowired
private HlsHobbyService hlsHobbyService;
@Override
public void batchChildUpdate(IRequest iRequest, HlsPerson hlsPerson) {
if(hlsPerson != null ){
hlsPerson.set__status("add");
List<HlsPerson> tempHlsPerson = new ArrayList<HlsPerson>();
tempHlsPerson.add(hlsPerson);
self().batchUpdate(iRequest,tempHlsPerson);
Long pid = hlsPerson.getPid();
List<HlsHobby> hlsHobbyList = hlsPerson.getHlsHobbyList();
for(HlsHobby hh : hlsHobbyList){
hh.setPid(pid);
}
hlsHobbyService.batchUpdate(iRequest,hlsHobbyList);
}
}
}
# RabbitMq消息队列 # RabbitMq消息队列
## 1.简介 ## 1.简介
融租易 的消息系统提供`唯一``广播`以及`主题`三种模式,实现方式为 RabbitMQ。 融租易 的消息系统提供`唯一``广播`以及`主题`三种模式,实现方式为 RabbitMQ。
### 1.1 RabbitMQ介绍 ### 1.1 RabbitMQ介绍
RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。消息中间件主要用于组件之间的解耦。rabbitmq多应用于批量数据异步处理、并行任务串行化,高负载任务的负载均衡等 重量级,高并发,异步高可靠性场景。 RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。消息中间件主要用于组件之间的解耦。rabbitmq多应用于批量数据异步处理、并行任务串行化,高负载任务的负载均衡等 重量级,高并发,异步高可靠性场景。
### 1.2 配置rabbit ### 1.2 配置rabbit
(1)用户要先在 `applicationContext-rabbitmq.xml` 中 添加`<beans:import resource="rabbitmq.xml"/>` (1)用户要先在 `applicationContext-rabbitmq.xml` 中 添加`<beans:import resource="rabbitmq.xml"/>`
(2)然后在`config.properties`中自行添加mq相关的配置如图: (2)然后在`config.properties`中自行添加mq相关的配置如图:
![](/assets/config.png) ![](/assets/config.png)
## 2 自定义消息 ## 2 自定义消息
在融租易的接口管理的消息队列模块定义功中,提供了自定义队列和交换机的功能,可以根据配置实现自定义的队列和交换机的匹配,避免了在xml中的繁琐配置。 在融租易的接口管理的消息队列模块定义功中,提供了自定义队列和交换机的功能,可以根据配置实现自定义的队列和交换机的匹配,避免了在xml中的繁琐配置。
### 2.1 定义交换机 ### 2.1 定义交换机
在接口管理的消息队列定义模块中,首先进行交换机的定义,界面如图:![](/assets/exchange.png)注意: 在接口管理的消息队列定义模块中,首先进行交换机的定义,界面如图:![](/assets/exchange.png)
注意:
交换机名称不可以重复定义,一个交换机可以对应多个队列。
交换机名称不可以重复定义,一个交换机可以对应多个队列。
交换机类型可以分为**direct\(唯一模式\),topic\(主题模式\),fanout\(广播模式\),**rabbitmq会根据你的交换机类型和定义的路由键,完成消息的转发**。**
交换机类型可以分为**direct\(唯一模式\),topic\(主题模式\),fanout\(广播模式\),**rabbitmq会根据你的交换机类型和定义的路由键,完成消息的转发**。**
持久化(durable):交换机在服务关闭后,清除与否。
持久化(durable):交换机在服务关闭后,清除与否。
自动删除(auto-delete):当交换机没有队列绑定时,删除与否。
自动删除(auto-delete):当交换机没有队列绑定时,删除与否。
### 2.2 定义队列和路由键
### 2.2 定义队列和路由键
定义完交换机后,你还需要定义你的队列和相应的匹配模式(既路由键)界面如图:![](/assets/queue.png)注意:
定义完交换机后,你还需要定义你的队列和相应的匹配模式(既路由键)界面如图:![](/assets/queue.png)
队列名称不可以重复,但是一个队列可以对应多个交换机。
注意:
匹配模式(routing-key):此处的匹配模式即为路由键
队列名称不可以重复,但是一个队列可以对应多个交换机。
持久化(durable):队列在服务关闭后,清除与否。
匹配模式(routing-key):此处的匹配模式即为路由键
自动删除(auto-delete):当队列没有绑定交换机时,删除与否。
持久化(durable):队列在服务关闭后,清除与否。
私有队列(exclusive): 仅创建者可以使用的私有队列,断开后自动删除.
自动删除(auto-delete):当队列没有绑定交换机时,删除与否。
## 3 发送消息/接收消息
私有队列(exclusive): 仅创建者可以使用的私有队列,断开后自动删除.
在融租易中,消息的发送和接收都提供了可以直接调用的接口
## 3 发送消息/接收消息
### 3.1 消息的匹配规则
在融租易中,消息的发送和接收都提供了可以直接调用的接口
1.唯一模式\(**Direct Exchange**\):
### 3.1 消息的匹配规则
处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “hls”,则只有被标记为“hls”的消息才被转发,不会转发hls.sys,也不会转发hls.fnd,只会转发hls。
1.唯一模式\(**Direct Exchange**\):
2.广播模式\(**Fanout Exchange**\):
处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “hls”,则只有被标记为“hls”的消息才被转发,不会转发hls.sys,也不会转发hls.fnd,只会转发hls。
不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。
2.广播模式\(**Fanout Exchange**\):
3.主题模式\(**Topic Exchange**\):
不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。
将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“\#”匹配一个或多个词,符号“\*”匹配不多不少一个词。因此“hls.\#”能够匹配到“hls.sys.adaptor”,但是“hls.\*” 只会匹配到“hls.sys”。
3.主题模式\(**Topic Exchange**\):
### 3.2 发送消息
将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“\#”匹配一个或多个词,符号“\*”匹配不多不少一个词。因此“hls.\#”能够匹配到“hls.sys.adaptor”,但是“hls.\*” 只会匹配到“hls.sys”。
融租易中,通过调用`IRabbitProducerService`接口中的`sendMessage(JSONObject json)`方法,来实现消息的发送
### 3.2 发送消息
注意:
融租易中,通过调用`IRabbitProducerService`接口中的`sendMessage(JSONObject json)`方法,来实现消息的发送
接口调用时必须使用spring中的注入方式。
注意:
json必须按照格式如:
接口调用时必须使用spring中的注入方式。
```json
{ json必须按照格式如:
"header":{
"orgCode":"hls", ```json
"apiName":"demoMQ", {
"sysCode":"fnd", "header":{
"routingKey":"hls", "orgCode":"hls",
"respCode":"sys", "apiName":"demoMQ",
"respMsg":"recived", "sysCode":"fnd",
"transDate":"Thu Jul 27 2017 10:47:17 GMT+0800 (CST)", "routingKey":"hls",
"transNo":"123" "respCode":"sys",
}, "respMsg":"recived",
"busiData":{ "transDate":"Thu Jul 27 2017 10:47:17 GMT+0800 (CST)",
"contractId":1 "transNo":"123"
}, },
"securityInfo":{ "busiData":{
"userName":"hd001", "contractId":1
"userPassword":"123456" },
} "securityInfo":{
} "userName":"hd001",
``` "userPassword":"123456"
}
### 3.3 接收消息 }
```
融租易中对消息的接收进行了统一处理,只需要单独编写业务的实现类即可(此处必须实现IRabbitMessageConsumerService接口),消息会先被内部的消息监听接口统一处理,然后再根据消息中的apiName找到对应的接口实现类,调用其中的process方法。
### 3.3 接收消息
示例代码:
融租易中对消息的接收进行了统一处理,只需要单独编写业务的实现类即可(此处必须实现IRabbitMessageConsumerService接口),消息会先被内部的消息监听接口统一处理,然后再根据消息中的apiName找到对应的接口实现类,调用其中的process方法。
```java
@Service 示例代码:
public class ConsumerDemoServiceImpl implements IRabbitMessageConsumerService {
```java
@Autowired(required = false) @Service
private IRabbitProducerService iRabbitProducerService;//消息发送类 public class ConsumerDemoServiceImpl implements IRabbitMessageConsumerService {
@Autowired
private IXXXService service;//业务类 @Autowired(required = false)
private IRabbitProducerService iRabbitProducerService;//消息发送类
@Override @Autowired
public String getApiName() { private IXXXService service;//业务类
return "demoMQ";
} @Override
public String getApiName() {
@Override return "demoMQ";
public void process(JSONObject json) { }
//业务处理
service.doSomething(json) @Override
//返回消息 public void process(JSONObject json) {
ResponseInfo responseInfo = null; //业务处理
try { service.doSomething(json)
responseInfo = RabbitMQUtils.getResposeInfo(json); //返回消息
} catch (ParseException e) { ResponseInfo responseInfo = null;
e.printStackTrace(); try {
} responseInfo = RabbitMQUtils.getResposeInfo(json);
} catch (ParseException e) {
JSONObject respose= new JSONObject().fromObject(responseInfo); e.printStackTrace();
}
iRabbitProducerService.sendMessage(respose);
JSONObject respose= new JSONObject().fromObject(responseInfo);
}
} iRabbitProducerService.sendMessage(respose);
```
}
### }
```
###
...@@ -40,14 +40,14 @@ ...@@ -40,14 +40,14 @@
#### 2.3 任务类的编写 #### 2.3 任务类的编写
想要自定义一个job,必须要继承一个抽象类AbstractJob,然后在`safeExecute()`方法中执行业务代码,示例代码如下: 想要自定义一个job,必须要继承一个抽象类AbstractJob或者AbstractJobWithIRequest,然后在`safeExecute()`方法中执行业务代码,示例代码如下:
```java ```java
public class demoJob extends AbstractJob{ public class demoJob extends AbstractJob{
@Autowired @Autowired
private xxxService service;//业务类 private xxxService service;//业务类
@Override @Override
public void safeExecute(JobExecutionContext jobExecutionContext) throws Exception { public void safeExecuteWithIRequest(JobExecutionContext jobExecutionContext) throws Exception {
//map中可以获取上方定义的参数,key为参数名称,value为参数值 //map中可以获取上方定义的参数,key为参数名称,value为参数值
JobDataMap map = jobExecutionContext.getMergedJobDataMap(); JobDataMap map = jobExecutionContext.getMergedJobDataMap();
try { try {
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
* II. 项目开发规范 * II. 项目开发规范
* [2.1 项目开发规范](/codeStyle.md#backEndDev) * [2.1 项目开发规范](/codeStyle.md#backEndDev)
* [2.2 编码规范](/codeStyle.md#backEndName)
* 2.3 Checkstyle * 2.3 Checkstyle
* III. 后端开发 * III. 后端开发
...@@ -35,6 +34,8 @@ ...@@ -35,6 +34,8 @@
* [4.2 字段级通用方法](/common-field-javascript.md) * [4.2 字段级通用方法](/common-field-javascript.md)
* [4.3 窗口级通用方法](/common-window-javascript.md) * [4.3 窗口级通用方法](/common-window-javascript.md)
* [4.4 锁屏和解屏通用方法](/common-mask-javascript.md) * [4.4 锁屏和解屏通用方法](/common-mask-javascript.md)
* [4.5 头行保存](/前端组件/头行保存.md)
* V. 前端UI开发 * V. 前端UI开发
...@@ -57,7 +58,7 @@ ...@@ -57,7 +58,7 @@
* [5.17 hlsGridBox\(表格\)](/前端组件/hlsGridBox.md) * [5.17 hlsGridBox\(表格\)](/前端组件/hlsGridBox.md)
* [5.18 hlsNumericTextBox\(数字框\)](/前端组件/hlsNumericTextBox.md) * [5.18 hlsNumericTextBox\(数字框\)](/前端组件/hlsNumericTextBox.md)
* [5.19 hlsNavigationBar\(导航栏\)](/前端组件/hlsNavigationBar.md) * [5.19 hlsNavigationBar\(导航栏\)](/前端组件/hlsNavigationBar.md)
* [5.20 头行保存](/前端组件/头行保存.md) * [5.20 hlsChart\(图表\)](/前端组件/hlsChart.md)
* VI. 框架功能描述 * VI. 框架功能描述
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment