ソースを参照

Merge branch 'master' of http://47.100.37.243:10080/wutt/manHourHousekeeper

ggooalice 2 年 前
コミット
1347595392
54 ファイル変更2647 行追加152 行削除
  1. 16 5
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/BusinessTripController.java
  2. 39 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/BustripAuditLogController.java
  3. 107 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ContractController.java
  4. 80 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ContractDocumentController.java
  5. 52 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ContractTypeController.java
  6. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/StagesController.java
  7. 13 5
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java
  8. 30 7
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/BusinessTrip.java
  9. 67 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/BustripAuditLog.java
  10. 113 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Contract.java
  11. 106 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ContractDocument.java
  12. 51 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ContractType.java
  13. 18 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ContractFileDelVo.java
  14. 18 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ContractFileVo.java
  15. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/BustripAuditLogMapper.java
  16. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ContractDocumentMapper.java
  17. 18 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ContractMapper.java
  18. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ContractTypeMapper.java
  19. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/TaskMapper.java
  20. 4 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/BusinessTripService.java
  21. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/BustripAuditLogService.java
  22. 30 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ContractDocumentService.java
  23. 37 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ContractService.java
  24. 24 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ContractTypeService.java
  25. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/TaskService.java
  26. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/WxCorpInfoService.java
  27. 2 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/AuditWorkflowSettingServiceImpl.java
  28. 314 14
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/BusinessTripServiceImpl.java
  29. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/BustripAuditLogServiceImpl.java
  30. 216 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractDocumentServiceImpl.java
  31. 535 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractServiceImpl.java
  32. 115 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractTypeServiceImpl.java
  33. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/InformationServiceImpl.java
  34. 4 13
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/LeaveSheetServiceImpl.java
  35. 16 5
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectMainServiceImpl.java
  36. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  37. 58 7
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  38. 3 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java
  39. 25 5
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java
  40. 3 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/i18n/messages.properties
  41. 3 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/i18n/messages_en_US.properties
  42. 7 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/BusinessTripMapper.xml
  43. 22 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/BustripAuditLogMapper.xml
  44. 27 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ContractDocumentMapper.xml
  45. 51 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ContractMapper.xml
  46. 17 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ContractTypeMapper.xml
  47. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/LeaveSheetMapper.xml
  48. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TaskMapper.xml
  49. 2 2
      fhKeeper/formulahousekeeper/timesheet/src/components/select.vue
  50. 5 1
      fhKeeper/formulahousekeeper/timesheet/src/views/Home.vue
  51. 237 46
      fhKeeper/formulahousekeeper/timesheet/src/views/awayOffice/awayOffice.vue
  52. 23 14
      fhKeeper/formulahousekeeper/timesheet/src/views/leave/list.vue
  53. 25 11
      fhKeeper/formulahousekeeper/timesheet/src/views/project/vueGantt.vue
  54. 17 1
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

+ 16 - 5
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/BusinessTripController.java

@@ -2,6 +2,7 @@ package com.management.platform.controller;
 
 
 import com.management.platform.entity.BusinessTrip;
+import com.management.platform.entity.LeaveSheet;
 import com.management.platform.mapper.UserMapper;
 import com.management.platform.service.BusinessTripService;
 import com.management.platform.util.HttpRespMsg;
@@ -45,6 +46,14 @@ public class BusinessTripController {
 
     }
 
