Commit 3d08514e by naan1993

增加审批流程管理

parent 5e6533a4
...@@ -10,7 +10,7 @@ Target Server Type : MYSQL ...@@ -10,7 +10,7 @@ Target Server Type : MYSQL
Target Server Version : 50621 Target Server Version : 50621
File Encoding : 65001 File Encoding : 65001
Date: 2017-07-11 22:39:28 Date: 2017-12-05 22:56:40
*/ */
SET FOREIGN_KEY_CHECKS=0; SET FOREIGN_KEY_CHECKS=0;
...@@ -29,7 +29,7 @@ CREATE TABLE `dept` ( ...@@ -29,7 +29,7 @@ CREATE TABLE `dept` (
`tips` varchar(255) DEFAULT NULL COMMENT '提示', `tips` varchar(255) DEFAULT NULL COMMENT '提示',
`version` int(11) DEFAULT NULL COMMENT '版本(乐观锁保留字段)', `version` int(11) DEFAULT NULL COMMENT '版本(乐观锁保留字段)',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8 COMMENT='部门表'; ) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='部门表';
-- ---------------------------- -- ----------------------------
-- Records of dept -- Records of dept
...@@ -67,6 +67,28 @@ INSERT INTO `dict` VALUES ('37', '2', '35', '冻结', null); ...@@ -67,6 +67,28 @@ INSERT INTO `dict` VALUES ('37', '2', '35', '冻结', null);
INSERT INTO `dict` VALUES ('38', '3', '35', '已删除', null); INSERT INTO `dict` VALUES ('38', '3', '35', '已删除', null);
-- ---------------------------- -- ----------------------------
-- Table structure for expense
-- ----------------------------
DROP TABLE IF EXISTS `expense`;
CREATE TABLE `expense` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`money` decimal(20,2) DEFAULT NULL COMMENT '报销金额',
`desc` varchar(255) DEFAULT '' COMMENT '描述',
`createtime` datetime DEFAULT CURRENT_TIMESTAMP,
`state` int(11) DEFAULT NULL COMMENT '状态: 1.待提交 2:待审核 3.审核通过 4:驳回',
`userid` int(11) DEFAULT NULL COMMENT '用户id',
`processId` varchar(255) DEFAULT NULL COMMENT '流程定义id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8 COMMENT='报销表';
-- ----------------------------
-- Records of expense
-- ----------------------------
INSERT INTO `expense` VALUES ('20', '100.00', '餐饮', '2017-12-05 22:52:48', '3', '1', '92501');
INSERT INTO `expense` VALUES ('21', '700.00', '住宿费', '2017-12-05 22:53:22', '3', '1', '92517');
INSERT INTO `expense` VALUES ('22', '100.00', '测试', '2017-12-05 22:53:56', '3', '1', '92533');
-- ----------------------------
-- Table structure for login_log -- Table structure for login_log
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `login_log`; DROP TABLE IF EXISTS `login_log`;
...@@ -79,15 +101,12 @@ CREATE TABLE `login_log` ( ...@@ -79,15 +101,12 @@ CREATE TABLE `login_log` (
`message` text COMMENT '具体消息', `message` text COMMENT '具体消息',
`ip` varchar(255) DEFAULT NULL COMMENT '登录ip', `ip` varchar(255) DEFAULT NULL COMMENT '登录ip',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=130 DEFAULT CHARSET=utf8 COMMENT='登录记录'; ) ENGINE=InnoDB AUTO_INCREMENT=214 DEFAULT CHARSET=utf8 COMMENT='登录记录';
-- ---------------------------- -- ----------------------------
-- Records of login_log -- Records of login_log
-- ---------------------------- -- ----------------------------
INSERT INTO `login_log` VALUES ('126', '退出日志', '1', '2017-06-04 10:21:55', '成功', null, '127.0.0.1'); INSERT INTO `login_log` VALUES ('213', '退出日志', '1', '2017-12-05 22:56:32', '成功', null, '0:0:0:0:0:0:0:1');
INSERT INTO `login_log` VALUES ('127', '登录日志', '1', '2017-06-04 10:21:59', '成功', null, '127.0.0.1');
INSERT INTO `login_log` VALUES ('128', '退出日志', '1', '2017-06-04 10:22:59', '成功', null, '127.0.0.1');
INSERT INTO `login_log` VALUES ('129', '登录日志', '1', '2017-06-04 10:23:01', '成功', null, '127.0.0.1');
-- ---------------------------- -- ----------------------------
-- Table structure for menu -- Table structure for menu
...@@ -108,7 +127,7 @@ CREATE TABLE `menu` ( ...@@ -108,7 +127,7 @@ CREATE TABLE `menu` (
`status` int(65) DEFAULT NULL COMMENT '菜单状态 : 1:启用 0:不启用', `status` int(65) DEFAULT NULL COMMENT '菜单状态 : 1:启用 0:不启用',
`isopen` int(11) DEFAULT NULL COMMENT '是否打开: 1:打开 0:不打开', `isopen` int(11) DEFAULT NULL COMMENT '是否打开: 1:打开 0:不打开',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=168 DEFAULT CHARSET=utf8 COMMENT='菜单表'; ) ENGINE=InnoDB AUTO_INCREMENT=171 DEFAULT CHARSET=utf8 COMMENT='菜单表';
-- ---------------------------- -- ----------------------------
-- Records of menu -- Records of menu
...@@ -168,6 +187,9 @@ INSERT INTO `menu` VALUES ('164', 'role_list', 'role', '[0],[system],[role],', ' ...@@ -168,6 +187,9 @@ INSERT INTO `menu` VALUES ('164', 'role_list', 'role', '[0],[system],[role],', '
INSERT INTO `menu` VALUES ('165', 'to_assign_role', 'mgr', '[0],[system],[mgr],', '分配角色跳转', '', '/mgr/role_assign', '8', '3', '0', null, '1', null); INSERT INTO `menu` VALUES ('165', 'to_assign_role', 'mgr', '[0],[system],[mgr],', '分配角色跳转', '', '/mgr/role_assign', '8', '3', '0', null, '1', null);
INSERT INTO `menu` VALUES ('166', 'to_user_edit', 'mgr', '[0],[system],[mgr],', '编辑用户跳转', '', '/mgr/user_edit', '9', '3', '0', null, '1', null); INSERT INTO `menu` VALUES ('166', 'to_user_edit', 'mgr', '[0],[system],[mgr],', '编辑用户跳转', '', '/mgr/user_edit', '9', '3', '0', null, '1', null);
INSERT INTO `menu` VALUES ('167', 'mgr_list', 'mgr', '[0],[system],[mgr],', '用户列表', '', '/mgr/list', '10', '3', '0', null, '1', null); INSERT INTO `menu` VALUES ('167', 'mgr_list', 'mgr', '[0],[system],[mgr],', '用户列表', '', '/mgr/list', '10', '3', '0', null, '1', null);
INSERT INTO `menu` VALUES ('168', 'expense', '0', '[0],', '报销管理', 'fa-clone', '#', '4', '1', '1', null, '1', null);
INSERT INTO `menu` VALUES ('169', 'expense_fill', 'expense', '[0],[expense],', '报销申请', '', '/expense', '1', '2', '1', null, '1', null);
INSERT INTO `menu` VALUES ('170', 'expense_progress', 'expense', '[0],[expense],', '报销审批', '', '/process', '2', '2', '1', null, '1', null);
-- ---------------------------- -- ----------------------------
-- Table structure for notice -- Table structure for notice
...@@ -181,7 +203,7 @@ CREATE TABLE `notice` ( ...@@ -181,7 +203,7 @@ CREATE TABLE `notice` (
`createtime` datetime DEFAULT NULL COMMENT '创建时间', `createtime` datetime DEFAULT NULL COMMENT '创建时间',
`creater` int(11) DEFAULT NULL COMMENT '创建人', `creater` int(11) DEFAULT NULL COMMENT '创建人',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COMMENT='通知表'; ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COMMENT='通知表';
-- ---------------------------- -- ----------------------------
-- Records of notice -- Records of notice
...@@ -204,14 +226,13 @@ CREATE TABLE `operation_log` ( ...@@ -204,14 +226,13 @@ CREATE TABLE `operation_log` (
`succeed` varchar(255) DEFAULT NULL COMMENT '是否成功', `succeed` varchar(255) DEFAULT NULL COMMENT '是否成功',
`message` text COMMENT '备注', `message` text COMMENT '备注',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=483 DEFAULT CHARSET=utf8 COMMENT='操作日志'; ) ENGINE=InnoDB AUTO_INCREMENT=540 DEFAULT CHARSET=utf8 COMMENT='操作日志';
-- ---------------------------- -- ----------------------------
-- Records of operation_log -- Records of operation_log
-- ---------------------------- -- ----------------------------
INSERT INTO `operation_log` VALUES ('480', '业务日志', '清空业务日志', '1', 'com.stylefeng.guns.modular.system.controller.LogController', 'delLog', '2017-06-03 23:04:22', '成功', '主键id=null'); INSERT INTO `operation_log` VALUES ('538', '业务日志', '清空业务日志', '1', 'com.stylefeng.guns.modular.system.controller.LogController', 'delLog', '2017-12-05 22:56:25', '成功', '主键id=null');
INSERT INTO `operation_log` VALUES ('481', '业务日志', '清空登录日志', '1', 'com.stylefeng.guns.modular.system.controller.LoginLogController', 'delLog', '2017-06-03 23:04:25', '成功', '主键id=null'); INSERT INTO `operation_log` VALUES ('539', '业务日志', '清空登录日志', '1', 'com.stylefeng.guns.modular.system.controller.LoginLogController', 'delLog', '2017-12-05 22:56:28', '成功', '主键id=null');
INSERT INTO `operation_log` VALUES ('482', '业务日志', '修改菜单', '1', 'com.stylefeng.guns.modular.system.controller.MenuController', 'edit', '2017-06-04 10:22:58', '成功', '菜单名称=分配角色跳转;;;字段名称:url地址,旧值:/role/role_assign,新值:/mgr/role_assign');
-- ---------------------------- -- ----------------------------
-- Table structure for relation -- Table structure for relation
...@@ -222,7 +243,7 @@ CREATE TABLE `relation` ( ...@@ -222,7 +243,7 @@ CREATE TABLE `relation` (
`menuid` int(11) DEFAULT NULL COMMENT '菜单id', `menuid` int(11) DEFAULT NULL COMMENT '菜单id',
`roleid` int(11) DEFAULT NULL COMMENT '角色id', `roleid` int(11) DEFAULT NULL COMMENT '角色id',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3679 DEFAULT CHARSET=utf8 COMMENT='角色和菜单关联表'; ) ENGINE=InnoDB AUTO_INCREMENT=3737 DEFAULT CHARSET=utf8 COMMENT='角色和菜单关联表';
-- ---------------------------- -- ----------------------------
-- Records of relation -- Records of relation
...@@ -247,61 +268,64 @@ INSERT INTO `relation` VALUES ('3393', '121', '5'); ...@@ -247,61 +268,64 @@ INSERT INTO `relation` VALUES ('3393', '121', '5');
INSERT INTO `relation` VALUES ('3394', '122', '5'); INSERT INTO `relation` VALUES ('3394', '122', '5');
INSERT INTO `relation` VALUES ('3395', '150', '5'); INSERT INTO `relation` VALUES ('3395', '150', '5');
INSERT INTO `relation` VALUES ('3396', '151', '5'); INSERT INTO `relation` VALUES ('3396', '151', '5');
INSERT INTO `relation` VALUES ('3624', '105', '1'); INSERT INTO `relation` VALUES ('3679', '105', '1');
INSERT INTO `relation` VALUES ('3625', '106', '1'); INSERT INTO `relation` VALUES ('3680', '106', '1');
INSERT INTO `relation` VALUES ('3626', '107', '1'); INSERT INTO `relation` VALUES ('3681', '107', '1');
INSERT INTO `relation` VALUES ('3627', '108', '1'); INSERT INTO `relation` VALUES ('3682', '108', '1');
INSERT INTO `relation` VALUES ('3628', '109', '1'); INSERT INTO `relation` VALUES ('3683', '109', '1');
INSERT INTO `relation` VALUES ('3629', '110', '1'); INSERT INTO `relation` VALUES ('3684', '110', '1');
INSERT INTO `relation` VALUES ('3630', '111', '1'); INSERT INTO `relation` VALUES ('3685', '111', '1');
INSERT INTO `relation` VALUES ('3631', '112', '1'); INSERT INTO `relation` VALUES ('3686', '112', '1');
INSERT INTO `relation` VALUES ('3632', '113', '1'); INSERT INTO `relation` VALUES ('3687', '113', '1');
INSERT INTO `relation` VALUES ('3633', '165', '1'); INSERT INTO `relation` VALUES ('3688', '165', '1');
INSERT INTO `relation` VALUES ('3634', '166', '1'); INSERT INTO `relation` VALUES ('3689', '166', '1');
INSERT INTO `relation` VALUES ('3635', '167', '1'); INSERT INTO `relation` VALUES ('3690', '167', '1');
INSERT INTO `relation` VALUES ('3636', '114', '1'); INSERT INTO `relation` VALUES ('3691', '114', '1');
INSERT INTO `relation` VALUES ('3637', '115', '1'); INSERT INTO `relation` VALUES ('3692', '115', '1');
INSERT INTO `relation` VALUES ('3638', '116', '1'); INSERT INTO `relation` VALUES ('3693', '116', '1');
INSERT INTO `relation` VALUES ('3639', '117', '1'); INSERT INTO `relation` VALUES ('3694', '117', '1');
INSERT INTO `relation` VALUES ('3640', '118', '1'); INSERT INTO `relation` VALUES ('3695', '118', '1');
INSERT INTO `relation` VALUES ('3641', '162', '1'); INSERT INTO `relation` VALUES ('3696', '162', '1');
INSERT INTO `relation` VALUES ('3642', '163', '1'); INSERT INTO `relation` VALUES ('3697', '163', '1');
INSERT INTO `relation` VALUES ('3643', '164', '1'); INSERT INTO `relation` VALUES ('3698', '164', '1');
INSERT INTO `relation` VALUES ('3644', '119', '1'); INSERT INTO `relation` VALUES ('3699', '119', '1');
INSERT INTO `relation` VALUES ('3645', '120', '1'); INSERT INTO `relation` VALUES ('3700', '120', '1');
INSERT INTO `relation` VALUES ('3646', '121', '1'); INSERT INTO `relation` VALUES ('3701', '121', '1');
INSERT INTO `relation` VALUES ('3647', '122', '1'); INSERT INTO `relation` VALUES ('3702', '122', '1');
INSERT INTO `relation` VALUES ('3648', '150', '1'); INSERT INTO `relation` VALUES ('3703', '150', '1');
INSERT INTO `relation` VALUES ('3649', '151', '1'); INSERT INTO `relation` VALUES ('3704', '151', '1');
INSERT INTO `relation` VALUES ('3650', '128', '1'); INSERT INTO `relation` VALUES ('3705', '128', '1');
INSERT INTO `relation` VALUES ('3651', '134', '1'); INSERT INTO `relation` VALUES ('3706', '134', '1');
INSERT INTO `relation` VALUES ('3652', '158', '1'); INSERT INTO `relation` VALUES ('3707', '158', '1');
INSERT INTO `relation` VALUES ('3653', '159', '1'); INSERT INTO `relation` VALUES ('3708', '159', '1');
INSERT INTO `relation` VALUES ('3654', '130', '1'); INSERT INTO `relation` VALUES ('3709', '130', '1');
INSERT INTO `relation` VALUES ('3655', '131', '1'); INSERT INTO `relation` VALUES ('3710', '131', '1');
INSERT INTO `relation` VALUES ('3656', '135', '1'); INSERT INTO `relation` VALUES ('3711', '135', '1');
INSERT INTO `relation` VALUES ('3657', '136', '1'); INSERT INTO `relation` VALUES ('3712', '136', '1');
INSERT INTO `relation` VALUES ('3658', '137', '1'); INSERT INTO `relation` VALUES ('3713', '137', '1');
INSERT INTO `relation` VALUES ('3659', '152', '1'); INSERT INTO `relation` VALUES ('3714', '152', '1');
INSERT INTO `relation` VALUES ('3660', '153', '1'); INSERT INTO `relation` VALUES ('3715', '153', '1');
INSERT INTO `relation` VALUES ('3661', '154', '1'); INSERT INTO `relation` VALUES ('3716', '154', '1');
INSERT INTO `relation` VALUES ('3662', '132', '1'); INSERT INTO `relation` VALUES ('3717', '132', '1');
INSERT INTO `relation` VALUES ('3663', '138', '1'); INSERT INTO `relation` VALUES ('3718', '138', '1');
INSERT INTO `relation` VALUES ('3664', '139', '1'); INSERT INTO `relation` VALUES ('3719', '139', '1');
INSERT INTO `relation` VALUES ('3665', '140', '1'); INSERT INTO `relation` VALUES ('3720', '140', '1');
INSERT INTO `relation` VALUES ('3666', '155', '1'); INSERT INTO `relation` VALUES ('3721', '155', '1');
INSERT INTO `relation` VALUES ('3667', '156', '1'); INSERT INTO `relation` VALUES ('3722', '156', '1');
INSERT INTO `relation` VALUES ('3668', '157', '1'); INSERT INTO `relation` VALUES ('3723', '157', '1');
INSERT INTO `relation` VALUES ('3669', '133', '1'); INSERT INTO `relation` VALUES ('3724', '133', '1');
INSERT INTO `relation` VALUES ('3670', '160', '1'); INSERT INTO `relation` VALUES ('3725', '160', '1');
INSERT INTO `relation` VALUES ('3671', '161', '1'); INSERT INTO `relation` VALUES ('3726', '161', '1');
INSERT INTO `relation` VALUES ('3672', '141', '1'); INSERT INTO `relation` VALUES ('3727', '141', '1');
INSERT INTO `relation` VALUES ('3673', '142', '1'); INSERT INTO `relation` VALUES ('3728', '142', '1');
INSERT INTO `relation` VALUES ('3674', '143', '1'); INSERT INTO `relation` VALUES ('3729', '143', '1');
INSERT INTO `relation` VALUES ('3675', '144', '1'); INSERT INTO `relation` VALUES ('3730', '144', '1');
INSERT INTO `relation` VALUES ('3676', '148', '1'); INSERT INTO `relation` VALUES ('3731', '148', '1');
INSERT INTO `relation` VALUES ('3677', '145', '1'); INSERT INTO `relation` VALUES ('3732', '145', '1');
INSERT INTO `relation` VALUES ('3678', '149', '1'); INSERT INTO `relation` VALUES ('3733', '149', '1');
INSERT INTO `relation` VALUES ('3734', '168', '1');
INSERT INTO `relation` VALUES ('3735', '169', '1');
INSERT INTO `relation` VALUES ('3736', '170', '1');
-- ---------------------------- -- ----------------------------
-- Table structure for role -- Table structure for role
...@@ -360,10 +384,12 @@ CREATE TABLE `user` ( ...@@ -360,10 +384,12 @@ CREATE TABLE `user` (
`createtime` datetime DEFAULT NULL COMMENT '创建时间', `createtime` datetime DEFAULT NULL COMMENT '创建时间',
`version` int(11) DEFAULT NULL COMMENT '保留字段', `version` int(11) DEFAULT NULL COMMENT '保留字段',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8 COMMENT='管理员表'; ) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8 COMMENT='管理员表';
-- ---------------------------- -- ----------------------------
-- Records of user -- Records of user
-- ---------------------------- -- ----------------------------
INSERT INTO `user` VALUES ('1', 'girl.gif', 'admin', 'ecfadcde9305f8891bcfe5a1e28c253e', '8pgby', '张三', '2017-05-05 00:00:00', '2', 'sn93@qq.com', '18200000000', '1', '27', '1', '2016-01-29 08:49:53', '25'); INSERT INTO `user` VALUES ('1', 'girl.gif', 'admin', 'ecfadcde9305f8891bcfe5a1e28c253e', '8pgby', '张三', '2017-05-05 00:00:00', '2', 'sn93@qq.com', '18200000000', '1', '27', '1', '2016-01-29 08:49:53', '25');
INSERT INTO `user` VALUES ('44', null, 'test', '45abb7879f6a8268f1ef600e6038ac73', 'ssts3', 'test', '2017-05-01 00:00:00', '1', 'abc@123.com', '', '5', '26', '1', '2017-05-16 20:33:37', null); INSERT INTO `user` VALUES ('44', null, 'test', '45abb7879f6a8268f1ef600e6038ac73', 'ssts3', 'test', '2017-05-01 00:00:00', '1', 'abc@123.com', '', '5', '26', '3', '2017-05-16 20:33:37', null);
INSERT INTO `user` VALUES ('45', null, 'boss', '71887a5ad666a18f709e1d4e693d5a35', '1f7bf', '老板', '2017-12-04 00:00:00', '1', '', '', '1', '24', '1', '2017-12-04 22:24:02', null);
INSERT INTO `user` VALUES ('46', null, 'manager', 'b53cac62e7175637d4beb3b16b2f7915', 'j3cs9', '经理', '2017-12-04 00:00:00', '1', '', '', '1', '24', '1', '2017-12-04 22:24:24', null);
package com.stylefeng.guns.common.constant.state;
/**
* 是否是菜单的枚举
*
* @author fengshuonan
* @date 2017年6月1日22:50:11
*/
public enum ExpenseState {
SUBMITING(1, "待提交"),
CHECKING(2, "待审核"),
PASS(3, "审核通过"),
UN_PASS(4, "未通过");
int code;
String message;
ExpenseState(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public static String valueOf(Integer status) {
if (status == null) {
return "";
} else {
for (ExpenseState s : ExpenseState.values()) {
if (s.getCode() == status) {
return s.getMessage();
}
}
return "";
}
}
}
package com.stylefeng.guns.common.persistence.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.common.persistence.model.Expense;
/**
* <p>
* 报销表 Mapper 接口
* </p>
*
* @author stylefeng
* @since 2017-12-04
*/
public interface ExpenseMapper extends BaseMapper<Expense> {
}
\ No newline at end of file
<?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.stylefeng.guns.common.persistence.dao.ExpenseMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.stylefeng.guns.common.persistence.model.Expense">
<id column="id" property="id" />
<result column="money" property="money" />
<result column="desc" property="desc" />
<result column="createtime" property="createtime" />
<result column="state" property="state" />
<result column="userid" property="userid" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, money, desc, createtime, state, userid
</sql>
</mapper>
package com.stylefeng.guns.common.persistence.model;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* <p>
* 报销表
* </p>
*
* @author stylefeng
* @since 2017-12-05
*/
public class Expense extends Model<Expense> {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id;
/**
* 报销金额
*/
private BigDecimal money;
/**
* 描述
*/
private String desc;
private Date createtime;
/**
* 状态: 1.待提交 2:待审核 3.审核通过
*/
private Integer state;
/**
* 用户id
*/
private Integer userid;
/**
* 流程定义id
*/
private String processId;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public BigDecimal getMoney() {
return money;
}
public void setMoney(BigDecimal money) {
this.money = money;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getProcessId() {
return processId;
}
public void setProcessId(String processId) {
this.processId = processId;
}
@Override
protected Serializable pkVal() {
return this.id;
}
@Override
public String toString() {
return "Expense{" +
"id=" + id +
", money=" + money +
", desc=" + desc +
", createtime=" + createtime +
", state=" + state +
", userid=" + userid +
", processId=" + processId +
"}";
}
}
package com.stylefeng.guns.modular.flowable.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.stylefeng.guns.common.persistence.model.Expense;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.log.LogObjectHolder;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.modular.flowable.service.IExpenseService;
import com.stylefeng.guns.modular.flowable.warpper.ExpenseWarpper;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.util.Map;
/**
* 报销管理控制器
*
* @author fengshuonan
* @Date 2017-12-04 21:11:36
*/
@Controller
@RequestMapping("/expense")
public class ExpenseController extends BaseController {
private String PREFIX = "/flowable/expense/";
@Autowired
private IExpenseService expenseService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
/**
* 跳转到报销管理首页
*/
@RequestMapping("")
public String index() {
return PREFIX + "expense.html";
}
/**
* 跳转到添加报销管理
*/
@RequestMapping("/expense_add")
public String expenseAdd() {
return PREFIX + "expense_add.html";
}
/**
* 跳转到修改报销管理
*/
@RequestMapping("/expense_update/{expenseId}")
public String expenseUpdate(@PathVariable Integer expenseId, Model model) {
Expense expense = expenseService.selectById(expenseId);
model.addAttribute("item", expense);
LogObjectHolder.me().set(expense);
return PREFIX + "expense_edit.html";
}
/**
* 获取报销管理列表
*/
@RequestMapping(value = "/list")
@ResponseBody
public Object list(String condition) {
EntityWrapper<Expense> expenseEntityWrapper = new EntityWrapper<>();
expenseEntityWrapper.eq("userid", ShiroKit.getUser().getId());
List<Map<String, Object>> stringObjectMap = expenseService.selectMaps(expenseEntityWrapper);
return super.warpObject(new ExpenseWarpper(stringObjectMap));
}
/**
* 新增报销管理
*/
@RequestMapping(value = "/add")
@ResponseBody
public Object add(Expense expense) {
expenseService.add(expense);
return super.SUCCESS_TIP;
}
/**
* 删除报销管理
*/
@RequestMapping(value = "/delete")
@ResponseBody
public Object delete(@RequestParam Integer expenseId) {
expenseService.delete(expenseId);
return SUCCESS_TIP;
}
/**
* 修改报销管理
*/
@RequestMapping(value = "/update")
@ResponseBody
public Object update(Expense expense) {
expenseService.updateById(expense);
return super.SUCCESS_TIP;
}
/**
* 报销管理详情
*/
@RequestMapping(value = "/detail/{expenseId}")
@ResponseBody
public Object detail(@PathVariable("expenseId") Integer expenseId) {
return expenseService.selectById(expenseId);
}
}
package com.stylefeng.guns.modular.flowable.controller;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.modular.flowable.service.IExpenseService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 审批管理控制器
*
* @author fengshuonan
* @Date 2017-12-04 21:11:36
*/
@Controller
@RequestMapping("/process")
public class ProcessController extends BaseController {
private String PREFIX = "/flowable/process/";
@Autowired
private IExpenseService expenseService;
@Autowired
private TaskService taskService;
@Autowired
private RuntimeService runtimeService;
/**
* 跳转到审批管理首页
*/
@RequestMapping("")
public String index() {
return PREFIX + "process.html";
}
/**
* 获取审批管理列表
*/
@RequestMapping(value = "/list")
@ResponseBody
public Object list(String condition) {
return expenseService.getProcessList();
}
/**
* 审核通过
*/
@RequestMapping(value = "/pass")
@ResponseBody
public Object pass(String taskId) {
expenseService.pass(taskId);
return super.SUCCESS_TIP;
}
/**
* 审核不通过
*/
@RequestMapping(value = "/unPass")
@ResponseBody
public Object unPass(String taskId) {
expenseService.unPass(taskId);
return super.SUCCESS_TIP;
}
}
package com.stylefeng.guns.modular.flowable.handler;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;
/**
* 员工经理任务分配
*/
public class BossTaskHandler implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
delegateTask.setAssignee("老板");
}
}
package com.stylefeng.guns.modular.flowable.handler; package com.stylefeng.guns.modular.flowable.handler;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.core.shiro.ShiroUser;
import org.flowable.engine.delegate.TaskListener; import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask; import org.flowable.task.service.delegate.DelegateTask;
...@@ -12,20 +10,7 @@ public class ManagerTaskHandler implements TaskListener { ...@@ -12,20 +10,7 @@ public class ManagerTaskHandler implements TaskListener {
@Override @Override
public void notify(DelegateTask delegateTask) { public void notify(DelegateTask delegateTask) {
/** delegateTask.setAssignee("经理");
* 获取当前用户
*/
ShiroUser user = ShiroKit.getUser();
/**
* 获取当前用户的上一级领导
*/
Integer deptId = user.getDeptId();
/**
* 设置个人任务的办理人
*/
delegateTask.setAssignee("");
} }
} }
package com.stylefeng.guns.modular.flowable.model;
import java.util.Date;
/**
* 任务列表vo
*
* @author fengshuonan
* @date 2017-12-04 23:18
*/
public class TaskVo {
private String id;
private String name;
private Date createTime;
private String assignee;
private Object money;
private Boolean selfFlag;
public TaskVo() {
}
public TaskVo(String id, String name, Date createTime, String assignee, Object money, Boolean flag) {
this.id = id;
this.name = name;
this.createTime = createTime;
this.assignee = assignee;
this.money = money;
this.selfFlag = flag;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getAssignee() {
return assignee;
}
public void setAssignee(String assignee) {
this.assignee = assignee;
}
public Object getMoney() {
return money;
}
public void setMoney(Object money) {
this.money = money;
}
public Boolean getSelfFlag() {
return selfFlag;
}
public void setSelfFlag(Boolean selfFlag) {
this.selfFlag = selfFlag;
}
}
package com.stylefeng.guns.modular.flowable.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.common.persistence.model.Expense;
import com.stylefeng.guns.modular.flowable.model.TaskVo;
import java.util.List;
/**
* <p>
* 报销表 服务类
* </p>
*
* @author stylefeng
* @since 2017-12-04
*/
public interface IExpenseService extends IService<Expense> {
/**
* 新增一个报销单
*/
void add(Expense expense);
/**
* 删除一个报销单
*/
void delete(Integer expenseId);
/**
* 通过审批
*/
void pass(String taskId);
/**
* 通过审批
*/
void unPass(String taskId);
/**
* 获取审批列表
*/
List<TaskVo> getProcessList();
}
package com.stylefeng.guns.modular.flowable.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.common.constant.state.ExpenseState;
import com.stylefeng.guns.common.persistence.dao.ExpenseMapper;
import com.stylefeng.guns.common.persistence.model.Expense;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.modular.flowable.model.TaskVo;
import com.stylefeng.guns.modular.flowable.service.IExpenseService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
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.HashMap;
import java.util.List;
/**
* <p>
* 报销表 服务实现类
* </p>
*
* @author stylefeng
* @since 2017-12-04
*/
@Service
public class ExpenseServiceImpl extends ServiceImpl<ExpenseMapper, Expense> implements IExpenseService {
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Override
@Transactional(rollbackFor = Exception.class)
public void add(Expense expense) {
//保存业务数据
expense.setUserid(ShiroKit.getUser().getId());
expense.setState(ExpenseState.SUBMITING.getCode());
//启动流程
HashMap<String, Object> map = new HashMap<>();
map.put("taskUser", ShiroKit.getUser().getName());
map.put("money", expense.getMoney());
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("Expense", map);
expense.setProcessId(processInstance.getId());
this.insert(expense);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Integer expenseId) {
Expense expense = this.selectById(expenseId);
List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().processInstanceId(expense.getProcessId()).list();
for (ProcessInstance processInstance : list) {
if (processInstance.getId().equals(expense.getProcessId())) {
runtimeService.deleteProcessInstance(processInstance.getProcessInstanceId(), "取消报销");
}
}
this.deleteById(expenseId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void pass(String taskId) {
//使用任务ID,查询任务对象,获取流程流程实例ID
Task task = taskService.createTaskQuery()//
.taskId(taskId)
.singleResult();
//通过审核
HashMap<String, Object> map = new HashMap<>();
map.put("outcome", "通过");
taskService.complete(taskId, map);
//判断流程是否结束,结束之后修改状态
ProcessInstance pi = runtimeService.createProcessInstanceQuery()//
.processInstanceId(task.getProcessInstanceId())//使用流程实例ID查询
.singleResult();
Wrapper<Expense> wrapper = new EntityWrapper<Expense>().eq("processId", task.getProcessInstanceId());
Expense expense = this.selectOne(wrapper);
//审核通过修改为通过状态
if (pi == null) {
expense.setState(ExpenseState.PASS.getCode());
expense.updateById();
} else {
//审核通过如果还有记录则为经理或boss审核中
expense.setState(ExpenseState.CHECKING.getCode());
expense.updateById();
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void unPass(String taskId) {
HashMap<String, Object> map = new HashMap<>();
map.put("outcome", "驳回");
taskService.complete(taskId, map);
}
@Override
public List<TaskVo> getProcessList() {
String name = ShiroKit.getUser().getName();
List<Task> list = taskService.createTaskQuery()
.taskAssignee(name)
.orderByTaskCreateTime().desc()
.list();
ArrayList<TaskVo> taskVos = new ArrayList<>();
for (Task task : list) {
Object money = runtimeService.getVariable(task.getExecutionId(), "money");
String taskUser = (String) taskService.getVariable(task.getId(), "taskUser");
boolean flag = false;
if (name.equals(taskUser)) {
flag = false;
} else {
flag = true;
}
taskVos.add(new TaskVo(task.getId(), task.getName(), task.getCreateTime(), taskUser, money, flag));
}
return taskVos;
}
}
package com.stylefeng.guns.modular.flowable.warpper;
import com.stylefeng.guns.common.constant.state.ExpenseState;
import com.stylefeng.guns.core.base.warpper.BaseControllerWarpper;
import java.util.Map;
/**
* 报销列表的包装
*
* @author fengshuonan
* @date 2017年12月4日21:56:06
*/
public class ExpenseWarpper extends BaseControllerWarpper {
public ExpenseWarpper(Object list) {
super(list);
}
@Override
public void warpTheMap(Map<String, Object> map) {
Integer state = (Integer) map.get("state");
map.put("stateName", ExpenseState.valueOf(state));
}
}
...@@ -59,18 +59,18 @@ public class GunsGeneratorConfig extends AbstractGeneratorConfig { ...@@ -59,18 +59,18 @@ public class GunsGeneratorConfig extends AbstractGeneratorConfig {
* mybatis-plus 生成器开关 * mybatis-plus 生成器开关
*/ */
contextConfig.setEntitySwitch(true); contextConfig.setEntitySwitch(true);
contextConfig.setDaoSwitch(true); contextConfig.setDaoSwitch(false);
contextConfig.setServiceSwitch(true); contextConfig.setServiceSwitch(false);
/** /**
* guns 生成器开关 * guns 生成器开关
*/ */
contextConfig.setControllerSwitch(true); contextConfig.setControllerSwitch(false);
contextConfig.setIndexPageSwitch(true); contextConfig.setIndexPageSwitch(false);
contextConfig.setAddPageSwitch(true); contextConfig.setAddPageSwitch(false);
contextConfig.setEditPageSwitch(true); contextConfig.setEditPageSwitch(false);
contextConfig.setJsSwitch(true); contextConfig.setJsSwitch(false);
contextConfig.setInfoJsSwitch(true); contextConfig.setInfoJsSwitch(false);
contextConfig.setSqlSwitch(true); contextConfig.setSqlSwitch(false);
} }
} }
...@@ -15,7 +15,7 @@ guns: ...@@ -15,7 +15,7 @@ guns:
################### 项目启动端口 ################### ################### 项目启动端口 ###################
server: server:
port: 8080 port: 80
################### beetl配置 ################### ################### beetl配置 ###################
beetl: beetl:
...@@ -61,7 +61,7 @@ mybatis-plus: ...@@ -61,7 +61,7 @@ mybatis-plus:
db-column-underline: false db-column-underline: false
refresh-mapper: true refresh-mapper: true
configuration: configuration:
map-underscore-to-camel-case: true map-underscore-to-camel-case: false
cache-enabled: true #配置的缓存的全局开关 cache-enabled: true #配置的缓存的全局开关
lazyLoadingEnabled: true #延时加载的开关 lazyLoadingEnabled: true #延时加载的开关
multipleResultSetsEnabled: true #开启的话,延时加载一个属性时会加载该对象全部属性,否则按需加载属性 multipleResultSetsEnabled: true #开启的话,延时加载一个属性时会加载该对象全部属性,否则按需加载属性
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
</userTask> </userTask>
<userTask id="bossTask" name="老板审批"> <userTask id="bossTask" name="老板审批">
<extensionElements> <extensionElements>
<flowable:taskListener event="create" class="com.stylefeng.guns.modular.flowable.handler.ManagerTaskHandler"></flowable:taskListener> <flowable:taskListener event="create" class="com.stylefeng.guns.modular.flowable.handler.BossTaskHandler"></flowable:taskListener>
</extensionElements> </extensionElements>
</userTask> </userTask>
<endEvent id="end" name="结束"></endEvent> <endEvent id="end" name="结束"></endEvent>
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
<sequenceFlow id="flow1" sourceRef="start" targetRef="fillTask"></sequenceFlow> <sequenceFlow id="flow1" sourceRef="start" targetRef="fillTask"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="fillTask" targetRef="judgeTask"></sequenceFlow> <sequenceFlow id="flow2" sourceRef="fillTask" targetRef="judgeTask"></sequenceFlow>
<sequenceFlow id="judgeMore" name="大于500元" sourceRef="judgeTask" targetRef="bossTask"> <sequenceFlow id="judgeMore" name="大于500元" sourceRef="judgeTask" targetRef="bossTask">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${money}>500]]></conditionExpression> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${money > 500}]]></conditionExpression>
</sequenceFlow> </sequenceFlow>
<sequenceFlow id="bossPassFlow" name="通过" sourceRef="bossTask" targetRef="end"> <sequenceFlow id="bossPassFlow" name="通过" sourceRef="bossTask" targetRef="end">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression>
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression>
</sequenceFlow> </sequenceFlow>
<sequenceFlow id="judgeLess" name="小于500元" sourceRef="judgeTask" targetRef="directorTak"> <sequenceFlow id="judgeLess" name="小于500元" sourceRef="judgeTask" targetRef="directorTak">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${money}<=500]]></conditionExpression> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${money <= 500}]]></conditionExpression>
</sequenceFlow> </sequenceFlow>
</process> </process>
<bpmndi:BPMNDiagram id="BPMNDiagram_Expense"> <bpmndi:BPMNDiagram id="BPMNDiagram_Expense">
......
@layout("/common/_container.html"){
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>报销管理管理</h5>
</div>
<div class="ibox-content">
<div class="row row-lg">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-3">
<#NameCon id="condition" name="名称" />
</div>
<div class="col-sm-3">
<#button name="搜索" icon="fa-search" clickFun="Expense.search()"/>
</div>
</div>
<div class="hidden-xs" id="ExpenseTableToolbar" role="group">
<#button name="新增报销单" icon="fa-plus" clickFun="Expense.openAddExpense()"/>
</div>
<#table id="ExpenseTable"/>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="${ctxPath}/static/modular/flowable/expense/expense.js"></script>
@}
@layout("/common/_container.html"){
<div class="ibox float-e-margins">
<div class="ibox-content">
<div class="form-horizontal">
<input type="hidden" id="id" value="">
<div class="row">
<div class="col-sm-12">
<#input id="money" name="报销金额" underline="true"/>
<#input id="desc" name="描述"/>
</div>
</div>
<div class="row btn-group-m-t">
<div class="col-sm-12">
<#button btnCss="info" name="提交" id="ensure" icon="fa-check" clickFun="ExpenseInfoDlg.addSubmit()"/>
<#button btnCss="danger" name="取消" id="cancel" icon="fa-eraser" clickFun="ExpenseInfoDlg.close()"/>
</div>
</div>
</div>
</div>
</div>
<script src="${ctxPath}/static/modular/flowable/expense/expense_info.js"></script>
@}
@layout("/common/_container.html"){
<div class="ibox float-e-margins">
<div class="ibox-content">
<div class="form-horizontal">
<input type="hidden" id="id" value="${item.id}">
<div class="row">
<div class="col-sm-12">
<#input id="money" name="报销金额" value="${item.money}"/>
<#input id="desc" name="描述" value="${item.desc}" />
</div>
</div>
<div class="row btn-group-m-t">
<div class="col-sm-10">
<#button btnCss="info" name="提交" id="ensure" icon="fa-check" clickFun="ExpenseInfoDlg.editSubmit()"/>
<#button btnCss="danger" name="取消" id="cancel" icon="fa-eraser" clickFun="ExpenseInfoDlg.close()"/>
</div>
</div>
</div>
</div>
</div>
<script src="${ctxPath}/static/modular/flowable/expense/expense_info.js"></script>
@}
@layout("/common/_container.html"){
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>报销管理管理</h5>
</div>
<div class="ibox-content">
<div class="row row-lg">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-3">
<#NameCon id="condition" name="名称" />
</div>
<div class="col-sm-3">
<#button name="搜索" icon="fa-search" clickFun="Process.search()"/>
</div>
</div>
<#table id="ProcessTable"/>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="${ctxPath}/static/modular/flowable/process/process.js"></script>
@}
/**
* 报销管理管理初始化
*/
var Expense = {
id: "ExpenseTable", //表格id
seItem: null, //选中的条目
table: null,
layerIndex: -1
};
/**
* 初始化表格的列
*/
Expense.initColumn = function () {
return [
{field: 'selectItem', radio: true},
{title: '报销id', field: 'id', visible: true, align: 'center', valign: 'middle'},
{title: '报销金额', field: 'money', visible: true, align: 'center', valign: 'middle'},
{title: '描述', field: 'desc', visible: true, align: 'center', valign: 'middle'},
{title: '状态', field: 'stateName', visible: true, align: 'center', valign: 'middle'},
{title: '创建时间', field: 'createtime', visible: true, align: 'center', valign: 'middle'},
{
title: '操作', visible: true, align: 'center', valign: 'middle', formatter: function (value, row, index) {
return '<button type="button" class="btn btn-primary button-margin" onclick="Expense.findRecord(' + row.id + ')" id=""><i class="fa fa-edit"></i>&nbsp;查看</button>' +
'<button type="button" class="btn btn-danger button-margin" onclick="Expense.deleteRecord(' + row.id + ')" id=""><i class="fa fa-arrows-alt"></i>&nbsp;删除</button>';
}
}
];
};
/**
* 查看审核记录
*/
Expense.findRecord = function (id) {
var index = layer.open({
type: 2,
title: '报销管理详情',
area: ['600px', '350px'], //宽高
fix: false, //不固定
maxmin: true,
content: Feng.ctxPath + '/expense/expense_update/' + id
});
this.layerIndex = index;
};
/**
* 删除审核记录
*/
Expense.deleteRecord = function (id) {
var ajax = new $ax(Feng.ctxPath + "/expense/delete", function (data) {
Feng.success("删除成功!");
Expense.table.refresh();
}, function (data) {
Feng.error("删除失败!" + data.responseJSON.message + "!");
});
ajax.set("expenseId", id);
ajax.start();
};
/**
* 点击添加报销管理
*/
Expense.openAddExpense = function () {
var index = layer.open({
type: 2,
title: '添加报销管理',
area: ['600px', '350px'], //宽高
fix: false, //不固定
maxmin: true,
content: Feng.ctxPath + '/expense/expense_add'
});
this.layerIndex = index;
};
/**
* 查询报销管理列表
*/
Expense.search = function () {
var queryData = {};
queryData['condition'] = $("#condition").val();
Expense.table.refresh({query: queryData});
};
$(function () {
var defaultColunms = Expense.initColumn();
var table = new BSTable(Expense.id, "/expense/list", defaultColunms);
table.setPaginationType("client");
Expense.table = table.init();
});
/**
* 初始化报销管理详情对话框
*/
var ExpenseInfoDlg = {
expenseInfoData : {}
};
/**
* 清除数据
*/
ExpenseInfoDlg.clearData = function() {
this.expenseInfoData = {};
}
/**
* 设置对话框中的数据
*
* @param key 数据的名称
* @param val 数据的具体值
*/
ExpenseInfoDlg.set = function(key, val) {
this.expenseInfoData[key] = (typeof val == "undefined") ? $("#" + key).val() : val;
return this;
}
/**
* 设置对话框中的数据
*
* @param key 数据的名称
* @param val 数据的具体值
*/
ExpenseInfoDlg.get = function(key) {
return $("#" + key).val();
}
/**
* 关闭此对话框
*/
ExpenseInfoDlg.close = function() {
parent.layer.close(window.parent.Expense.layerIndex);
}
/**
* 收集数据
*/
ExpenseInfoDlg.collectData = function() {
this
.set('id')
.set('money')
.set('desc')
;
}
/**
* 提交添加
*/
ExpenseInfoDlg.addSubmit = function() {
this.clearData();
this.collectData();
//提交信息
var ajax = new $ax(Feng.ctxPath + "/expense/add", function(data){
Feng.success("添加成功!");
window.parent.Expense.table.refresh();
ExpenseInfoDlg.close();
},function(data){
Feng.error("添加失败!" + data.responseJSON.message + "!");
});
ajax.set(this.expenseInfoData);
ajax.start();
}
/**
* 提交修改
*/
ExpenseInfoDlg.editSubmit = function() {
this.clearData();
this.collectData();
//提交信息
var ajax = new $ax(Feng.ctxPath + "/expense/update", function(data){
Feng.success("修改成功!");
window.parent.Expense.table.refresh();
ExpenseInfoDlg.close();
},function(data){
Feng.error("修改失败!" + data.responseJSON.message + "!");
});
ajax.set(this.expenseInfoData);
ajax.start();
}
$(function() {
});
/**
* 报销管理管理初始化
*/
var Process = {
id: "ProcessTable", //表格id
seItem: null, //选中的条目
table: null,
layerIndex: -1
};
/**
* 初始化表格的列
*/
Process.initColumn = function () {
return [
{field: 'selectItem', radio: true},
{title: '任务id', field: 'id', visible: true, align: 'center', valign: 'middle'},
{title: '名称', field: 'name', visible: true, align: 'center', valign: 'middle'},
{title: '金额', field: 'money', visible: true, align: 'center', valign: 'middle'},
{title: '创建时间', field: 'createTime', visible: true, align: 'center', valign: 'middle'},
{title: '申请人', field: 'assignee', visible: true, align: 'center', valign: 'middle'},
{
title: '操作', visible: true, align: 'center', valign: 'middle', formatter: function (value, row, index) {
if (row.selfFlag == true) {
return '<button type="button" class="btn btn-primary button-margin" onclick="Process.pass(' + row.id + ')" id=""><i class="fa fa-edit"></i>&nbsp;通过</button>' +
'<button type="button" class="btn btn-danger button-margin" onclick="Process.unPass(' + row.id + ')" id=""><i class="fa fa-arrows-alt"></i>&nbsp;不通过</button>';
} else {
return '<button type="button" class="btn btn-primary button-margin" onclick="Process.pass(' + row.id + ')" id=""><i class="fa fa-edit"></i>&nbsp;通过</button>';
}
}
}
];
};
/**
* 通过审核
*/
Process.pass = function (id) {
var ajax = new $ax(Feng.ctxPath + "/process/pass", function (data) {
Feng.success("审核成功!");
Process.table.refresh();
}, function (data) {
Feng.error("审核失败!" + data.responseJSON.message + "!");
});
ajax.set("taskId", id);
ajax.start();
};
/**
* 未通过审核
*/
Process.unPass = function (id) {
var ajax = new $ax(Feng.ctxPath + "/process/unPass", function (data) {
Feng.success("审核成功!");
Process.table.refresh();
}, function (data) {
Feng.error("审核失败!" + data.responseJSON.message + "!");
});
ajax.set("taskId", id);
ajax.start();
};
/**
* 查询报销管理列表
*/
Process.search = function () {
var queryData = {};
queryData['condition'] = $("#condition").val();
Process.table.refresh({query: queryData});
};
$(function () {
var defaultColunms = Process.initColumn();
var table = new BSTable(Process.id, "/process/list", defaultColunms);
table.setPaginationType("client");
Process.table = table.init();
});
/**
* 初始化报销管理详情对话框
*/
var ExpenseInfoDlg = {
expenseInfoData : {}
};
/**
* 清除数据
*/
ExpenseInfoDlg.clearData = function() {
this.expenseInfoData = {};
}
/**
* 设置对话框中的数据
*
* @param key 数据的名称
* @param val 数据的具体值
*/
ExpenseInfoDlg.set = function(key, val) {
this.expenseInfoData[key] = (typeof val == "undefined") ? $("#" + key).val() : val;
return this;
}
/**
* 设置对话框中的数据
*
* @param key 数据的名称
* @param val 数据的具体值
*/
ExpenseInfoDlg.get = function(key) {
return $("#" + key).val();
}
/**
* 关闭此对话框
*/
ExpenseInfoDlg.close = function() {
parent.layer.close(window.parent.Expense.layerIndex);
}
/**
* 收集数据
*/
ExpenseInfoDlg.collectData = function() {
this
.set('id')
.set('money')
.set('desc')
;
}
/**
* 提交添加
*/
ExpenseInfoDlg.addSubmit = function() {
this.clearData();
this.collectData();
//提交信息
var ajax = new $ax(Feng.ctxPath + "/expense/add", function(data){
Feng.success("添加成功!");
window.parent.Expense.table.refresh();
ExpenseInfoDlg.close();
},function(data){
Feng.error("添加失败!" + data.responseJSON.message + "!");
});
ajax.set(this.expenseInfoData);
ajax.start();
}
/**
* 提交修改
*/
ExpenseInfoDlg.editSubmit = function() {
this.clearData();
this.collectData();
//提交信息
var ajax = new $ax(Feng.ctxPath + "/expense/update", function(data){
Feng.success("修改成功!");
window.parent.Expense.table.refresh();
ExpenseInfoDlg.close();
},function(data){
Feng.error("修改失败!" + data.responseJSON.message + "!");
});
ajax.set(this.expenseInfoData);
ajax.start();
}
$(function() {
});
package com.stylefeng.guns.flowable; package com.stylefeng.guns.flowable;
import com.alibaba.fastjson.JSON;
import org.flowable.engine.*; import org.flowable.engine.*;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration; import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.Deployment;
...@@ -54,6 +55,21 @@ public class FlowableTest { ...@@ -54,6 +55,21 @@ public class FlowableTest {
} }
/** /**
* 查看发布
*/
@Test
public void findDeploy() {
RepositoryService repositoryService = processEngine.getRepositoryService();
List<Deployment> list = repositoryService.createDeploymentQuery().list();
for (Deployment deployment : list) {
System.out.println(deployment.getCategory());
System.out.println(deployment.getName());
System.out.println("deploy = " + deployment.getId());
System.out.println("key = " + deployment.getKey());
}
}
/**
* 启动流程 * 启动流程
*/ */
@Test @Test
...@@ -71,10 +87,18 @@ public class FlowableTest { ...@@ -71,10 +87,18 @@ public class FlowableTest {
*/ */
@Test @Test
public void queryProcess() { public void queryProcess() {
List<ProcessInstance> list1 = processEngine.getRuntimeService().createProcessInstanceQuery().list();
for (ProcessInstance processDefinition : list1) {
System.out.println("id = " + processDefinition.getId());
System.out.println("getDeploymentId = " + processDefinition.getDeploymentId());
System.out.println("getTenantId = " + processDefinition.getTenantId());
System.out.println("name = " + processDefinition.getName());
}
System.err.println("---------------------------------");
List<ProcessDefinition> list = processEngine.getRepositoryService() List<ProcessDefinition> list = processEngine.getRepositoryService()
.createProcessDefinitionQuery() .createProcessDefinitionQuery()
.list(); .list();
for (ProcessDefinition processDefinition : list) { for (ProcessDefinition processDefinition : list) {
System.out.println("id = " + processDefinition.getId()); System.out.println("id = " + processDefinition.getId());
System.out.println("getDeploymentId = " + processDefinition.getDeploymentId()); System.out.println("getDeploymentId = " + processDefinition.getDeploymentId());
...@@ -91,7 +115,8 @@ public class FlowableTest { ...@@ -91,7 +115,8 @@ public class FlowableTest {
*/ */
@Test @Test
public void delProcess() { public void delProcess() {
processEngine.getRepositoryService().deleteDeployment("1", true); processEngine.getRuntimeService().deleteProcessInstance("67501","abcd");
//processEngine.getRepositoryService().deleteDeployment("25001", true);
System.out.println("删除成功"); System.out.println("删除成功");
} }
...@@ -100,17 +125,29 @@ public class FlowableTest { ...@@ -100,17 +125,29 @@ public class FlowableTest {
*/ */
@Test @Test
public void queryMyTask() { public void queryMyTask() {
String name = "fsn"; String name = "张三";
TaskQuery taskQuery = processEngine.getTaskService().createTaskQuery().taskAssignee(name); TaskQuery taskQuery = processEngine.getTaskService().createTaskQuery().taskAssignee(name);
List<Task> list = taskQuery.list(); List<Task> list = taskQuery.list();
for (Task task : list) { for (Task task : list) {
System.out.println("name = " + task.getName()); System.out.println("name = " + task.getName());
System.out.println(JSON.toJSON(task.getTaskLocalVariables()));
} }
System.out.println("查询完毕!"); System.out.println("查询完毕!");
} }
/**
* 完成任务
*/
@Test
public void complete() {
HashMap<String, Object> map = new HashMap<>();
map.put("money", 600);
TaskService taskService = processEngine.getTaskService();
taskService.complete("47513", map);
}
public static void main(String[] args) { public static void main(String[] args) {
ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration() ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull") .setJdbcUrl("jdbc:mysql://127.0.0.1:3306/flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull")
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
</userTask> </userTask>
<userTask id="bossTask" name="老板审批"> <userTask id="bossTask" name="老板审批">
<extensionElements> <extensionElements>
<flowable:taskListener event="create" class="com.stylefeng.guns.modular.flowable.handler.ManagerTaskHandler"></flowable:taskListener> <flowable:taskListener event="create" class="com.stylefeng.guns.modular.flowable.handler.BossTaskHandler"></flowable:taskListener>
</extensionElements> </extensionElements>
</userTask> </userTask>
<endEvent id="end" name="结束"></endEvent> <endEvent id="end" name="结束"></endEvent>
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
<sequenceFlow id="flow1" sourceRef="start" targetRef="fillTask"></sequenceFlow> <sequenceFlow id="flow1" sourceRef="start" targetRef="fillTask"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="fillTask" targetRef="judgeTask"></sequenceFlow> <sequenceFlow id="flow2" sourceRef="fillTask" targetRef="judgeTask"></sequenceFlow>
<sequenceFlow id="judgeMore" name="大于500元" sourceRef="judgeTask" targetRef="bossTask"> <sequenceFlow id="judgeMore" name="大于500元" sourceRef="judgeTask" targetRef="bossTask">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${money}>500]]></conditionExpression> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${money > 500}]]></conditionExpression>
</sequenceFlow> </sequenceFlow>
<sequenceFlow id="bossPassFlow" name="通过" sourceRef="bossTask" targetRef="end"> <sequenceFlow id="bossPassFlow" name="通过" sourceRef="bossTask" targetRef="end">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression>
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression>
</sequenceFlow> </sequenceFlow>
<sequenceFlow id="judgeLess" name="小于500元" sourceRef="judgeTask" targetRef="directorTak"> <sequenceFlow id="judgeLess" name="小于500元" sourceRef="judgeTask" targetRef="directorTak">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${money}<=500]]></conditionExpression> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${money <= 500}]]></conditionExpression>
</sequenceFlow> </sequenceFlow>
</process> </process>
<bpmndi:BPMNDiagram id="BPMNDiagram_Expense"> <bpmndi:BPMNDiagram id="BPMNDiagram_Expense">
......
...@@ -5,476 +5,504 @@ import com.stylefeng.guns.core.util.Convert; ...@@ -5,476 +5,504 @@ import com.stylefeng.guns.core.util.Convert;
import java.beans.*; import java.beans.*;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashMap; import java.util.*;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
/** /**
* Bean工具类 * Bean工具类
* @author Looly
* *
* @author Looly
*/ */
public class BeanKit { public class BeanKit {
/** /**
* 判断是否为Bean对象 * 判断是否为Bean对象
* @param clazz 待测试类 *
* @return 是否为Bean对象 * @param clazz 待测试类
*/ * @return 是否为Bean对象
public static boolean isBean(Class<?> clazz){ */
if(ClassKit.isNormalClass(clazz)){ public static boolean isBean(Class<?> clazz) {
Method[] methods = clazz.getMethods(); if (ClassKit.isNormalClass(clazz)) {
for (Method method : methods) { Method[] methods = clazz.getMethods();
if(method.getParameterTypes().length == 1 && method.getName().startsWith("set")){ for (Method method : methods) {
//检测包含标准的setXXX方法即视为标准的JavaBean if (method.getParameterTypes().length == 1 && method.getName().startsWith("set")) {
return true; //检测包含标准的setXXX方法即视为标准的JavaBean
} return true;
} }
} }
return false; }
} return false;
}
public static PropertyEditor findEditor(Class<?> type){
return PropertyEditorManager.findEditor(type); public static PropertyEditor findEditor(Class<?> type) {
} return PropertyEditorManager.findEditor(type);
}
/**
* 获得Bean字段描述数组 /**
* * 获得Bean字段描述数组
* @param clazz Bean类 *
* @return 字段描述数组 * @param clazz Bean类
* @throws IntrospectionException * @return 字段描述数组
*/ * @throws IntrospectionException
public static PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz) throws IntrospectionException { */
return Introspector.getBeanInfo(clazz).getPropertyDescriptors(); public static PropertyDescriptor[] getPropertyDescriptors(Class<?> clazz) throws IntrospectionException {
} return Introspector.getBeanInfo(clazz).getPropertyDescriptors();
}
/**
* 获得字段名和字段描述Map /**
* @param clazz Bean类 * 获得字段名和字段描述Map
* @return 字段名和字段描述Map *
* @throws IntrospectionException * @param clazz Bean类
*/ * @return 字段名和字段描述Map
public static Map<String, PropertyDescriptor> getFieldNamePropertyDescriptorMap(Class<?> clazz) throws IntrospectionException{ * @throws IntrospectionException
final PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz); */
Map<String, PropertyDescriptor> map = new HashMap<>(); public static Map<String, PropertyDescriptor> getFieldNamePropertyDescriptorMap(Class<?> clazz) throws IntrospectionException {
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { final PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz);
map.put(propertyDescriptor.getName(), propertyDescriptor); Map<String, PropertyDescriptor> map = new HashMap<>();
} for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
return map; map.put(propertyDescriptor.getName(), propertyDescriptor);
} }
return map;
/** }
* 获得Bean类属性描述
* /**
* @param clazz Bean类 * 获得Bean类属性描述
* @param fieldName 字段名 *
* @return PropertyDescriptor * @param clazz Bean类
* @throws IntrospectionException * @param fieldName 字段名
*/ * @return PropertyDescriptor
public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, final String fieldName) throws IntrospectionException { * @throws IntrospectionException
PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz); */
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, final String fieldName) throws IntrospectionException {
if (ObjectKit.equals(fieldName, propertyDescriptor.getName())) { PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(clazz);
return propertyDescriptor; for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
} if (ObjectKit.equals(fieldName, propertyDescriptor.getName())) {
} return propertyDescriptor;
return null; }
} }
return null;
/** }
* Map转换为Bean对象
* /**
* @param map Map * Map转换为Bean对象
* @param beanClass Bean Class *
* @return Bean * @param map Map
*/ * @param beanClass Bean Class
public static <T> T mapToBean(Map<?, ?> map, Class<T> beanClass) { * @return Bean
return fillBeanWithMap(map, ClassKit.newInstance(beanClass)); */
} public static <T> T mapToBean(Map<?, ?> map, Class<T> beanClass) {
return fillBeanWithMap(map, ClassKit.newInstance(beanClass));
/** }
* Map转换为Bean对象<br>
* 忽略大小写 /**
* * Map转换为Bean对象<br>
* @param map Map * 忽略大小写
* @param beanClass Bean Class *
* @return Bean * @param map Map
*/ * @param beanClass Bean Class
public static <T> T mapToBeanIgnoreCase(Map<?, ?> map, Class<T> beanClass) { * @return Bean
return fillBeanWithMapIgnoreCase(map, ClassKit.newInstance(beanClass)); */
} public static <T> T mapToBeanIgnoreCase(Map<?, ?> map, Class<T> beanClass) {
return fillBeanWithMapIgnoreCase(map, ClassKit.newInstance(beanClass));
/** }
* 使用Map填充Bean对象
* /**
* @param map Map * 使用Map填充Bean对象
* @param bean Bean *
* @return Bean * @param map Map
*/ * @param bean Bean
public static <T> T fillBeanWithMap(final Map<?, ?> map, T bean) { * @return Bean
return fillBean(bean, new ValueProvider(){ */
@Override public static <T> T fillBeanWithMap(final Map<?, ?> map, T bean) {
public Object value(String name) { return fillBean(bean, new ValueProvider() {
return map.get(name); @Override
} public Object value(String name) {
}); return map.get(name);
} }
});
/** }
* 使用Map填充Bean对象,可配置将下划线转换为驼峰
* /**
* @param map Map * 使用Map填充Bean对象,可配置将下划线转换为驼峰
* @param bean Bean *
* @param isToCamelCase 是否将下划线模式转换为驼峰模式 * @param map Map
* @return Bean * @param bean Bean
*/ * @param isToCamelCase 是否将下划线模式转换为驼峰模式
public static <T> T fillBeanWithMap(Map<?, ?> map, T bean, boolean isToCamelCase) { * @return Bean
if(isToCamelCase){ */
final Map<Object, Object> map2 = new HashMap<Object, Object>(); public static <T> T fillBeanWithMap(Map<?, ?> map, T bean, boolean isToCamelCase) {
for (Entry<?, ?> entry : map.entrySet()) { if (isToCamelCase) {
final Object key = entry.getKey(); final Map<Object, Object> map2 = new HashMap<Object, Object>();
if (null != key && key instanceof String) { for (Entry<?, ?> entry : map.entrySet()) {
final String keyStr = (String) key; final Object key = entry.getKey();
map2.put(StrKit.toCamelCase(keyStr), entry.getValue()); if (null != key && key instanceof String) {
} else { final String keyStr = (String) key;
map2.put(key, entry.getValue()); map2.put(StrKit.toCamelCase(keyStr), entry.getValue());
} } else {
} map2.put(key, entry.getValue());
return fillBeanWithMap(map2, bean); }
} }
return fillBeanWithMap(map2, bean);
return fillBeanWithMap(map, bean); }
}
return fillBeanWithMap(map, bean);
/** }
* 使用Map填充Bean对象,忽略大小写
* /**
* @param map Map * 使用Map填充Bean对象,忽略大小写
* @param bean Bean *
* @return Bean * @param map Map
*/ * @param bean Bean
public static <T> T fillBeanWithMapIgnoreCase(Map<?, ?> map, T bean) { * @return Bean
final Map<Object, Object> map2 = new HashMap<Object, Object>(); */
for (Entry<?, ?> entry : map.entrySet()) { public static <T> T fillBeanWithMapIgnoreCase(Map<?, ?> map, T bean) {
final Object key = entry.getKey(); final Map<Object, Object> map2 = new HashMap<Object, Object>();
if (key instanceof String) { for (Entry<?, ?> entry : map.entrySet()) {
final String keyStr = (String) key; final Object key = entry.getKey();
map2.put(keyStr.toLowerCase(), entry.getValue()); if (key instanceof String) {
} else { final String keyStr = (String) key;
map2.put(key, entry.getValue()); map2.put(keyStr.toLowerCase(), entry.getValue());
} } else {
} map2.put(key, entry.getValue());
}
return fillBean(bean, new ValueProvider(){ }
@Override
public Object value(String name) { return fillBean(bean, new ValueProvider() {
return map2.get(name.toLowerCase()); @Override
} public Object value(String name) {
}); return map2.get(name.toLowerCase());
} }
});
/** }
* ServletRequest 参数转Bean
* /**
* @param request ServletRequest * ServletRequest 参数转Bean
* @param beanClass Bean Class *
* @return Bean * @param request ServletRequest
*/ * @param beanClass Bean Class
public static <T> T requestParamToBean(javax.servlet.ServletRequest request, Class<T> beanClass) { * @return Bean
return fillBeanWithRequestParam(request, ClassKit.newInstance(beanClass)); */
} public static <T> T requestParamToBean(javax.servlet.ServletRequest request, Class<T> beanClass) {
return fillBeanWithRequestParam(request, ClassKit.newInstance(beanClass));
/** }
* ServletRequest 参数转Bean
* /**
* @param request ServletRequest * ServletRequest 参数转Bean
* @param bean Bean *
* @return Bean * @param request ServletRequest
*/ * @param bean Bean
public static <T> T fillBeanWithRequestParam(final javax.servlet.ServletRequest request, T bean) { * @return Bean
final String beanName = StrKit.lowerFirst(bean.getClass().getSimpleName()); */
return fillBean(bean, new ValueProvider(){ public static <T> T fillBeanWithRequestParam(final javax.servlet.ServletRequest request, T bean) {
@Override final String beanName = StrKit.lowerFirst(bean.getClass().getSimpleName());
public Object value(String name) { return fillBean(bean, new ValueProvider() {
String value = request.getParameter(name); @Override
if (StrKit.isEmpty(value)) { public Object value(String name) {
// 使用类名前缀尝试查找值 String value = request.getParameter(name);
value = request.getParameter(beanName + StrKit.DOT + name); if (StrKit.isEmpty(value)) {
if (StrKit.isEmpty(value)) { // 使用类名前缀尝试查找值
// 此处取得的值为空时跳过,包括null和"" value = request.getParameter(beanName + StrKit.DOT + name);
value = null; if (StrKit.isEmpty(value)) {
} // 此处取得的值为空时跳过,包括null和""
} value = null;
return value; }
} }
}); return value;
} }
});
/** }
* ServletRequest 参数转Bean
* /**
* @param <T> * ServletRequest 参数转Bean
* @param beanClass Bean Class *
* @param valueProvider 值提供者 * @param <T>
* @return Bean * @param beanClass Bean Class
*/ * @param valueProvider 值提供者
public static <T> T toBean(Class<T> beanClass, ValueProvider valueProvider) { * @return Bean
return fillBean(ClassKit.newInstance(beanClass), valueProvider); */
} public static <T> T toBean(Class<T> beanClass, ValueProvider valueProvider) {
return fillBean(ClassKit.newInstance(beanClass), valueProvider);
/** }
* 填充Bean
* /**
* @param <T> * 填充Bean
* @param bean Bean *
* @param valueProvider 值提供者 * @param <T>
* @return Bean * @param bean Bean
*/ * @param valueProvider 值提供者
public static <T> T fillBean(T bean, ValueProvider valueProvider) { * @return Bean
if (null == valueProvider) { */
return bean; public static <T> T fillBean(T bean, ValueProvider valueProvider) {
} if (null == valueProvider) {
return bean;
Class<?> beanClass = bean.getClass(); }
try {
PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(beanClass); Class<?> beanClass = bean.getClass();
String propertyName; try {
Object value; PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(beanClass);
for (PropertyDescriptor property : propertyDescriptors) { String propertyName;
propertyName = property.getName(); Object value;
value = valueProvider.value(propertyName); for (PropertyDescriptor property : propertyDescriptors) {
if (null == value) { propertyName = property.getName();
continue; value = valueProvider.value(propertyName);
} if (null == value) {
try { continue;
property.getWriteMethod().invoke(bean, Convert.parse(property.getPropertyType(), value)); }
} catch (Exception e) { try {
e.printStackTrace(); property.getWriteMethod().invoke(bean, Convert.parse(property.getPropertyType(), value));
} } catch (Exception e) {
} e.printStackTrace();
} catch (Exception e) { }
throw new ToolBoxException(e); }
} } catch (Exception e) {
return bean; throw new ToolBoxException(e);
} }
return bean;
/** }
* 对象转Map
* /**
* @param bean bean对象 * 对象转Map
* @return Map *
*/ * @param bean bean对象
public static <T> Map<String, Object> beanToMap(T bean) { * @return Map
return beanToMap(bean, false); */
} public static <T> Map<String, Object> beanToMap(T bean) {
return beanToMap(bean, false);
/** }
* 对象转Map
* /**
* @param bean bean对象 * 对象转Map
* @param isToUnderlineCase 是否转换为下划线模式 *
* @return Map * @param bean bean对象
*/ * @return Map
public static <T> Map<String, Object> beanToMap(T bean, boolean isToUnderlineCase) { */
public static <T> List<Map<String, Object>> listToMapList(List<T> bean) {
if (bean == null) { ArrayList<Map<String, Object>> maps = new ArrayList<>();
return null; for (T t : bean) {
} maps.add(beanToMap(bean, false));
Map<String, Object> map = new HashMap<String, Object>(); }
try { return maps;
final PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(bean.getClass()); }
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName(); /**
// 过滤class属性 * 对象转Map
if (false == key.equals("class")) { *
// 得到property对应的getter方法 * @param bean bean对象
Method getter = property.getReadMethod(); * @param isToUnderlineCase 是否转换为下划线模式
Object value = getter.invoke(bean); * @return Map
if (null != value) { */
map.put(isToUnderlineCase ? StrKit.toUnderlineCase(key) : key, value); public static <T> Map<String, Object> beanToMap(T bean, boolean isToUnderlineCase) {
}
} if (bean == null) {
} return null;
} catch (Exception e) { }
throw new ToolBoxException(e); Map<String, Object> map = new HashMap<String, Object>();
} try {
return map; final PropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(bean.getClass());
} for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
/** // 过滤class属性
* 复制Bean对象属性 if (false == key.equals("class")) {
* @param source 源Bean对象 // 得到property对应的getter方法
* @param target 目标Bean对象 Method getter = property.getReadMethod();
*/ Object value = getter.invoke(bean);
public static void copyProperties(Object source, Object target) { if (null != value) {
copyProperties(source, target, CopyOptions.create()); map.put(isToUnderlineCase ? StrKit.toUnderlineCase(key) : key, value);
} }
}
/** }
* 复制Bean对象属性<br> } catch (Exception e) {
* 限制类用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类 throw new ToolBoxException(e);
* @param source 源Bean对象 }
* @param target 目标Bean对象 return map;
* @param ignoreProperties 不拷贝的的属性列表 }
*/
public static void copyProperties(Object source, Object target, String... ignoreProperties) { /**
copyProperties(source, target, CopyOptions.create().setIgnoreProperties(ignoreProperties)); * 复制Bean对象属性
} *
* @param source 源Bean对象
/** * @param target 目标Bean对象
* 复制Bean对象属性<br> */
* 限制类用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类 public static void copyProperties(Object source, Object target) {
* @param source 源Bean对象 copyProperties(source, target, CopyOptions.create());
* @param target 目标Bean对象 }
* @param copyOptions 拷贝选项,见 {@link CopyOptions}
*/ /**
public static void copyProperties(Object source, Object target, CopyOptions copyOptions) { * 复制Bean对象属性<br>
if(null == copyOptions){ * 限制类用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类
copyOptions = new CopyOptions(); *
} * @param source 源Bean对象
* @param target 目标Bean对象
Class<?> actualEditable = target.getClass(); * @param ignoreProperties 不拷贝的的属性列表
if (copyOptions.editable != null) { */
//检查限制类是否为target的父类或接口 public static void copyProperties(Object source, Object target, String... ignoreProperties) {
if (!copyOptions.editable.isInstance(target)) { copyProperties(source, target, CopyOptions.create().setIgnoreProperties(ignoreProperties));
throw new IllegalArgumentException(StrKit.format("Target class [{}] not assignable to Editable class [{}]", target.getClass().getName(), copyOptions.editable.getName())); }
}
actualEditable = copyOptions.editable; /**
} * 复制Bean对象属性<br>
PropertyDescriptor[] targetPds = null; * 限制类用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类
Map<String, PropertyDescriptor> sourcePdMap; *
try { * @param source 源Bean对象
sourcePdMap = getFieldNamePropertyDescriptorMap(source.getClass()); * @param target 目标Bean对象
targetPds = getPropertyDescriptors(actualEditable); * @param copyOptions 拷贝选项,见 {@link CopyOptions}
} catch (IntrospectionException e) { */
throw new ToolBoxException(e); public static void copyProperties(Object source, Object target, CopyOptions copyOptions) {
} if (null == copyOptions) {
copyOptions = new CopyOptions();
HashSet<String> ignoreSet = copyOptions.ignoreProperties != null ? CollectionKit.newHashSet(copyOptions.ignoreProperties) : null; }
for (PropertyDescriptor targetPd : targetPds) {
Method writeMethod = targetPd.getWriteMethod(); Class<?> actualEditable = target.getClass();
if (writeMethod != null && (ignoreSet == null || false == ignoreSet.contains(targetPd.getName()))) { if (copyOptions.editable != null) {
PropertyDescriptor sourcePd = sourcePdMap.get(targetPd.getName()); //检查限制类是否为target的父类或接口
if (sourcePd != null) { if (!copyOptions.editable.isInstance(target)) {
Method readMethod = sourcePd.getReadMethod(); throw new IllegalArgumentException(StrKit.format("Target class [{}] not assignable to Editable class [{}]", target.getClass().getName(), copyOptions.editable.getName()));
// 源对象字段的getter方法返回值必须可转换为目标对象setter方法的第一个参数 }
if (readMethod != null && ClassKit.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) { actualEditable = copyOptions.editable;
try { }
Object value = ClassKit.setAccessible(readMethod).invoke(source); PropertyDescriptor[] targetPds = null;
if(null != value || false == copyOptions.isIgnoreNullValue){ Map<String, PropertyDescriptor> sourcePdMap;
ClassKit.setAccessible(writeMethod).invoke(target, value); try {
} sourcePdMap = getFieldNamePropertyDescriptorMap(source.getClass());
} catch (Throwable ex) { targetPds = getPropertyDescriptors(actualEditable);
throw new ToolBoxException(ex, "Copy property [{}] to [{}] error: {}", sourcePd.getName(), targetPd.getName(), ex.getMessage()); } catch (IntrospectionException e) {
} throw new ToolBoxException(e);
} }
}
} HashSet<String> ignoreSet = copyOptions.ignoreProperties != null ? CollectionKit.newHashSet(copyOptions.ignoreProperties) : null;
} for (PropertyDescriptor targetPd : targetPds) {
} Method writeMethod = targetPd.getWriteMethod();
if (writeMethod != null && (ignoreSet == null || false == ignoreSet.contains(targetPd.getName()))) {
/** PropertyDescriptor sourcePd = sourcePdMap.get(targetPd.getName());
* 值提供者,用于提供Bean注入时参数对应值得抽象接口<br> if (sourcePd != null) {
* 继承或匿名实例化此接口<br> Method readMethod = sourcePd.getReadMethod();
* 在Bean注入过程中,Bean获得字段名,通过外部方式根据这个字段名查找相应的字段值,然后注入Bean<br> // 源对象字段的getter方法返回值必须可转换为目标对象setter方法的第一个参数
* if (readMethod != null && ClassKit.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
* @author Looly try {
* Object value = ClassKit.setAccessible(readMethod).invoke(source);
*/ if (null != value || false == copyOptions.isIgnoreNullValue) {
public static interface ValueProvider { ClassKit.setAccessible(writeMethod).invoke(target, value);
/** }
* 获取值 } catch (Throwable ex) {
* throw new ToolBoxException(ex, "Copy property [{}] to [{}] error: {}", sourcePd.getName(), targetPd.getName(), ex.getMessage());
* @param name Bean对象中参数名 }
* @return 对应参数名的值 }
*/ }
public Object value(String name); }
} }
}
/**
* 属性拷贝选项<br> /**
* 包括:<br> * 值提供者,用于提供Bean注入时参数对应值得抽象接口<br>
* 1、限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类<br> * 继承或匿名实例化此接口<br>
* 2、是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null<br> * 在Bean注入过程中,Bean获得字段名,通过外部方式根据这个字段名查找相应的字段值,然后注入Bean<br>
* 3、忽略的属性列表,设置一个属性列表,不拷贝这些属性值<br> *
* * @author Looly
* @author Looly */
*/ public static interface ValueProvider {
public static class CopyOptions { /**
/** 限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类 */ * 获取值
private Class<?> editable; *
/** 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null */ * @param name Bean对象中参数名
private boolean isIgnoreNullValue; * @return 对应参数名的值
/** 忽略的属性列表,设置一个属性列表,不拷贝这些属性值 */ */
private String[] ignoreProperties; public Object value(String name);
}
/**
* 创建拷贝选项 /**
* @return 拷贝选项 * 属性拷贝选项<br>
*/ * 包括:<br>
public static CopyOptions create(){ * 1、限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类<br>
return new CopyOptions(); * 2、是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null<br>
} * 3、忽略的属性列表,设置一个属性列表,不拷贝这些属性值<br>
*
/** * @author Looly
* 创建拷贝选项 */
* @param editable 限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性 public static class CopyOptions {
* @param isIgnoreNullValue 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null /**
* @param ignoreProperties 忽略的属性列表,设置一个属性列表,不拷贝这些属性值 * 限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类
* @return 拷贝选项 */
*/ private Class<?> editable;
public static CopyOptions create(Class<?> editable, boolean isIgnoreNullValue, String... ignoreProperties){ /**
return new CopyOptions(editable, isIgnoreNullValue, ignoreProperties); * 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null
} */
private boolean isIgnoreNullValue;
/** /**
* 构造拷贝选项 * 忽略的属性列表,设置一个属性列表,不拷贝这些属性值
*/ */
public CopyOptions() { private String[] ignoreProperties;
}
/**
/** * 创建拷贝选项
* 构造拷贝选项 *
* @param editable 限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性 * @return 拷贝选项
* @param isIgnoreNullValue 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null */
* @param ignoreProperties 忽略的属性列表,设置一个属性列表,不拷贝这些属性值 public static CopyOptions create() {
*/ return new CopyOptions();
public CopyOptions(Class<?> editable, boolean isIgnoreNullValue, String... ignoreProperties) { }
this.editable = editable;
this.isIgnoreNullValue = isIgnoreNullValue; /**
this.ignoreProperties = ignoreProperties; * 创建拷贝选项
} *
* @param editable 限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性
/** * @param isIgnoreNullValue 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null
* 设置限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性 * @param ignoreProperties 忽略的属性列表,设置一个属性列表,不拷贝这些属性值
* @param editable 限制的类或接口 * @return 拷贝选项
* @return CopyOptions */
*/ public static CopyOptions create(Class<?> editable, boolean isIgnoreNullValue, String... ignoreProperties) {
public CopyOptions setEditable(Class<?> editable){ return new CopyOptions(editable, isIgnoreNullValue, ignoreProperties);
this.editable = editable; }
return this;
} /**
* 构造拷贝选项
/** */
* 设置是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null public CopyOptions() {
* @param isIgnoreNullVall 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null }
* @return CopyOptions
*/ /**
public CopyOptions setIgnoreNullValue(boolean isIgnoreNullVall){ * 构造拷贝选项
this.isIgnoreNullValue = isIgnoreNullVall; *
return this; * @param editable 限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性
} * @param isIgnoreNullValue 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null
* @param ignoreProperties 忽略的属性列表,设置一个属性列表,不拷贝这些属性值
/** */
* 设置忽略的属性列表,设置一个属性列表,不拷贝这些属性值 public CopyOptions(Class<?> editable, boolean isIgnoreNullValue, String... ignoreProperties) {
* @param ignoreProperties 忽略的属性列表,设置一个属性列表,不拷贝这些属性值 this.editable = editable;
* @return CopyOptions this.isIgnoreNullValue = isIgnoreNullValue;
*/ this.ignoreProperties = ignoreProperties;
public CopyOptions setIgnoreProperties(String... ignoreProperties){ }
this.ignoreProperties = ignoreProperties;
return this; /**
} * 设置限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性
} *
* @param editable 限制的类或接口
* @return CopyOptions
*/
public CopyOptions setEditable(Class<?> editable) {
this.editable = editable;
return this;
}
/**
* 设置是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null
*
* @param isIgnoreNullVall 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null
* @return CopyOptions
*/
public CopyOptions setIgnoreNullValue(boolean isIgnoreNullVall) {
this.isIgnoreNullValue = isIgnoreNullVall;
return this;
}
/**
* 设置忽略的属性列表,设置一个属性列表,不拷贝这些属性值
*
* @param ignoreProperties 忽略的属性列表,设置一个属性列表,不拷贝这些属性值
* @return CopyOptions
*/
public CopyOptions setIgnoreProperties(String... ignoreProperties) {
this.ignoreProperties = ignoreProperties;
return this;
}
}
} }
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
<mybatisplus-spring-boot-starter.version>1.0.4</mybatisplus-spring-boot-starter.version> <mybatisplus-spring-boot-starter.version>1.0.4</mybatisplus-spring-boot-starter.version>
<shiro.version>1.4.0</shiro.version> <shiro.version>1.4.0</shiro.version>
<mybatis-plus.version>2.1.0</mybatis-plus.version> <mybatis-plus.version>2.1.0</mybatis-plus.version>
<fastjson.version>1.2.31</fastjson.version> <fastjson.version>1.2.41</fastjson.version>
<commons.io.version>2.5</commons.io.version> <commons.io.version>2.5</commons.io.version>
<velocity.version>1.7</velocity.version> <velocity.version>1.7</velocity.version>
<kaptcha.version>2.3.2</kaptcha.version> <kaptcha.version>2.3.2</kaptcha.version>
......
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