浏览代码

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

ggooalice 2 年之前
父节点
当前提交
2c4952002f
共有 30 个文件被更改,包括 1151 次插入233 次删除
  1. 二进制
      fhKeeper/formulahousekeeper/management-platform/chi_sim.traineddata
  2. 51 74
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/AuditWorkflowSettingController.java
  3. 37 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/LeaveAuditLogController.java
  4. 16 5
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/LeaveSheetController.java
  5. 72 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/LeaveAuditLog.java
  6. 13 18
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/LeaveSheet.java
  7. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/LeaveAuditLogMapper.java
  8. 5 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/AuditWorkflowSettingService.java
  9. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/LeaveAuditLogService.java
  10. 5 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/LeaveSheetService.java
  11. 47 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/AuditWorkflowSettingServiceImpl.java
  12. 7 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java
  13. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/LeaveAuditLogServiceImpl.java
  14. 406 47
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/LeaveSheetServiceImpl.java
  15. 8 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  16. 0 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java
  17. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml
  18. 22 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/LeaveAuditLogMapper.xml
  19. 2 3
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/LeaveSheetMapper.xml
  20. 二进制
      fhKeeper/formulahousekeeper/management-platform/项目导入模板.xlsx
  21. 二进制
      fhKeeper/formulahousekeeper/timesheet/src/assets/image/qwcode.png
  22. 59 4
      fhKeeper/formulahousekeeper/timesheet/src/components/cascader.vue
  23. 34 5
      fhKeeper/formulahousekeeper/timesheet/src/components/cascaderOption.vue
  24. 19 1
      fhKeeper/formulahousekeeper/timesheet/src/i18n/en.json
  25. 19 1
      fhKeeper/formulahousekeeper/timesheet/src/i18n/zh.json
  26. 9 1
      fhKeeper/formulahousekeeper/timesheet/src/views/Home.vue
  27. 28 25
      fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue
  28. 230 40
      fhKeeper/formulahousekeeper/timesheet/src/views/leave/list.vue
  29. 8 2
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/index/index.vue
  30. 1 1
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/view/index.vue

二进制
fhKeeper/formulahousekeeper/management-platform/chi_sim.traineddata


+ 51 - 74
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/AuditWorkflowSettingController.java

@@ -9,6 +9,7 @@ import com.management.platform.entity.AuditWorkflowSetting;
 import com.management.platform.entity.Department;
 import com.management.platform.entity.Report;
 import com.management.platform.mapper.*;