+
+    @RequestMapping("/cancel")
+    public HttpRespMsg cancel(Integer id) {
+        String userId = request.getHeader("Token");
+        return businessTripService.cancel(id, userId);
+    }
+
+
     @RequestMapping("/delete")
     public HttpRespMsg delete(Integer id) {
         return businessTripService.delete(id);
@@ -55,16 +64,18 @@ public class BusinessTripController {
         return businessTripService.queryList(sheet, pageIndex, pageSize,checkState);
     }
 
+    @RequestMapping("/auditList")
+    public HttpRespMsg auditList(BusinessTrip sheet, @RequestParam Integer pageIndex, @RequestParam Integer pageSize, @RequestParam(defaultValue = "0") Integer checkState) {
+        return businessTripService.auditList(sheet, pageIndex, pageSize, checkState);
+    }
+
     @RequestMapping("/approve")
     public HttpRespMsg approve(Integer id) {
-
         return businessTripService.approve(id);
-
     }
     @RequestMapping("/deny")
-    public HttpRespMsg deny(Integer id, String denyReason) {
-
-        return businessTripService.deny(id, denyReason);
+    public HttpRespMsg deny(Integer id, String reason) {
+        return businessTripService.deny(id, reason);
 
     }
 

+ 39 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/BustripAuditLogController.java

@@ -0,0 +1,39 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.BustripAuditLog;
+import com.management.platform.entity.LeaveAuditLog;
+import com.management.platform.mapper.BustripAuditLogMapper;
+import com.management.platform.mapper.LeaveAuditLogMapper;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-12
+ */
+@RestController
+@RequestMapping("/bustrip-audit-log")
+public class BustripAuditLogController {
+    @Resource
+    BustripAuditLogMapper bustripAuditLogMapper;
+
+    @RequestMapping("/getBySheetId")
+    public HttpRespMsg getBySheetId(int sheetId) {
+        List<BustripAuditLog> list = bustripAuditLogMapper.selectList(new QueryWrapper<BustripAuditLog>().eq("sheet_id", sheetId));
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = list;
+        return msg;
+    }
+}
+

+ 107 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ContractController.java

@@ -0,0 +1,107 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.Contract;
+import com.management.platform.entity.User;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.ContractService;
+import com.management.platform.service.ContractTypeService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.http.HttpRequest;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-29
+ */
+@RestController
+@RequestMapping("/contract")
+public class ContractController {
+    @Resource
+    private ContractService contractService;
+    @Resource
+    private UserMapper userMapper;
+
+    /**
+     * 分页查询合同
+     */
+    @RequestMapping("/getContractPage")
+    public HttpRespMsg getContractPage (HttpServletRequest request, @RequestParam Integer pageIndex, @RequestParam Integer pageSize, String number,String name,String typeName,Integer status,String startDate,String endDate){
+        return contractService.getContractPage(request,pageIndex,pageSize,number,name,typeName,status,startDate,endDate);
+    }
+
+    /**
+     * 导出合同
+     */
+    @RequestMapping("/ExportContract")
+    public HttpRespMsg ExportContract (HttpServletRequest request, String number,String name,String typeName,Integer status,String startDate,String endDate){
+        return contractService.ExportContract(request,number,name,typeName,status,startDate,endDate);
+    }
+
+    /**
+     * 导入合同
+     */
+    @RequestMapping("/importContract")
+    public HttpRespMsg importContract (HttpServletRequest request, MultipartFile file){
+        return contractService.importContract(request,file);
+    }
+
+    /**
+     * 新增合同
+     */
+    @RequestMapping("/addContract")
+    public HttpRespMsg addContract (HttpServletRequest request,Contract contract){
+        return contractService.addContract(request,contract);
+    }
+
+    /**
+     * 编辑合同
+     */
+    @RequestMapping("/editContract")
+    public HttpRespMsg editContract (HttpServletRequest request,Contract contract){
+        return contractService.editContract(request,contract);
+    }
+
+    /**
+     * 审核合同
+     */
+    @RequestMapping("/processContract")
+    public HttpRespMsg processContract (HttpServletRequest request,Integer id,Integer status){
+        return contractService.processContract(request,id,status);
+    }
+
+    /**
+     * 删除合同
+     * @param request
+     * @param id
+     * @return
+     */
+    @RequestMapping("/deleteContract")
+    public HttpRespMsg deleteContract (HttpServletRequest request,Integer id){
+        return contractService.deleteContract(request,id);
+    }
+
+
+    /**
+     * 返回该合同的附件列表
+     */
+    @RequestMapping("/contractFile")
+    public HttpRespMsg contractFile (HttpServletRequest request,Integer id){
+        return contractService.contractFile(request,id);
+    }
+}
+

+ 80 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ContractDocumentController.java

@@ -0,0 +1,80 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.ContractDocument;
+import com.management.platform.entity.vo.ContractFileDelVo;
+import com.management.platform.entity.vo.ContractFileVo;
+import com.management.platform.service.ContractDocumentService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-09
+ */
+@RestController
+@RequestMapping("/contract-document")
+public class ContractDocumentController {
+    @Resource
+    private ContractDocumentService contractDocumentService;
+
+    /**
+     * 上传附件
+     * @param request
+     * @param ContractId
+     * @param folderId
+     * @param files
+     * @return
+     */
+    @RequestMapping("/fileUpload")
+    public HttpRespMsg fileUpload (HttpServletRequest request, @RequestParam Integer ContractId, @RequestParam(required=false) Integer folderId, @RequestParam("file") MultipartFile[] files){
+        return contractDocumentService.fileUpload(request,ContractId,folderId,files);
+    }
+
+    /**
+     * 下载文件
+     * @param request
+     * @param folderId
+     * @param contractFileVo
+     * @return
+     */
+    @RequestMapping("/fileDown")
+    public HttpRespMsg fileDown (HttpServletRequest request, HttpServletResponse response, @RequestParam(required=false) Integer folderId, ContractFileVo contractFileVo){
+        return contractDocumentService.fileDown(request,response,folderId,contractFileVo);
+    }
+
+    /**
+     * 删除文件
+     * @param request
+     * @param contractFileDelVo
+     * @return
+     */
+    @RequestMapping("/fileDelete")
+    public HttpRespMsg fileDelete (HttpServletRequest request, ContractFileDelVo contractFileDelVo){
+        return contractDocumentService.fileDelete(request,contractFileDelVo);
+    }
+
+    /**
+     * 在线预览
+     * @param inputFilePath
+     * @return
+     */
+    @RequestMapping("/onlineShow")
+    public HttpRespMsg onlineShow (@RequestParam String inputFilePath){
+        return contractDocumentService.onlineShow(inputFilePath);
+    }
+}
+

+ 52 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ContractTypeController.java

@@ -0,0 +1,52 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.ContractType;
+import com.management.platform.service.ContractTypeService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-29
+ */
+@RestController
+@RequestMapping("/contractType")
+public class ContractTypeController {
+    @Resource
+    private ContractTypeService contractTypeService;
+
+    /**
+     * 返回公司自定义合同类型
+     */
+    @RequestMapping("/getContractType")
+    public HttpRespMsg getContractType (HttpServletRequest request){
+        return contractTypeService.getContractType(request);
+    }
+
+    /**
+     * 新增、修改合同类型
+     */
+    @RequestMapping("/changeContractType")
+    public HttpRespMsg changeContractType (HttpServletRequest request, ContractType contractType){
+        return contractTypeService.changeContractType(request,contractType);
+    }
+
+    /**
+     * 删除合同类型
+     */
+    @RequestMapping("/deleteContractType")
+    public HttpRespMsg deleteContractType (HttpServletRequest request, Integer deleteId){
+        return contractTypeService.deleteContractType(request,deleteId);
+    }
+}
+

+ 2 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/StagesController.java

@@ -197,7 +197,7 @@ public class StagesController {
         } else {
             queryWrapper.orderByAsc(order);
         }
-        List<Task> tasks = taskService.simpleList(queryWrapper);
+        List<Task> tasks = taskService.simpleList(queryWrapper,null,null);
         //没有权限只能看到自己创建的,负责的和待分配的任务
         List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全部任务");
         if (functionList.size() == 0 && !userId.equals(project.getInchargerId())) {
@@ -206,7 +206,7 @@ public class StagesController {
         List<Task> subTasks = new ArrayList<>();
         if (tasks.size() > 0) {
             List<Integer> collect = tasks.stream().map(Task::getId).collect(Collectors.toList());
-            List<Task> subLists = taskService.simpleList(new QueryWrapper<Task>().in("parent_tid", collect));
+            List<Task> subLists = taskService.simpleList(new QueryWrapper<Task>().in("parent_tid", collect),null,null);
             if (functionList.size() == 0 && !userId.equals(project.getInchargerId())) {
                 subLists = subLists.stream().filter(t->t.getExecutorId() == null || t.getExecutorId().contains(userId) || userId.equals(t.getCreaterId())).collect(Collectors.toList());
             }

+ 13 - 5
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java

@@ -3,7 +3,10 @@ package com.management.platform.controller;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.pagehelper.IPage;
 import com.management.platform.entity.*;
 import com.management.platform.entity.vo.SysRichFunction;
 import com.management.platform.mapper.*;
@@ -289,7 +292,7 @@ public class TaskController {
 
     private void updateProjectProgress(Integer projectId) {
         //只有里程碑才更新项目进度, 非已撤销状态的
-        List<Task> all = taskMapper.simpleList(new QueryWrapper<Task>().eq("project_id", projectId).ne("task_status", 2).eq("task_type",1));
+        List<Task> all = taskMapper.simpleList(new QueryWrapper<Task>().eq("project_id", projectId).ne("task_status", 2).eq("task_type",1),null,null);
         Project project = new Project();
         project.setId(projectId);
         if (all.size() > 0) {
@@ -441,8 +444,10 @@ public class TaskController {
 
 
     @RequestMapping("/list")
-    public HttpRespMsg list(Task task, Integer viewId, String order, boolean isDesc) {
+    public HttpRespMsg list(Task task, Integer viewId, String order, boolean isDesc,Integer pageIndex,Integer pageSize) {
         HttpRespMsg msg = new HttpRespMsg();
+        Integer size=pageSize;
+        Integer start=(pageIndex-1)*pageSize;
         String userId = request.getHeader("Token");
         User user = userMapper.selectById(userId);
         Project project = projectService.getById(task.getProjectId());
@@ -480,8 +485,8 @@ public class TaskController {
             //已超期的任务,未完成的任务
             queryWrapper.lt("end_date", LocalDate.now()).eq("task_status", 0);
         }
-        List<Task> list = taskService.simpleList(queryWrapper);
-
+        List<Task> list = taskService.simpleList(queryWrapper,start,size);
+        int total = taskMapper.selectCount(queryWrapper);
         //没有权限只能看到自己创建的,负责的和待分配的任务
         List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全部任务");
         if (functionList.size() == 0 && !userId.equals(project.getInchargerId())) {
@@ -495,7 +500,10 @@ public class TaskController {
             }
 
         });
-        msg.data = list;
+        Map map=new HashMap();
+        map.put("records",list);
+        map.put("total",total);
+        msg.data = map;
         return msg;
     }
 

+ 30 - 7
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/BusinessTrip.java

@@ -21,7 +21,7 @@ import org.springframework.format.annotation.DateTimeFormat;
  * </p>
  *
  * @author Seyason
- * @since 2022-07-15
+ * @since 2022-12-12
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -127,12 +127,6 @@ public class BusinessTrip extends Model<BusinessTrip> {
     @JsonFormat(pattern = "yyyy-MM-dd")
     private LocalDateTime indate;
 
-    @TableField(exist = false)
-    private String departmentName;
-
-    @TableField(exist = false)
-    List<BustripProject> projectList;
-
     /**
      * 是否已经关联
      */
@@ -151,6 +145,35 @@ public class BusinessTrip extends Model<BusinessTrip> {
     @TableField("gmt_finished")
     private String gmtFinished;
 
+    /**
+     * 审核人id
+     */
+    @TableField("auditor_id")
+    private String auditorId;
+
+    /**
+     * 审核人姓名
+     */
+    @TableField("auditor_name")
+    private String auditorName;
+
+    /**
+     * 1-部门审核,2-指定人员审核
+     */
+    @TableField("auditor_type")
+    private Integer auditorType;
+
+    /**
+     * 当前审核节点id
+     */
+    @TableField("cur_audit_setting_id")
+    private Integer curAuditSettingId;
+
+    @TableField(exist = false)
+    private String departmentName;
+
+    @TableField(exist = false)
+    List<BustripProject> projectList;
 
     @Override
     protected Serializable pkVal() {

+ 67 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/BustripAuditLog.java

@@ -0,0 +1,67 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-12
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class BustripAuditLog extends Model<BustripAuditLog> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 表单id
+     */
+    @TableField("sheet_id")
+    private Integer sheetId;
+
+    /**
+     * 审批节点id
+     */
+    @TableField("audit_node_id")
+    private Integer auditNodeId;
+
+    @TableField("auditor_id")
+    private String auditorId;
+
+    @TableField("auditor_name")
+    private String auditorName;
+
+    /**
+     * 是否审核通过,1-通过,0-驳回
+     */
+    @TableField("is_pass")
+    private Integer isPass;
+
+    @TableField("indate")
+    private LocalDateTime indate;
+
+    @TableField("deny_reason")
+    private String denyReason;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 113 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Contract.java

@@ -0,0 +1,113 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-29
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class Contract extends Model<Contract> {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 合同表主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 公司id
+     */
+    @TableField("company_id")
+    private Integer companyId;
+
+    /**
+     * 创建者Id
+     */
+    @TableField("creator_id")
+    private String creatorId;
+
+    /**
+     * 合同编号
+     */
+    @TableField("number")
+    private String number;
+
+    /**
+     * 合同名称
+     */
+    @TableField("name")
+    private String name;
+
+    /**
+     * 金额
+     */
+    @TableField("amounts")
+    private Integer amounts;
+
+    /**
+     * 合同类型的id
+     */
+    @TableField("type_id")
+    private Integer typeId;
+
+    /**
+     * 合同类型的名称
+     */
+    @TableField(exist = false)
+    private String typeName;
+
+    /**
+     * 审核人Id
+     */
+    @TableField("checkerId")
+    private String checkerId;
+
+    /**
+     * 0-审核通过,1-待审核,2-驳回, 3-导入待审核
+     */
+    @TableField("status")
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    @TableField("indate")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate indate;
+
+    /**
+     * 备注
+     */
+    @TableField("remarks")
+    private String remarks;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 106 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ContractDocument.java

@@ -0,0 +1,106 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-09
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ContractDocument extends Model<ContractDocument> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 文件名
+     */
+    @TableField("document_name")
+    private String documentName;
+
+    /**
+     * 服务器生成的文件名
+     */
+    @TableField("server_name")
+    private String serverName;
+
+    /**
+     * 对外访问地址
+     */
+    @TableField("url")
+    private String url;
+
+    /**
+     * 创建人id
+     */
+    @TableField("creator_id")
+    private String creatorId;
+
+    /**
+     * 创建人姓名
+     */
+    @TableField("creator_name")
+    private String creatorName;
+
+    /**
+     * 创建时间
+     */
+    @TableField("indate")
+    private LocalDateTime indate;
+
+    /**
+     * 合同id
+     */
+    @TableField("contract_id")
+    private Integer contractId;
+
+    @TableField("folder_id")
+    private Integer folderId;
+
+    /**
+     * 文件大小
+     */
+    @TableField("size")
+    private String size;
+
+    /**
+     * 文件类型
+     */
+    @TableField("document_type")
+    private Integer documentType;
+
+    /**
+     * 文件状态0-存在,1-删除
+     */
+    @TableField("is_deleted")
+    private Integer isDeleted;
+
+    /**
+     * 是否是文件夹
+     */
+    @TableField("is_folder")
+    private Integer isFolder;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 51 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ContractType.java

@@ -0,0 +1,51 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-29
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class ContractType extends Model<ContractType> {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 合同类型id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 公司id
+     */
+    @TableField("company_id")
+    private Integer companyId;
+
+    /**
+     * 合同类型
+     */
+    @TableField("type_name")
+    private String typeName;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 18 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ContractFileDelVo.java

@@ -0,0 +1,18 @@
+package com.management.platform.entity.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author cs
+ * @version 1.0
+ * @ClassName contractFileDelVo
+ * @Description
+ * @date 2022-12-12 16:16
+ */
+@Data
+public class ContractFileDelVo {
+    private Integer contractId;
+    private List<Integer> fileIds;
+}

+ 18 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ContractFileVo.java

@@ -0,0 +1,18 @@
+package com.management.platform.entity.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author cs
+ * @version 1.0
+ * @ClassName contractFileVo
+ * @Description
+ * @date 2022-12-09 17:29
+ */
+@Data
+public class ContractFileVo {
+    private Integer ContractId;
+    private Integer fileId;
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/BustripAuditLogMapper.java

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.BustripAuditLog;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-12
+ */
+public interface BustripAuditLogMapper extends BaseMapper<BustripAuditLog> {
+
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ContractDocumentMapper.java

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.ContractDocument;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-09
+ */
+public interface ContractDocumentMapper extends BaseMapper<ContractDocument> {
+
+}

+ 18 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ContractMapper.java

@@ -0,0 +1,18 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.Contract;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-29
+ */
+public interface ContractMapper extends BaseMapper<Contract> {
+    List<Contract> selectContract(Integer companyId, Integer pageStart, Integer pageSize, String number, String name, String typeName, Integer status, String startDate,String endDate);
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ContractTypeMapper.java

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.ContractType;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-29
+ */
+public interface ContractTypeMapper extends BaseMapper<ContractType> {
+
+}

+ 2 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/TaskMapper.java

@@ -1,6 +1,7 @@
 package com.management.platform.mapper;
 
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.toolkit.Constants;
 import com.management.platform.entity.Task;
@@ -24,7 +25,7 @@ public interface TaskMapper extends BaseMapper<Task> {
     List getStagesPanel(Integer projectId);
     List getTopCostTask(Integer projectId);
 
-    List<Task> simpleList(@Param(Constants.WRAPPER) Wrapper wrapper);
+    List<Task> simpleList(@Param(Constants.WRAPPER) Wrapper wrapper,Integer start,Integer size);
 
     List<Task> nameList(@Param(Constants.WRAPPER) Wrapper wrapper);
 

+ 4 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/BusinessTripService.java

@@ -29,4 +29,8 @@ public interface BusinessTripService extends IService<BusinessTrip> {
     HttpRespMsg modifyProject(BusinessTrip sheet);
 
     HttpRespMsg exportData(BusinessTrip sheet,Integer keyword, String startDate, String endDate, String userId);
+
+    HttpRespMsg auditList(BusinessTrip sheet, Integer pageIndex, Integer pageSize, Integer checkState);
+
+    HttpRespMsg cancel(Integer id, String userId);
 }

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/BustripAuditLogService.java

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.BustripAuditLog;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-12
+ */
+public interface BustripAuditLogService extends IService<BustripAuditLog> {
+
+}

+ 30 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ContractDocumentService.java

@@ -0,0 +1,30 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.ContractDocument;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.entity.vo.ContractFileDelVo;
+import com.management.platform.entity.vo.ContractFileVo;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-09
+ */
+public interface ContractDocumentService extends IService<ContractDocument> {
+    HttpRespMsg fileUpload(HttpServletRequest request, @RequestParam Integer ContractId, @RequestParam(required=false) Integer folderId, @RequestParam("file") MultipartFile[] files);
+
+    HttpRespMsg fileDown(HttpServletRequest request, HttpServletResponse response, Integer folderId, ContractFileVo contractFileVo);
+
+    HttpRespMsg onlineShow(String inputFilePath);
+
+    HttpRespMsg fileDelete(HttpServletRequest request, ContractFileDelVo contractFileDelVo);
+}

+ 37 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ContractService.java

@@ -0,0 +1,37 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.Contract;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-29
+ */
+public interface ContractService extends IService<Contract> {
+
+    HttpRespMsg getContractPage(HttpServletRequest request, @RequestParam Integer pageIndex, @RequestParam Integer pageSize, String number, String name, String typeName, Integer status, String startDate, String endDate);
+
+    HttpRespMsg ExportContract(HttpServletRequest request, String number, String name, String typeName, Integer status, String startDate, String endDate);
+
+    HttpRespMsg addContract(HttpServletRequest request, Contract contract);
+
+    HttpRespMsg editContract(HttpServletRequest request, Contract contract);
+
+    HttpRespMsg importContract(HttpServletRequest request, MultipartFile file);
+
+    HttpRespMsg processContract(HttpServletRequest request, Integer id, Integer status);
+
+    HttpRespMsg contractFile(HttpServletRequest request, Integer id);
+
+    HttpRespMsg deleteContract(HttpServletRequest request, Integer id);
+}

+ 24 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ContractTypeService.java

@@ -0,0 +1,24 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.ContractType;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.util.HttpRespMsg;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-29
+ */
+public interface ContractTypeService extends IService<ContractType> {
+
+    HttpRespMsg getContractType(HttpServletRequest request);
+
+    HttpRespMsg changeContractType(HttpServletRequest request, ContractType contractType);
+
+    HttpRespMsg deleteContractType(HttpServletRequest request, Integer deleteId);
+}

+ 2 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/TaskService.java

@@ -1,6 +1,7 @@
 package com.management.platform.service;
 
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.management.platform.entity.Task;
 import com.management.platform.entity.TaskGroup;
@@ -27,7 +28,7 @@ public interface TaskService extends IService<Task> {
     HttpRespMsg getTopCostTask(Integer projectId);
 
     //获取不带任务描述的列表数据
-    List<Task> simpleList(Wrapper<Task> queryWrapper);
+    List<Task> simpleList(Wrapper<Task> queryWrapper,Integer start,Integer size);
     List<Task> nameList(Wrapper<Task> queryWrapper);
 
 

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/WxCorpInfoService.java

@@ -22,7 +22,7 @@ import java.util.List;
  */
 public interface WxCorpInfoService extends IService<WxCorpInfo> {
 
-    public void sendWXCorpMsg(WxCorpInfo corpInfo, String corpUserid, String msg);
+    public void sendWXCorpMsg(WxCorpInfo corpInfo, String corpUserid, String msg, String pageRouter, Integer msgType);
 
     public void sendWXCorpTemplateCardMsg(WxCorpInfo corpInfo, String corpUserid, JSONObject msg);
 

+ 2 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/AuditWorkflowSettingServiceImpl.java

@@ -35,8 +35,6 @@ public class AuditWorkflowSettingServiceImpl extends ServiceImpl<AuditWorkflowSe
     UserMapper userMapper;
     @Resource
     DepartmentMapper departmentMapper;
-    @Resource
-    ReportMapper reportMapper;
 
     @Override
     public List<AuditWorkflowSetting> get(Integer deptId, Integer type) {
@@ -55,7 +53,8 @@ public class AuditWorkflowSettingServiceImpl extends ServiceImpl<AuditWorkflowSe
                 setting.setAuditDeptId(dept.getDepartmentId());
                 setting.setAuditDeptName(dept.getDepartmentName());
                 setting.setIsFinal(1);
-                setting.setAuditorType(type);
+                setting.setAuditorType(1);//按部门
+                setting.setType(type);
                 auditWorkflowSettingMapper.insert(setting);
                 auditWorkflowTimeSettings.add(setting);
             }

+ 314 - 14
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/BusinessTripServiceImpl.java

@@ -1,14 +1,19 @@
 package com.management.platform.service.impl;
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.management.platform.controller.AuditWorkflowSettingController;
 import com.management.platform.entity.*;
 import com.management.platform.entity.vo.SysRichFunction;
 import com.management.platform.mapper.*;
+import com.management.platform.service.AuditWorkflowSettingService;
 import com.management.platform.service.BusinessTripService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.service.DepartmentService;
+import com.management.platform.service.WxCorpInfoService;
 import com.management.platform.util.ExcelUtil;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.MessageUtils;
@@ -42,6 +47,10 @@ public class BusinessTripServiceImpl extends ServiceImpl<BusinessTripMapper, Bus
     @Resource
     private BustripProjectMapper bustripProjectMapper;
     @Resource
+    AuditWorkflowSettingMapper auditWorkflowSettingMapper;
+    @Resource
+    BustripAuditLogMapper bustripAuditLogMapper;
+    @Resource
     private TimeTypeMapper timeTypeMapper;
     @Resource
     private HttpServletRequest request;
@@ -57,6 +66,14 @@ public class BusinessTripServiceImpl extends ServiceImpl<BusinessTripMapper, Bus
     LocaleInformationMapper localeInformationMapper;
     @Resource
     CompanyMapper companyMapper;
+    @Resource
+    AuditWorkflowSettingService auditWorkflowSettingService;
+    @Resource
+    WxCorpInfoMapper wxCorpInfoMapper;
+    @Resource
+    WxCorpInfoService wxCorpInfoService;
+    @Resource
+    InformationMapper informationMapper;
 
     @Override
     public HttpRespMsg modifyProject(BusinessTrip sheet) {
@@ -153,6 +170,73 @@ public class BusinessTripServiceImpl extends ServiceImpl<BusinessTripMapper, Bus
         return httpRespMsg;
     }
 
+    @Override
+    public HttpRespMsg auditList(BusinessTrip sheet, Integer pageIndex, Integer pageSize, Integer checkState) {
+        QueryWrapper<BusinessTrip> queryWrapper = new QueryWrapper<BusinessTrip>();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+
+        sheet.setCompanyId(user.getCompanyId());
+
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        queryWrapper.eq("company_id", sheet.getCompanyId()).orderByDesc("id");
+        queryWrapper.eq("status", 1);
+        queryWrapper.eq("auditor_id", user.getId());
+
+        if (!StringUtils.isEmpty(sheet.getOwnerId())) {
+            queryWrapper.eq("owner_id", sheet.getOwnerId());
+        }
+        if (sheet.getStartDate() != null && sheet.getEndDate() != null) {
+            queryWrapper.le("start_date", sheet.getEndDate()).ge("end_date", sheet.getStartDate());
+        }
+        if (!StringUtils.isEmpty(sheet.getWay())) {
+            queryWrapper.eq("way", sheet.getWay());
+        }
+        if (checkState==1){
+            queryWrapper.ge("day_count",10);
+        }
+        IPage<BusinessTrip> listIPager = businessTripMapper.selectPage(new Page<>(pageIndex, pageSize),
+                queryWrapper);
+        List<BusinessTrip> records = listIPager.getRecords();
+//        List<String> userIds = records.stream().map(BusinessTrip::getOwnerId).collect(Collectors.toList());
+//        if (userIds.size() > 0) {
+//            List<User> userList = userMapper.getUserWithDept(new QueryWrapper<User>().in("id", userIds));
+//            records.stream().forEach(r->{
+//                Optional<User> find = userList.stream().filter(u->u.getId().equals(r.getOwnerId())).findFirst();
+//                if (find.isPresent()) {
+//                    r.setDept(find.get().getDepartmentName());
+//                }
+//            });
+//        }
+
+        Long total = listIPager.getTotal();
+
+        Map<String, Object> map = new HashMap<>();
+        map.put("records", records);
+        map.put("total", total);
+        httpRespMsg.data = map;
+        return httpRespMsg;
+    }
+
+    @Override
+    public HttpRespMsg cancel(Integer id, String userId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        BusinessTrip oldSheet = businessTripMapper.selectById(id);
+        if (oldSheet.getStatus() == 0) {
+            msg.setError("当前出差申请已通过,无法撤销");
+        } else if (oldSheet.getStatus() == 2) {
+            msg.setError("当前出差申请已驳回,无法撤销");
+        } else {
+            BusinessTrip sheet = new BusinessTrip();
+            sheet.setId(id);
+            sheet.setStatus(3);//撤销状态
+            businessTripMapper.updateById(sheet);
+            //删除相关的审批记录
+            bustripAuditLogMapper.delete(new QueryWrapper<BustripAuditLog>().eq("sheet_id", id));
+        }
+        return msg;
+    }
+
     @Override
     public HttpRespMsg add(BusinessTrip sheet) {
         HttpRespMsg msg = new HttpRespMsg();
@@ -166,8 +250,36 @@ public class BusinessTripServiceImpl extends ServiceImpl<BusinessTripMapper, Bus
         sheet.setOwnerName(user.getName());
         sheet.setCompanyId(user.getCompanyId());
         sheet.setStatus(1);//填报时是待审核状态
+
+        //获取第一个审批人
+        User owner = userMapper.selectById(sheet.getOwnerId());
+        if (owner.getDepartmentId() == 0) {
+            //没有部门,不能提交出差申请
+            msg.setError("请联系管理员设置您所在部门");
+            return msg;
+        } else {
+            List<AuditWorkflowSetting> auditList = auditWorkflowSettingService.get(owner.getDepartmentId(), AuditWorkflowSettingController.TYPE_LEAVE);
+            if (auditList.size() > 0) {
+                AuditWorkflowSetting workflowNode = auditList.get(0);
+                if (workflowNode.getAuditorType() == 1) {
+                    //部门负责人
+                    Department dept = departmentMapper.selectById(workflowNode.getAuditDeptId());
+                    if (dept.getManagerId() == null) {
+                        msg.setError("请联系管理员设置您所在部门的主要负责人");
+                        return msg;
+                    }
+                    sheet.setAuditorId(dept.getManagerId());
+                    sheet.setAuditorName(userMapper.selectById(dept.getManagerId()).getName());
+                } else if (workflowNode.getAuditorType() == 2) {
+                    //指定一个人审批
+                    sheet.setAuditorId(workflowNode.getUserId());
+                    sheet.setAuditorName(workflowNode.getUserName());
+                }
+                sheet.setCurAuditSettingId(workflowNode.getId());
+            }
+        }
+
         if (isNew) {
-            //检查该时间段是否已经有按天请假
             QueryWrapper<BusinessTrip> queryWrapper = new QueryWrapper<>();
             queryWrapper.eq("owner_id", sheet.getOwnerId());
             queryWrapper.le("start_date", sheet.getEndDate()).ge("end_date", sheet.getStartDate());
@@ -176,16 +288,97 @@ public class BusinessTripServiceImpl extends ServiceImpl<BusinessTripMapper, Bus
             if (count > 0) {
                 //msg.setError("该时间段已有出差申请,不能重复提交");
                 msg.setError(MessageUtils.message("leave.businessRepeat"));
+                return msg;
             } else {
                 businessTripMapper.insert(sheet);
             }
         } else {
             businessTripMapper.updateById(sheet);
         }
-
+        sheet = businessTripMapper.selectById(sheet.getId());
+        saveNotifyToAuditor(sheet);
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+        if (wxCorpInfo != null) {
+            sendAuditNotifyMsg(wxCorpInfo, user, sheet);
+        }
         return msg;
     }
 
+
+    //发送审核结果消息提醒
+    private void sendAuditResult(WxCorpInfo wxCorpInfo, User auditor, BusinessTrip sheet, String denyReason) {
+        //推送到企业微信
+        StringBuilder stringBuilder = new StringBuilder();
+        String applyTimeDesc = "";
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("M月d日");
+        if (sheet.getStartDate().isEqual(sheet.getEndDate())) {
+            applyTimeDesc = dateTimeFormatter.format(sheet.getStartDate());
+        } else {
+            applyTimeDesc = dateTimeFormatter.format(sheet.getStartDate()) +"至" + dateTimeFormatter.format(sheet.getEndDate());
+        }
+
+        stringBuilder.append("$userName="+auditor.getCorpwxUserid()+"$")
+                .append(sheet.getStatus() == 0?"通过":"驳回")
+                .append("了您")
+                .append(applyTimeDesc)
+                .append("的出差申请。");
+        if (sheet.getStatus() == 2) {
+            //驳回加原因
+            stringBuilder.append("原因: ").append(denyReason);
+        }
+
+        String ownerId = sheet.getOwnerId();
+        User owner = userMapper.selectById(ownerId);
+        wxCorpInfoService.sendWXCorpMsg(wxCorpInfo,owner.getCorpwxUserid(), stringBuilder.toString(), "awayOffice",
+                sheet.getStatus() == 0?WxCorpInfoServiceImpl.TEXT_CARD_MSG_BUSTRIP_AGREE:WxCorpInfoServiceImpl.TEXT_CARD_MSG_BUSTRIP_DENY);
+
+    }
+
+    private void saveNotifyToApplier(BusinessTrip sheet) {
+        String applyTimeDesc = "";
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("M月d日");
+        if (sheet.getStartDate().isEqual(sheet.getEndDate())) {
+            applyTimeDesc = dateTimeFormatter.format(sheet.getStartDate());
+        } else {
+            applyTimeDesc = dateTimeFormatter.format(sheet.getStartDate()) +"至" + dateTimeFormatter.format(sheet.getEndDate()) ;
+        }
+        String ownerId = sheet.getOwnerId();
+        User owner = userMapper.selectById(ownerId);
+        User auditor = userMapper.selectById(sheet.getAuditorId());
+        //系统内消息
+        Information information=new Information();
+        information.setUserId(owner.getId());
+        information.setTime(LocalDateTime.now());
+        information.setMsg("您"+applyTimeDesc + "出差申请审核"+(sheet.getStatus() == 0?"已通过":"已驳回")+", 审核人:"
+                +(auditor.getCorpwxUserid() != null ? ("$userName="+auditor.getCorpwxUserid()+"$"):auditor.getName()));
+        information.setType(5);
+        information.setContent(sheet.getId()+"");
+        informationMapper.insert(information);
+    }
+
+    private void saveNotifyToAuditor(BusinessTrip sheet) {
+        //系统内消息
+        Information information=new Information();
+        information.setUserId(sheet.getAuditorId());
+        information.setTime(LocalDateTime.now());
+        User owner = userMapper.selectById(sheet.getOwnerId());
+        information.setMsg("出差待审核, 申请人:" + (owner.getCorpwxUserid() != null?("$userName="+owner.getCorpwxUserid()+"$"):owner.getName()));
+        information.setType(5);
+        information.setContent(sheet.getId()+"");
+        informationMapper.insert(information);
+    }
+
+    //发送待审核提醒
+    private void sendAuditNotifyMsg(WxCorpInfo wxCorpInfo, User applier, BusinessTrip sheet) {
+        //推送到企业微信
+        StringBuilder sb = new StringBuilder();
+        sb.append("出差申请待审核,申请人:").append("$userName="+applier.getCorpwxUserid()+"$");
+
+        String auditorId = sheet.getAuditorId();
+        User auditor = userMapper.selectById(auditorId);
+        wxCorpInfoService.sendWXCorpMsg(wxCorpInfo,auditor.getCorpwxUserid(), sb.toString(), "awayOffice", WxCorpInfoServiceImpl.TEXT_CARD_MSG_BUSTRIP_WAITING_AUDIT);
+    }
+
     @Override
     public HttpRespMsg delete(Integer id) {
         HttpRespMsg msg=new HttpRespMsg();
@@ -298,21 +491,128 @@ public class BusinessTripServiceImpl extends ServiceImpl<BusinessTripMapper, Bus
 
     @Override
     public HttpRespMsg approve(Integer id) {
-        BusinessTrip sheet = new BusinessTrip();
-        sheet.setId(id);
-        sheet.setStatus(0);
-        businessTripMapper.updateById(sheet);
-        return new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        //检查操作人权限
+        User user = userMapper.selectById(token);
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        BusinessTrip originSheet = businessTripMapper.selectById(id);
+        if (user.getId().equals(originSheet.getAuditorId())) {
+            //是当前的审核人,获取下个审核节点
+            AuditWorkflowSetting auditWorkflowSetting = auditWorkflowSettingMapper.selectById(originSheet.getCurAuditSettingId());
+            BusinessTrip sheet = new BusinessTrip();
+            sheet.setId(id);
+            if (auditWorkflowSetting == null) {
+                //当前审核节点已不存在,直接审核通过
+                sheet.setStatus(0);
+            } else {
+                Integer seq = auditWorkflowSetting.getSeq();
+                AuditWorkflowSetting nextAuditNode = auditWorkflowSettingMapper.selectOne(new QueryWrapper<AuditWorkflowSetting>().eq("type", 2).eq("seq", (seq + 1)).eq("dept_id", auditWorkflowSetting.getDeptId()));
+                System.out.println("nextAuditNode=="+nextAuditNode);
+                if (nextAuditNode == null) {
+                    sheet.setStatus(0);
+                } else {
+                    //进入下个审核节点
+                    if (nextAuditNode.getAuditorType() == 1) {
+                        //部门负责人审核
+                        Department department = departmentMapper.selectById(nextAuditNode.getAuditDeptId());
+                        if (department == null) {
+                            //部门已被删除,直接审核通过
+                            sheet.setStatus(0);
+                        } else {
+                            if (department.getManagerId() == null) {
+                                httpRespMsg.setError("尚未设置下个节点的部门负责人,请联系管理员");
+                                return httpRespMsg;
+                            } else {
+                                sheet.setCurAuditSettingId(nextAuditNode.getId());
+                                sheet.setAuditorId(department.getManagerId());
+                                sheet.setAuditorName(userMapper.selectById(department.getManagerId()).getName());
+                                sheet.setAuditorType(nextAuditNode.getAuditorType());
+                            }
+                        }
+                    } else if (nextAuditNode.getAuditorType() == 2){
+                        //指定人员审核
+                        sheet.setCurAuditSettingId(nextAuditNode.getId());
+                        sheet.setAuditorId(nextAuditNode.getUserId());
+                        sheet.setAuditorName(nextAuditNode.getUserName());
+                        sheet.setAuditorType(nextAuditNode.getAuditorType());
+                    }
+                }
+            }
+            businessTripMapper.updateById(sheet);
+            //保存审核记录
+            saveAgreeLog(id, auditWorkflowSetting, user);
+            //最终审核通过,发送通过消息
+            sheet = businessTripMapper.selectById(id);
+            WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+            if (wxCorpInfo != null) {
+                if (sheet.getStatus() == 0) {
+                    //最终通过
+                    sendAuditResult(wxCorpInfo, user, sheet, null);
+                } else {
+                    //通知下个节点的审核人去审核
+                    sendAuditNotifyMsg(wxCorpInfo, user, sheet);
+                }
+            }
+            if (sheet.getStatus() == 0) {
+                //最终通过
+                saveNotifyToApplier(sheet);
+            } else {
+                //通知下个节点的审核人去审核
+                saveNotifyToAuditor(sheet);
+            }
+        }
+        return httpRespMsg;
+    }
+
+
+    private void saveAgreeLog(int sheetId, AuditWorkflowSetting curAuditNode, User operator) {
+        BustripAuditLog log = new BustripAuditLog();
+        log.setSheetId(sheetId);
+        if (curAuditNode != null) {
+            log.setAuditNodeId(curAuditNode.getId());
+        }
+        log.setAuditorId(operator.getId());
+        log.setAuditorName(operator.getName());
+        log.setIsPass(1);
+        bustripAuditLogMapper.insert(log);
+    }
+    private void saveDenyLog(int sheetId, AuditWorkflowSetting curAuditNode, User operator, String reason) {
+        BustripAuditLog log = new BustripAuditLog();
+        log.setSheetId(sheetId);
+        if (curAuditNode != null) {
+            log.setAuditNodeId(curAuditNode.getId());
+        }
+        log.setAuditorId(operator.getId());
+        log.setAuditorName(operator.getName());
+        log.setIsPass(0);
+        log.setDenyReason(reason);
+        bustripAuditLogMapper.insert(log);
     }
 
     @Override
-    public HttpRespMsg deny(Integer id, String denyReason) {
-        BusinessTrip sheet = new BusinessTrip();
-        sheet.setId(id);
-        sheet.setStatus(2);
-        sheet.setDenyReason(denyReason);
-        businessTripMapper.updateById(sheet);
-        return new HttpRespMsg();
+    public HttpRespMsg deny(Integer id, String reason) {
+        String token = request.getHeader("TOKEN");
+        //检查操作人权限
+        User user = userMapper.selectById(token);
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        BusinessTrip originSheet = businessTripMapper.selectById(id);
+        if (user.getId().equals(originSheet.getAuditorId())) {
+            //是当前的审核人,获取当前审核节点
+            AuditWorkflowSetting auditWorkflowSetting = auditWorkflowSettingMapper.selectById(originSheet.getCurAuditSettingId());
+            BusinessTrip sheet = new BusinessTrip();
+            sheet.setId(id);
+            sheet.setStatus(2);
+            businessTripMapper.updateById(sheet);
+            saveDenyLog(id, auditWorkflowSetting, user, reason);
+            sheet = businessTripMapper.selectById(id);
+            WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+            if (wxCorpInfo != null) {
+                sendAuditResult(wxCorpInfo, user, sheet, reason);
+            }
+            saveNotifyToApplier(sheet);
+        }
+
+        return httpRespMsg;
     }
 
     @Override

+ 20 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/BustripAuditLogServiceImpl.java

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.BustripAuditLog;
+import com.management.platform.mapper.BustripAuditLogMapper;
+import com.management.platform.service.BustripAuditLogService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-12
+ */
+@Service
+public class BustripAuditLogServiceImpl extends ServiceImpl<BustripAuditLogMapper, BustripAuditLog> implements BustripAuditLogService {
+
+}

+ 216 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractDocumentServiceImpl.java

@@ -0,0 +1,216 @@
+package com.management.platform.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.Contract;
+import com.management.platform.entity.ContractDocument;
+import com.management.platform.entity.User;
+import com.management.platform.entity.vo.ContractFileDelVo;
+import com.management.platform.entity.vo.ContractFileVo;
+import com.management.platform.mapper.ContractDocumentMapper;
+import com.management.platform.mapper.ContractMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.ContractDocumentService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.util.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-09
+ */
+@Service
+public class ContractDocumentServiceImpl extends ServiceImpl<ContractDocumentMapper, ContractDocument> implements ContractDocumentService {
+    @Resource
+    private ContractMapper contractMapper;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private ContractDocumentMapper contractDocumentMapper;
+    @Value(value = "${upload.path}")
+    private String path;
+    /**
+     * 上传合同附件
+     * @param request
+     * @param ContractId
+     * @param folderId
+     * @param files
+     * @return
+     */
+    @Override
+    public HttpRespMsg fileUpload(HttpServletRequest request, @RequestParam Integer ContractId, @RequestParam(required=false) Integer folderId, @RequestParam("file") MultipartFile[] files) {
+        HttpRespMsg msg = new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("Token"));
+        for (MultipartFile file : files) {
+            ContractDocument record = new ContractDocument();
+            record.setCreatorId(user.getId());
+            record.setCreatorName(user.getName());
+            record.setDocumentName(file.getOriginalFilename());
+            record.setFolderId(folderId);
+            record.setContractId(ContractId);
+            if (file != null && !file.isEmpty()) {
+                //截取文件后缀
+                String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
+                record.setDocumentType(DocumentTypeUtil.DocumentType(fileSuffix));
+                //处理文件
+                File dir = new File(path);
+                if (!dir.exists()) {
+                    dir.mkdir();
+                }
+                String fileName= "";
+                if (file!=null && !file.isEmpty()) {
+                    fileName = file.getOriginalFilename();
+
+                    int pos = fileName.lastIndexOf(".");
+                    String suffix = fileName.substring(pos).toLowerCase();
+                    //用uuid替换原始的文件名
+                    String purFName = UUID.randomUUID().toString().replaceAll("-", "");
+                    fileName = purFName + suffix;
+                    File saveFile = new File(dir, fileName);
+                    try {
+                        saveFile.createNewFile();
+                        file.transferTo(saveFile);
+                        //计算文件大小
+                        long fileSize = saveFile.length();
+                        String fileLength = FileUtil.getReadableFileSize(fileSize);
+                        record.setServerName(path + fileName);
+                        record.setSize(fileLength);
+                        String pathPrefix = "/upload/";
+                        record.setUrl(pathPrefix + fileName);
+                        contractDocumentMapper.insert(record);
+                        msg.data = record;
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                        fileName = null;
+                        msg.setError(e.getMessage()+", path="+dir.getAbsolutePath());
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        fileName = null;
+                        msg.setError(e.getMessage()+", path="+dir.getAbsolutePath());
+                    }
+                } else {
+                    msg.setError(MessageUtils.message("file.nonExistentError"));
+                }
+            }
+        }
+
+        return msg;
+    }
+
+    /**
+     * 下载文件
+     * @param request
+     * @param response
+     * @param folderId
+     * @param contractFileVo
+     * @return
+     */
+    @Override
+    public HttpRespMsg fileDown(HttpServletRequest request, HttpServletResponse response, Integer folderId, ContractFileVo contractFileVo) {
+        HttpRespMsg msg = new HttpRespMsg();
+        Integer fileId = contractFileVo.getFileId();
+        Integer contractId = contractFileVo.getContractId();
+        List<ContractDocument> files = contractDocumentMapper.selectList(new QueryWrapper<ContractDocument>().eq("contract_id", contractId));
+        try {
+            ServletOutputStream os = response.getOutputStream();
+            for (ContractDocument file : files) {
+                if (fileId.equals(file.getId())){
+                    File uploadFile = new File(file.getServerName());
+                    response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getDocumentName(), "UTF-8"));
+                    response.setContentType("application/octet-stream");
+                    // 读取文件的字节流
+                    os.write(FileUtil.readFileByBytes(uploadFile));
+                    os.flush();
+                    os.close();
+                    break;
+                }
+            }
+        }catch (IOException e) {
+            msg.setError(MessageUtils.message("file.error"));
+            e.printStackTrace();
+        }
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg onlineShow(String inputFilePath) {
+        String destFileName = inputFilePath.substring(0, inputFilePath.lastIndexOf(".")+1)+"pdf";
+        File dir = new File(path);
+        if (!dir.exists()) {
+            dir.mkdir();
+        }
+
+        HttpRespMsg msg = new HttpRespMsg();
+        Map<String,String> map = new HashMap<String,String>();
+        File destFile = new File(dir, destFileName);
+        if(destFile.exists()) {
+            //文件已存在直接显示
+            map.put("pdfFileName", path + destFile.getName());
+        }else {
+            //文件不存在,转化后显示
+            OpenOfficeService service = new OpenOfficeService();
+            service.start();
+            File inputFile = new File(dir, inputFilePath);
+            Integer state = service.office2PDF(inputFile.getAbsolutePath(),destFile.getAbsolutePath());
+            if(state == 0){
+                //转换成功
+                map.put("pdfFileName", path + destFile.getName());
+            }else {
+                //转换失败
+            }
+            service.shutdown();
+        }
+        msg.data = map;
+        return msg;
+    }
+
+    /**
+     * 删除文件
+     * @param request
+     * @param contractFileDelVo
+     * @return
+     */
+    @Override
+    public HttpRespMsg fileDelete(HttpServletRequest request, ContractFileDelVo contractFileDelVo) {
+        HttpRespMsg msg = new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("Token"));
+        Integer contractId = contractFileDelVo.getContractId();
+        List<Integer> fileIds = contractFileDelVo.getFileIds();
+        //删除文件,只有文件上传者和合同创建者才可以删除
+        Contract contract = contractMapper.selectById(contractId);
+        List<ContractDocument> contractDocuments = contractDocumentMapper.selectBatchIds(fileIds);
+        for (ContractDocument contractDocument : contractDocuments) {
+            if (user.getId().equals(contractDocument.getCreatorId()) || user.getId().equals(contract.getCreatorId())){
+                contractDocument.setIsDeleted(1);
+            }else {
+                //无权删除
+                msg.msg = "[" + contractDocument.getDocumentName() + "]" + MessageUtils.message("access.deleteError");
+                return msg;
+            }
+        }
+        for (ContractDocument contractDocument : contractDocuments) {
+            contractDocumentMapper.updateById(contractDocument);
+        }
+        msg.msg = MessageUtils.message("file.deleteSuc");
+        return msg;
+    }
+}

+ 535 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractServiceImpl.java

@@ -0,0 +1,535 @@
+package com.management.platform.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.*;
+import com.management.platform.service.ContractDocumentService;
+import com.management.platform.service.ContractService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.service.ExcelExportService;
+import com.management.platform.util.*;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.EncryptedDocumentException;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.ss.usermodel.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.io.*;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-29
+ */
+@Service
+public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> implements ContractService {
+    @Resource
+    private ContractTypeMapper contractTypeMapper;
+    @Resource
+    private ContractMapper contractMapper;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private CompanyMapper companyMapper;
+    @Resource
+    private LocaleInformationMapper localeInformationMapper;
+    @Resource
+    private ExcelExportService excelExportService;
+    @Resource
+    private WxCorpInfoMapper wxCorpInfoMapper;
+    @Resource
+    private ContractDocumentMapper contractDocumentMapper;
+    @Value(value = "${upload.path}")
+    private String path;
+
+    /**
+     * 分页查询合同
+     * @param request
+     * @param pageIndex
+     * @param pageSize
+     * @param number
+     * @param name
+     * @param typeName
+     * @param status
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    @Override
+    public HttpRespMsg getContractPage(HttpServletRequest request, @RequestParam Integer pageIndex, @RequestParam Integer pageSize, String number, String name, String typeName, Integer status, String startDate, String endDate) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            String token = request.getHeader("token");
+            User user = userMapper.selectById(token);
+            List<ContractType> types = contractTypeMapper.selectList(new QueryWrapper<ContractType>().eq("company_id", user.getCompanyId()));
+            if (types.size() == 0){
+                //String[] typeNames = {"买卖合同","赠与合同","租赁合同","借款合同","仓储合同","委托合同"};
+                String[] typeNames = {MessageUtils.message("contract.business"),MessageUtils.message("contract.gift"),MessageUtils.message("contract.lease"),MessageUtils.message("contract.loan"),MessageUtils.message("contract.warehousing"),MessageUtils.message("contract.entrust")};
+                for (String s : typeNames) {
+                    ContractType contractType = new ContractType();
+                    contractType.setCompanyId(user.getCompanyId());
+                    contractType.setTypeName(s);
+                    contractTypeMapper.insert(contractType);
+                }
+            }
+            Integer pageStart = null;
+            if (pageIndex!=null){
+                pageStart = (pageIndex -1) * pageSize;
+            }
+            if (StringUtils.isNotBlank(number)){
+                number = "%" + number + "%";
+            }
+            if (StringUtils.isNotBlank(name)){
+                name = "%" + name + "%";
+            }
+            if (StringUtils.isNotBlank(typeName)){
+                typeName = typeName;
+            }
+            List<Contract> contracts = contractMapper.selectContract(user.getCompanyId(), pageStart, pageSize, number, name , typeName , status, startDate,endDate);
+            List<Contract> total = contractMapper.selectContract(user.getCompanyId(), null, null, number, name, typeName, status, startDate, endDate);
+            for (Contract contract : contracts) {
+                List<ContractDocument> fileUrl = contractDocumentMapper.selectList(new QueryWrapper<ContractDocument>().eq("contract_id", id).eq("is_deleted",0));
+                List<User> users = userMapper.selectList(new QueryWrapper<User>().eq("company_id", user.getCompanyId()));
+                WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+                for (ContractDocument contractDocument : fileUrl) {
+                    if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                        for (User item : users) {
+                            if (item.getId().equals(contractDocument.getCreatorId())){
+                                contractDocument.setCreatorName(item.getCorpwxUserid());
+                            }
+                        }
+                    }
+                }
+            }
+            HashMap<String, Object> map = new HashMap<>();
+            map.put("data",contracts);
+            map.put("total",total.size());
+            httpRespMsg.data = map;
+            return httpRespMsg;
+        }catch (NullPointerException e) {
+            //httpRespMsg.setError("验证失败");
+            httpRespMsg.setError(MessageUtils.message("access.verificationError"));
+            return httpRespMsg;
+        }
+    }
+
+    /**
+     * 导出合同
+     * @param request
+     * @param number
+     * @param name
+     * @param typeName
+     * @param status
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    @Override
+    public HttpRespMsg ExportContract(HttpServletRequest request, String number, String name, String typeName, Integer status, String startDate, String endDate) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+        HttpRespMsg contractPage = getContractPage(request, null, null, number, name, typeName, status, startDate, endDate);
+        List<Contract> data = (List<Contract>) contractPage.data;
+        List<String> headList = new ArrayList<String>();
+//        headList.add("合同编号");
+//        headList.add("合同名称");
+//        headList.add("合同金额(¥)");
+//        headList.add("合同类型");
+//        headList.add("状态");
+//        headList.add("创建时间");
+//        headList.add("备注");
+        headList.add(MessageUtils.message("entry.contractNo"));
+        headList.add(MessageUtils.message("contract.name"));
+        headList.add(MessageUtils.message("entry.contract"));
+        headList.add(MessageUtils.message("contract.type"));
+        headList.add(MessageUtils.message("leave.status"));
+        headList.add(MessageUtils.message("excel.creatTime"));
+        headList.add(MessageUtils.message("leave.task"));
+        ArrayList<List<String>> allList = new ArrayList<>();
+        allList.add(headList);
+        for (Contract contract : data) {
+            ArrayList<String> item = new ArrayList<>();
+            item.add(contract.getNumber()==null?"":contract.getNumber());
+            item.add(contract.getName());
+            item.add(contract.getAmounts()==null?"":contract.getAmounts().toString() + "元");
+            item.add(contract.getTypeName());
+            switch (contract.getStatus()){
+                case 0 :
+                    item.add("审核通过");
+                    break;
+                case 1 :
+                    item.add("待审核");
+                    break;
+                case 2 :
+                    item.add("驳回");
+                    break;
+                case 3 :
+                    item.add("导入待审核");
+                    break;
+                default:
+                    item.add("");
+            }
+            item.add(contract.getIndate().toString());
+            item.add(contract.getRemarks()==null?"":contract.getRemarks());
+            allList.add(item);
+        }
+        String fileName = MessageUtils.message("contract.export")+System.currentTimeMillis();
+        try {
+            return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,fileName,allList, path);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return httpRespMsg;
+    }
+
+    /**
+     * 新增合同
+     * @param request
+     * @param contract
+     * @return
+     */
+    @Override
+    public HttpRespMsg addContract(HttpServletRequest request, Contract contract) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        List<Contract> contracts = contractMapper.selectList(new QueryWrapper<Contract>().eq("company_id", user.getCompanyId()));
+        if (StringUtils.isBlank(contract.getName())){
+            //名称不可为空
+            httpRespMsg.setError(MessageUtils.message("name.nullNameError"));
+            return httpRespMsg;
+        }
+        //合同编号不可重复
+        if (StringUtils.isNotBlank(contract.getNumber())){
+            for (Contract ContractNumber: contracts) {
+                if (ContractNumber.getNumber() != null && ContractNumber.getNumber().equals(contract.getNumber())){
+                    httpRespMsg.setError("[" + ContractNumber.getNumber() + "]" + MessageUtils.message("contract.numberRepeat"));
+                    return httpRespMsg;
+                }
+            }
+        }
+        //合同金额不可为负
+        if (contract.getAmounts()!=null && contract.getAmounts() < 0){
+            httpRespMsg.msg = MessageUtils.message("Contract.amountNegative");
+            return httpRespMsg;
+        }
+        //若日期为空,则写入当前日期
+        if (contract.getIndate() == null){
+            contract.setIndate(LocalDate.now());
+        }
+        contract.setCreatorId(user.getId());
+        contract.setCompanyId(user.getCompanyId());
+        contractMapper.insert(contract);
+        httpRespMsg.msg = MessageUtils.message("contract.addSuc");
+        return httpRespMsg;
+    }
+
+    /**
+     * 编辑合同
+     * @param request
+     * @param contract
+     * @return
+     */
+    @Override
+    public HttpRespMsg editContract(HttpServletRequest request, Contract contract) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        try {
+            if (StringUtils.isBlank(contract.getName())){
+                //名称不可为空
+                httpRespMsg.setError(MessageUtils.message("name.nullNameError"));
+                return httpRespMsg;
+            }
+            //合同金额不可为负
+            if (contract.getAmounts()!=null && contract.getAmounts() < 0){
+                httpRespMsg.msg = MessageUtils.message("Contract.amountNegative");
+                return httpRespMsg;
+            }
+            //合同编号不可重复
+            if (StringUtils.isNotBlank(contract.getNumber())){
+                Contract number = contractMapper.selectOne(new QueryWrapper<Contract>().eq("number", contract.getNumber()));
+                if (number != null && !number.getId().equals(contract.getId())){
+                    httpRespMsg.setError("[" + contract.getNumber() + "]" + MessageUtils.message("contract.numberRepeat"));
+                    return httpRespMsg;
+                }
+            }
+            contractMapper.updateById(contract);
+            httpRespMsg.msg = MessageUtils.message("contract.editSuc");
+            return httpRespMsg;
+        }catch (NullPointerException e) {
+            //httpRespMsg.setError("验证失败");
+            httpRespMsg.setError(MessageUtils.message("access.verificationError"));
+            return httpRespMsg;
+        }
+    }
+
+    /**
+     * 导入合同
+     * @param request
+     * @param multipartFile
+     * @return
+     */
+    @Override
+    public HttpRespMsg importContract(HttpServletRequest request, MultipartFile multipartFile) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+        Integer companyId = wxCorpInfo.getCompanyId();
+        //然后处理文件
+        String fileName = multipartFile.getOriginalFilename();
+        File file = new File(fileName == null ? "file" : fileName);
+        InputStream inputStream = null;
+        OutputStream outputStream = null;
+        try {
+            inputStream = multipartFile.getInputStream();
+            outputStream = new FileOutputStream(file);
+            byte[] buffer = new byte[4096];
+            int temp = 0;
+            while ((temp = inputStream.read(buffer, 0, 4096)) != -1) {
+                outputStream.write(buffer, 0, temp);
+            }
+            inputStream.close();
+            outputStream.close();
+            //然后解析表格
+            Workbook workbook = WorkbookFactory.create(new FileInputStream(file));
+            //时间格式
+            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/M/d");
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/M/d");
+            Sheet sheet = workbook.getSheetAt(0);
+            int rowNum = sheet.getLastRowNum();
+            if (rowNum == 0) {
+                //msg.setError("请填写合同数据");
+                msg.setError(MessageUtils.message("Contract.dataNull"));
+                return msg;
+            }
+            List<Contract> contractList = contractMapper.selectList(new QueryWrapper<Contract>().eq("company_id", companyId));
+            List<ContractType> typeList = contractTypeMapper.selectList(new QueryWrapper<ContractType>().eq("company_id", companyId));
+            ArrayList<Contract> saveContract = new ArrayList<>();
+            for (int rowIndex = 1; rowIndex <= rowNum; rowIndex++) {
+                int cellIndex = 0;
+                int dataIndex = 1;
+                Row row = sheet.getRow(rowIndex);
+                if (row == null) {
+                    continue;
+                }
+                if (ExcelUtil.isRowEmpty(row)) {
+                    continue;
+                }
+                boolean NoExists = false;
+                boolean TypeExists = false;
+                if (row.getCell(cellIndex) != null) {
+                    row.getCell(cellIndex).setCellType(CellType.STRING);
+                }
+                if (row.getCell(1) == null) {
+                    //msg.setError("第"+dataIndex+"行缺少合同名称");
+                    msg.setError(MessageUtils.message("",dataIndex));
+                    return msg;
+                }
+                String No = row.getCell(0).getStringCellValue().trim();
+                String name = row.getCell(1).getStringCellValue().trim();
+                String amounts = row.getCell(2).getStringCellValue().trim();
+                String type = row.getCell(3).getStringCellValue().trim();
+                String remarks = row.getCell(3).getStringCellValue().trim();
+                Contract item = new Contract();
+                //检查合同编号是否存在
+                if (StringUtils.isNotBlank(No)){
+                    for (Contract contract : contractList) {
+                        if (contract.getNumber().equals(No)){
+                            NoExists = true;
+                            break;
+                        }
+                    }
+                    if (NoExists){
+                        //msg.setError("第"+dataIndex+"行合同编号已存在");
+                        msg.setError(MessageUtils.message("Contract.NoExists",dataIndex));
+                        return msg;
+                    }
+                    for (int i = 0; i < saveContract.size(); i++) {
+                        if (saveContract.get(i).getNumber().equals(No)){
+                            //msg.setError("第"+dataIndex+"行合同编号与第"第"+dataIndex+"行合同编号重复);
+                            msg.setError(MessageUtils.message("Contract.NoRepeat",dataIndex,i+1));
+                            return msg;
+                        }
+                    }
+                    item.setNumber(No);
+                }
+                //检查类型名称是否存在
+                if (StringUtils.isNotBlank(type)){
+                    for (ContractType contractType : typeList) {
+                        if (contractType.getTypeName().equals(type)){
+                            TypeExists = true;
+                            break;
+                        }
+                    }
+                    if (!TypeExists){
+                        //msg.setError("第"+dataIndex+"行和合同类型不存在");
+                        msg.setError(MessageUtils.message("Contract.typeExists",dataIndex));
+                        return msg;
+                    }
+                    item.setName(name);
+                }
+                item.setCompanyId(companyId);
+                item.setCreatorId(user.getId());
+                item.setIndate(LocalDate.now());
+                item.setStatus(3);
+                item.setAmounts(Integer.parseInt(amounts));
+                item.setRemarks(remarks);
+                saveContract.add(item);
+            }
+            if(saveContract.size()>0){
+                int i = 0;
+                for (Contract contract : saveContract) {
+                    contractMapper.insert(contract);
+                    i++;
+                }
+                msg.data = i;
+                String originName = fileName;
+                //定义一个独立的文件夹
+                String importFolder = "contract_import";
+                File dir = new File(path, importFolder);
+                if (!dir.exists()) {
+                    dir.mkdir();
+                }
+
+                System.out.println("fileName=="+originName);
+                String[] names = originName.split("\\.");
+                String destFileName = names[0] + "_"+System.currentTimeMillis()+"."+names[1];
+                File destFile = new File(dir, destFileName);
+                FileUtils.copyFile(file, destFile);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            //msg.setError("文件处理出错");
+            msg.setError(MessageUtils.message("file.error"));
+            return msg;
+        } catch (NullPointerException e) {
+            e.printStackTrace();
+            //msg.setError("数据格式有误或存在空数据 导入失败");
+            msg.setError(MessageUtils.message("file.dataFormatError"));
+            return msg;
+        }catch (InvalidFormatException e) {
+            e.printStackTrace();
+            //msg.setError("文件格式错误,如果安装了加密软件需要先解密再上传");
+            msg.setError(MessageUtils.message("file.FormatErrorAndDecrypt"));
+            return msg;
+        }catch (EncryptedDocumentException e) {
+            e.printStackTrace();
+            //msg.setError("文件加密状态,需要先解除加密状态再上传");
+            msg.setError(MessageUtils.message("file.encryption"));
+            return msg;
+        } catch (Exception e) {
+            e.printStackTrace();
+            //msg.setError("发生其他错误:"+e.getMessage());
+            msg.setError(MessageUtils.message("other.errorByParameter",e.getMessage()));
+            return msg;
+        } finally {
+            //关闭流
+            try {
+                if (outputStream != null && inputStream != null) {
+                    outputStream.close();
+                    inputStream.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            file.delete();
+        }
+        return msg;
+    }
+
+    /**
+     * 合同审核
+     * @param request
+     * @param id
+     * @param status
+     * @return
+     */
+    @Override
+    public HttpRespMsg processContract(HttpServletRequest request, Integer id, Integer status) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        Contract contract = new Contract();
+        contract.setId(id);
+        contract.setCheckerId(user.getId());
+        contract.setStatus(status);
+        contractMapper.updateById(contract);
+        return msg;
+    }
+
+    /**
+     * 返回合同的附件列表
+     * @param request
+     * @param id
+     * @return
+     */
+    @Override
+    public HttpRespMsg contractFile(HttpServletRequest request, Integer id) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        List<ContractDocument> fileUrl = contractDocumentMapper.selectList(new QueryWrapper<ContractDocument>().eq("contract_id", id).eq("is_deleted",0));
+        List<User> users = userMapper.selectList(new QueryWrapper<User>().eq("company_id", user.getCompanyId()));
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+        for (ContractDocument contractDocument : fileUrl) {
+            if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                for (User item : users) {
+                    if (item.getId().equals(contractDocument.getCreatorId())){
+                        contractDocument.setCreatorName(item.getCorpwxUserid());
+                    }
+                }
+            }
+        }
+        msg.data = fileUrl;
+        return msg;
+    }
+
+    /**
+     * 删除合同
+     * @param request
+     * @param id
+     * @return
+     */
+    @Override
+    public HttpRespMsg deleteContract(HttpServletRequest request, Integer id) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        //只有创建者才可以删除
+        Contract contract = contractMapper.selectById(id);
+        if (user.getId().equals(contract.getCreatorId())){
+            contractMapper.deleteById(id);
+            //删除附件
+            List<ContractDocument> contractFile = contractDocumentMapper.selectList(new QueryWrapper<ContractDocument>().eq("contract_id", id));
+            for (ContractDocument contractDocument : contractFile) {
+                contractDocument.setIsDeleted(1);
+            }
+            for (ContractDocument contractDocument : contractFile) {
+                contractDocumentMapper.updateById(contractDocument);
+            }
+            msg.msg = MessageUtils.message("other.deleteScu");
+        }else {
+            msg.msg = MessageUtils.message("access.createDelete");
+        }
+        return msg;
+    }
+
+}

+ 115 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractTypeServiceImpl.java

@@ -0,0 +1,115 @@
+package com.management.platform.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.*;
+import com.management.platform.service.ContractTypeService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.service.ExcelExportService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-29
+ */
+@Service
+public class ContractTypeServiceImpl extends ServiceImpl<ContractTypeMapper, ContractType> implements ContractTypeService {
+    @Resource
+    private ContractTypeMapper contractTypeMapper;
+    @Resource
+    private ContractMapper contractMapper;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private CompanyMapper companyMapper;
+    @Resource
+    private LocaleInformationMapper localeInformationMapper;
+    @Resource
+    private ExcelExportService excelExportService;
+    @Resource
+    private WxCorpInfoMapper wxCorpInfoMapper;
+
+    /**
+     * 返回公司自定义合同类型
+     * @param request
+     * @return
+     */
+    @Override
+    public HttpRespMsg getContractType(HttpServletRequest request) {
+        String token = request.getHeader("token");
+        User user = userMapper.selectById(token);
+        List<ContractType> types = contractTypeMapper.selectList(new QueryWrapper<ContractType>().eq("company_id", user.getCompanyId()));
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        httpRespMsg.data = types;
+        return httpRespMsg;
+    }
+
+    /**
+     * 新增、修改合同类型
+     * @param request
+     * @param contractType
+     * @return
+     */
+    @Override
+    public HttpRespMsg changeContractType(HttpServletRequest request, ContractType contractType) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        String token = request.getHeader("token");
+        User user = userMapper.selectById(token);
+        if (StringUtils.isBlank(contractType.getTypeName())){
+            //合同类型名不可为空
+            httpRespMsg.setError(MessageUtils.message("contract.typeNameEmpty"));
+            return httpRespMsg;
+        }
+        List<ContractType> types = contractTypeMapper.selectList(new QueryWrapper<ContractType>().eq("company_id", user.getCompanyId()));
+        //新增或修改自定义类型
+        for (ContractType type : types) {
+            if (type.getTypeName().equals(contractType.getTypeName()) && !type.getId().equals(contractType.getId())){
+                //类型名不可重复
+                httpRespMsg.setError("[" + type.getTypeName() + "]" + MessageUtils.message("contract.typeNameRepeat"));
+                return httpRespMsg;
+            }
+        }
+        if (contractType.getId() == null){
+            contractType.setCompanyId(user.getCompanyId());
+            contractTypeMapper.insert(contractType);
+        }else {
+            contractType.setCompanyId(null);
+            contractTypeMapper.updateById(contractType);
+        }
+        //操作成功
+        httpRespMsg.msg = MessageUtils.message("contract.operationSuc");
+        return httpRespMsg;
+    }
+
+    /**
+     * 删除合同类型
+     * @param request
+     * @param deleteId
+     * @return
+     */
+    @Override
+    public HttpRespMsg deleteContractType(HttpServletRequest request, Integer deleteId) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        List<Contract> types = contractMapper.selectList(new QueryWrapper<Contract>().eq("type_id", deleteId));
+        if (types.size() > 0){
+            //该类型尚有合同在使用,无法删除!
+            httpRespMsg.msg = MessageUtils.message("Contract.typeDelError");
+        }else {
+            contractTypeMapper.deleteById(deleteId);
+            httpRespMsg.msg = MessageUtils.message("file.deleteSuc");
+        }
+        return httpRespMsg;
+    }
+
+}

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/InformationServiceImpl.java

@@ -44,7 +44,7 @@ public class InformationServiceImpl extends ServiceImpl<InformationMapper, Infor
         try {
             User user = userMapper.selectById(request.getHeader("token"));
             List<Information> information = informationMapper.selectList(new QueryWrapper<Information>()
-                    .eq("user_id", user.getId()).orderByDesc("time").last("LIMIT 10"));
+                    .eq("user_id", user.getId()).orderByDesc("time").last("LIMIT 20"));
             WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id",user.getCompanyId()));
             if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
                 List<User> users = userMapper.selectList(new QueryWrapper<User>().eq("company_id",user.getCompanyId()));

+ 4 - 13
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/LeaveSheetServiceImpl.java

@@ -104,6 +104,7 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
             if (count > 0) {
                 //msg.setError("该时间段已有请假申请,不能重复请假");
                 msg.setError(MessageUtils.message("leave.repeatedLeave"));
+                return msg;
             }
         }
 
@@ -188,16 +189,6 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
         String ownerId = sheet.getOwnerId();
         User owner = userMapper.selectById(ownerId);
         wxCorpInfoService.sendWXCorpTemplateMsg(wxCorpInfo,owner.getCorpwxUserid(), json);
-
-        //系统内消息
-        Information information=new Information();
-        information.setUserId(owner.getId());
-        information.setTime(LocalDateTime.now());
-        information.setMsg("您"+applyTimeDesc + "请假申请审核"+(sheet.getStatus() == 1?"已通过":"已驳回")+", 审核人:"+("$userName="+auditor.getCorpwxUserid()+"$"));
-        information.setType(4);
-        information.setContent(sheet.getId()+"");
-        information.setMsg(applyTimeDesc);
-        informationMapper.insert(information);
     }
 
     private void saveNotifyToApplier(LeaveSheet sheet) {
@@ -216,7 +207,7 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
         Information information=new Information();
         information.setUserId(owner.getId());
         information.setTime(LocalDateTime.now());
-        information.setMsg("您"+applyTimeDesc + "请假申请审核"+(sheet.getStatus() == 1?"已通过":"已驳回")+", 审核人:"
+        information.setMsg("您"+applyTimeDesc + "请假申请审核"+(sheet.getStatus() == 0?"已通过":"已驳回")+", 审核人:"
                 +(auditor.getCorpwxUserid() != null ? ("$userName="+auditor.getCorpwxUserid()+"$"):auditor.getName()));
         information.setType(4);
         information.setContent(sheet.getId()+"");
@@ -361,7 +352,7 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
                 sheet.setStatus(0);
             } else {
                 Integer seq = auditWorkflowSetting.getSeq();
-                AuditWorkflowSetting nextAuditNode = auditWorkflowSettingMapper.selectOne(new QueryWrapper<AuditWorkflowSetting>().eq("seq", (seq + 1)).eq("dept_id", auditWorkflowSetting.getDeptId()));
+                AuditWorkflowSetting nextAuditNode = auditWorkflowSettingMapper.selectOne(new QueryWrapper<AuditWorkflowSetting>().eq("type", 1).eq("seq", (seq + 1)).eq("dept_id", auditWorkflowSetting.getDeptId()));
                 if (nextAuditNode == null) {
                     sheet.setStatus(0);
                 } else {
@@ -665,7 +656,7 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
         if (oldSheet.getStatus() == 0) {
             msg.setError("当前请假申请已通过,无法撤销");
         } else if (oldSheet.getStatus() == 2) {
-            msg.setError("当前请假申已驳回,无法撤销");
+            msg.setError("当前请假申已驳回,无法撤销");
         } else {
             LeaveSheet sheet = new LeaveSheet();
             sheet.setId(id);

+ 16 - 5
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectMainServiceImpl.java

@@ -49,25 +49,36 @@ public class ProjectMainServiceImpl extends ServiceImpl<ProjectMainMapper, Proje
         ProjectCategory projectCategory = projectCategoryMapper.selectById(projectMain.getCategoryId());
         projectMain.setCategoryName(projectCategory.getName());
         if(projectMain.getId()!=null){
+            ProjectMain oldProject = projectMainMapper.selectById(projectMain.getId());
             Integer count = projectMainMapper.selectCount(new QueryWrapper<ProjectMain>().eq("company_id", projectMain.getCompanyId())
                     .eq("code", projectMain.getCode()).ne("id", projectMain.getId()));
-            Integer count1 = projectMainMapper.selectCount(new QueryWrapper<ProjectMain>().eq("company_id", projectMain.getCompanyId())
-                    .eq("name", projectMain.getName()).ne("id", projectMain.getId()));
             if(count>0){
                 //httpRespMsg.setError("编号已存在");
                 httpRespMsg.setError(MessageUtils.message("other.NumAlreadyExists"));
                 return httpRespMsg;
             }
+            Integer count1 = projectMainMapper.selectCount(new QueryWrapper<ProjectMain>().eq("company_id", projectMain.getCompanyId())
+                    .eq("name", projectMain.getName()).ne("id", projectMain.getId()));
             if(count1>0){
                 //httpRespMsg.setError("名称已存在");
                 httpRespMsg.setError(MessageUtils.message("name.nameRepeat"));
                 return httpRespMsg;
             }
+            boolean nameChanged = !oldProject.getName().equals(projectMain.getName());
+            boolean categoryChanged = !oldProject.getCategoryId().equals(projectMain.getCategoryId());
             projectMainMapper.updateById(projectMain);
             //修改主项目名称  更新项目表
-            List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().eq("project_main_id", projectMain.getId()));
-            projectList.forEach(pl->pl.setProjectMainName(projectMain.getName()));
-            projectService.updateBatchById(projectList);
+            Project updateP = new Project();
+            if (nameChanged) {
+                updateP.setProjectMainName(projectMain.getName());
+            }
+            if (categoryChanged) {
+                updateP.setCategory(projectMain.getCategoryId());
+                updateP.setCategoryName(projectMain.getCategoryName());
+            }
+            if (nameChanged || categoryChanged) {
+                projectService.update(updateP, new QueryWrapper<Project>().eq("project_main_id", projectMain.getId()));
+            }
         }else {
             Integer count2 = projectMainMapper.selectCount(new QueryWrapper<ProjectMain>().eq("company_id", projectMain.getCompanyId())
                     .eq("code", projectMain.getCode()));

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -1509,7 +1509,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
 
     @Override
     public HttpRespMsg taskSum(Integer id, HttpServletRequest request) {
-        List<Task> allTask = taskMapper.simpleList(new QueryWrapper<Task>().eq("project_id", id));
+        List<Task> allTask = taskMapper.simpleList(new QueryWrapper<Task>().eq("project_id", id),null,null);
         long finishCount = allTask.stream().filter(t -> t.getTaskStatus() == 1).count();
         long unfinishCount = allTask.stream().filter(t -> t.getTaskStatus() == 0).count();
         long timeupCount = allTask.stream().filter(t -> t.getTaskStatus() == 0 && t.getEndDate() != null && t.getEndDate().isBefore(LocalDate.now())).count();

+ 58 - 7
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -97,6 +97,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     @Resource
     private SysFunctionMapper sysFunctionMapper;
     @Resource
+    private UserFvTimeMapper userFvTimeMapper;
+    @Resource
     private ProjectBasecostSettingMapper projectBasecostSettingMapper;
     @Resource
     private UserDingdingTimeMapper userDingdingTimeMapper;
@@ -658,6 +660,13 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     UserDingdingTime time = dingdingTimes.get(0);
                     resultMap.put("time", time);
                 }
+            }else if(timeType.getSyncFanwei()==1){
+                List<UserFvTime> userFvTimeList = userFvTimeMapper.selectList(new QueryWrapper<UserFvTime>()
+                        .eq("user_id", userId).eq("work_date", date));
+                if (userFvTimeList.size() > 0) {
+                    UserFvTime time = userFvTimeList.get(0);
+                    resultMap.put("time", time);
+                }
             } else if (timeType.getShowCorpwxCardtime() == 1) {
                 User user = userMapper.selectById(userId);
                 List<UserCorpwxTime> corpwxTimes = userCorpwxTimeMapper.selectList(new QueryWrapper<UserCorpwxTime>()
@@ -713,7 +722,14 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 UserDingdingTime time = dingdingTimes.get(0);
                 msg.data = time;
             }
-        } else if (timeType.getShowCorpwxCardtime() == 1) {
+        }else if(timeType.getSyncFanwei()==1){
+            List<UserFvTime> userFvTimeList = userFvTimeMapper.selectList(new QueryWrapper<UserFvTime>()
+                    .eq("user_id", userId).eq("work_date", date));
+            if (userFvTimeList.size() > 0) {
+                UserFvTime time = userFvTimeList.get(0);
+                msg.data=time;
+            }
+        }  else if (timeType.getShowCorpwxCardtime() == 1) {
             List<UserCorpwxTime> corpwxTimes = userCorpwxTimeMapper.selectList(new QueryWrapper<UserCorpwxTime>()
                     .eq("corpwx_userid", user.getCorpwxUserid()).eq("create_date", date));
             if (corpwxTimes.size() > 0) {
@@ -845,6 +861,15 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 reportAuditorSettingService.saveOrUpdateBatch(collect);
             }
         }
+        //插入所有动态和任务进展
+        ArrayList<TaskComment> taskComments = new ArrayList<>();
+        ArrayList<TaskProgress> taskProgresses = new ArrayList<>();
+        for (Report report : reportList) {
+            TaskComment taskComment = new TaskComment();
+            taskComment.setCreateTime(LocalDateTime.now());
+//            taskComment.setUserName(report.get);
+        }
+
         return httpRespMsg;
     }
 
@@ -1246,6 +1271,28 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         }
                     }
                 }
+            } else if(timeType.getSyncFanwei()==1){
+                //泛微的情况
+                QueryWrapper<UserFvTime> userFvTimeQueryWrapper = new QueryWrapper<>();
+                if (nameList.size() > 0) {
+                    for (Map map : nameList) {
+                        String itemUid = (String)map.get("userId");
+                        String dateStr = (String)map.get("dateStr");
+                        userFvTimeQueryWrapper.or(wrapper->wrapper.eq("user_id", itemUid).eq("work_date", dateStr));
+                    }
+                    List<UserFvTime> timeList = userFvTimeMapper.selectList(userFvTimeQueryWrapper);
+                    //过滤匹配当前的数据
+                    for (Map map : nameList) {
+                        String itemUid = (String)map.get("userId");
+                        String dateStr = (String)map.get("dateStr");
+                        Optional<UserFvTime> first = timeList.stream().filter(time -> time.getUserId().equals(itemUid) && dtf.format(time.getWorkDate()).equals(dateStr)).findFirst();
+                        if (first.isPresent()) {
+                            double wh = first.get().getWorkHours();
+                            //赋值打卡时长
+                            map.put("cardHours", wh);
+                        }
+                    }
+                }
             }
             httpRespMsg.data = nameList;
         } catch (NullPointerException e) {
@@ -1815,7 +1862,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         User user = userList.stream().filter(u -> u.getId().equals(uid)).findFirst().get();
                         //优先企业微信推送消息
                         if (wxCorpInfo != null && user.getCorpwxUserid() != null) {
-                            wxCorpInfoService.sendWXCorpMsg(wxCorpInfo, user.getCorpwxUserid(), msg);
+                            wxCorpInfoService.sendWXCorpMsg(wxCorpInfo, user.getCorpwxUserid(), msg, null, WxCorpInfoServiceImpl.TEXT_CARD_MSG_REPORT_AGREE);
                         } else if (user.getWxOpenid() != null){
                             pushPass(p.getProjectName(), user);
                         }
@@ -2030,7 +2077,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         }
         if (corpwxUserid != null) {
             WxCorpInfo info = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", company.getId()));
-            wxCorpInfoService.sendWXCorpMsg(info, corpwxUserid, str);
+            wxCorpInfoService.sendWXCorpMsg(info, corpwxUserid, str, null, WxCorpInfoServiceImpl.TEXT_CARD_MSG_REPORT_DENY);
         } else if (reporter.getWxOpenid() != null){
             //发送个人微信通知
             pushReject(str, reporter, user.getName(), reason);
@@ -3245,7 +3292,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         TimeType timeType = timeTypeMapper.selectById(companyId);
         //获取钉钉的请假日期
         List<LeaveSheet> leaveSheets = null;
-        if (timeType.getSyncDingding() == 1) {
+        if (timeType.getSyncDingding() == 1||timeType.getSyncFanwei()==1) {
             List<String> userIds = new ArrayList<>();
             for (UserMonthWork work : userMonthWorks) {
                 userIds.add(work.userId);
@@ -3283,7 +3330,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 }
             });
             //钉钉请假的数据
-            if (timeType.getSyncDingding() == 1 && leaveSheets != null && leaveSheets.size() > 0) {
+            if ((timeType.getSyncDingding() == 1 || timeType.getSyncFanwei()==1)&& leaveSheets != null && leaveSheets.size() > 0) {
                 List<LeaveSheet> curUserLeaveList = leaveSheets.stream().filter(leave -> leave.getOwnerId().equals(userMonthWork.userId)).collect(Collectors.toList());
                 curUserLeaveList.forEach(leave->{
                     LocalDate startDate1 = leave.getStartDate();
@@ -4754,7 +4801,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             }
             if (corpwxUserid != null) {
                 WxCorpInfo info = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", company.getId()));
-                wxCorpInfoService.sendWXCorpMsg(info, corpwxUserid, str);
+                wxCorpInfoService.sendWXCorpMsg(info, corpwxUserid, str, null, WxCorpInfoServiceImpl.TEXT_CARD_MSG_REPORT_DENY);
             } else if (reporter.getWxOpenid() != null){
                 //发送个人微信通知
                 pushReject(str, reporter, user.getName(), reason);
@@ -4949,7 +4996,11 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             List<UserDingdingTime> dingdingTimes = userDingdingTimeMapper.selectList(new QueryWrapper<UserDingdingTime>()
                     .eq("user_id", userId).in("work_date", dateList));
             msg.data = dingdingTimes;
-        } else if (timeType.getShowCorpwxCardtime() == 1) {
+        } else if(timeType.getSyncFanwei()==1){
+            List<UserFvTime> userFvTimes = userFvTimeMapper.selectList(new QueryWrapper<UserFvTime>()
+                    .eq("user_id", userId).in("work_date", dateList));
+            msg.data = userFvTimes;
+        }else if (timeType.getShowCorpwxCardtime() == 1) {
             List<UserCorpwxTime> corpwxTimes = userCorpwxTimeMapper.selectList(new QueryWrapper<UserCorpwxTime>()
                     .eq("corpwx_userid", user.getCorpwxUserid()).in("create_date", dateList));
             msg.data = corpwxTimes;

+ 3 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java

@@ -103,10 +103,11 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
     }
 
     @Override
-    public List<Task> simpleList(Wrapper<Task> queryWrapper) {
-        return taskMapper.simpleList(queryWrapper);
+    public List<Task> simpleList(Wrapper<Task> queryWrapper,Integer start,Integer size) {
+        return taskMapper.simpleList(queryWrapper,start,size);
     }
 
+
     @Override
     public List<Task> nameList(Wrapper<Task> queryWrapper) {
         return taskMapper.nameList(queryWrapper);
@@ -692,5 +693,4 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         httpRespMsg.data=list;
         return httpRespMsg;
     }
-
 }

+ 25 - 5
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java

@@ -66,6 +66,7 @@ import java.util.stream.Collectors;
 @Service
 @Slf4j
 public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpInfo> implements WxCorpInfoService {
+
     public static String URL_SEND_WXCORP_MSG = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN";
     //获取临时素材url
     public static String URL_GET_MEDIA = "https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
@@ -82,6 +83,11 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
 
     public static final String GET_USER_INFO_WITHDP = "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID";
 
+    public static final int TEXT_CARD_MSG_BUSTRIP_WAITING_AUDIT = 0;//出差待审核
+    public static final int TEXT_CARD_MSG_BUSTRIP_AGREE = 1;//出差审核通过
+    public static final int TEXT_CARD_MSG_BUSTRIP_DENY = 2;//出差审核驳回
+    public static final int TEXT_CARD_MSG_REPORT_DENY = 10;//日报驳回
+    public static final int TEXT_CARD_MSG_REPORT_AGREE = 11; //日报审核通过
 
     @Value("${suitId}")
     private String suitId;
@@ -236,7 +242,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
         return resultUrl;
     }
     @Override
-    public void sendWXCorpMsg(WxCorpInfo corpInfo, String corpUserid, String msg) {
+    public void sendWXCorpMsg(WxCorpInfo corpInfo, String corpUserid, String msg, String pageRouter, Integer msgType) {
         try {
             if (isDev) return;
             log.info("发送企业微信消息===" + corpUserid);
@@ -247,12 +253,26 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
             headers.setContentType(MediaType.APPLICATION_JSON);
             JSONObject reqParam = new JSONObject();
             reqParam.put("touser", corpUserid);
-            reqParam.put("msgtype", "text");
+            reqParam.put("msgtype", "textcard");
             reqParam.put("enable_id_trans", 1);
             reqParam.put("agentid", corpInfo.getAgentid());
-            JSONObject contentJson = new JSONObject();
-            contentJson.put("content", msg);
-            reqParam.put("text", contentJson);
+            JSONObject cardJson = new JSONObject();
+            String title = "";
+            String jumpUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=ww4e237fd6abb635af&redirect_uri=http://worktime.ttkuaiban.com/api/corpWXAuth&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
+
+            if (StringUtils.isEmpty(pageRouter)) {
+                title = "通知";
+                jumpUrl = jumpUrl.replace("STATE", "0");
+            } else {
+                jumpUrl = jumpUrl.replace("STATE", pageRouter);
+                if ("awayOffice".equals(pageRouter)) {
+                    //出差
+                    title = "出差通知";
+                }
+            }
+            cardJson.put("title", title);
+            cardJson.put("description", msg);
+            reqParam.put("textcard", cardJson);
 
             HttpEntity<String> requestEntity = new HttpEntity<String>(reqParam.toJSONString(), headers);
             ResponseEntity<String> responseEntity = this.restTemplate.exchange(url,

+ 3 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/i18n/messages.properties

@@ -760,4 +760,6 @@ Contract.dataNull = 请填写合同数据
 Contract.nameNullError=第{0}行缺少合同名称
 Contract.NoExists=第{0}行合同编号已存在
 Contract.NoRepeat=第{0}行合同编号与第{1}行合同编号重复
-Contract.typeExists=第{0}行合同类型不存在
+Contract.typeExists=第{0}行合同类型不存在
+Contract.amountNegative = 合同金额不可为负
+Contract.typeDelError = 该类型尚有合同在使用,无法删除!

+ 3 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/i18n/messages_en_US.properties

@@ -760,4 +760,6 @@ Contract.dataNull = Please fill in the contract data
 Contract.nameNullError=The contract name is missing in row {0}
 Contract.NoExists=Contract No. in row {0} already exists
 Contract.NoRepeat=The contract number in line {0} is duplicate with that in line {1}
-Contract.typeExists=The contract type in row {0} does not exist
+Contract.typeExists=The contract type in row {0} does not exist
+Contract.amountNegative = The contract amount cannot be negative
+Contract.typeDelError = This type is still in use and cannot be deleted!

+ 7 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/BusinessTripMapper.xml

@@ -23,6 +23,10 @@
         <result column="is_linked" property="isLinked" />
         <result column="procinst_id" property="procinstId" />
         <result column="gmt_finished" property="gmtFinished" />
+        <result column="auditor_id" property="auditorId" />
+        <result column="auditor_name" property="auditorName" />
+        <result column="auditor_type" property="auditorType" />
+        <result column="cur_audit_setting_id" property="curAuditSettingId" />
     </resultMap>
     <resultMap id="BaseResultMap1" type="com.management.platform.entity.BusinessTrip">
         <result column="owner_id" property="ownerId" />
@@ -32,8 +36,9 @@
     </resultMap>
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, company_id, owner_id, owner_name, reason, start_date, end_date, way, city_from, city_to, go_back, day_count, remark, status, deny_reason, indate, is_linked, procinst_id, gmt_finished
+        id, company_id, owner_id, owner_name, reason, start_date, end_date, way, city_from, city_to, go_back, day_count, remark, status, deny_reason, indate, is_linked, procinst_id, gmt_finished, auditor_id, auditor_name, auditor_type, cur_audit_setting_id
     </sql>
+
     <select id="summaryData"  resultMap="BaseResultMap1">
         select owner_id, owner_name, sum(day_count) as day_count, department.department_name as department_name from business_trip
         left join user on user.id = business_trip.owner_id
@@ -43,6 +48,7 @@
             and owner_name like '%${keyword}%'
         </if>
         and business_trip.company_id = #{companyId}
+        and business_trip.status = 0
         group by owner_id
     </select>
 

+ 22 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/BustripAuditLogMapper.xml

@@ -0,0 +1,22 @@
+<?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.management.platform.mapper.BustripAuditLogMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.BustripAuditLog">
+        <id column="id" property="id" />
+        <result column="sheet_id" property="sheetId" />
+        <result column="audit_node_id" property="auditNodeId" />
+        <result column="auditor_id" property="auditorId" />
+        <result column="auditor_name" property="auditorName" />
+        <result column="is_pass" property="isPass" />
+        <result column="indate" property="indate" />
+        <result column="deny_reason" property="denyReason" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, sheet_id, audit_node_id, auditor_id, auditor_name, is_pass, indate, deny_reason
+    </sql>
+
+</mapper>

+ 27 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ContractDocumentMapper.xml

@@ -0,0 +1,27 @@
+<?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.management.platform.mapper.ContractDocumentMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.ContractDocument">
+        <id column="id" property="id" />
+        <result column="document_name" property="documentName" />
+        <result column="server_name" property="serverName" />
+        <result column="url" property="url" />
+        <result column="creator_id" property="creatorId" />
+        <result column="creator_name" property="creatorName" />
+        <result column="indate" property="indate" />
+        <result column="contract_id" property="contractId" />
+        <result column="folder_id" property="folderId" />
+        <result column="size" property="size" />
+        <result column="document_type" property="documentType" />
+        <result column="is_deleted" property="isDeleted" />
+        <result column="is_folder" property="isFolder" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, document_name, server_name, url, creator_id, creator_name, indate, contract_id, folder_id, size, document_type, is_deleted, is_folder
+    </sql>
+
+</mapper>

+ 51 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ContractMapper.xml

@@ -0,0 +1,51 @@
+<?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.management.platform.mapper.ContractMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.Contract">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="number" property="number" />
+        <result column="creator_id" property="creatorId" />
+        <result column="name" property="name" />
+        <result column="amounts" property="amounts" />
+        <result column="type_id" property="typeId" />
+        <result column="type_name" property="typeName" />
+        <result column="status" property="status" />
+        <result column="indate" property="indate" />
+        <result column="remarks" property="remarks" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, creator_id, number, name, amounts, type_id, type_name,status, indate, remarks
+    </sql>
+
+    <select id="selectContract" resultType="com.management.platform.entity.Contract">
+        select contract.id,contract.company_id,contract.creator_id,contract.number,contract.name,contract.amounts,contract.type_id,contract_type.type_name,contract.status,contract.indate,contract.remarks
+        from contract
+        left join contract_type
+        on contract.type_id = contract_type.id
+        where contract.company_id = #{companyId}
+        <if test="number!=null">
+        and number like #{number}
+        </if>
+        <if test="name!=null">
+        and name like #{name}
+        </if>
+        <if test="typeName!=null">
+        and contract_type.id = #{typeName}
+        </if>
+        <if test="status!=null">
+        and status = #{status}
+        </if>
+        <if test="startDate!=null and endDate !=null">
+        and indate between #{startDate} and #{endDate}
+        </if>
+        order by indate desc
+        <if test="pageStart!=null and pageSize!=null">
+            limit #{pageStart},#{pageSize}
+        </if>
+    </select>
+</mapper>

+ 17 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ContractTypeMapper.xml

@@ -0,0 +1,17 @@
+<?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.management.platform.mapper.ContractTypeMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.ContractType">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="type_name" property="typeName" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, type_name
+    </sql>
+
+</mapper>

+ 1 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/LeaveSheetMapper.xml

@@ -38,6 +38,7 @@
             and owner_name like '%${keyword}%'
         </if>
         and company_id = #{companyId}
+        and status = 0
         group by owner_id
     </select>
 

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TaskMapper.xml

@@ -98,6 +98,9 @@
         select id, name, creater_id, creater_name, creator_color, executor_id, executor_name, executor_color, task_level, task_status, create_date, end_date, project_id, stages_id, company_id, indate, parent_tid, group_id, seq, plan_hours, task_type, parent_tname, finish_date, start_date
         from task
         ${ew.customSqlSegment}
+        <if test="start!=null and size!=null">
+            limit #{start},#{size}
+        </if>
     </select>
     <select id="nameList" resultMap="BaseResultMap">
         select id, name, task_level, stages_id, company_id, indate,  group_id, seq,task_type,task_desc

+ 2 - 2
fhKeeper/formulahousekeeper/timesheet/src/components/select.vue

@@ -36,11 +36,11 @@
     <transition name="el-zoom-in-top">
       <div v-show="show" style="position: relative;z-index: 999;"> 
         <!-- 搜索框 -->
-        <div class="searchBox">
+        <!-- <div class="searchBox">
             <el-input :placeholder="$t('peaseenterthe')" size="mini" v-model="searchTex" style="width: 150px" @focus="searchBox()">
                 <el-button slot="append" icon="el-icon-search" size="mini" @click="searchLick()"></el-button>
             </el-input>
-        </div>
+        </div> -->
         <div class="transitionBox" :style="filterable ? 'margin: 30px 0;' : ''">
             <ul class="transitionBoxUl">
                 <li :class="transitionBoxLiIdx == index ? 'liHover' : ''" v-for="(item, index) in options" :key="index" @mouseover="liMouseOver(index)" @click="liClick(item, index)"> 

+ 5 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/Home.vue

@@ -521,9 +521,13 @@
                             this.$router.push("/expense");
                             this.drawer = false;
                         } else if (type == 4) {
-                            //4- 任务有新进展
+                            //4- 请假消息
                             this.$router.push("/leave");
                             this.drawer = false;
+                        } else if (type == 5) {
+                            //5- 出差消息
+                            this.$router.push("/awayOffice");
+                            this.drawer = false;
                         }
                         
                     } else {

+ 237 - 46
fhKeeper/formulahousekeeper/timesheet/src/views/awayOffice/awayOffice.vue

@@ -9,31 +9,27 @@
                     <i class="iconfont firerock-icontianbao"></i>
                     <span slot="title">{{ $t('businesstriisallowed') }}</span>
                 </el-menu-item>
-                <el-submenu index="2" v-if="permissions.awayOfficeAll">
-                    <template slot="title">
-                        <i class="iconfont firerock-iconbaoxiaodan"></i>
-                        <span>{{ $t('businesstriplist') }}</span>
-                    </template>
-                    <!-- 导航切换 -->
-                    <el-menu-item index="2-1" v-if="permissions.awayOfficeAll"><p @click="bills(false, 2)">{{ $t('all') }}</p></el-menu-item>
-                    <el-menu-item index="2-2" v-if="permissions.awayOfficeAudit && !isSyncData"><p @click="bills(true, 1)">{{ $t('state.WaitingAudit') }}</p></el-menu-item>
-                </el-submenu>
-                <el-menu-item index="3" @click="bills(false, 2)" v-if="!permissions.awayOfficeAll">
-                    <i class="iconfont firerock-iconbaoxiaodan"></i>
-                    <span slot="title">{{ $t('mbusinesstrip') }}</span>
+                <el-menu-item index="2" @select="bills" @click="auditList()" v-if="permissions.awayOfficeAudit">
+                <i class="iconfont firerock-iconbaoxiaodan"></i>
+                <span slot="title">出差审核</span>
                 </el-menu-item>
+                <el-menu-item index="3" @select="bills" @click="bills(false, 2)" >
+                <i class="iconfont firerock-iconbaoxiaodan"></i>
+                <span slot="title">{{ $t('businesstriplist') }}</span>
+                </el-menu-item>
+                
                 <el-menu-item index="4" v-if="permissions.awayOfficeStatistical">
                     <template slot="title">
                         <i class="iconfont firerock-icontianbao"></i>
                         <span slot="title">{{ $t('businessstatistics') }}</span>
                     </template>
                 </el-menu-item>
-                <!-- <el-menu-item index="5" v-if="permissions.awayOfficeProcess">
+                <el-menu-item index="5" v-if="permissions.awayOfficeProcess">
                     <template slot="title">
                         <i class="iconfont firerock-iconliucheng"></i>
                         <span slot="title">{{ $t('businesstriApprovalProcess') }}</span>
                     </template>
-                </el-menu-item> -->
+                </el-menu-item>
             </el-menu>
         </el-col>
     </div>
@@ -144,6 +140,20 @@
                         <el-form-item :label="$t('travelnote')" style="width:635px">
                             <el-input type="textarea" v-model="addform.remark" :rows="3" style="width: 100%" maxlength="100" show-word-limit></el-input>
                         </el-form-item>
+                        <!--流程显示-->
+                        <el-form-item label="审批流程" style="width: 100%;color:#606266" >
+                        <span v-for="(item, index) in curWorkflowList" :key="item.id" >
+                            <span v-if="index>0"><i class="el-icon-right"></i></span>
+                            <span><i class="el-icon-s-custom"></i></span>
+                            <span v-if="user.userNameNeedTranslate == 1">
+                            <span v-if="item.auditorType == 1"><ww-open-data type='departmentName' :openid='item.auditDeptName' ></ww-open-data>(主要负责人)</span>
+                            <ww-open-data type='userName' :openid='item.userName' v-if="item.auditorType == 2"></ww-open-data>
+                            </span>
+                            <span v-if="user.userNameNeedTranslate == 0">
+                            {{item.auditorType == 1?(item.auditDeptName+'(主要负责人)'):item.userName}}
+                            </span>
+                        </span>
+                        </el-form-item>
                 </el-form>
                 <div>
                     <p style="width:635px;text-align:center;">
@@ -219,7 +229,7 @@
                             <div><span :style="scope.row.dayCount >= 10 ? 'color:#e62412' : ''">{{scope.row.dayCount}}{{ $t('time.day') }}</span></div>
                         </template>
                     </el-table-column>
-                    <el-table-column :label="$t('detailsbusinessrip')" width="600" align="center">
+                    <el-table-column :label="$t('detailsbusinessrip')" width="600" align="center" v-if="isSyncData">
                         <template slot-scope="scope">
                             <div v-for="item in scope.row.projectList" :key="item.projectId" class="detailsScope">
                                 <span>{{item.startDate + $t('other.to') + item.endDate}}</span><span>{{item.projectName}}</span><span>{{item.degreeName}}</span>
@@ -258,13 +268,18 @@
                     <el-table-column prop="status" :label="$t('state.states')" width="100" fixed="right">
                         <template slot-scope="scope">
                             <span v-if="scope.row.status == 0">{{ $t('state.approved') }}</span>
-                            <span v-if="scope.row.status == 1" style="color: orange">{{ $t('state.WaitingAudit') }}</span>
+                            <div v-if="scope.row.status == 1" style="color: orange"><span>{{ $t('state.WaitingAudit') }}-</span>
+                                <span v-if="user.userNameNeedTranslate != 1">{{scope.row.auditorName}}</span>
+                                <span v-if="user.userNameNeedTranslate == 1">
+                                <ww-open-data type='userName' :openid='scope.row.auditorName'></ww-open-data>
+                                </span>
+                            </div>
                             <span v-if="scope.row.status == 2" style="color: red">{{ $t('btn.rejected') }}</span>
                             <span v-if="scope.row.status == 3" style="color: #666666">{{ $t('btn.undo') }}</span>
                         </template>
                     </el-table-column>
                     <el-table-column v-if="!isSyncData" :label="isAuditList ? $t('other.audit') : $t('operation')" width="180" fixed="right" >
-                        <template slot-scope="scope">
+                        <!-- <template slot-scope="scope">
                             <div v-if="isAuditList">
                                 <el-button icon="el-icon-check" circle size="mini" @click="approve(scope.row)"></el-button>
                                 <el-button icon="el-icon-close" circle size="mini"  @click="deny(scope.row)"></el-button>
@@ -273,6 +288,17 @@
                                 <el-button v-if="permissions.awayOfficeDelete && ((scope.row.status != 0 && scope.row.ownerId == user.id) || permissions.awayOfficeAll)" icon="el-icon-delete" circle size="mini"  @click="deletes(scope.row)"></el-button>
                                 <el-button v-if="((scope.row.status != 0 && scope.row.ownerId == user.id) || permissions.awayOfficeAll) || scope.row.status == 1" icon="el-icon-edit" circle size="mini" @click="editor(scope.row)"></el-button>
                             </div>
+                        </template> -->
+                        <template slot-scope="scope">
+                        <div v-if="isAuditList" >
+                            <el-button icon="el-icon-check" circle size="mini" @click.stop.native="approve(scope.row)"></el-button>
+                            <el-button icon="el-icon-close" circle size="mini"  @click.stop.native="deny(scope.row)"></el-button>
+                        </div>
+                        <div v-if="!isAuditList && ((scope.row.status != 0 && scope.row.ownerId == user.id) || permissions.awayOfficeAll)">
+                            <el-button size="mini" v-if="scope.row.status == 3 ||scope.row.status == 2" @click.stop.native="deletes(scope.row)" >删除</el-button>
+                            <el-button size="mini" v-if="scope.row.status == 1" @click.stop.native="cancel(scope.row)">撤回</el-button>
+                            <el-button size="mini" v-if="scope.row.status == 3 ||scope.row.status == 2 " type="primary" @click.stop.native="editor(scope.row)">重新提交</el-button>
+                        </div>
                         </template>
                     </el-table-column>
                     <el-table-column v-if="isSyncData" :label="$t('operation')" width="150" fixed="right">
@@ -281,6 +307,9 @@
                             <el-button v-if="permissions.awayOfficeDelete" icon="el-icon-delete" circle size="mini" @click="deleteOfDingding(scope.row)"></el-button>
                         </template>
                     </el-table-column>
+
+                    
+                    
                 </el-table>
                 <!-- 页码 -->
                 <div class="poss">
@@ -362,7 +391,19 @@
                 <el-col :span="6" >
                     <el-scrollbar style="height:100%;border:1px solid #dddddd;margin-left:15px;" >
                         <div class="tree" :style="'height:'+ (tableHeight-120) + 'px'">
-                            <el-tree :data="sdata" :props="sdefaultProps" @node-click="handleNodeClick" accordion></el-tree>
+                            <el-tree :data="sdata" :props="sdefaultProps" @node-click="handleNodeClick" accordion>
+                                <!-- 添加试试看 -->
+                                <span class="custom-tree-node" slot-scope="{ node, data }">
+                                    <!-- <span>{{ node.label }}</span> -->
+                                    <span v-if="user.userNameNeedTranslate == '1'">
+                                        <ww-open-data type='departmentName' :openid='node.label'></ww-open-data>
+                                    </span>
+                                    <span v-else>
+                                        {{ node.label }}
+                                        <span v-if="false">{{data}}</span>
+                                    </span>
+                                </span>
+                            </el-tree>
                         </div>
                     </el-scrollbar>
                 </el-col>
@@ -394,7 +435,7 @@
                             <div style="width:100%;margin:0 auto;margin-bottom:30px;position: absolute;bottom: 0px;text-align: center; ">
                                 <el-button type="primary" @click="submitInsert">{{ $t('save') }}</el-button>
                             </div>
-                        </div>
+                        </div> 
                     </el-scrollbar>
                 </el-col>
             </div>
@@ -402,7 +443,8 @@
                 <el-form label-width="140px">
                     <el-form-item :label="$t('selectdepartmentsdesignatepersonnel')" >
                         <el-cascader filterable ref="deptCascader" v-model="curDeptId" :placeholder="$t('defaultText.pleaseChoose')" style="width: 100%" @change="chooseDept" v-if="user.userNameNeedTranslate != 1" :options="soption" :props="{ checkStrictly: true,expandTrigger: 'hover' }" :show-all-levels="false" clearable></el-cascader>
-                        <vueCascader :size="'small'" :widthStr="'200'" :clearable="true" :subject="soption" :radios="true" :distinction="'1'" @vueCasader="vueCasader" v-if="user.userNameNeedTranslate == 1"></vueCascader>
+                        <!-- <vueCascader :size="'small'" :widthStr="'200'" :clearable="true" :subjectId="this.selectedAuuid" :subject="soption" :radios="true" :distinction="'1'" @vueCasader="vueCasader" v-if="user.userNameNeedTranslate == 1"></vueCascader> -->
+                        <vueCascader :size="'small'" :widthStr="'200'" :clearable="true" :userName="true" :subjectId="this.selectedAuuid" :subject="soption" :radios="true" :distinction="'1'" @vueCasader="vueCasader" v-if="user.userNameNeedTranslate == 1"></vueCascader>
                     </el-form-item>
                 </el-form>
                 <div slot="footer" class="dialog-footer">
@@ -529,7 +571,7 @@
                 </template>
             </el-table-column>
             <el-table-column prop="reason" :label="$t('travelreason')" width="150" header-align="center"></el-table-column>
-            <el-table-column prop="projectName" :label="$t('screening.inputProject')" width="150" align="center"></el-table-column>
+            <el-table-column prop="projectName" :label="$t('screening.inputProject')" width="150" align="center" v-if="isSyncData"></el-table-column>
             <el-table-column :label="$t('traffictools')" width="120" align="center">
                 <template slot-scope="scope">
                     <span v-if="scope.row.way == 0">{{ $t('plane') }}</span>
@@ -550,7 +592,7 @@
             <el-table-column prop="endDate" :label="$t('endtimeofbusinesstrip')" width="150" align="center"></el-table-column>
             <el-table-column prop="remark" :label="$t('bei-zhu')" width="200">
                 <template slot-scope="scope">
-                    <el-popover placement="top-start" title="$t('biao-ti')" width="200" trigger="hover" :content="scope.row.remark">
+                    <el-popover placement="top-start" width="200" trigger="hover" :content="scope.row.remark">
                         <div slot="reference" class="apls">{{scope.row.remark}}</div>
                     </el-popover>
                 </template>
@@ -659,6 +701,28 @@
             <el-button type="primary" @click="listSynchronize()" :loading="synchronizeLoading">{{ $t('synchronous') }}</el-button>
         </span>
     </el-dialog>
+
+    <el-dialog :title="$t('defaultText.pleaseEnterTheReason')"  v-if="denyDialogV" :visible.sync="denyDialogV" :close-on-click-modal="false" customClass="customWidth" width="500px">
+        <div>
+            <el-input type="textarea" v-model="denyInfo.reason" rows="2" :placeholder="$t('reasonforyourdecisiontoreject')" />
+        </div>
+        <div slot="footer" class="dialog-footer">
+            <el-button  @click="denyDialogV = false" >{{ $t('btn.cancel') }}</el-button>
+            <el-button type="primary" @click="submitDeny()" >{{ $t('btn.determine') }}</el-button>
+        </div>
+    </el-dialog>
+    <el-dialog :title="$t('title.reviewProcess')" v-if="denyReasonVisible" :visible.sync="denyReasonVisible" customClass="customWidth" width="400px">
+        <div style="padding:20px 40px 20px 0">
+            <el-timeline :reverse="false">
+                <el-timeline-item v-for="item in auditLogList" :key="item.id" :timestamp="item.indate">
+                  <span v-if="user.userNameNeedTranslate == 1"><ww-open-data type='userName' :openid='item.auditorName'></ww-open-data> </span>
+                  <span v-if="user.userNameNeedTranslate == 0">{{item.auditorName}}</span>
+                  <span> {{item.isPass==0?"驳回了请假申请。":"审核通过。"}}</span>
+                  <span v-if="item.isPass == 0">原因:{{item.denyReason}}</span>
+                  </el-timeline-item>
+            </el-timeline>
+        </div>
+    </el-dialog>
 </section>
 </template>
 
@@ -691,6 +755,8 @@ export default {
         //         }
         //     };
         return {
+            denyDialogV: false,
+            denyInfo: {},
             summaryLoading: false,
             displayTable: false,
             formloading: false,
@@ -807,7 +873,10 @@ export default {
 
             isOverTendays: false,
             tableListLoading: false,
-
+            
+            curWorkflowList:{},
+            denyReasonVisible : false,
+            auditLogList:[],
         }
     },
     created(){
@@ -828,9 +897,8 @@ export default {
         this.getTableList()
         this.getProjectList()
         this.getDepartment()
-        
-        
-        // console.log("session",this.wuduData);
+        this.getAuditWorkflow();
+        this.getUsers()
     },
     methods: {
         // 自定义事件
@@ -842,6 +910,25 @@ export default {
                 this.ownerIdsId = obj.id
             }
         },
+        //获取添加出差单时的审批流
+        getAuditWorkflow() {
+            this.http.post('/audit-workflow-setting/get',{userId: this.user.id, type: 2},
+                res => {
+                if(res.code == 'ok'){
+                    this.curWorkflowList = res.data;
+                }else{
+                    this.$message({
+                    message: res.msg,
+                    type: 'error'
+                    })
+                }
+                },err => {
+                this.$message({
+                    message: err,
+                    type: 'error'
+                })
+            })
+        },
         dingdingListExport(){
             let parameter = {
                 keyword: ''
@@ -1097,7 +1184,8 @@ export default {
             // console.log("keypath",keyPath)
             if (keyPath[0] == '1') {
                 this.displayTable = false;
-                this.apk = 0
+                this.apk = 0;
+                this.getAuditWorkflow();
             } else if(keyPath[0] == '2' || keyPath[0] == '3') {
                 this.displayTable = true;
                 this.apk = 0
@@ -1116,6 +1204,46 @@ export default {
                 this.apk = 2
             }
         },
+        auditList() {
+            this.falg = 1
+            this.code = 1
+            this.tableList = []
+            this.displayTable = true;
+            this.isAuditList = true;
+            this.loading = true
+            this.page = '1'
+            var param = { pageIndex: this.page,
+                            pageSize: this.size,
+                            // createDate: this.createDate,
+                            startDate: this.createDate == null ? '' : this.createDate[0],
+                            endDate: this.createDate == null ? '' : this.createDate[1],
+                            ownerId: this.ownerIds,
+                            way: this.type,
+                        };
+            this.tableList = [];
+            this.total = 0;
+            this.http.post('/business-trip/auditList', param,
+                res => {
+                    if (res.code == "ok") {
+                        this.tableList = res.data.records
+                        this.total = res.data.total
+                        this.loading = false
+                    } else {
+                    this.loading = false
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                this.loading = false
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+            });
+        },
         // 导航切换
         bills(audit, tr){
             if(tr) {
@@ -1347,7 +1475,11 @@ export default {
             },
             res => {
                 if (res.code == "ok") {
-                    this.billss(true);
+                    this.auditList();
+                    this.$message({
+                        message: '操作成功',
+                        type: "success"
+                        });
                 } else {
                     this.$message({
                     message: res.msg,
@@ -1363,12 +1495,21 @@ export default {
             });
         },
         deny(item) {
-            //审核驳回
-            this.http.post('/business-trip/deny', {id:item.id
-            },
+            this.denyDialogV = true;
+            this.denyInfo = {id:item.id, reason:null};
+        },
+        
+        submitDeny(id) {
+        //审核驳回
+        this.http.post('/business-trip/deny', this.denyInfo,
             res => {
                 if (res.code == "ok") {
-                    this.billss(true);
+                    this.auditList();
+                    this.denyDialogV = false;
+                    this.$message({
+                        message: '操作成功',
+                        type: "success"
+                        });
                 } else {
                     this.$message({
                     message: res.msg,
@@ -1383,6 +1524,33 @@ export default {
                 });
             });
         },
+        cancel(e) {
+            this.$confirm('确定要撤回该出差申请吗', this.$t('other.prompts'), {
+                //type: 'warning'
+            }).then(() => {
+                this.http.post('/business-trip/cancel', {id:e.id},
+                res => {
+                    if (res.code == "ok") {
+                        this.bills();
+                        this.$message({
+                            message: '操作成功',
+                            type: "success"
+                        });
+                    } else {
+                        this.$message({
+                        message: res.msg,
+                        type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                });
+            });
+        },
         // 操作 - 删除
         deletes(e) {
             this.$confirm(this.$t('deleteit'), this.$t('other.prompts'), {}).then(() => {
@@ -1516,8 +1684,8 @@ export default {
                 pageIndex: this.detailspage,
                 pageSize: this.detailssize,
                 status: 0,
-                startDate: '',
-                endDate: '',
+                startDate: this.searchDates[0],
+                endDate: this.searchDates[1],
                 ownerId: this.detailsuserid,
                 way: '',
             };
@@ -1570,8 +1738,8 @@ export default {
                     var list = res.data , list1 = JSON.parse(JSON.stringify(res.data));
                     this.sdata = list;
                     this.soption = [
-                        {value: 1 , label : this.$t('lable.department') , children : this.changeArr(list1)},
-                        {value: 2 , label : this.$t('designatedpersonnel'),children : this.susers}
+                        {value: 1 , label : this.$t('lable.department') , children : this.changeArr(list1), type: 'dep'},
+                        {value: 2 , label : this.$t('designatedpersonnel'),children : this.susers, type: 'user'}
                     ]
                 } else {
                     this.$message({
@@ -1698,7 +1866,14 @@ export default {
             this.dialogVisible = false;
             if (this.curDeptId == null) return;
 
-            var node = this.user.userNameNeedTranslate != '1' ? this.vueCasaderItem : this.$refs.deptCascader.getCheckedNodes()[0];
+            // var node = this.user.userNameNeedTranslate != '1' ? this.vueCasaderItem : this.$refs.deptCascader.getCheckedNodes()[0];
+            var node = ''
+            if(this.user.userNameNeedTranslate != 1) {
+              // node = this.user.userNameNeedTranslate != '1' ? this.vueCasaderItem : this.$refs.deptCascader.getCheckedNodes()[0];
+              node = this.$refs.deptCascader.getCheckedNodes()[0];
+            } else {
+              node = this.addNodeObj
+            }
 
             // var node = this.$refs.deptCascader.getCheckedNodes()[0];
             if (this.isAdd) {
@@ -1726,19 +1901,24 @@ export default {
                 this.dataArray.splice(this.sindex, 0, nodes);
             } else {
             //编辑
-                this.dataArray[this.sindex].auditDeptId = node.value;
-                this.dataArray[this.sindex].auditDeptName = node.label;
+                if(node.type == 'dep') {
+                  this.dataArray[this.sindex].auditDeptId = node.value;
+                  this.dataArray[this.sindex].auditDeptName = node.label;
+                  this.dataArray[this.sindex].auditorType = 1
+                  this.dataArray[this.sindex].userId = ''
+                  this.dataArray[this.sindex].userName = ''
+                } else {
+                  this.dataArray[this.sindex].userId = node.value;
+                  this.dataArray[this.sindex].userName = node.label;
+                  this.dataArray[this.sindex].auditDeptId = ''
+                  this.dataArray[this.sindex].auditDeptName = ''
+                  this.dataArray[this.sindex].auditorType = 2
+                }
             }
         },
 
 
         getUsers() {
-            // this.http.post(this.port.manage.list, {
-            //     departmentId: -1,
-            //     pageIndex: 1,
-            //     // pageSize: 99999
-            //     pageSize: -1
-            // },
             this.http.post('/user/getSimpleActiveUserList', {},
             res => {
                 if (res.code == "ok") {
@@ -1746,7 +1926,8 @@ export default {
                     // this.users = res.data.records;
                     this.users = res.data;
                     for (let i = 0; i < this.users.length; i++) {
-                        this.susers.push({value:this.users[i].id,label:this.users[i].name})
+                        // this.susers.push({value:this.users[i].id,label:this.users[i].name})
+                        this.susers.push({value:this.users[i].id,label:this.users[i].name,type: 'user'})
                     }
                     // if (this.user.role == 0) {
                     //     this.editItemForm.ownerId = this.user.id;
@@ -1837,6 +2018,16 @@ export default {
                     }
                 );
             },
+            vueCasader(obj) {
+                if(obj.distinction == 1) {
+                    let arr = []
+                    arr.push(obj.id)
+                    this.curDeptId = arr
+                    this.vueCasaderItem = obj.item
+                    this.addNodeObj = obj.item
+                    console.log(obj, '选中的')
+                }
+            }
         //获取项目列表
             // getProjectList() {
             //     this.listLoading = true;

+ 23 - 14
fhKeeper/formulahousekeeper/timesheet/src/views/leave/list.vue

@@ -130,7 +130,7 @@
                     <el-input ref="ipts" v-model="addForm.tel" :placeholder="$t('peaseenterthe')" style="width: 250px"></el-input>
                 </el-form-item>
                 <!-- 单选 -->
-                <el-form-item style="display: inline-block;width:300px" :label="$t('lengthunit')">
+                <el-form-item style="display: inline-block;width:300px;margin-right: 400px" :label="$t('lengthunit')">
                     <el-radio-group v-model="addForm.timeType" @change="chanRadio()" style="display:inline-block;width:240px">
                         <el-radio label="0">{{ $t('accordingdays') }}</el-radio>
                         <el-radio label="1" v-if="addForm.leaveType != 6">{{ $t('leavehour') }}</el-radio>
@@ -284,7 +284,7 @@
                 <el-table-column prop="remark" :label="$t('bei-zhu')" min-width="200" header-align="center">
                   <template slot-scope="scope">
                     <!-- <div class="apls">{{scope.row.remark}}</div> -->
-                    <el-popover placement="top-start" :title="$t('biao-ti')" width="200" trigger="hover" :content="scope.row.remark">
+                    <el-popover placement="top-start"  width="200" trigger="hover" :content="scope.row.remark">
                       <div slot="reference" class="apls">{{scope.row.remark}}</div>
                     </el-popover>
                   </template>
@@ -950,10 +950,10 @@ export default {
       this.getUsers()
     }else{
       this.getUsers() // 获取人员信息
-    this.getDepartment();
-    this.getAl();
-    this.getApproverList();
-    this.getAuditWorkflow();
+      this.getDepartment();
+      this.getAl();
+      this.getApproverList();
+      this.getAuditWorkflow();
     }
   },
   filters: {},
@@ -980,7 +980,7 @@ export default {
     },
     //获取添加请假单时的审批流
     getAuditWorkflow() {
-      this.http.post('/audit-workflow-setting/get',{deptId: this.user.departmentId, type: 1},
+      this.http.post('/audit-workflow-setting/get',{userId: this.user.id, type: 1},
         res => {
           if(res.code == 'ok'){
             this.curWorkflowList = res.data;
@@ -1495,11 +1495,18 @@ export default {
                 if(node.type == 'dep') {
                   this.dataArray[this.sindex].auditDeptId = node.value;
                   this.dataArray[this.sindex].auditDeptName = node.label;
+                  this.dataArray[this.sindex].auditorType = 1
+                  this.dataArray[this.sindex].userId = ''
+                  this.dataArray[this.sindex].userName = ''
                 } else {
                   this.dataArray[this.sindex].userId = node.value;
                   this.dataArray[this.sindex].userName = node.label;
+                  this.dataArray[this.sindex].auditDeptId = ''
+                  this.dataArray[this.sindex].auditDeptName = ''
+                  this.dataArray[this.sindex].auditorType = 2
                 }
               }
+              console.log(this.dataArray, '数据')
             },
     deleteNode() {
                 this.dialogVisible = false;
@@ -1539,6 +1546,10 @@ export default {
         res => {
             if (res.code == "ok") {
                 this.auditList();
+                this.$message({
+                        message: '操作成功',
+                        type: "success"
+                        });
             } else {
                 this.$message({
                 message: res.msg,
@@ -1565,6 +1576,10 @@ export default {
             if (res.code == "ok") {
                 this.auditList();
                 this.denyDialogV = false;
+                this.$message({
+                        message: '操作成功',
+                        type: "success"
+                        });
             } else {
                 this.$message({
                 message: res.msg,
@@ -1580,12 +1595,6 @@ export default {
         });
     },
     getUsers() {
-      // this.http.post(this.port.manage.list, {
-      //       departmentId: -1,
-      //       pageIndex: 1,
-      //       // pageSize: 99999
-      //       pageSize: -1
-      //   },
       this.http.post('/user/getSimpleActiveUserList', {},
         res => {
             if (res.code == "ok") {
@@ -1670,7 +1679,7 @@ export default {
                     startDate: this.createDate == null ? '' : this.createDate[0],
                     endDate: this.createDate == null ? '' : this.createDate[1],
                     ownerId: this.ownerIds,
-                    leaveType: this.type,
+                    way: this.type,
                   };
       this.list = [];
       // this.total = 0;

+ 25 - 11
fhKeeper/formulahousekeeper/timesheet/src/views/project/vueGantt.vue

@@ -14,7 +14,9 @@
           <template slot-scope="scope">
             <span v-if="user.userNameNeedTranslate == 1 && scope.row.translationType == 'user'">
               <span v-for="(item, index) in scope.row.userNameList" :key="index">
-                <ww-open-data type='userName' :openid='scope.row.text'></ww-open-data>
+                <!-- <ww-open-data type='userName' :openid='scope.row.text'></ww-open-data> -->
+                <ww-open-data type='userName' :openid='item'></ww-open-data>
+                <span v-if="index < scope.row.userNameList.length - 1">,</span>
               </span>
             </span>
             <span v-if="user.userNameNeedTranslate == 1 && scope.row.translationType == 'user'">{{scope.row.proNameText}}</span>
@@ -99,6 +101,7 @@ export default {
 
     // this.treeDataList = this.integrationTree(this.tasks.data)
     console.log(this.mergeList, '合并数据')
+    console.log(this.treeDataList, '合并完全的数据')
   },
   methods: {
     // 递归加颜色以及存储需要合并的数据
@@ -106,20 +109,31 @@ export default {
       for (let i in data) {
             if(this.stafforpro == '按项目查看') {
               data[i].color = '#409EFF'
-              if(data[i].type == 'user' && data[i].text) {
+              // if(data[i].type == 'user' && data[i].text) {
+              //   let arr = []
+              //   if(data[i].text.indexOf('/') != '-1') {
+              //     let str = data[i].text.split('/')[0]
+              //     if(str.indexOf(',') != '-1') {
+              //       let arrList = str.split(',')
+              //       data[i].userNameList = arrList
+              //     } else {
+              //       arr.push(str)
+              //       data[i].userNameList = arr
+              //     }
+              //     data[i].proNameText = data[i].text.split('/')[1]
+              //   }
+              // }
+              if(data[i].translationType == 'user' && data[i].text) {
                 let arr = []
-                if(data[i].text.indexOf('/') != '-1') {
-                  let str = data[i].text.split('/')[0]
-                  if(str.indexOf(',') != '-1') {
-                    let arrList = str.split(',')
-                    data[i].userNameList = arrList
-                  } else {
-                    arr.push(str)
-                    data[i].userNameList = arr
+                arr = data[i].text.split(',')
+                for(var j in arr) {
+                  if(arr[j].indexOf('/') != '-1') {
+                    arr[j] = arr[j].split('/')[0]
                   }
-                  data[i].proNameText = data[i].text.split('/')[1]
                 }
+                data[i].userNameList = arr
               }
+
             }
             this.num++
             let obj = {

+ 17 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -1630,7 +1630,14 @@
         <el-dialog :title="$t('title.reviewProcess')" v-if="approvalProcessDialog" :visible.sync="approvalProcessDialog" customClass="customWidth" width="400px">
             <div style="padding:20px 40px 20px 0">
                 <el-timeline :reverse="false">
-                    <el-timeline-item v-for="item in approvalProcessData" :key="item.id" :timestamp="item.operateDate">{{item.msg}}</el-timeline-item>
+                    <el-timeline-item v-for="item in approvalProcessData" :key="item.id" :timestamp="item.operateDate">
+                        {{item.msg}}
+                        <span v-if="user.userNameNeedTranslate != 1">{{msg}}</span>
+                        <span v-if="user.userNameNeedTranslate == 1">
+                            <span><ww-open-data type='userName' :openid='msgCon.one'></ww-open-data></span>
+                            <span>{{msgCon.two}}</span>
+                        </span>
+                    </el-timeline-item>
                 </el-timeline>
             </div>
         </el-dialog>
@@ -2100,6 +2107,15 @@
                 },res => {
                     if(res.code == 'ok'){
                         this.approvalProcessDialog = true
+                        if(this.user.userNameNeedTranslate == 1) {
+                            for(var i in res.data) {
+                                let obj = {
+                                    one: res.data[i].msg.split('$userName=')[1].split('$')[0],
+                                    two: res.data[i].msg.split('$userName=')[1].split('$')[1],
+                                }
+                                res.data[i].msgCon = obj
+                            }
+                        }
                         this.approvalProcessData = res.data
                     }else{
                         this.$message({