src/main/java/com/zy/crm/common/model/SettleDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/crm/manager/controller/ContractController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/crm/manager/entity/Contract.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/resources/mapper/ContractMapper.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/webapp/static/js/common.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/webapp/static/js/contract/contract.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/webapp/views/contract/contract.html | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/webapp/views/contract/contract_more.html | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/zy/crm/common/model/SettleDto.java
@@ -243,4 +243,49 @@ return list; } public static List<SettleDto> initContract(User manager ,User user,User president,List<String> names ,int nodes) { List<SettleDto> list = new ArrayList<>(); for (int i = 0; i < nodes+1; i++) { SettleDto dto = new SettleDto(); dto.setStep(i); switch (i) { case 0: dto.setTitle("开始"); dto.setMsg(user.getUsername() + names.get(i)); dto.setUserId(user.getId()); dto.setUsername(user.getUsername()); dto.setTime(DateUtils.convert(new Date())); dto.setCurr(Boolean.TRUE); list.add(dto); break; case 1: dto.setTitle(names.get(i)); dto.setUserId(user.getId()); dto.setUsername(user.getNickname()); list.add(dto); break; case 2: dto.setTitle(names.get(i)); dto.setUserId(manager.getId()); dto.setUsername(manager.getNickname()); list.add(dto); break; case 3: dto.setTitle(names.get(i)); dto.setUserId(president.getId()); dto.setUsername(president.getNickname()); list.add(dto); break; case 4: dto.setTitle(names.get(i)); list.add(dto); break; default: break; } } return list; } } src/main/java/com/zy/crm/manager/controller/ContractController.java
@@ -1,15 +1,16 @@ package com.zy.crm.manager.controller; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.baomidou.mybatisplus.mapper.Wrapper; import com.baomidou.mybatisplus.plugins.Page; import com.core.common.DateUtils; import com.core.exception.CoolException; import com.zy.crm.common.model.SettleDto; import com.zy.crm.common.service.OssService; import com.zy.crm.manager.entity.Contract; import com.zy.crm.manager.entity.ContractSales; import com.zy.crm.manager.entity.PriOnline; import com.zy.crm.manager.entity.*; import com.zy.crm.manager.service.ContractSalesService; import com.zy.crm.manager.service.ContractService; import com.core.annotations.ManagerAuth; @@ -18,8 +19,11 @@ import com.core.common.R; import com.core.domain.KeyValueVo; import com.zy.crm.common.web.BaseController; import com.zy.crm.manager.service.ProcessPermissionsService; import com.zy.crm.manager.utils.ChineseNumberUtils; import com.zy.crm.manager.utils.WordUtils; import com.zy.crm.system.entity.User; import com.zy.crm.system.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.InputStreamResource; import org.springframework.http.HttpHeaders; @@ -44,11 +48,20 @@ private ContractSalesService contractSalesService; @Autowired private OssService ossService; @Autowired private UserService userService; @Autowired private ProcessPermissionsService processPermissionsService; @RequestMapping(value = "/contract/{id}/auth") @ManagerAuth public R get(@PathVariable("id") String id) { return R.ok(contractService.selectById(String.valueOf(id))); Contract contract = contractService.selectById(String.valueOf(id)); assert contract != null; JSONObject resultObj = JSON.parseObject(JSON.toJSONString(contract)); // 步骤条相关 resultObj.put("step", contract.getSettle() == 5 ? 0 : contract.getSettle() + 1); return R.ok().add(resultObj); } @RequestMapping(value = "/contract/list/auth") @@ -83,10 +96,27 @@ @RequestMapping(value = "/contract/add/auth") @ManagerAuth(memo = "添加合同") public R add(Contract contract) { Date now = new Date(); contract.setUserId(getUserId()); //创建人员部门 contract.setDeptId(getDeptId()); contract.setCreateTime(new Date()); contract.setCreateTime(now); contract.setSettle(0); User manager = userService.getDeptManager(getHostId(), getUser().getDeptId()); // 获取部门领导 List<String> initNames = new ArrayList<>(); initNames.add("创建产品费用明细模板"); initNames.add("提交产品费用明细"); initNames.add("部门经理审核"); ProcessPermissions processPermissions = processPermissionsService.selectOne(new EntityWrapper<ProcessPermissions>().eq("process_memo", 7).eq("process", "3-1" ));//7:合同管理 User president = userService.selectById(processPermissions.getUserId()); initNames.add("总裁办"+president.getNickname()+"审核"); initNames.add("业务员确认"); contract.setSettleMsg(JSON.toJSONString(SettleDto.initContract(manager,getUser(),president,initNames,4))); contract.setUpdateTime(now); contract.setUpdateBy(getUserId()); contractService.insert(contract); return R.ok(); } @@ -296,4 +326,152 @@ return R.ok().add(vos); } @PostMapping(value = "/contracr/approval/auth") @ManagerAuth public R approvalBusinessTrip(@RequestParam Long contracrId, @RequestParam(required = false) Long plannerId){ Contract contract = contractService.selectById(contracrId); assert contract != null; Date now = new Date(); switch (contract.getSettle()) { case 0: User user2 = userService.selectById(contract.getUserId()); User manager1 = userService.getDeptManager(getHostId(), user2.getDeptId()); if (Cools.isEmpty(getUser())) { return R.error("抱歉,您没有提交的权限"); } if (!getUserId().equals(getUser().getId())) { return R.error("抱歉,您没有提交的权限"); } // 修改 settle 步骤数据 List<SettleDto> list1 = JSON.parseArray(contract.getSettleMsg(), SettleDto.class); for (SettleDto dto : list1) { switch (dto.getStep()) { case 0: dto.setCurr(Boolean.FALSE); break; case 1: dto.setCurr(Boolean.TRUE); dto.setMsg(getUser().getNickname() + "提交完成"); dto.setTime(DateUtils.convert(now)); break; default: break; } } contract.setSettleMsg(JSON.toJSONString(list1)); // 修改规划单状态 contract.setSettle(1); contract.setUpdateTime(now); if (!contractService.updateById(contract)) { throw new CoolException("提交失败,请联系管理员"); } break; case 1: // 本部门经理审核 User user = userService.selectById(contract.getUserId()); User manager = userService.getDeptManager(getHostId(), user.getDeptId()); if (manager.getId().equals(getUserId())) { // 修改 settle 步骤数据 List<SettleDto> list = JSON.parseArray(contract.getSettleMsg(), SettleDto.class); for (SettleDto dto : list) { switch (dto.getStep()) { case 1: dto.setCurr(Boolean.FALSE); break; case 2: dto.setCurr(Boolean.TRUE); dto.setMsg("部门经理" + manager.getNickname() + "审批通过"); dto.setTime(DateUtils.convert(now)); break; default: break; } } contract.setSettleMsg(JSON.toJSONString(list)); // 修改规划单状态 contract.setSettle(2); // 申请通过 contract.setUpdateTime(now); if (!contractService.updateById(contract)) { throw new CoolException("审核失败,请联系管理员"); } } else { return R.error("抱歉,您没有审核的权限!!!"); } break; case 2: ProcessPermissions processPermissions = processPermissionsService.selectOne(new EntityWrapper<ProcessPermissions>().eq("process_memo", 7).eq("process", "3-1"));//3:报销流程 User planLeader = userService.selectById(processPermissions.getUserId()); // 获取合同管理流程节点确认人 if (planLeader.getId().equals(getUserId())) { // 修改 settle 步骤数据 List<SettleDto> list = JSON.parseArray(contract.getSettleMsg(), SettleDto.class); for (SettleDto dto : list) { switch (dto.getStep()) { case 2: dto.setCurr(Boolean.FALSE); break; case 3: dto.setCurr(Boolean.TRUE); dto.setMsg("总裁办" + planLeader.getNickname() + "审批通过"); dto.setTime(DateUtils.convert(now)); break; default: break; } } contract.setSettleMsg(JSON.toJSONString(list)); // 修改规划单状态 contract.setSettle(3); // 申请通过 contract.setUpdateTime(now); if (!contractService.updateById(contract)) { throw new CoolException("审核失败,请联系管理员"); } } else { return R.error("抱歉,您没有审核的权限!!!"); } break; case 3: // 业务员 User salesman0 = userService.selectById(contract.getUserId()); if (!getUserId().equals(salesman0.getId())) { return R.error("抱歉,您无需确认!!!"); } // 修改 settle 步骤数据 List<SettleDto> list2 = JSON.parseArray(contract.getSettleMsg(), SettleDto.class); for (SettleDto dto : list2) { switch (dto.getStep()) { case 3: dto.setCurr(Boolean.TRUE); break; case 4: dto.setCurr(Boolean.TRUE); dto.setMsg("业务员" + salesman0.getNickname() + "以确认"); dto.setTime(DateUtils.convert(new Date())); break; default: break; } } contract.setSettleMsg(JSON.toJSONString(list2)); // 修改规划单状态 contract.setSettle(4); // 审批通过 contract.setUpdateTime(new Date()); if (!contractService.updateById(contract)) { throw new CoolException("确认失败,请联系管理员"); } break; default: return R.error(); } return R.ok("审批成功"); } } src/main/java/com/zy/crm/manager/entity/Contract.java
@@ -185,9 +185,29 @@ @TableField("dept_id") private Long deptId; /** * hostId */ @ApiModelProperty(value= "hostId") @TableField("host_id") private Long hostId; /** * 进度 */ @ApiModelProperty(value= "进度") private Integer settle; /** * 流程进度 */ @ApiModelProperty(value= "流程进度") @TableField("settle_msg") private String settleMsg; public Contract() {} public Contract(Long id, String customer, String address, String company, String companyAddress, String taxNum, String bank, String bankNum, Date createTime, Date updateTime, Long userId, Long updateBy, String filepath, String city, String shippingAddress, String shippingName, String shippingPhone, Double price, String email, String name, Integer status, String memo, String boss, String serial, Long deptId) { public Contract(Long id, String customer, String address, String company, String companyAddress, String taxNum, String bank, String bankNum, Date createTime, Date updateTime, Long userId, Long updateBy, String filepath, String city, String shippingAddress, String shippingName, String shippingPhone, Double price, String email, String name, Integer status, String memo, String boss, String serial, Long deptId, Long hostId,Integer settle,String settleMsg) { this.id = id; this.customer = customer; this.address = address; @@ -213,6 +233,9 @@ this.boss = boss; this.serial = serial; this.deptId = deptId; this.hostId = hostId; this.settle = settle; this.settleMsg = settleMsg; } // Contract contract = new Contract( @@ -237,6 +260,22 @@ // null // 电子邮箱 // ); public String getSettle$(){ if (null == this.settle){ return null; } switch (this.settle){ case 0: return "等待提交"; case 1: return "等待审批"; case 2: return "等待确认"; case 3: return "审批通过"; default: return String.valueOf(this.settle); } } public String getCreateTime$(){ if (Cools.isEmpty(this.createTime)){ return ""; src/main/resources/mapper/ContractMapper.xml
@@ -29,6 +29,9 @@ <result column="boss" property="boss" /> <result column="serial" property="serial" /> <result column="dept_id" property="deptId" /> <result column="settle" property="settle" /> <result column="settle_msg" property="settleMsg" /> <result column="host_id" property="hostId" /> </resultMap> src/main/webapp/static/js/common.js
@@ -239,3 +239,4 @@ var priOnlineByMore; var priSalesByMore; var priQuoteBudgetByMore; var contractByMore; src/main/webapp/static/js/contract/contract.js
@@ -88,11 +88,12 @@ , {field: 'status$', align: 'center', title: '状态'} , {field: 'userId$', align: 'center', title: '添加人员'} , {field: 'createTime$', align: 'center', title: '添加时间'} , {field: 'settle$', align: 'center',title: '进度', style: 'color: #1890ff;cursor:pointer', event: 'more',hide: false} , {field: 'updateBy$', align: 'center', title: '修改人员'} , {field: 'updateTime$', align: 'center', title: '修改时间'} , {field: 'memo', align: 'center', title: '备注'} , {fixed: 'right', title: '操作', align: 'center', toolbar: '#operate', width: 400} , {fixed: 'right', title: '操作', align: 'center', toolbar: '#operate', width: 500} ]], request: { pageName: 'curr', @@ -193,6 +194,29 @@ table.on('tool(contract)', function (obj) { var data = obj.data; switch (obj.event) { case 'approval': layer.confirm('审批通过?', { skin: 'layui-layer-admin', shade: .1, offset: '200px', title: data.name }, function (i) { layer.close(i); approval(data.id); }); break; case 'more': top.contractByMore = data.id; admin.popupRight({ type: 1, window: "top", area: "1250px", url: "contract_more.html", end: function () { // $(".layui-laypage-btn")[0].click(); } }) break; case 'edit': showEditModel(data); break; @@ -472,6 +496,33 @@ layDateRender(); function approval(contractId, plannerId, dIdx) { let loadIndex = layer.load(2); $.ajax({ url: baseUrl+"/contract/approval/auth", headers: {'token': localStorage.getItem('token')}, data: { contractId: contractId, plannerId: plannerId }, method: 'POST', success: function (res) { if (dIdx) { layer.close(dIdx); } layer.close(loadIndex); if (res.code === 200){ layer.msg(res.msg, {icon: 1}); tableReload(); } else if (res.code === 403){ top.location.href = baseUrl+"/"; } else { layer.msg(res.msg, {icon: 2}); } } }) } }); // 关闭动作 src/main/webapp/views/contract/contract.html
@@ -71,17 +71,29 @@ </script> <script type="text/html" id="operate"> <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="edit">修改</a> {{# if (d.settle == 0) { }} <a class="layui-btn layui-btn-xs btn-edit" lay-event="approval">提交</a> {{# } }} {{# if (d.settle == 1) { }} <a class="layui-btn layui-btn-xs btn-edit" lay-event="approval">审批</a> {{# } }} {{# if (d.settle == 2) { }} <a class="layui-btn layui-btn-xs btn-edit" lay-event="approval">确认</a> {{# } }} {{# if (d.settle == 0 || d.settle == 1) { }} <a class="layui-btn layui-btn-danger layui-btn-xs btn-edit" lay-event="del">删除</a> <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="edit">编辑</a> {{# } }} <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="sales">合同明细</a> <a class="layui-btn layui-btn-xs btn-edit" lay-event="generate">生成合同</a> <a class="layui-btn layui-btn-xs btn-edit" lay-event="upload">上传合同</a> <a class="layui-btn layui-btn-xs btn-edit" lay-event="download">下载</a> <a class="layui-btn layui-btn-danger layui-btn-xs btn-edit" lay-event="del">删除</a> </script> <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> <script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script> <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> <script type="text/javascript" src="../../static/js/handlebars/handlebars-v4.5.3.js"></script> <script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script> <script type="text/javascript" src="../../static/js/contract/contract.js" charset="utf-8"></script> </body> src/main/webapp/views/contract/contract_more.html
New file @@ -0,0 +1,187 @@ <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <style> #formAdvForm { background-color: #f3f3f3; } #formAdvForm .layui-form-item { margin-top: 20px; margin-bottom: 0; } #formAdvForm .layui-form-item .layui-inline { margin-bottom: 25px; margin-right: 0; } .form-group-bottom { position: fixed; left: 0; right: 0; bottom: 0; padding: 10px 20px; background-color: #fff; box-shadow: 0 -1px 2px 0 rgba(0, 0, 0, .05); } </style> <!-- 正文开始 --> <form class="layui-form" id="formAdvForm" lay-filter="formAdvForm" style="height: 100%"> <div class="layui-fluid" style="padding-bottom: 75px;height: 100%; overflow: scroll;box-sizing: border-box"> <!-- 标题 --> <div class="layui-card"> <div class="layui-card-header" style="padding-top: 5px; padding-bottom: 5px"> <div> <i class="layui-icon" style="font-size: 20px;color: #1890ff;font-weight: bold"></i> <span id="form-name" style="margin: 0 6px;font-size: 18px;font-weight: bold;letter-spacing: 1px"></span> <span style="opacity: .5;font-size: small;margin-left: 5px">核价单</span> </div> </div> <div class="layui-card-body" style="padding: 30px 20px"> <div class="layui-tab layui-steps"> <ul class="layui-tab-title" id="stepBox"> </ul> </div> </div> </div> <div class="layui-row"> <!-- 数据 --> <!-- <div class="layui-col-md9">--> <!-- <div class="layui-card">--> <!-- <div class="layui-card-header">--> <!-- 基本信息--> <!-- </div>--> <!-- <div class="layui-card-body">--> <!-- </div>--> <!-- </div>--> <!-- </div>--> <!-- 动态 --> <!-- <div class="layui-col-md3" style="width: 24%;margin-left: 1%">--> <div class="layui-col-md3" style="width: 100%;"> <!-- 时间线 --> <div class="layui-card"> <div class="layui-card-header"> <span>流程动态</span> </div> <div class="layui-card-body"> <ul class="layui-timeline" id="timelineBox"> </ul> </div> </div> </div> </div> </div> <div class="form-group-bottom text-right"> <button class="layui-btn" lay-filter="refresh" lay-submit><i class="layui-icon"></i> 刷新 </button> </div> </form> <script type="text/html" id="followerTabOperate"> <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="del">删除</a> </script> <script type="text/template" id="stepTpl"> {{#each list}} <li id="step-{{step}}" style="pointer-events: none"> <i class="layui-icon layui-icon-ok">{{step}}</i> <span class="layui-steps-title">{{title}}</span> {{# if username}} <span class="layui-steps-content">{{username}}</span> {{ else }} <span class="layui-steps-content"> </span> {{/if}} </li> {{/each}} </script> <script type="text/template" id="timelineTpl"> {{#each list}} <li class="layui-timeline-item"> <i class="layui-icon layui-timeline-axis"></i> <div class="layui-timeline-content layui-text"> <h4 class="layui-timeline-title" style="display: inline;margin-right: 10px;">{{title}}</h4> <span>{{time}}</span> <p> {{msg}} </p> </div> </li> {{/each}} </script> <script> var contractId = top.contractByMore; $('.layui-layer-close').hide(); layui.config({ base: baseUrl + "/static/layui/lay/modules/" }).extend({ notice: 'notice/notice', steps: 'steps/steps', }).use(['form', 'table', 'laydate', 'notice', 'xmSelect', 'steps'], function () { var $ = layui.jquery; var form = layui.form; var table = layui.table; var laydate = layui.laydate; var notice = layui.notice; var xmSelect = layui.xmSelect; var steps = layui.steps; form.render('select'); init(); function init(){ notice.msg('正在载入数据......', {icon: 4, position: "topRight"}); $.ajax({ url: baseUrl + "/contract/" + contractId + "/auth", headers: {'token': localStorage.getItem('token')}, method: 'GET', success: function (res) { notice.destroy(); if (res.code === 200) { let contract = res.data; top.contractByMore = null; $("#form-name").html(contract.name); // 进度步骤图 let template0 = Handlebars.compile($('#stepTpl').html()); $('#stepBox').html(template0({list: JSON.parse(contract.settleMsg)})); $('#step-' + Number(contract.step)).addClass("layui-this"); let template1 = Handlebars.compile($('#timelineTpl').html()); $('#timelineBox').html(template1({list: JSON.parse(contract.settleMsg)})); // 补充html $('#customizeBox').html(contract.formHtml); // 设备明细 // form.val('formAdvForm', contract); // top.convertDisabled($('#formAdvForm :input'), true); // 跟进人 // initFollowers(contract.id); layDateRender(); } else if (res.code === 403) { top.location.href = baseUrl + "/"; } else { layer.msg(res.msg, {icon: 2}) } } }) } /* 渲染laydate */ function layDateRender() { laydate.render({ elem: '#endTime', type: 'datetime' }); } layDateRender(); /* 监听表单提交 */ form.on('submit(refresh)', function (data) { init(); return false; }); }) </script>