+import com.management.platform.service.AuditWorkflowSettingService;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.MessageUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -20,6 +21,7 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -32,6 +34,9 @@ import java.util.List;
 @RestController
 @RequestMapping("/audit-workflow-setting")
 public class AuditWorkflowSettingController {
+    public static final int TYPE_LEAVE = 1;//请假
+    public static final int TYPE_BUSTRIP = 2;//出差
+    public static final int TYPE_EXPENSE = 3;//费用报销
     @Resource
     private HttpServletRequest request;
     @Resource
@@ -39,50 +44,58 @@ public class AuditWorkflowSettingController {
     @Resource
     UserMapper userMapper;
     @Resource
-    DepartmentMapper departmentMapper;
-    @Resource
-    ReportMapper reportMapper;
-
+    AuditWorkflowSettingService auditWorkflowSettingService;
 
     @RequestMapping("/add")
     public HttpRespMsg add(String json, Integer deptId, @RequestParam Integer type) {
         String token = request.getHeader("TOKEN");
         Integer companyId = userMapper.selectById(token).getCompanyId();
-        auditWorkflowSettingMapper.delete(new QueryWrapper<AuditWorkflowSetting>().eq("dept_id", deptId).eq("type", type));
+        QueryWrapper<AuditWorkflowSetting> eq = new QueryWrapper<AuditWorkflowSetting>().eq("dept_id", deptId).eq("type", type);
+        List<AuditWorkflowSetting> oldAuditSettingList = auditWorkflowSettingMapper.selectList(eq);
         JSONArray array = JSONArray.parseArray(json);
-
-        if (array.size() == 1 && array.getJSONObject(0).getInteger("auditorType") == 0) {
-            //只有一个项目负责人审核,不保存
-        } else {
-            //检查是否有重复的部门
-            List<Integer> auditDeptIds = new ArrayList<>();
-            for (int i=0;i<array.size(); i++) {
-                JSONObject obj = array.getJSONObject(i);
-                AuditWorkflowSetting auditWorkflowTimeSetting = JSONObject.toJavaObject(obj, AuditWorkflowSetting.class);
-                if (auditWorkflowTimeSetting.getAuditDeptId() != null) {
-                    if (auditDeptIds.contains(auditWorkflowTimeSetting.getAuditDeptId())) {
-                        HttpRespMsg msg = new HttpRespMsg();
-                        msg.setError(MessageUtils.message("department.duplicateError", auditWorkflowTimeSetting.getAuditDeptName()));
-                        return msg;
-                    } else {
-                        auditDeptIds.add(auditWorkflowTimeSetting.getAuditDeptId());
-                    }
+        //检查是否有重复的部门
+        List<Integer> auditDeptIds = new ArrayList<>();
+        for (int i=0;i<array.size(); i++) {
+            JSONObject obj = array.getJSONObject(i);
+            AuditWorkflowSetting auditWorkflowTimeSetting = JSONObject.toJavaObject(obj, AuditWorkflowSetting.class);
+            if (auditWorkflowTimeSetting.getAuditDeptId() != null) {
+                if (auditDeptIds.contains(auditWorkflowTimeSetting.getAuditDeptId())) {
+                    HttpRespMsg msg = new HttpRespMsg();
+                    msg.setError(MessageUtils.message("department.duplicateError", auditWorkflowTimeSetting.getAuditDeptName()));
+                    return msg;
+                } else {
+                    auditDeptIds.add(auditWorkflowTimeSetting.getAuditDeptId());
                 }
             }
+        }
 
-            for (int i=0;i<array.size(); i++) {
-                JSONObject obj = array.getJSONObject(i);
-                AuditWorkflowSetting auditWorkflowTimeSetting = JSONObject.toJavaObject(obj, AuditWorkflowSetting.class);
-                auditWorkflowTimeSetting.setCompanyId(companyId);
-                auditWorkflowTimeSetting.setType(type);
-                auditWorkflowTimeSetting.setSeq(i+1);
-                if (i == array.size() -1) {
-                    auditWorkflowTimeSetting.setIsFinal(1);
-                } else {
-                    auditWorkflowTimeSetting.setIsFinal(0);
-                }
-                auditWorkflowTimeSetting.setDeptId(deptId);
+        //
+        List<Integer> existingIds = new ArrayList<>();
+        for (int i=0;i<array.size(); i++) {
+            JSONObject obj = array.getJSONObject(i);
+            AuditWorkflowSetting auditWorkflowTimeSetting = JSONObject.toJavaObject(obj, AuditWorkflowSetting.class);
+            auditWorkflowTimeSetting.setCompanyId(companyId);
+            auditWorkflowTimeSetting.setType(type);
+            auditWorkflowTimeSetting.setSeq(i+1);
+            if (i == array.size() -1) {
+                auditWorkflowTimeSetting.setIsFinal(1);
+            } else {
+                auditWorkflowTimeSetting.setIsFinal(0);
+            }
+            auditWorkflowTimeSetting.setDeptId(deptId);
+            if (auditWorkflowTimeSetting.getId() == null) {
                 auditWorkflowSettingMapper.insert(auditWorkflowTimeSetting);
+            } else {
+                auditWorkflowSettingMapper.updateById(auditWorkflowTimeSetting);
+                existingIds.add(auditWorkflowTimeSetting.getId());
+            }
+        }
+
+        //移除不在本次保存范围内的已有节点数据
+        if (oldAuditSettingList.size() > 0) {
+            List<Integer> collect = oldAuditSettingList.stream().map(AuditWorkflowSetting::getId).filter(oldId -> !existingIds.stream().anyMatch(ex -> ex.equals(oldId))).collect(Collectors.toList());
+            if (collect.size() > 0) {
+                auditWorkflowSettingMapper.deleteBatchIds(collect);
             }
         }
         return new HttpRespMsg();
@@ -91,55 +104,19 @@ public class AuditWorkflowSettingController {
     @RequestMapping("/checkNodeInUse")
     public HttpRespMsg checkNodeInUse(String auditDeptId, Integer deptId, Integer type) {
         String token = request.getHeader("TOKEN");
-        Integer companyId = userMapper.selectById(token).getCompanyId();
         HttpRespMsg msg = new HttpRespMsg();
         List<AuditWorkflowSetting> targetNode = auditWorkflowSettingMapper.selectList(new QueryWrapper<AuditWorkflowSetting>().eq("dept_id", deptId).eq("audit_dept_id", auditDeptId).eq("type", type));
-//        if (targetNode.size() > 0) {
-//            //要删除的部门节点是存在的,需要检测是否有待审核的走到这个流程点了
-//            long num = reportMapper.selectCount(new QueryWrapper<Report>().eq("state", 0).eq("is_dept_audit", 1).eq("audit_deptid", auditDeptId));
-//            if (num > 0) {
-//                msg.setError("当前部门存在待审核报告,无法操作!");
-//            }
-//        }
+        if (targetNode.size() > 0) {
+
+        }
 
         return msg;
     }
 
     @RequestMapping("/get")
     public HttpRespMsg get(Integer deptId, @RequestParam Integer type) {
-        String token = request.getHeader("TOKEN");
-        Integer companyId = userMapper.selectById(token).getCompanyId();
-        List<AuditWorkflowSetting> auditWorkflowTimeSettings = auditWorkflowSettingMapper.selectList(new QueryWrapper<AuditWorkflowSetting>().eq("dept_id", deptId).eq("type", type).orderByAsc("seq"));
         HttpRespMsg msg = new HttpRespMsg();
-        if (auditWorkflowTimeSettings.size() == 0) {
-            int seq = 1;
-            //出差,默认是项目负责人审批
-            Department dept = departmentMapper.selectById(deptId);
-            AuditWorkflowSetting setting = new AuditWorkflowSetting();
-            setting.setSeq(seq);
-            setting.setCompanyId(companyId);
-            setting.setDeptId(dept.getDepartmentId());
-            setting.setIsFinal(1);
-            setting.setAuditorType(0);
-            auditWorkflowTimeSettings.add(setting);
-//            if (type ==1) {
-//
-//            } else {
-//                //获取默认的设置,默认直接就是部门负责人审批
-//                Department dept = departmentMapper.selectById(deptId);
-//                AuditWorkflowSetting setting = new AuditWorkflowSetting();
-//                setting.setSeq(seq);
-//                setting.setCompanyId(companyId);
-//                setting.setDeptId(dept.getDepartmentId());
-//                setting.setAuditDeptId(dept.getDepartmentId());
-//                setting.setAuditDeptName(dept.getDepartmentName());
-//                setting.setIsFinal(1);
-//                setting.setAuditorType(1);
-//                auditWorkflowTimeSettings.add(setting);
-//            }
-
-        }
-        msg.data = auditWorkflowTimeSettings;
+        msg.data = auditWorkflowSettingService.get(deptId, type);
         return msg;
     }
 

+ 37 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/LeaveAuditLogController.java

@@ -0,0 +1,37 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.LeaveAuditLog;
+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-10
+ */
+@RestController
+@RequestMapping("/leave-audit-log")
+public class LeaveAuditLogController {
+    @Resource
+    LeaveAuditLogMapper leaveAuditLogMapper;
+
+    @RequestMapping("/getBySheetId")
+    public HttpRespMsg getBySheetId(int sheetId) {
+        List<LeaveAuditLog> list = leaveAuditLogMapper.selectList(new QueryWrapper<LeaveAuditLog>().eq("sheet_id", sheetId));
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = list;
+        return msg;
+    }
+}
+

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

@@ -52,7 +52,7 @@ public class LeaveSheetController {
 
 
     /**
-     *
+     * 提交请假申请单
      * @param sheet 请假单封装数据
      * @return
      */
@@ -63,6 +63,14 @@ public class LeaveSheetController {
 
     }
 
+    @RequestMapping("/cancel")
+    public HttpRespMsg cancel(Integer id) {
+        String userId = request.getHeader("Token");
+        return leaveSheetService.cancel(id, userId);
+    }
+
+
+
     @RequestMapping("/delete")
     public HttpRespMsg delete(Integer id) {
         return leaveSheetService.delete(id);
@@ -74,15 +82,18 @@ public class LeaveSheetController {
         return leaveSheetService.queryList(sheet, pageIndex, pageSize);
     }
 
+    @RequestMapping("/auditList")
+    public HttpRespMsg auditList(LeaveSheet sheet, @RequestParam Integer pageIndex, @RequestParam Integer pageSize) {
+        return leaveSheetService.auditList(sheet, pageIndex, pageSize);
+    }
+
     @RequestMapping("/approve")
     public HttpRespMsg approve(Integer id) {
         return leaveSheetService.approve(id);
     }
     @RequestMapping("/deny")
-    public HttpRespMsg deny(Integer id) {
-
-        return leaveSheetService.deny(id);
-
+    public HttpRespMsg deny(Integer id, String reason) {
+        return leaveSheetService.deny(id, reason);
     }
 
     /**

+ 72 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/LeaveAuditLog.java

@@ -0,0 +1,72 @@
+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 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-12-10
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class LeaveAuditLog extends Model<LeaveAuditLog> {
+
+    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")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime indate;
+
+    @TableField("deny_reason")
+    private String denyReason;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 13 - 18
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/LeaveSheet.java

@@ -20,12 +20,13 @@ import org.springframework.format.annotation.DateTimeFormat;
  * </p>
  *
  * @author Seyason
- * @since 2022-07-15
+ * @since 2022-12-10
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
 @Accessors(chain = true)
 public class LeaveSheet extends Model<LeaveSheet> {
+
     private static final long serialVersionUID=1L;
 
     @TableId(value = "id", type = IdType.AUTO)
@@ -73,7 +74,6 @@ public class LeaveSheet extends Model<LeaveSheet> {
 
     /**
      * 0-审核通过,1-待审核,2-驳回,3-已撤回
-     * WX状态:1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付
      */
     @TableField("status")
     private Integer status;
@@ -106,6 +106,8 @@ public class LeaveSheet extends Model<LeaveSheet> {
      * 时间
      */
     @TableField("indate")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime indate;
 
     /**
@@ -133,38 +135,31 @@ public class LeaveSheet extends Model<LeaveSheet> {
     private String auditorName;
 
     /**
-     * 审核流程:当前审核的部门id
-     */
-    @TableField("audit_deptid")
-    private Integer auditDeptid;
-
-    /**
-     * 是否是最后一步审核
-     */
-    @TableField("is_final_audit")
-    private Integer isFinalAudit;
-
-    /**
-     * 1-部门审核,0-项目负责人审核,2-指定人员审核
+     * 1-部门审核,2-指定人员审核
      */
     @TableField("auditor_type")
     private Integer auditorType;
 
-    @TableField(exist = false)
-    private String dept;
     /**
      * 钉钉审批实例procInst_id
      */
     @TableField("procinst_id")
     private String procinstId;
 
-
     /**
      * 钉钉审批实例的审批通过时间
      */
     @TableField("gmt_finished")
     private String gmtFinished;
 
+    /**
+     * 当前审核节点id
+     */
+    @TableField("cur_audit_setting_id")
+    private Integer curAuditSettingId;
+
+    @TableField(exist = false)
+    private String dept;
 
     @Override
     protected Serializable pkVal() {

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

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

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

@@ -2,6 +2,10 @@ package com.management.platform.service;
 
 import com.management.platform.entity.AuditWorkflowSetting;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
 
 /**
  * <p>
@@ -12,5 +16,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @since 2022-03-28
  */
 public interface AuditWorkflowSettingService extends IService<AuditWorkflowSetting> {
-
+    public List<AuditWorkflowSetting> get(Integer deptId, @RequestParam Integer type);
 }

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

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

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

@@ -26,11 +26,15 @@ public interface LeaveSheetService extends IService<LeaveSheet> {
 
     HttpRespMsg approve(Integer id);
 
-    HttpRespMsg deny(Integer id);
+    HttpRespMsg deny(Integer id, String reason);
 
     HttpRespMsg summaryData(String keyword, String startDate, String endDate, String userId);
 
     HttpRespMsg getOTAvaiDays(String userId);
 
     HttpRespMsg exportLeaveData(String userId,Integer status, Integer leaveType, String startTime,String endTime);
+
+    HttpRespMsg cancel(Integer id, String userId);
+
+    HttpRespMsg auditList(LeaveSheet sheet, Integer pageIndex, Integer pageSize);
 }

+ 47 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/AuditWorkflowSettingServiceImpl.java

@@ -1,11 +1,22 @@
 package com.management.platform.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.entity.AuditWorkflowSetting;
+import com.management.platform.entity.Department;
 import com.management.platform.mapper.AuditWorkflowSettingMapper;
+import com.management.platform.mapper.DepartmentMapper;
+import com.management.platform.mapper.ReportMapper;
+import com.management.platform.mapper.UserMapper;
 import com.management.platform.service.AuditWorkflowSettingService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.util.HttpRespMsg;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * <p>
  *  服务实现类
@@ -16,5 +27,41 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class AuditWorkflowSettingServiceImpl extends ServiceImpl<AuditWorkflowSettingMapper, AuditWorkflowSetting> implements AuditWorkflowSettingService {
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    AuditWorkflowSettingMapper auditWorkflowSettingMapper;
+    @Resource
+    UserMapper userMapper;
+    @Resource
+    DepartmentMapper departmentMapper;
+    @Resource
+    ReportMapper reportMapper;
 
+    @Override
+    public List<AuditWorkflowSetting> get(Integer deptId, Integer type) {
+        if (deptId != null && deptId > 0) {
+            List<AuditWorkflowSetting> auditWorkflowTimeSettings = auditWorkflowSettingMapper.selectList(new QueryWrapper<AuditWorkflowSetting>().eq("dept_id", deptId).eq("type", type).orderByAsc("seq"));
+            Integer companyId = departmentMapper.selectById(deptId).getCompanyId();
+            if (auditWorkflowTimeSettings.size() == 0) {
+                //生成默认数据
+                int seq = 1;
+                //获取默认的设置,默认直接就是部门负责人审批
+                Department dept = departmentMapper.selectById(deptId);
+                AuditWorkflowSetting setting = new AuditWorkflowSetting();
+                setting.setSeq(seq);
+                setting.setCompanyId(companyId);
+                setting.setDeptId(dept.getDepartmentId());
+                setting.setAuditDeptId(dept.getDepartmentId());
+                setting.setAuditDeptName(dept.getDepartmentName());
+                setting.setIsFinal(1);
+                setting.setAuditorType(type);
+                auditWorkflowSettingMapper.insert(setting);
+                auditWorkflowTimeSettings.add(setting);
+            }
+            return auditWorkflowTimeSettings;
+        } else {
+            return new ArrayList<>();
+        }
+    }
 }

+ 7 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java

@@ -149,6 +149,13 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
                 department.setManagerId(managerId);
                 department.setReportAuditUserid(reportAuditUserid);
 
+                //修改审批流中的部门名称
+                if (deptNameChanged) {
+                    AuditWorkflowSetting auditWorkflowSetting = new AuditWorkflowSetting();
+                    auditWorkflowSetting.setAuditDeptName(departmentName);
+                    auditWorkflowSettingMapper.update(auditWorkflowSetting, new QueryWrapper<AuditWorkflowSetting>().eq("audit_dept_id", departmentId));
+                }
+
                 if (departmentMapper.updateById(department) == 0) {
                     //httpRespMsg.setError("修改失败");
                     httpRespMsg.setError(MessageUtils.message("other.modifyFail"));

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

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

+ 406 - 47
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/LeaveSheetServiceImpl.java

@@ -5,6 +5,7 @@ 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.*;
@@ -23,6 +24,7 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.xml.transform.Source;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -39,6 +41,7 @@ import java.util.stream.Collectors;
 @Transactional
 public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSheet> implements LeaveSheetService {
     public static final Integer exLeaveDay = 6;
+    public static final String[] LEAVE_TYPES = new String[]{"事假","病假","年假","产假","婚假","丧假","调休假","陪产假","其他"};
     @Resource
     private UserMapper userMapper;
     @Resource
@@ -48,14 +51,12 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
     @Resource
     private ReportMapper reportMapper;
     @Resource
+    private AuditWorkflowSettingService auditWorkflowSettingService;
+    @Resource
     private AuditWorkflowSettingMapper auditWorkflowSettingMapper;
     @Resource
     private DepartmentMapper departmentMapper;
     @Resource
-    private LeavePmauditService leavePmauditService;
-    @Resource
-    private UserYearleaveSettingMapper userYearleaveSettingMapper;
-    @Resource
     private HttpServletRequest request;
     @Resource
     SysFunctionMapper sysFunctionMapper;
@@ -65,6 +66,15 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
     WxCorpInfoMapper wxCorpInfoMapper;
     @Resource
     ExcelExportService excelExportService;
+    @Resource
+    LeaveAuditLogMapper leaveAuditLogMapper;
+    @Resource
+    WxCorpInfoService wxCorpInfoService;
+    @Resource
+    InformationMapper informationMapper;
+
+    @Value(value = "${upload.path}")
+    private String path;
 
     @Override
     public HttpRespMsg add(LeaveSheet sheet, String userId) {
@@ -94,36 +104,174 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
             if (count > 0) {
                 //msg.setError("该时间段已有请假申请,不能重复请假");
                 msg.setError(MessageUtils.message("leave.repeatedLeave"));
-            } else {
-                //校验当前的指定的项目审核人
-                //获取第一个审批人
-                User owner = userMapper.selectById(sheet.getOwnerId());
-                AuditWorkflowSetting workflowNode = auditWorkflowSettingMapper.selectOne(new QueryWrapper<AuditWorkflowSetting>().eq("type", 0)
-                        .eq("dept_id", owner.getDepartmentId()).orderByAsc("seq").last("limit 1"));
-                if (workflowNode != null) {
-                    if (workflowNode.getAuditorType() == 0) {
-                        //项目负责人审核, 创建时指定的项目审核人
-
-                    } else if (workflowNode.getAuditorType() == 1) {
-                        //部门负责人
-                        Department dept = departmentMapper.selectById(workflowNode.getAuditDeptId());
-                        sheet.setAuditorId(dept.getManagerId());
-
-                    } else {
-                        //指定一个人审批
-                        sheet.setAuditorId(workflowNode.getUserId());
-                        sheet.setAuditorName(workflowNode.getUserName());
+            }
+        }
+
+        //获取第一个审批人
+        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());
                 }
-                leaveSheetMapper.insert(sheet);
+                sheet.setCurAuditSettingId(workflowNode.getId());
             }
+        }
+
+        if (isNew) {
+            leaveSheetMapper.insert(sheet);
         } else {
+            //编辑修改
             leaveSheetMapper.updateById(sheet);
+            //之前的审批流程要删除
+            leaveAuditLogMapper.delete(new QueryWrapper<LeaveAuditLog>().eq("sheet_id", sheet.getId()));
+        }
+        sheet = leaveSheetMapper.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, LeaveSheet sheet, String denyReason) {
+        //推送到企业微信
+        JSONObject json=new JSONObject();
+        JSONArray dataJson=new JSONArray();
+        JSONObject jsonObj=new JSONObject();
+        jsonObj.put("key", "审核结果");
+        jsonObj.put("value",sheet.getStatus() == 0?"通过":"驳回");
+//        jsonObj.put("value",("$userName="+applier.getCorpwxUserid()+"$"));
+        JSONObject jsonObj1=new JSONObject();
+        jsonObj1.put("key", "审核人");
+        jsonObj1.put("value",("$userName="+auditor.getCorpwxUserid()+"$"));
+        String applyTimeDesc = "";
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("M月d日");
+        if (sheet.getStartDate().isEqual(sheet.getEndDate())) {
+            applyTimeDesc = dateTimeFormatter.format(sheet.getStartDate()) + ", "+sheet.getTimeHours()+"小时";
+        } else {
+            applyTimeDesc = dateTimeFormatter.format(sheet.getStartDate()) +"至" + dateTimeFormatter.format(sheet.getEndDate()) + ", "+sheet.getTimeHours()+"小时";
+        }
+
+        JSONObject jsonObj2=new JSONObject();
+        jsonObj2.put("key", "请假时间");
+        jsonObj2.put("value",applyTimeDesc);
+        JSONObject jsonObj4=new JSONObject();
+        jsonObj4.put("key", "备注");
+        jsonObj4.put("value",sheet.getStatus()==2?("原因:"+denyReason):"请假申请通过了");
+        dataJson.add(jsonObj);
+        dataJson.add(jsonObj1);
+        dataJson.add(jsonObj2);
+        dataJson.add(jsonObj4);
+        json.put("template_id","tty9TkCAAARfwRKiqfj47qNE70KvGhqg");
+        json.put("url","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=leave#wechat_redirect");
+        json.put("content_item",dataJson);
+        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) {
+        //推送到企业微信
+        String applyTimeDesc = "";
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("M月d日");
+        if (sheet.getStartDate().isEqual(sheet.getEndDate())) {
+            applyTimeDesc = dateTimeFormatter.format(sheet.getStartDate()) + ", "+sheet.getTimeHours()+"小时";
+        } else {
+            applyTimeDesc = dateTimeFormatter.format(sheet.getStartDate()) +"至" + dateTimeFormatter.format(sheet.getEndDate()) + ", "+sheet.getTimeHours()+"小时";
+        }
+        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() == 1?"已通过":"已驳回")+", 审核人:"
+                +(auditor.getCorpwxUserid() != null ? ("$userName="+auditor.getCorpwxUserid()+"$"):auditor.getName()));
+        information.setType(4);
+        information.setContent(sheet.getId()+"");
+        informationMapper.insert(information);
+    }
+
+    private void saveNotifyToAuditor(LeaveSheet 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(4);
+        information.setContent(sheet.getId()+"");
+        informationMapper.insert(information);
+    }
+
+    //发送待审核提醒
+    private void sendAuditNotifyMsg(WxCorpInfo wxCorpInfo, User applier, LeaveSheet sheet) {
+        //推送到企业微信
+        JSONObject json=new JSONObject();
+        JSONArray dataJson=new JSONArray();
+        JSONObject jsonObj=new JSONObject();
+        jsonObj.put("key", "请假人");
+        jsonObj.put("value",("$userName="+applier.getCorpwxUserid()+"$"));
+        JSONObject jsonObj1=new JSONObject();
+        jsonObj1.put("key", "请假类型");
+        jsonObj1.put("value",LEAVE_TYPES[sheet.getLeaveType()]);
+        String applyTimeDesc = "";
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("M月d日");
+        if (sheet.getStartDate().isEqual(sheet.getEndDate())) {
+            applyTimeDesc = dateTimeFormatter.format(sheet.getStartDate()) + ", "+sheet.getTimeHours()+"小时";
+        } else {
+            applyTimeDesc = dateTimeFormatter.format(sheet.getStartDate()) +"至" + dateTimeFormatter.format(sheet.getEndDate()) + ", "+sheet.getTimeHours()+"小时";
+        }
+
+        JSONObject jsonObj2=new JSONObject();
+        jsonObj2.put("key", "请假时间");
+        jsonObj2.put("value",applyTimeDesc);
+        JSONObject jsonObj4=new JSONObject();
+        jsonObj4.put("key", "备注");
+        jsonObj4.put("value",sheet.getRemark()==null?"":sheet.getRemark());
+        dataJson.add(jsonObj);
+        dataJson.add(jsonObj1);
+        dataJson.add(jsonObj2);
+        dataJson.add(jsonObj4);
+        json.put("template_id","tty9TkCAAA4WvYmTnsAVoUmdYxHdSG9A");
+        json.put("url","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=leave#wechat_redirect");
+        json.put("content_item",dataJson);
+        String auditorId = sheet.getAuditorId();
+        User auditor = userMapper.selectById(auditorId);
+        wxCorpInfoService.sendWXCorpTemplateMsg(wxCorpInfo,auditor.getCorpwxUserid(), json);
+    }
+
     @Override
     public HttpRespMsg delete(Integer id) {
         leaveSheetMapper.deleteById(id);
@@ -135,6 +283,7 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
         QueryWrapper<LeaveSheet> queryWrapper = new QueryWrapper<LeaveSheet>();
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
+
         List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全部请假单");
         if (functionList.size() == 0) {
             //部门负责人可以看这个部门的
@@ -197,20 +346,127 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
 
     @Override
     public HttpRespMsg approve(Integer id) {
-        LeaveSheet sheet = new LeaveSheet();
-        sheet.setId(id);
-        sheet.setStatus(0);
-        leaveSheetMapper.updateById(sheet);
-        return new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        //检查操作人权限
+        User user = userMapper.selectById(token);
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        LeaveSheet originSheet = leaveSheetMapper.selectById(id);
+        if (user.getId().equals(originSheet.getAuditorId())) {
+            //是当前的审核人,获取下个审核节点
+            AuditWorkflowSetting auditWorkflowSetting = auditWorkflowSettingMapper.selectById(originSheet.getCurAuditSettingId());
+            LeaveSheet sheet = new LeaveSheet();
+            sheet.setId(id);
+            if (auditWorkflowSetting == null) {
+                //当前审核节点已不存在,直接审核通过
+                sheet.setStatus(0);
+            } else {
+                Integer seq = auditWorkflowSetting.getSeq();
+                AuditWorkflowSetting nextAuditNode = auditWorkflowSettingMapper.selectOne(new QueryWrapper<AuditWorkflowSetting>().eq("seq", (seq + 1)).eq("dept_id", auditWorkflowSetting.getDeptId()));
+                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());
+                    }
+                }
+            }
+            leaveSheetMapper.updateById(sheet);
+            //保存审核记录
+            saveAgreeLog(id, auditWorkflowSetting, user);
+            //最终审核通过,发送通过消息
+            sheet = leaveSheetMapper.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) {
+        LeaveAuditLog log = new LeaveAuditLog();
+        log.setSheetId(sheetId);
+        if (curAuditNode != null) {
+            log.setAuditNodeId(curAuditNode.getId());
+        }
+        log.setAuditorId(operator.getId());
+        log.setAuditorName(operator.getName());
+        log.setIsPass(1);
+        leaveAuditLogMapper.insert(log);
+    }
+    private void saveDenyLog(int sheetId, AuditWorkflowSetting curAuditNode, User operator, String reason) {
+        LeaveAuditLog log = new LeaveAuditLog();
+        log.setSheetId(sheetId);
+        if (curAuditNode != null) {
+            log.setAuditNodeId(curAuditNode.getId());
+        }
+        log.setAuditorId(operator.getId());
+        log.setAuditorName(operator.getName());
+        log.setIsPass(0);
+        log.setDenyReason(reason);
+        leaveAuditLogMapper.insert(log);
     }
 
+
     @Override
-    public HttpRespMsg deny(Integer id) {
-        LeaveSheet sheet = new LeaveSheet();
-        sheet.setId(id);
-        sheet.setStatus(2);
-        leaveSheetMapper.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();
+        LeaveSheet originSheet = leaveSheetMapper.selectById(id);
+        if (user.getId().equals(originSheet.getAuditorId())) {
+            //是当前的审核人,获取当前审核节点
+            AuditWorkflowSetting auditWorkflowSetting = auditWorkflowSettingMapper.selectById(originSheet.getCurAuditSettingId());
+            LeaveSheet sheet = new LeaveSheet();
+            sheet.setId(id);
+            sheet.setStatus(2);
+            leaveSheetMapper.updateById(sheet);
+            saveDenyLog(id, auditWorkflowSetting, user, reason);
+            sheet = leaveSheetMapper.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
@@ -238,22 +494,54 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
         return msg;
     }
 
-    @Value(value = "${upload.path}")
-    private String path;
+
     @Override
     public HttpRespMsg exportLeaveData(String userId,Integer status,Integer leaveType,String startTime,String endTime) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         Integer companyId = userMapper.selectById(userId).getCompanyId();
         WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", companyId));
         List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).select("id","name","corpwx_userid"));
-        QueryWrapper<LeaveSheet> qw = new QueryWrapper<LeaveSheet>()
-                .select("owner_id","tel","owner_name", "leave_type", "start_date","end_date","time_days", "time_hours", "status", "remark")
-                .eq("company_id", companyId)
-                .eq(status != null, "status", status)
-                .eq(leaveType != null, "leave_type", leaveType)
-                .le(endTime != "" && endTime != null, "start_date", endTime)
-                .ge(startTime != "" && startTime != null, "end_date", startTime).orderByDesc("id");
-        List<LeaveSheet> leaveSheets = leaveSheetMapper.selectList(qw);
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        QueryWrapper<LeaveSheet> queryWrapper = new QueryWrapper<>();
+        LeaveSheet sheet = new LeaveSheet();
+        List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全部请假单");
+        if (functionList.size() == 0) {
+            //部门负责人可以看这个部门的
+            List<Integer> mdids = departmentService.getAllManagedDeptIdList(user, null);
+//            List<Department> departmentList = departmentMapper.selectList(new QueryWrapper<Department>().eq("manager_id", user.getId()));
+            if (mdids.size() > 0) {
+                //负责的部门的人员
+                //先是自己的
+                List<String> userIds = new ArrayList<>();
+                userIds.add(user.getId());
+                List<User> deptUserList = userMapper.selectList(new QueryWrapper<User>().select("id").in("department_id", mdids));
+                List<String> collect = deptUserList.stream().map(User::getId).collect(Collectors.toList());
+                userIds.addAll(collect);
+                queryWrapper.in("owner_id", userIds);
+            } else {
+                //普通员工只能看自己的
+                sheet.setOwnerId(user.getId());
+            }
+        }
+        sheet.setCompanyId(user.getCompanyId());
+
+        queryWrapper.eq("company_id", sheet.getCompanyId()).orderByDesc("id");
+        //增加状态
+        if (sheet.getStatus() != null) {
+            queryWrapper.eq("status", sheet.getStatus());
+        }
+        if (!StringUtils.isEmpty(sheet.getOwnerId())) {
+            queryWrapper.eq("owner_id", sheet.getOwnerId());
+        }
+        if (sheet.getLeaveType() != null) {
+            queryWrapper.eq("leave_type", leaveType);
+        }
+        if (sheet.getStartDate() != null && sheet.getEndDate() != null) {
+            queryWrapper.le("start_date", startTime).ge("end_date", endTime);
+        }
+
+        List<LeaveSheet> leaveSheets = leaveSheetMapper.selectList(queryWrapper);
         if (leaveSheets.size()==0){
             return httpRespMsg;
         };
@@ -330,6 +618,12 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
             item.add(eds);
             item.add(leaveSheet.getTimeDays()==null?"":leaveSheet.getTimeDays().toString());
             item.add(leaveSheet.getTimeHours()==null?"":leaveSheet.getTimeHours().toString());
+            Optional<User> first = userList.stream().filter(u -> u.getId().equals(leaveSheet.getAuditorId())).findFirst();
+            String auditorName = first.isPresent()?first.get().getName():"";
+            //转译处理
+            if (wxCorpInfo != null && wxCorpInfo.getSaasSyncContact() == 1) {
+                auditorName = "$userName="+auditorName+"$";
+            }
             String statusS = "";
             switch (leaveSheet.getStatus()){
                 case 0:
@@ -338,7 +632,8 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
                     break;
                 case 1:
                     //statusS = "待审核";
-                    statusS = MessageUtils.message("stages.reviewed");
+                    statusS = MessageUtils.message("stages.reviewed")
+                            + "-" + auditorName;
                     break;
                 case 2:
                     //statusS = "驳回";
@@ -362,4 +657,68 @@ public class LeaveSheetServiceImpl extends ServiceImpl<LeaveSheetMapper, LeaveSh
         }
         return httpRespMsg;
     }
+
+    @Override
+    public HttpRespMsg cancel(Integer id, String userId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        LeaveSheet oldSheet = leaveSheetMapper.selectById(id);
+        if (oldSheet.getStatus() == 0) {
+            msg.setError("当前请假申请已通过,无法撤销");
+        } else if (oldSheet.getStatus() == 2) {
+            msg.setError("当前请假申已驳回,无法撤销");
+        } else {
+            LeaveSheet sheet = new LeaveSheet();
+            sheet.setId(id);
+            sheet.setStatus(3);//撤销状态
+            leaveSheetMapper.updateById(sheet);
+            //删除相关的审批记录
+            leaveAuditLogMapper.delete(new QueryWrapper<LeaveAuditLog>().eq("sheet_id", id));
+        }
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg auditList(LeaveSheet sheet, Integer pageIndex, Integer pageSize) {
+        QueryWrapper<LeaveSheet> queryWrapper = new QueryWrapper<LeaveSheet>();
+        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.getLeaveType() != null) {
+            queryWrapper.eq("leave_type", sheet.getLeaveType());
+        }
+        if (sheet.getStartDate() != null && sheet.getEndDate() != null) {
+            queryWrapper.le("start_date", sheet.getEndDate()).ge("end_date", sheet.getStartDate());
+        }
+        IPage<LeaveSheet> listIPager = leaveSheetMapper.selectPage(new Page<>(pageIndex, pageSize),
+                queryWrapper);
+        List<LeaveSheet> records = listIPager.getRecords();
+        List<String> userIds = records.stream().map(LeaveSheet::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;
+    }
 }

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

@@ -8668,7 +8668,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         List<SysRichFunction> functionInchargeList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "负责项目分组阶段工时");
         //判断查看权限
         List<Integer> inchagerIds=null;
-        if(false){
+        if(functionAllList.size()==0){
             inchagerIds=new ArrayList<>();
             if(functionInchargeList.size()>0){
                 List<Project> list = projectList.stream().filter(pl -> (pl.getInchargerId()==null?0:pl.getInchargerId()).equals(user.getId())).collect(Collectors.toList());
@@ -8683,6 +8683,9 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         List<Map<String,Object>> projectGroupAndCategoryList=projectMapper.getProjectGroupAndCategoryList(startDate,endDate,projectId,user.getCompanyId(),start,size,inchagerIds);
         long total=projectMapper.getProjectGroupAndCategoryCount(startDate,endDate,projectId,user.getCompanyId(),null,null,inchagerIds);
         List<Integer> projectIds = projectGroupAndCategoryList.stream().map(pl ->Integer.valueOf(String.valueOf(pl.get("projectId")))).distinct().collect(Collectors.toList());
+        if(projectIds.size()==0){
+            projectIds.add(-1);
+        }
         List<Stages> stagesList = stagesMapper.selectList(new QueryWrapper<Stages>().in("project_id", projectIds));
         List<String> titleList=new ArrayList<>();
         List<String> stagesNameList = stagesList.stream().map(sl -> sl.getStagesName()).distinct().collect(Collectors.toList());
@@ -8710,7 +8713,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         List<SysRichFunction> functionInchargeList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "负责项目任务阶段工时");
         //判断查看权限
         List<Integer> inchagerIds=null;
-        if(false){
+        if(functionAllList.size()==0){
             inchagerIds=new ArrayList<>();
             if(functionInchargeList.size()>0){
                 List<Project> list = projectList.stream().filter(pl -> (pl.getInchargerId()==null?0:pl.getInchargerId()).equals(user.getId())).collect(Collectors.toList());
@@ -8724,6 +8727,9 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         }
         List<Map<String,Object>> projectGroupAndCategoryList=projectMapper.getProjectGroupAndCategoryList(startDate,endDate,projectId,user.getCompanyId(),null,null,inchagerIds);
         List<Integer> projectIds = projectGroupAndCategoryList.stream().map(pl ->Integer.valueOf(String.valueOf(pl.get("projectId")))).distinct().collect(Collectors.toList());
+        if(projectIds.size()==0){
+            projectIds.add(-1);
+        }
         List<Stages> stagesList = stagesMapper.selectList(new QueryWrapper<Stages>().in("project_id", projectIds));
         List<String> titleList=new ArrayList<>();
         titleList.add("项目编号");

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

@@ -1544,7 +1544,6 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                             String leaveType = date_range.getString("type");
                             LeaveSheet leaveSheet = new LeaveSheet();
                             leaveSheet.setProcinstId(sp_no_lists[i].toString());
-                            leaveSheet.setIsFinalAudit(1);
                             leaveSheet.setIndate(applyTime);
                             leaveSheet.setOwnerName(name);
                             leaveSheet.setOwnerId(user==null?"":user.getId());

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml

@@ -15,7 +15,7 @@ spring:
       location: C:/upload/
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://47.101.180.183:3306/man_mld?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=false
+    url: jdbc:mysql://47.101.180.183:3306/man_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=false
     username: root
     password: HuoshiDB@2022
     hikari:

+ 22 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/LeaveAuditLogMapper.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.LeaveAuditLogMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.LeaveAuditLog">
+        <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>

+ 2 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/LeaveSheetMapper.xml

@@ -21,16 +21,15 @@
         <result column="tel" property="tel" />
         <result column="auditor_id" property="auditorId" />
         <result column="auditor_name" property="auditorName" />
-        <result column="audit_deptid" property="auditDeptid" />
-        <result column="is_final_audit" property="isFinalAudit" />
         <result column="auditor_type" property="auditorType" />
         <result column="procinst_id" property="procinstId" />
         <result column="gmt_finished" property="gmtFinished" />
+        <result column="cur_audit_setting_id" property="curAuditSettingId" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, company_id, owner_id, owner_name, start_date, end_date, leave_type, status, remark, operator_id, time_hours, time_days, indate, time_type, tel, auditor_id, auditor_name, audit_deptid, is_final_audit, auditor_type, procinst_id, gmt_finished
+        id, company_id, owner_id, owner_name, start_date, end_date, leave_type, status, remark, operator_id, time_hours, time_days, indate, time_type, tel, auditor_id, auditor_name, auditor_type, procinst_id, gmt_finished, cur_audit_setting_id
     </sql>
     <select id="summaryData"  resultMap="BaseResultMap">
         select owner_id, owner_name, sum(time_hours) as time_hours, sum(time_days) as time_days from leave_sheet

二进制
fhKeeper/formulahousekeeper/management-platform/项目导入模板.xlsx


二进制
fhKeeper/formulahousekeeper/timesheet/src/assets/image/qwcode.png


+ 59 - 4
fhKeeper/formulahousekeeper/timesheet/src/components/cascader.vue

@@ -3,8 +3,19 @@
     <div :class="disabled ? 'disabledTrue' : 'disabledFalse'" @mouseenter="moveIonDiv" @mouseleave="outIonDiv">
         <div :style="`width:${selectWidth}px;height:${selectHeight}px`" :class="classDiv ? 'select selectDiv' : 'select'" @click.stop="selectCli" :ref="disabled ? '' : 'selectDiv'">
             <div :style="'line-height: '+selectHeight+'px;font-size: '+selectFontSize+'px;'" :class="(selectName == $t('defaultText.pleaseChoose') || selectName == $t('qing-xuan-ze-bu-men') || selectName == $t('other.allDepartments')) ? 'selecttex selecttexXuan' : 'selecttex'">
-                <ww-open-data type='departmentName' :openid='selectName'></ww-open-data>
+                <!-- <ww-open-data type='departmentName' :openid='selectName'></ww-open-data> -->
                 <!-- {{selectName}} -->
+                 <span v-if="userName">
+                    <span v-if="selectNameType == 'dep'">
+                        <ww-open-data type='departmentName' :openid='selectName'></ww-open-data>
+                    </span>
+                    <span v-if="selectNameType == 'user'">
+                        <ww-open-data type='userName' :openid='selectName'></ww-open-data>
+                    </span>
+                </span>
+                <span v-if="!userName">
+                    <ww-open-data type='departmentName' :openid='selectName'></ww-open-data>
+                </span>
             </div>
             <i :class=" move ? 'el-icon-arrow-down iostu iostuHover' : 'el-icon-arrow-down iostu'" v-if="!moveIon"></i>
             <i v-if="moveIon" class="el-icon-circle-close iostu" @click.stop="clearDelete"></i>
@@ -17,13 +28,35 @@
                 <li :class="transitionBoxLiIdx == index ? 'liHover' : ''" v-for="(item, index) in options" :key="index" @mouseover="liMouseOver(index, item)" @click.stop="liClist(item)"> 
                     <span :class="item.children ? 'idxspan' : ''" v-if="!radios">
                         <!-- {{item.label}} -->
-                        <ww-open-data type='departmentName' :openid='item.label'></ww-open-data>
+                        <span v-if="userName">
+                            <span v-if="item.type == 'dep'">
+                                <ww-open-data type='departmentName' :openid='item.label'></ww-open-data>
+                            </span>
+                            <span v-if="item.type == 'user'">
+                                <ww-open-data type='userName' :openid='item.label'></ww-open-data>
+                            </span>
+                        </span>
+                        <span v-if="!userName">
+                            <ww-open-data type='departmentName' :openid='item.label'></ww-open-data>
+                        </span>
+                        <!-- <ww-open-data type='departmentName' :openid='item.label'></ww-open-data> -->
                     </span>
                     <span v-if="radios" style="margin-left: -15px">
                         <el-radio v-model="optionsOId" :label="item.value">
                             <span class="idxspan" style="margin-left: -10px"> 
                                 <!-- {{item.label}}  -->
-                                <ww-open-data type='departmentName' :openid='item.label'></ww-open-data>
+                                <span v-if="userName">
+                                    <span v-if="item.type == 'dep'">
+                                        <ww-open-data type='departmentName' :openid='item.label'></ww-open-data>
+                                    </span>
+                                    <span v-if="item.type == 'user'">
+                                        <ww-open-data type='userName' :openid='item.label'></ww-open-data>
+                                    </span>
+                                </span>
+                                <span v-if="!userName">
+                                    <ww-open-data type='departmentName' :openid='item.label'></ww-open-data>
+                                </span>
+                                <!-- <ww-open-data type='departmentName' :openid='item.label'></ww-open-data> -->
                             </span>
                         </el-radio>
                     </span>
@@ -34,7 +67,7 @@
 
         <div v-for="(item, index) in options" :key="index">
             <div v-if="item.children" style="position: absolute;left: 200px;top: 6px">
-                <cascaderOption :subject="item.children" :radios="radios" v-show="transitionBoxLiIdx == index" @cascaderOptionClick="cascaderOptionClick"></cascaderOption>
+                <cascaderOption :subject="item.children" :userName="userName" :radios="radios" v-show="transitionBoxLiIdx == index" @cascaderOptionClick="cascaderOptionClick"></cascaderOption>
             </div>
         </div>
 
@@ -111,6 +144,10 @@ export default {
         selectNameChuan: {
             type: String
         },
+        userName: {
+            type: Boolean,
+            default: false
+        }
     },
     data() {
         return {
@@ -197,6 +234,9 @@ export default {
             for(let i in this.options) {
                 if(this.options[i].id == this.optionsOId || this.options[i].auditorId == this.optionsOId) {
                      this.selectName = this.options[i].name || this.options[i].auditorName
+                     if(this.options[i].type) {
+                        this.selectNameType = this.options[i].type
+                     }
                 }
             }
         }
@@ -213,6 +253,9 @@ export default {
                 for(var i in arr) {
                     if(arr[i].value == id) {
                         this.selectName = arr[i].label
+                        if(arr[i].type) {
+                            this.selectNameType = arr[i].type
+                        }
                         return
                     }
                     if(arr[i].children) {
@@ -255,6 +298,9 @@ export default {
             console.log('我被你点击了')
             if(!item.children) {
                 this.selectName = item.label
+                if(item.type) {
+                    this.selectNameType = item.type
+                }
                 let obj = {
                     id: item.value,
                     distinction: this.distinction
@@ -264,6 +310,9 @@ export default {
             }
             if(this.radios) {
                 this.selectName = item.label
+                if(item.type) {
+                    this.selectNameType = item.type
+                }
                 let obj = {
                     id: item.value,
                     distinction: this.distinction,
@@ -358,6 +407,9 @@ export default {
         text-overflow: ellipsis;
         font-size: 12px;
     }
+    .selecttex span {
+        padding: 0 !important;
+    }
     .iostu {
         position: absolute;
         top: 50%;
@@ -415,6 +467,9 @@ export default {
         color: #409eff !important;
         font-weight: 700;
     }
+    .idxspan span{
+        padding: 0 !important;
+    }
     .transitionBoxUl span {
         flex: 1;
         width: 110px;

+ 34 - 5
fhKeeper/formulahousekeeper/timesheet/src/components/cascaderOption.vue

@@ -3,15 +3,37 @@
     <div class="child">
         <ul class="transitionBoxUl">
             <li :class="transitionBoxLiIdx == index ? 'liHover' : ''" v-for="(item, index) in options" :key="index" @mouseover="liMouseOver(index, item)" @click.stop="liClick(item)"> 
-                <span :class="item.children ? 'idxspan' : ''" v-if="!radios">
+                <span :class="item.children ? 'idxspan idxSpanspan' : 'idxSpanspan'" v-if="!radios">
                     <!-- {{item.label}} -->
-                    <ww-open-data type='departmentName' :openid='item.label'></ww-open-data>
+                    <span v-if="userName">
+                        <span v-if="item.type == 'dep'">
+                            <ww-open-data type='departmentName' :openid='item.label'></ww-open-data>
+                        </span>
+                        <span v-if="item.type == 'user'">
+                            <ww-open-data type='userName' :openid='item.label'></ww-open-data>
+                        </span>
+                    </span>
+                    <span v-if="!userName">
+                        <ww-open-data type='departmentName' :openid='item.label'></ww-open-data>
+                    </span>
+                    <!-- <ww-open-data type='departmentName' :openid='item.label'></ww-open-data> -->
                 </span>
                 <span v-if="radios" style="margin-left: -15px">
                     <el-radio v-model="departmentId" :label="item.value">
-                        <span class="idxspan" style="margin-left: -10px"> 
+                        <span class="idxspan idxSpanspan" style="margin-left: -10px"> 
                             <!-- {{item.label}}  -->
-                            <ww-open-data type='departmentName' :openid='item.label'></ww-open-data>
+                            <span v-if="userName">
+                                <span v-if="item.type == 'dep'">
+                                    <ww-open-data type='departmentName' :openid='item.label'></ww-open-data>
+                                </span>
+                                <span v-if="item.type == 'user'">
+                                    <ww-open-data type='userName' :openid='item.label'></ww-open-data>
+                                </span>
+                            </span>
+                            <span v-if="!userName">
+                                <ww-open-data type='departmentName' :openid='item.label'></ww-open-data>
+                            </span>
+                            <!-- <ww-open-data type='departmentName' :openid='item.label'></ww-open-data> -->
                         </span>
                     </el-radio>
                 </span>
@@ -22,7 +44,7 @@
 
     <div v-for="(item, index) in options" :key="index">
         <div v-if="item.children">
-            <cascaderOption :subject="item.children" :radios="radiosFlg" :subjectId="departmentId" v-show="transitionBoxLiIdx == index" @cascaderOptionClick="cascaderOptionClick"></cascaderOption>
+            <cascaderOption :subject="item.children" :userName="userName" :radios="radiosFlg" :subjectId="departmentId" v-show="transitionBoxLiIdx == index" @cascaderOptionClick="cascaderOptionClick"></cascaderOption>
         </div>
     </div>
   </div>
@@ -48,6 +70,10 @@ export default {
         type: Boolean,
         default: false
     },
+    userName: {
+        type: Boolean,
+        default: false
+    }
   },
   watch: {
     subject: {
@@ -131,6 +157,9 @@ export default {
         margin: 5px 0;
         // box-shadow: 0 2px 12px #dfdfdf;
     }
+    .idxSpanspan span{
+        padding: 0 !important;
+    }
     .child {
         width: 100%;
         max-height: 270px;

+ 19 - 1
fhKeeper/formulahousekeeper/timesheet/src/i18n/en.json

@@ -1461,5 +1461,23 @@
   "xiu-gai-xiang-mu-dang-qian-jie-duan": "Modifying the current phase",
   "zheng-shi-xiang-mu": "Formal Project",
   "fei-xiang-mu": "Non item",
-  "zheng-shi-xiang-mu-zhi-dui-can-yu-ren-kai-fang-fei-xiang-mu-dui-suo-you-cheng-yuan-kai-fang": "Formal projects are open to participants only, non-projects are open to all members"
+  "zheng-shi-xiang-mu-zhi-dui-can-yu-ren-kai-fang-fei-xiang-mu-dui-suo-you-cheng-yuan-kai-fang": "Formal projects are open to participants only, non-projects are open to all members",
+  "bu-men-ren-shu": "Number of Departments",
+  "chu-cha-ren-shu": "Number of business trips",
+  "di": "The ",
+  "di-er-ji-du": "Second Quarter",
+  "di-san-ji-du": "Third Quarter",
+  "di-si-ji-du": "Fourth Quarter",
+  "di-yi-ji-du": "First quarter",
+  "fei-xiang-mu-gong-shi": "Non-project hours",
+  "fei-xiang-mu-gong-shi-zhan-bi": "Proportion of non-project working hours",
+  "fen-zu-he-ji-gong-shi": "Total working hours by group",
+  "ge-fen-zu-jie-duan-gong-shi-biao": " group stage timesheet",
+  "ge-fen-zu-yu-jie-duan-gong-shi-biao": "Timesheets for groups and stages",
+  "shu-liang": "number ",
+  "xiang-mu-ge-fen-zu-yu-jie-duan-gong-shi-biao": "Project with each group and stage timesheet",
+  "xuan-ze-ji-du": "Choose a quarter",
+  "xuan-ze-nian": "Choose the Year",
+  "xuan-ze-nian-fen": "Choose the Month",
+  "zheng-shi-xiang-mu-gong-shi": "Official project hours"
 }

+ 19 - 1
fhKeeper/formulahousekeeper/timesheet/src/i18n/zh.json

@@ -1461,5 +1461,23 @@
   "xiu-gai-xiang-mu-dang-qian-jie-duan": "修改项目当前阶段",
   "zheng-shi-xiang-mu": "正式项目",
   "fei-xiang-mu": "非项目",
-  "zheng-shi-xiang-mu-zhi-dui-can-yu-ren-kai-fang-fei-xiang-mu-dui-suo-you-cheng-yuan-kai-fang": "正式项目只对参与人开放,非项目对所有成员开放"
+  "zheng-shi-xiang-mu-zhi-dui-can-yu-ren-kai-fang-fei-xiang-mu-dui-suo-you-cheng-yuan-kai-fang": "正式项目只对参与人开放,非项目对所有成员开放",
+  "xiang-mu-ge-fen-zu-yu-jie-duan-gong-shi-biao": "项目各分组与阶段工时表",
+  "zheng-shi-xiang-mu-gong-shi": "正式项目工时",
+  "fei-xiang-mu-gong-shi": "非项目工时",
+  "fei-xiang-mu-gong-shi-zhan-bi": "非项目工时占比",
+  "bu-men-ren-shu": "部门人数",
+  "shu-liang": "数量",
+  "chu-cha-ren-shu": "出差人数",
+  "fen-zu-he-ji-gong-shi": "分组合计工时",
+  "xuan-ze-nian-fen": "选择年份",
+  "xuan-ze-nian": "选择年",
+  "xuan-ze-ji-du": "选择季度",
+  "di-yi-ji-du": "第一季度",
+  "di-er-ji-du": "第二季度",
+  "di-san-ji-du": "第三季度",
+  "di-si-ji-du": "第四季度",
+  "ge-fen-zu-yu-jie-duan-gong-shi-biao": "各分组与阶段工时表",
+  "ge-fen-zu-jie-duan-gong-shi-biao": "各分组阶段工时表",
+  "di": "第"
 }

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

@@ -48,7 +48,7 @@
                             <div v-if="isCorpWX">
                                 <div>扫码添加企业微信客服</div>
                                 <img
-                                style="width: 120px; height: 120px"
+                                style="width: 153px; height: 153px"
                                 src="../assets/image/qwcode.png" />
                             </div>
                             <div>
@@ -516,6 +516,14 @@
                             //2- 任务有新进展
                             this.$router.push("/projectInside/"+date);
                             this.drawer = false;
+                        } else if (type == 3) {
+                            //3- 费用报销
+                            this.$router.push("/expense");
+                            this.drawer = false;
+                        } else if (type == 4) {
+                            //4- 任务有新进展
+                            this.$router.push("/leave");
+                            this.drawer = false;
                         }
                         
                     } else {

+ 28 - 25
fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue

@@ -36,7 +36,7 @@
                   <el-menu-item index="1-12" v-if="permissions.reportPersonnel || permissions.reportResponsible" @click="ssl(11)"><p>{{ $t('statisticsofpersonnelhours') }}</p></el-menu-item>
                   <el-menu-item index="1-15" v-if="permissions.reportMonthlyPersonnel || permissions.reportResponsiblePersonnel" @click="ssl(14)"><p>{{ $t('ren-yuan-yue-du-gong-shi-biao') }}</p></el-menu-item>
                   <el-menu-item index="1-16" v-if="permissions.reportAllDepartmentParticipation || permissions.reportResponsibleDepartmentParticipation" @click="ssl(15)"><p>{{ $t('bumenchanyuqingkuang') }}</p></el-menu-item>
-                  <el-menu-item index="1-17" v-if="permissions.reportPhaseHours || permissions.reportStageWorkingTime" @click="ssl(16)"><p>项目各分组与阶段工时表</p></el-menu-item>
+                  <el-menu-item index="1-17" v-if="permissions.reportPhaseHours || permissions.reportStageWorkingTime" @click="ssl(16)"><p>{{ $t('xiang-mu-ge-fen-zu-yu-jie-duan-gong-shi-biao') }}</p></el-menu-item>
                   <!-- <el-menu-item index="1-12"><p @click="ssl(11)">人员工时统计表</p></el-menu-item> -->
                 </el-submenu>
               </el-menu>
@@ -512,12 +512,14 @@
                   </template>
               </el-table-column>
               <el-table-column prop="jobNumber" :label="$t('Worknumber')" width="150"></el-table-column>
-              <el-table-column prop="unPublic" :label="$t('ordinaryprojecthours')" min-width="160" align="right">
+              <!-- <el-table-column prop="unPublic" :label="$t('ordinaryprojecthours')" min-width="160" align="right"> -->
+              <el-table-column prop="unPublic" :label="$t('zheng-shi-xiang-mu-gong-shi')" min-width="160" align="right">
                 <template slot-scope="scope">
                   <span>{{scope.row.unPublic == null? 0 + 'h' : scope.row.unPublic.toFixed(1) + 'h'}}</span>
                 </template>
               </el-table-column>
-              <el-table-column prop="isPublic" :label="$t('publicprojecthours')" min-width="160" align="right">
+              <!-- <el-table-column prop="isPublic" :label="$t('publicprojecthours')" min-width="160" align="right"> -->
+              <el-table-column prop="isPublic" :label="$t('fei-xiang-mu-gong-shi')" min-width="160" align="right">
                 <template slot-scope="scope">
                   <span>{{scope.row.isPublic == null? 0 + 'h' : scope.row.isPublic.toFixed(1) + 'h'}}</span>
                 </template>
@@ -529,7 +531,8 @@
                   <span>{{scope.row.workingTime == null? 0 + 'h' : scope.row.workingTime.toFixed(1) + 'h'}}</span>
                 </template>
               </el-table-column>
-              <el-table-column prop="proportion" :label="$t('publicprojecthourszan')" min-width="130" align="right">
+              <el-table-column prop="proportion" :label="$t('fei-xiang-mu-gong-shi-zhan-bi')" min-width="160" align="right">
+              <!-- <el-table-column prop="proportion" :label="$t('publicprojecthourszan')" min-width="160" align="right"> -->
                 
               </el-table-column>
             </el-table>
@@ -773,20 +776,20 @@
                     </div>
                   </template>
                 </el-table-column>
-                <el-table-column align="center" prop="deptHeadCount" :label="'部门人数'" min-width="150"></el-table-column>
+                <el-table-column align="center" prop="deptHeadCount" :label="$t('bu-men-ren-shu')" min-width="150"></el-table-column>
                 <el-table-column align="center" prop="projectCount" :label="$t('can-yu-de-xiang-mu-de-shu-liang')" min-width="150"></el-table-column>
-                <el-table-column align="center" prop="centerCount" :label="this.user.timeType.customDegreeName + '数量'" min-width="150"></el-table-column>
+                <el-table-column align="center" prop="centerCount" :label="this.user.timeType.customDegreeName + $t('shu-liang')" min-width="150"></el-table-column>
                 <el-table-column align="center" prop="peopleCount" :label="$t('can-yu-ren-ci')" min-width="150"></el-table-column>
                 <el-table-column align="center" prop="tripCount" :label="$t('chu-cha-de-tian-shu')" min-width="150"></el-table-column>
-                <el-table-column align="center" prop="tripPeopleCount" :label="'出差人数'" min-width="150"></el-table-column>
+                <el-table-column align="center" prop="tripPeopleCount" :label="$t('chu-cha-ren-shu')" min-width="150"></el-table-column>
             </el-table>
 
             <!-- 项目各分组与阶段工时表 -->
             <el-table v-if="ins == 16"  key="16" border :data="groupingItemsArr" highlight-current-row v-loading="listLoading" :height="tableHeight" style="width: 100%;">
-                <el-table-column align="center" prop="projectCode" label="项目编号" min-width="150"></el-table-column>
-                <el-table-column align="center" prop="projectName" label="项目名称" min-width="150"></el-table-column>
-                <el-table-column align="center" prop="groupName" label="任务分组" min-width="150"></el-table-column>
-                <el-table-column align="center" prop="workingTime" label="分组合计工时" min-width="150"></el-table-column>
+                <el-table-column align="center" prop="projectCode" :label="$t('Itemno')" min-width="150"></el-table-column>
+                <el-table-column align="center" prop="projectName" :label="$t('headerTop.projectName')" min-width="150"></el-table-column>
+                <el-table-column align="center" prop="groupName" :label="$t('other.taskGroup')" min-width="150"></el-table-column>
+                <el-table-column align="center" prop="workingTime" :label="$t('fen-zu-he-ji-gong-shi')" min-width="150"></el-table-column>
                 <el-table-column align="center" :label="item" min-width="150" v-for="(item, index) in groupingItemsArrTitle" :key="index">
                   <template slot-scope="scope">
                     <div>
@@ -972,29 +975,29 @@
           </el-table>
         </el-dialog>
 
-        <el-dialog title="按季度导出" :visible.sync="byQuarterDialog" width="500px">
+        <el-dialog :title="$t('an-ji-du-dao-chu')" :visible.sync="byQuarterDialog" width="500px">
           <el-form>
-            <el-form-item label="选择年份">
+            <el-form-item :label="$t('xuan-ze-nian-fen')">
               <el-date-picker
                 v-model="quarterParameter.year"
                 type="year"
                 value-format="yyyy"
                 :clearable="false"
                 style="width:200px"
-                placeholder="选择年">
+                :placeholder="$t('xuan-ze-nian')">
               </el-date-picker>
             </el-form-item>
-            <el-form-item label="选择季度">
+            <el-form-item :label="$t('xuan-ze-ji-du')">
               <el-select v-model="quarterParameter.quarter" style="width:200px">
-                <el-option label="第一季度" :value="1"></el-option>
-                <el-option label="第二季度" :value="2"></el-option>
-                <el-option label="第三季度" :value="3"></el-option>
-                <el-option label="第四季度" :value="4"></el-option>
+                <el-option :label="$t('di-yi-ji-du')" :value="1"></el-option>
+                <el-option :label="$t('di-er-ji-du')" :value="2"></el-option>
+                <el-option :label="$t('di-san-ji-du')" :value="3"></el-option>
+                <el-option :label="$t('di-si-ji-du')" :value="4"></el-option>
               </el-select>
             </el-form-item>
           </el-form>
           <div slot="footer" class="dialog-footer" style="text-align: center;">
-            <el-button @click.native="quarterExport" :loading="exportLoading" type="primary">导出</el-button>
+            <el-button @click.native="quarterExport" :loading="exportLoading" type="primary">{{ $t('export.export') }}</el-button>
           </div>
         </el-dialog>
   </section>
@@ -1063,13 +1066,13 @@ export default {
       this.$t('pojectbalancesheetincomestatement'),this.$t('customerprojectprofitstatement'),this.$t('projectphasetimesheet'),
       this.$t('statisticsofovertimework'),this.$t('timecostearlywarningtable'),this.$t('personneltimeallocationtable'),
       this.$t('statisticsofstafffillingintimerate'),this.$t('dailyreporttobereviewedstatistics'),this.$t('statisticsofpersonnelhours'),this.$t('taskgrouptimesheet'),this.$t('projectcostbaselinetable'),
-      this.$t('ren-yuan-yue-du-gong-shi-biao'), this.$t('bumenchanyuqingkuang'), '各分组与阶段工时表'],
+      this.$t('ren-yuan-yue-du-gong-shi-biao'), this.$t('bumenchanyuqingkuang'), this.$t('ge-fen-zu-yu-jie-duan-gong-shi-biao')],
 
       shuzArr: [this.$t('projectreport'),this.$t('projectTaskReport'),this.$t('projectcoststatement'),
       this.$t('projectbalancesheet'),this.$t('customerprojectincomestatement'),this.$t('projectphasetimesheet'),
       this.$t('statisticsofovertimework'),this.$t('timecostearlywarningtable'),this.$t('personneltimeallocationtable'),
       this.$t('employeereporttimelinessrate'),this.$t('dailyreporttobereviewedstatistics'),this.$t('statisticsofpersonnelhours'),this.$t('taskgrouptimesheet'),this.$t('projectcostbaselinetable'),
-      this.$t('ren-yuan-yue-du-gong-shi-biao'), this.$t('bumenchanyuqingkuang'), '各分组与阶段工时表'],
+      this.$t('ren-yuan-yue-du-gong-shi-biao'), this.$t('bumenchanyuqingkuang'), this.$t('ge-fen-zu-yu-jie-duan-gong-shi-biao')],
 
       ins: 10000,
       user: JSON.parse(sessionStorage.user),
@@ -1262,7 +1265,7 @@ export default {
     getUserList() {
       console.log(this.shuzArr[this.ins])
       this.http.post('/user/getUserListByRole', {
-        tableName: this.shuzArr[this.ins] || '加班情况统计表'
+        tableName: this.shuzArr[this.ins] || this.$t('statisticsofovertimework')
       },
       res => {
           if (res.code == "ok") {
@@ -1572,7 +1575,7 @@ export default {
           sl.month = this.monthPersonnel + '-01'
           sl.departmentId = this.departmentIdArray.length > 0 ? this.departmentIdArray[this.departmentIdArray.length - 1] : ''
         } else if(this.ins == 16) {
-          fName = '各分组阶段工时表' + '.xls'
+          fName = this.$t('ge-fen-zu-jie-duan-gong-shi-biao') + '.xls'
           url += "/exportProjectGroupAndCategoryWorkTime"
           sl.startDate = this.rangeDatas[0]
           sl.endDate = this.rangeDatas[1]
@@ -1610,7 +1613,7 @@ export default {
             res => {
                 if (res.code == "ok") {
                     var filePath = res.data;
-                    var fName = this.$t('personnelfillingtimelyratestatistics') + '(' + this.quarterParameter.year + '第' + this.quarterParameter.quarter  + '季度).xls'
+                    var fName = this.$t('personnelfillingtimelyratestatistics') + '(' + this.quarterParameter.year + this.$t('di') + this.quarterParameter.quarter  + '季度).xls'
                     const a = document.createElement('a'); // 创建a标签
                     a.setAttribute('download', fName);// download属性
                     a.setAttribute('href', filePath);// href链接

+ 230 - 40
fhKeeper/formulahousekeeper/timesheet/src/views/leave/list.vue

@@ -20,18 +20,28 @@
             <i class="iconfont firerock-icontianbao"></i>
             <span slot="title">{{ $t('staffleavetofillin') }}</span>
           </el-menu-item>
-          <el-submenu index="2" v-if="permissions.leaveAll">
+          <!-- <el-submenu index="2" v-if="permissions.leaveAll || permissions.leaveAudit">
             <template slot="title">
               <i class="iconfont firerock-iconbaoxiaodan"></i>
               <span>{{ $t('singlelistofleave') }}</span>
             </template>
             <el-menu-item index="2-1" ><p @click="bills(false, 2)" v-if="permissions.leaveAll">{{ $t('all') }}</p></el-menu-item>
             <el-menu-item index="2-2" ><p @click="bills(true, 1)" v-if="permissions.leaveAudit">{{ $t('state.WaitingAudit') }}</p></el-menu-item>
-          </el-submenu>
-            <el-menu-item index="3" @select="bills" @click="bills(false, 2)" v-if="!permissions.leaveAll">
+          </el-submenu> -->
+
+          <el-menu-item index="2" @select="bills" @click="auditList()" v-if="permissions.leaveAudit">
               <i class="iconfont firerock-iconbaoxiaodan"></i>
-              <span slot="title">{{ $t('myleaveform') }}</span>
+              <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('singlelistofleave') }}</span>
             </el-menu-item>
+            <!-- <el-menu-item index="3" @select="bills" @click="bills(false, 2)" v-if="!permissions.leaveAll">
+              <i class="iconfont firerock-iconbaoxiaodan"></i>
+              <span slot="title">{{ $t('myleaveform') }}</span>
+            </el-menu-item> -->
+            
             <el-menu-item index="4" v-if="permissions.leaveStatistical">
               <template slot="title">
                 <i class="iconfont firerock-icontianbao"></i>
@@ -153,8 +163,22 @@
                 <el-form-item :label="$t('bei-zhu')" style="width: 100%">
                     <el-input type="textarea" v-model="addForm.remark" :rows="5" style="width: 550px" 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="margin-left: 20%"><el-button type="primary" @click="submits('addFormRules')" size="mini" :disabled="txselnum == 0 && addForm.leaveType == 6 && addForm.ownerId != '' ? true : false">{{ $t('btn.submit') }}</el-button></p>
             </div>
@@ -202,7 +226,7 @@
                 <el-date-picker v-model="createDate" type="daterange" :range-separator="$t('other.to')" :start-placeholder="$t('time.startDate')" :end-placeholder="$t('time.endDate')" @change="chufas()" value-format="yyyy-MM-dd" :placeholder="$t('optiondate')" size="small" clearable style="width:250px"></el-date-picker>
             </div>
             <div>
-              <el-button type="primary" size="small" style="margin-left:20px" @click="exportLeave()">{{ $t('dao-chu-qing-jia-dan') }}</el-button>
+              <el-button type="primary" v-if="!isAuditList" size="small" style="margin-left:20px" @click="exportLeave()">{{ $t('dao-chu-qing-jia-dan') }}</el-button>
             </div>
           </div>
             <el-table v-loading="loading" :data="tableData" style="width: 100%" height="94%">
@@ -239,13 +263,18 @@
                     <div>{{scope.row.timeHours}} {{ $t('time.hour') }}</div>
                   </template>
                 </el-table-column>
-                <el-table-column prop="status" :label="$t('state.states')" min-width="100">
+                <el-table-column prop="status" :label="$t('state.states')" min-width="180">
                   <template slot-scope="scope">
                     <div v-if="scope.row.status == 0 || scope.row.status == 1 || scope.row.status == 2 || scope.row.status == 3 || scope.row.status == 4">
                       <div v-if="scope.row.status == 0" >{{ $t('state.approved') }}</div>
-                      <div v-if="scope.row.status == 1" style="color: orange">{{ $t('state.WaitingAudit') }}</div>
-                      <div v-if="scope.row.status == 2" style="color: red">{{ $t('btn.rejected') }}</div>
-                      <div v-if="scope.row.status == 3" style="color: #666666">{{ $t('btn.undo') }}</div>
+                      <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>
+                      <div v-if="scope.row.status == 2" style="color: red">{{ $t('btn.rejected') }}<el-link style="margin-left:5px;" @click="showDenyReason(scope.row.id)">查看原因</el-link></div>
+                      <div v-if="scope.row.status == 3" style="color: #666666">已撤回</div>
                     </div>
                     <div v-else>
                       <span>{{ $t('norequestforleaveatpresent') }}</span>
@@ -271,26 +300,14 @@
                 <el-table-column :label="$t('operation')" min-width="180" fixed="right" v-if="!isAuditList && !isSyncData">
                     <template slot-scope="scope">
                       <div v-if="(scope.row.status != 0 && scope.row.ownerId == user.id) || permissions.leaveAll">
-                        <el-button icon="el-icon-delete" circle size="mini"  @click.stop.native="deletes(scope.row)" ></el-button>
-                        <el-button icon="el-icon-edit" circle size="mini" @click.stop.native="editor(scope.row)"></el-button>
+                        <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>
-                      <!-- <div>
-                        <el-button icon="el-icon-delete" circle size="mini"  @click.stop.native="deletes(scope.row)"></el-button>
-                        <el-button icon="el-icon-edit" circle size="mini" @click.stop.native="editor(scope.row)"></el-button>
-                      </div> -->
                     </template>
                 </el-table-column>
             </el-table>
             <div class="poss">
-                <!-- <el-pagination
-                  @size-change="handleSizeChange"
-                  @current-change="handleCurrentChange"
-                  :current-page="currentPage4"
-                  :page-sizes="[20, 50, 100, 200]"
-                  :page-size="20"
-                  layout="total, sizes, prev, pager, next"
-                  :total="total">
-                </el-pagination> -->
                 <el-pagination
                   @size-change="handleSizeChange"
                   @current-change="handleCurrentChange"
@@ -413,8 +430,20 @@
                     <icon class="iconfont firerock-iconright"></icon>
                     <span v-for="(item, index) in dataArray" :key="item.seq" >
                         
-                        <el-button type="primary" v-if="item.auditorType == 1" @click="editNodeDialog(index, item)">{{item.auditDeptName}}</el-button>
-                        <el-button type="primary" v-if="item.auditorType == 2" @click="editNodeDialog(index, item)">{{item.userName}}</el-button>
+                        <el-button type="primary" v-if="item.auditorType == 1 && user.userNameNeedTranslate == 1" @click="editNodeDialog(index, item)">
+                          <!-- {{item.auditDeptName}} -->
+                          <ww-open-data type='departmentName' :openid='item.auditDeptName'></ww-open-data>
+                        </el-button>
+                        <el-button type="primary" v-if="item.auditorType == 2 && user.userNameNeedTranslate == 1" @click="editNodeDialog(index, item)">
+                          <!-- {{item.userName}} -->
+                            <ww-open-data type='userName' :openid='item.userName'></ww-open-data>
+                        </el-button>
+                        <el-button type="primary" v-if="item.auditorType == 1 && user.userNameNeedTranslate != 1" @click="editNodeDialog(index, item)">
+                          {{item.auditDeptName}}
+                        </el-button>
+                        <el-button type="primary" v-if="item.auditorType == 2 && user.userNameNeedTranslate != 1" @click="editNodeDialog(index, item)">
+                          {{item.userName}}
+                        </el-button>
                         <template v-if="item.auditorType == 1 || item.auditorType == 2">
                         <icon class="iconfont firerock-iconright"></icon>
                         <icon class="iconfont firerock-iconInsertLine addNode" @click="showNodeDialog(index+1)"></icon>
@@ -627,12 +656,13 @@
         <!-- 请假人 -->
         <el-form-item :label="$t('leavepeople')" prop="ownerId"  style="width: 300px;display: inline-block;">
             <!--普通员工只能自己填报自己的 -->
-            <!-- <el-select v-if="user.userNameNeedTranslate != 1" v-model="addForm.ownerId" @change="selts()" :placeholder="$t('pleaseselectthepersonaskingforleave')" style="width: 240px" :disabled="true" filterable="true">
+            <el-select v-if="user.userNameNeedTranslate != 1" v-model="addForm.ownerId" @change="selts()" :placeholder="$t('pleaseselectthepersonaskingforleave')" style="width: 240px" :disabled="true" filterable="true">
                 <span v-for="(item, index) in users" :key="index">
                 <el-option :label="item.name" :value="item.id"></el-option>
                 </span>
-            </el-select> -->
+            </el-select>
             <selectCat v-if="user.userNameNeedTranslate == 1" :size="'mini'" :subject="users" :subjectId="addForm.ownerId" :disabled="true" :distinction="'4'" :filterable="false" @selectCal="selectCal"></selectCat>
+
         </el-form-item>
         <!-- 电话 -->
         <el-form-item :label="$t('phone')" prop="tel" style="width: 300px;display: inline-block;">
@@ -678,7 +708,39 @@
       <el-button type="primary" @click="determine()">{{ $t('btn.determine') }}</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>
+    <!-- <el-dialog title="审批流程" v-if="denyReasonVisible" :visible.sync="denyReasonVisible" :close-on-click-modal="false" customClass="customWidth" width="500px">
+        <div>
+          <el-steps direction="vertical" >
+            <el-step v-for="item in auditLogList" :title="item.auditorName" description="这是一段很长很长很长的描述性文字"></el-step>
+          </el-steps>
+          
+        </div>
+        <div slot="footer" class="dialog-footer">
+            <el-button  @click="denyReasonVisible = false" >{{ $t('btn.cancel') }}</el-button>
+        </div>
+    </el-dialog> -->
   </section>
 </template>
 
@@ -725,6 +787,8 @@ export default {
         }
     };
     return {
+      denyDialogV: false,
+      denyInfo: {},
       addFormRules: {
         ownerId: [{ required: true, message: this.$t('pleaseselectthepersonaskingforleave'), trigger: "blur" }],
         tel: [{required: true, validator: checkTel, trigger: 'blur'}],
@@ -856,7 +920,11 @@ export default {
       hubs: 0,
       vueCasaderItem: [], // 仿数据
       vueIAlDataSItems: undefined, // 仿数据
-      exporLoading: false
+      exporLoading: false,
+      addNodeObj: {},
+      curWorkflowList:{},
+      denyReasonVisible : false,
+      auditLogList:[],
     };
   },
   computed: {},
@@ -884,11 +952,51 @@ export default {
       this.getUsers() // 获取人员信息
     this.getDepartment();
     this.getAl();
-    this.getApproverList()
+    this.getApproverList();
+    this.getAuditWorkflow();
     }
   },
   filters: {},
   methods: {
+    showDenyReason(sheetId) {
+      this.denyReasonVisible = true;
+      this.auditLogList = [];
+      this.http.post('/leave-audit-log/getBySheetId',{sheetId: sheetId},
+        res => {
+          if(res.code == 'ok'){
+            this.auditLogList = res.data;
+          }else{
+            this.$message({
+              message: res.msg,
+              type: 'error'
+            })
+          }
+        },err => {
+          this.$message({
+            message: err,
+            type: 'error'
+          })
+        })
+    },
+    //获取添加请假单时的审批流
+    getAuditWorkflow() {
+      this.http.post('/audit-workflow-setting/get',{deptId: this.user.departmentId, type: 1},
+        res => {
+          if(res.code == 'ok'){
+            this.curWorkflowList = res.data;
+          }else{
+            this.$message({
+              message: res.msg,
+              type: 'error'
+            })
+          }
+        },err => {
+          this.$message({
+            message: err,
+            type: 'error'
+          })
+        })
+    },
     // 导出请假单
     exportLeave(){
       let param = {}
@@ -1271,9 +1379,10 @@ 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'}
                         ]
+                        console.log(this.soption, '选人的数据')
                         this.Nsdata = list1
                     } else {
                         this.$message({
@@ -1349,8 +1458,15 @@ export default {
               this.dialogVisible = false;
               if (this.curDeptId == null) return;
               // if(this.user.userNameNeedTranslate != '1') {
-              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 = 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
+              }
               console.log(this.vueCasaderItem)
               console.log("node",node);
               
@@ -1415,7 +1531,7 @@ export default {
         },
         res => {
             if (res.code == "ok") {
-                this.bills(true);
+                this.auditList();
             } else {
                 this.$message({
                 message: res.msg,
@@ -1431,12 +1547,17 @@ export default {
         });
     },
     deny(item) {
+      this.denyDialogV = true;
+      this.denyInfo = {id:item.id, reason:null};
+    },
+
+    submitDeny(id) {
       //审核驳回
-      this.http.post('/leave-sheet/deny', {id:item.id
-        },
+      this.http.post('/leave-sheet/deny', this.denyInfo,
         res => {
             if (res.code == "ok") {
-                this.bills(true);
+                this.auditList();
+                this.denyDialogV = false;
             } else {
                 this.$message({
                 message: res.msg,
@@ -1493,7 +1614,8 @@ export default {
       // console.log("keypath",key,keyPath)
       if (keyPath[0] == '1') {
         this.displayTable = false;
-        this.apk = false
+        this.apk = false;
+        this.getAuditWorkflow();
       } else if(keyPath[0] == '2' || keyPath[0] == '3') {
         this.displayTable = true;
         this.apk = false
@@ -1527,6 +1649,46 @@ export default {
         this.getDepartmentOptions()
       }
     },
+    auditList() {
+      this.falg = 1
+      this.code = 1
+      this.tableData = []
+      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,
+                    leaveType: this.type,
+                  };
+      this.list = [];
+      // this.total = 0;
+      this.http.post('/leave-sheet/auditList', param,
+        res => {
+            if (res.code == "ok") {
+              this.tableData = 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) {
         this.code = ''
@@ -1861,6 +2023,33 @@ export default {
       }
       // console.log(this.addForm)
     },
+    cancel(e) {
+      this.$confirm('确定要撤回该请假申请吗', this.$t('other.prompts'), {
+          //type: 'warning'
+      }).then(() => {
+          this.http.post('/leave-sheet/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'), {
           //type: 'warning'
@@ -1970,6 +2159,7 @@ export default {
         arr.push(obj.id)
         this.curDeptId = arr
         this.vueCasaderItem = obj.item
+        this.addNodeObj = obj.item
         console.log(obj)
       } else if(obj.distinction == 2) {
         let arr = []

+ 8 - 2
fhKeeper/formulahousekeeper/timesheet_h5/src/views/index/index.vue

@@ -30,7 +30,7 @@
             return {
                 isCorpWX:false,
                 isWX:false,
-                user: '',
+                user: null,
                 unreadNum:0,
                 images: [
                     // require('../../assets/img/index/banner_1.png'),
@@ -60,6 +60,7 @@
             let that = this;
             //企业微信是从后台授权后跳转过来的
             if (this.isCorpWX) {
+                //后台自动授权登录的用户
                 if(window.location.href.indexOf('userId') != '-1') {
                     let href = window.location.href;
                     var loginUserId = href.substring(href.indexOf("userId=")+"userId=".length);
@@ -68,7 +69,12 @@
                     }
                     that.getAccountInfo(loginUserId)
                 } else {
-                    this.$router.push("/login");
+                    //存在一部分用户,没有绑定企业微信,进来后跳到登录页面,登录页面输入账号密码进来后不带userId
+                    if (this.user) {
+                        that.getAccountInfo(that.user.id);
+                    } else {
+                        that.$router.push("/login");
+                    }
                 }
             } else {
                 //其他情况,刷新用户信息

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet_h5/src/views/view/index.vue

@@ -47,7 +47,7 @@
                             </span>
                             <span v-else-if="item1.isDeptAudit==1">
-                                <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName' :openid='item1.auditDeptName'></ww-open-data></span>
+                                <span v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='departmentName' :openid='item1.auditDeptName'></ww-open-data></span>
                                 <span v-else>{{item1.auditDeptName}}</span>
                                 审核
                             </span>