Commit aea254fa authored by zydgitboox's avatar zydgitboox

Track 6 files into repository.

- untracked 前端组件/hlsCircularChart.md
- modified 前端组件/头行保存.md
- modified 后端开发/activiti_demo.md
- modified 后端开发/RabbitMq消息队列.md
- modified 框架功能描述/计划任务.md
- modified 融租易开发手册.md

Auto commit by GitBook Editor
parent 667c9c99
## hlsCircularChart(环状图)
使用方法:
```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 | 图表中各数据块的点击回调事件 |
\ No newline at end of file
......@@ -6,50 +6,75 @@
假设我们有两张表
**hls_person(头表)**
pid | name | age |
-------- | ----- | -----|
1|张三|21
2|李四|36
*hls_hobby(行表)**
hid | pid |hobby| cause|
-------- | -----|----- |-----|
1|1|篮球| 因为篮球好玩
2|1|游泳| 因为游泳好玩
3|1|动画片|最爱看大头儿子
4|2|画画|梵高的画也不过如此
| pid | name | age |
|:---: | :---: | :---: |
| 1 | 张三 | 21 |
| 2 | 李四| 36 |
**hls_hobby(行表)**
| hid | pid | hobby | cause |
|:---: | :---: | :---: | :---:|
| 1 | 1 | 篮球 |因为篮球好玩|
| 2 | 1| 游泳 | 因为游泳好玩|
| 3 | 1 |动画片 | 最爱看大头儿子|
| 4 | 2 |画画| 因为画画好玩|
需求是新增一个人的信息以及它的爱好(向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
<script><![CDATA[
//提交数据用到的容器
var viewModel = kendo.observable({
var viewModel = kendo.observable({
isEnabled: true,
data:{},
mySubmit:function(e){
if(e){
data: {},
mySubmit: function (e) {
if (e) {
e.preventDefault();
}
Hap.submitForm({
url : '${base.contextPath}/hls/test/save',
formModel : viewModel.data,
asArray:false,
grid: { "hobby": $("#grid")
url: '${base.contextPath}/hls/test/hdLnSave',
formModel: viewModel.data,
asArray: false,
grid: {
"hlsHobbyList": $("#grid")
},
success:function(){
showInfoDialog("保存成功!");
success: function () {
viewModel.showInfoDialog("保存成功!");
$('#grid').data('kendoGrid').dataSource.page(1);
},
error:function(){
viewModel.showInfoDialog("保存失败!");
}
});
},
function:showInfoDialog(pMessage){
showInfoDialog: function(pMessage)
{
kendo.ui.showInfoDialog({
title: $l('提示'),
message: pMessage
......@@ -57,7 +82,7 @@ var viewModel = kendo.observable({
}
});
});
//请求处理方法
function parameterMap(options, type){
......@@ -72,13 +97,9 @@ function parameterMap(options, type){
return kendo.stringify(datas);
} else if (type === "read") {
var map = {};
map.page = options.page;
map.pagesize = options.pageSize;
for (var k in map) {
if (map[k] === '' || map[k] === null || map[k] === undefined)
delete map[k]
}
return Hap.prepareQueryParameter(viewModel.model.toJSON(), options);
map.page = options.page || 1;
map.pagesize = options.pageSize|| 5;
return kendo.stringify(map);
}
}
......@@ -94,8 +115,8 @@ function dsEditable(field){
<!--头-->
<h:hlsForm title="个人信息" width="100%">
<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="age" id="age" bind="enabled: isEnabled, value:model.age" 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:data.age" colspan="3" prompt="年龄:" required="true" style="width:100%;"/>
</h:hlsHBox>
</h:hlsForm>
......@@ -103,9 +124,8 @@ function dsEditable(field){
<!--行-->
<h:dataSource id="dataSource" batch="true" pageSize="10" serverPaging="true">
<h:transport parameterMap="parameterMap">
<h:read url="${base.contextPath}/hls/test/query" type="GET" dataType="json"/>
<h:create url="${base.contextPath}/hls/test/create" type="POST" contentType="application/json" />
<h:update url="${base.contextPath}/hls/test/save" type="POST" contentType="application/json" />
<h:read url="${base.contextPath}/hls/test/ln/query" type="GET" dataType="json"/>
<h:destroy url="${base.contextPath}/hls/test/ln/remove" type="POST" contentType="application/json" />
</h:transport>
<h:schema data="rows" total="total" errors="schemaError">
<h:model id="pid" editable="dsEditable">
......@@ -133,50 +153,116 @@ function dsEditable(field){
<!--按钮-->
<h:hlsToolBar>
<h:hlsButton click="mySubmit" text="保存"></h:hlsButton>
<h:hlsButton click="viewModel.mySubmit" text="保存"></h:hlsButton>
</h:hlsToolBar>
```
#### 后台
保存按钮注册了点了事件,点击保存将数据提交到'${base.contextPath}/hls/test/hdLnSave'
保存按钮注册了点了事件,点击保存将数据提交到'${base.contextPath}/hls/test/save'
> 在后端controller通过定义 @RequestMapping("/hls/test/save") 注解映射到对应的url,捕获到对应请求。
> 在后端controller通过定义 @RequestMapping("/hls/test/hdLnSave") 注解映射到对应的url,捕获到对应请求。
后端收到前台传过来的数据,调用service层对数据进行持久化。
controller
HlsTESTController.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
public ResponseData hdQuery(final HlsPerson hlsPerson, @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(hlsPersonService.select(requestContext,hlsPerson,page,pagesize));
}
@RequestMapping(value="/hls/test/hdLnSave",method=RequestMethod.POST)
@ResponseBody
public ResponseData save(HttpServletRequest request,@RequestBody HlsPerson hlsPerson, @RequestParam(defaultValue = DEFAULT_PAGE) final int page,
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);
testService.batchChildUpdate(iRequest, hlsPerson ,hlsPerson.getHlsHobby());
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));
}
@RequestMapping(value="/hls/test/ln/remove",method=RequestMethod.POST)
@ResponseBody
public ResponseData delete(HttpServletRequest request, @RequestBody List<HlsHobby> hlsHobbyList) {
hlsHobbyService.batchDelete(hlsHobbyList);
return new ResponseData();
}
}
```
> **提示:**
>* 通常头行结构还会涉及对头行数据的删和查,根据需要在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);
}
```
testService的实现类testServiceImpl定义了batchChildUpdate方法:
接口实现类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, List<HlsHobby> hlsHobbyList) {
List<HlsPerson> tempHlsPerson = new ArrayList<HlsPerson>();
public void batchChildUpdate(IRequest iRequest, HlsPerson hlsPerson) {
if(hlsPerson != null ){
hlsPerson.set__status("add");
List<HlsPerson> tempHlsPerson = new ArrayList<HlsPerson>();
tempHlsPerson.add(hlsPerson);
hlsPersonService.batchUpdate(iRequest,tempHlsPerson);
Long pid = tempHlsPerson.get(0).getPid();
self().batchUpdate(iRequest,tempHlsPerson);
Long pid = hlsPerson.getPid();
List<HlsHobby> hlsHobbyList = hlsPerson.getHlsHobbyList();
for(HlsHobby hh : hlsHobbyList){
hh.setPid(pid);
}
hlsHobbyService.batchUpdate(iRequest,hlsHobbyList);
}
}
}
}
```
> bathUpdate会根据传入的List对象中单个对象的属性值__status判断,如为update即做更新操作,add为插入操作, __status的值由前端paramter函数决定。
\ No newline at end of file
......@@ -22,7 +22,8 @@ RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种
### 2.1 定义交换机
在接口管理的消息队列定义模块中,首先进行交换机的定义,界面如图:![](/assets/exchange.png)注意:
在接口管理的消息队列定义模块中,首先进行交换机的定义,界面如图:![](/assets/exchange.png)
注意:
交换机名称不可以重复定义,一个交换机可以对应多个队列。
......@@ -34,7 +35,9 @@ RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种
### 2.2 定义队列和路由键
定义完交换机后,你还需要定义你的队列和相应的匹配模式(既路由键)界面如图:![](/assets/queue.png)注意:
定义完交换机后,你还需要定义你的队列和相应的匹配模式(既路由键)界面如图:![](/assets/queue.png)
注意:
队列名称不可以重复,但是一个队列可以对应多个交换机。
......@@ -137,3 +140,6 @@ public class ConsumerDemoServiceImpl implements IRabbitMessageConsumerService {
```
###
# 工作流demo
# 工作流开发指南
整体流程
* 打开工作流模块,设计工作流流程
* 实现一个当前功能启动工作流的接口
* 在自己的业务层调用自己实现的工作流
一、工作流开发整体思路
* 流程设计
* 实现启动接口
* 调用实现
* 启动工作流
二、流程设计
1 新建工作流并填写对应的信息
![](/assets/wfl_demo_1.png)
![](/assets/wfl_demo_2.png)
2 编辑对应的审批节点链,可参考已实现的工作流程
*这里需要注意分类跟唯一标识这个字段,后面编写实现类的时候需要传入分类跟唯一标识。
2 保存之后点击对应工作流的第一个图标,即可编辑对应的工作流节点,下面将详细介绍一些常用的工作流属性(新建工作流的时候可参考已实现工作流)
* ID:自动生成,节点唯一标识
* 名称:当前节点中文描述
* 文档:消息机制,可在上下文中取到,如:我是${name},name为实现类里面配置的参数
* 审批方式:默认为全部通过
* 审批方式变量:当审批方式选择一定比例时,可设置变量如0.4,表示当审批人数达到这个比例后将会通过
* 审批规则:选择对应的审批人,可在审批规则中定义
* 加签:若勾选,则当前审批者可添加审批人
* 表单url:表示审批流程中可插入的页面,能让审判者读阅
* 执行监听器:执行监听器start跟end两种分别代表在该节点之前跟在该节点之后,在代理表达式里面可调用对应自己写的java类,格式如下:${endActionEventTask}
* 任务监听器:任务监听器可参考执行监听器
下图是一个完整的工作流流程设计
![](/assets/wfl_demo_3.png)
3 编写一个自己的实现类,实现IActivitiCommonService接口
二、实现启动接口
* 编写一个自己的实现类,实现IActivitiCommonService接口
![](/assets/wfl_demo_4.png)
......@@ -22,88 +42,88 @@
实现类代码如下
```java
package hls.core.wfl.service.impl;
import com.hand.hap.activiti.dto.ReProcdef;
import com.hand.hap.activiti.service.IActivitiService;
import com.hand.hap.activiti.service.IReProcdefService;
import com.hand.hap.core.IRequest;
import hls.core.prj.dto.PrjProject;
import hls.core.prj.dto.PrjProjectMeeting;
import hls.core.prj.mapper.PrjProjectMeetingMapper;
import hls.core.prj.service.PrjProjectService;
import hls.core.wfl.service.IActivitiCommonService;
import net.sf.json.JSONObject;
import org.activiti.rest.service.api.engine.variable.RestVariable;
import org.activiti.rest.service.api.runtime.process.ProcessInstanceCreateRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;import java.util.List;
import java.util.Map;
@Service
@Transactional
public class PrjActivitStartServiceImpl implements IActivitiCommonService
{
private static final String workFlowType = "PRJ_PROJECT"; @Autowired
private IActivitiService activitiService;
@Autowired
private IReProcdefService reProcdefService;
@Autowired
private PrjProjectService projectService;
@Autowired
private PrjProjectMeetingMapper meetingMapper;
@Override
public String getWorkFlowType() { return workFlowType; }
@Override
public void process(IRequest iRequest, List list, Map params)
{
private static final String workFlowType = "PRJ_PROJECT";
@Autowired
private IActivitiService activitiService;
@Autowired
private IReProcdefService reProcdefService;
@Autowired
private PrjProjectService projectService;
@Autowired
private PrjProjectMeetingMapper meetingMapper;
@Override
public String getWorkFlowType() { return workFlowType; }
@Override
public void process(IRequest iRequest, List list, Map params)
{
ProcessInstanceCreateRequest processInstanceCreateRequest = getProcessInstanceCreateRequest((PrjProject)list.get(0),iRequest);
activitiService.startProcess(iRequest, processInstanceCreateRequest);
}
private ProcessInstanceCreateRequest getProcessInstanceCreateRequest(PrjProject prjProject, IRequest iRequest)
{
ProcessInstanceCreateRequest createRequest = new ProcessInstanceCreateRequest();
{
ProcessInstanceCreateRequest createRequest = new ProcessInstanceCreateRequest();
PrjProject project=projectService.selectByPrimaryKey(iRequest,prjProject); ReProcdef reProcdefs ;
reProcdefs = reProcdefService.queryReProcdef("PRJ_PROJECT_APPROVE","PRJ_PROJECT");
String id = reProcdefs.getId_();
String name = reProcdefs.getName_(); createRequest.setProcessDefinitionId(id); createRequest.setBusinessKey(prjProject.getProjectId().toString());
List<RestVariable> variables = new ArrayList<RestVariable>(); List<RestVariable> transientVariables = new ArrayList<RestVariable>();
reProcdefs = reProcdefService.queryReProcdef("PRJ_PROJECT_APPROVE","PRJ_PROJECT");
String id = reProcdefs.getId_();
String name = reProcdefs.getName_(); createRequest.setProcessDefinitionId(id);
createRequest.setBusinessKey(prjProject.getProjectId().toString());
List<RestVariable> variables = new ArrayList<RestVariable>(); List<RestVariable> transientVariables = new ArrayList<RestVariable>();
RestVariable restVariable1 = new RestVariable(); RestVariable restVariable2 = new RestVariable();
RestVariable restVariable3 = new RestVariable();
RestVariable restVariable4 = new RestVariable();
RestVariable restVariable3 = new RestVariable();
RestVariable restVariable4 = new RestVariable();
RestVariable restVariable5 = new RestVariable();
RestVariable restVariable6 = new RestVariable();
restVariable1.setName("processDefinitionId");
restVariable1.setValue(id); variables.add(restVariable1);
restVariable2.setName("prjProject");
JSONObject jsonObject= new JSONObject().fromObject(prjProject); restVariable2.setValue(jsonObject.toString()); variables.add(restVariable2);
restVariable3.setName("iRequest"); restVariable3.setValue(iRequest);
variables.add(restVariable3);
restVariable4.setName("projectNum"); restVariable4.setValue(project.getProjectNumber()); variables.add(restVariable4); restVariable5.setName("projectName"); restVariable5.setValue(project.getProjectName()); variables.add(restVariable5); restVariable6.setName("startUserName"); restVariable6.setValue(iRequest.getEmployeeCode()); variables.add(restVariable6);
RestVariable restVariable6 = new RestVariable();
restVariable1.setName("processDefinitionId");
restVariable1.setValue(id); variables.add(restVariable1);
restVariable2.setName("prjProject");
JSONObject jsonObject= new JSONObject().fromObject(prjProject); restVariable2.setValue(jsonObject.toString());
variables.add(restVariable2);
restVariable3.setName("iRequest"); restVariable3.setValue(iRequest);
variables.add(restVariable3);
restVariable4.setName("projectNum"); restVariable4.setValue(project.getProjectNumber()); variables.add(restVariable4);
restVariable5.setName("projectName"); restVariable5.setValue(project.getProjectName()); variables.add(restVariable5);
restVariable6.setName("startUserName"); restVariable6.setValue(iRequest.getEmployeeCode()); variables.add(restVariable6);
RestVariable restVariable7 = new RestVariable();
RestVariable restVariable8 = new RestVariable(); RestVariable restVariable9 = new RestVariable(); restVariable7.setName("documentCategory"); restVariable7.setValue(project.getDocumentCategory()); variables.add(restVariable7); restVariable8.setName("documentType"); restVariable8.setValue(project.getDocumentType());
variables.add(restVariable8); restVariable9.setName("documentId"); restVariable9.setValue(project.getProjectId());
variables.add(restVariable9);
RestVariable restVariable8 = new RestVariable(); RestVariable restVariable9 = new RestVariable();
restVariable7.setName("documentCategory"); restVariable7.setValue(project.getDocumentCategory()); variables.add(restVariable7);
restVariable8.setName("documentType"); restVariable8.setValue(project.getDocumentType());
variables.add(restVariable8); restVariable9.setName("documentId"); restVariable9.setValue(project.getProjectId());
variables.add(restVariable9);
RestVariable restVariable10 = new RestVariable();
restVariable10.setName("doubleFlag");
restVariable10.setName("doubleFlag");
PrjProjectMeeting meeting = new PrjProjectMeeting();
meeting.setProjectId(prjProject.getProjectId());
List<PrjProjectMeeting> list = meetingMapper.select(meeting); if(list.size() >0) { restVariable10.setValue("Y"); }else{ restVariable10.setValue("N"); }
meeting.setProjectId(prjProject.getProjectId());
List<PrjProjectMeeting> list = meetingMapper.select(meeting); if(list.size() >0) { restVariable10.setValue("Y"); }else{
restVariable10.setValue("N"); }
variables.add(restVariable10);
RestVariable restVariable11 = new RestVariable(); restVariable11.setName("pName");
restVariable11.setValue(name);
restVariable11.setValue(name);
variables.add(restVariable11); createRequest.setVariables(variables); createRequest.setTransientVariables(transientVariables);
return createRequest;
}}
```
4 启动工作流
* 关键参数讲解:
private static final String workFlowType = "PRJ_PROJECT";在启动工作流的时候工作流会根据这个类型找到对应的实现类,
在启动工作流的时候会调用process方法,该方法会调用getProcessInstanceCreateRequest方法,在getProcessInstanceCreateRequest方法里面
可以将自己工作流所需参数都放到里面去,可以在后面的流程中取到自己所需参数。
reProcdefs = reProcdefService.queryReProcdef("PRJ_PROJECT_APPROVE","PRJ_PROJECT");参数一为创建工作流时候的唯一标志,参数二为工作流的分类
三 调用实现类并启动工作流
```
Map<String,Object> params = new HashMap<String,Object>();
params.put("workFlowType","PRJ_PROJECT");
activitiStartService.start(iRequest,projects,params);
```
* 代码解析
params.put("workFlowType","PRJ_PROJECT");放入的为工作流实现类的类型
......@@ -40,14 +40,14 @@
#### 2.3 任务类的编写
想要自定义一个job,必须要继承一个抽象类AbstractJob,然后在`safeExecute()`方法中执行业务代码,示例代码如下:
想要自定义一个job,必须要继承一个抽象类AbstractJob或者AbstractJobWithIRequest,然后在`safeExecute()`方法中执行业务代码,示例代码如下:
```java
public class demoJob extends AbstractJob{
@Autowired
private xxxService service;//业务类
@Override
public void safeExecute(JobExecutionContext jobExecutionContext) throws Exception {
public void safeExecuteWithIRequest(JobExecutionContext jobExecutionContext) throws Exception {
//map中可以获取上方定义的参数,key为参数名称,value为参数值
JobDataMap map = jobExecutionContext.getMergedJobDataMap();
try {
......
......@@ -35,6 +35,8 @@
* [4.2 字段级通用方法](/common-field-javascript.md)
* [4.3 窗口级通用方法](/common-window-javascript.md)
* [4.4 锁屏和解屏通用方法](/common-mask-javascript.md)
* [4.5 头行保存](/前端组件/头行保存.md)
* V. 前端UI开发
......@@ -66,10 +68,7 @@
* [6.4 合同文本生成](/框架功能描述/docx4j.md)
* [6.5 Excel导入导出](/框架功能描述/jad.md)
* [6.6 redis安装和部署](/后端开发/redis.md)
* [6.7 工作流功能说明](/后端开发/activiti-helper.md)
* [6.8 工作流开发指南](/后端开发/activiti.md)
* [6.9 工作流demo](/后端开发/activiti_demo.md)
* [6.10 流程设计](/后端开发/activiti_editor_helper.md)
* [6.9 工作流开发指南](/后端开发/activiti_demo.md)
......
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