瀏覽代碼

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

ggooalice 2 年之前
父節點
當前提交
6f2dac6ac2
共有 31 個文件被更改,包括 13920 次插入1521 次删除
  1. 27 1
      fhKeeper/formulahousekeeper/inva_4_tivo/css/index.css
  2. 25 0
      fhKeeper/formulahousekeeper/inva_4_tivo/index.html
  3. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java
  4. 37 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java
  5. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Task.java
  6. 17 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/User.java
  7. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/UserVO.java
  8. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java
  9. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/WxCorpInfoService.java
  10. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ContractTypeServiceImpl.java
  11. 6 6
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  12. 15 8
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  13. 25 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  14. 35 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java
  15. 96 57
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java
  16. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/DockWithMLD.java
  17. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserMapper.xml
  18. 5 1
      fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/controller/OperationLogController.java
  19. 19 1
      fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/entity/TimeType.java
  20. 4 1
      fhKeeper/formulahousekeeper/ops-platform/src/main/resources/mapper/TimeTypeMapper.xml
  21. 4 4
      fhKeeper/formulahousekeeper/timesheet/config/index.js
  22. 10941 441
      fhKeeper/formulahousekeeper/timesheet/package-lock.json
  23. 1 0
      fhKeeper/formulahousekeeper/timesheet/package.json
  24. 6 0
      fhKeeper/formulahousekeeper/timesheet/src/App.vue
  25. 1333 28
      fhKeeper/formulahousekeeper/timesheet/src/components/taskComponent.vue
  26. 5 0
      fhKeeper/formulahousekeeper/timesheet/src/main.js
  27. 152 6
      fhKeeper/formulahousekeeper/timesheet/src/views/Home.vue
  28. 608 541
      fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue
  29. 93 40
      fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue
  30. 423 372
      fhKeeper/formulahousekeeper/timesheet/src/views/task/list.vue
  31. 27 0
      fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue

+ 27 - 1
fhKeeper/formulahousekeeper/inva_4_tivo/css/index.css

@@ -550,7 +550,7 @@
     background: url(../image/rke.jpg) no-repeat center;
     background-size: 120rem 62.5rem;
 }
-.kehu h2, .pricings h2 {
+.kehu h2, .pricings h2{
     font-size: 2.625rem;
     color: #333;
     padding: 6.25rem 5rem 4rem 5rem;
@@ -953,3 +953,29 @@ body {
     z-index: 1;
 }
 
+/* qanda */
+.QandA {
+    padding: 0 0 5rem 0;
+    background: url(../image/dingj.jpg) no-repeat center;
+    background-size: 120rem 58.8125rem;
+}
+.QandA h2 {
+    font-size: 2.625rem;
+    color: #333;
+    padding: 5.25rem 5rem 2rem 5rem;
+}
+.QandACon {
+    margin: auto;
+}
+.QandAConUl {
+    margin-top: 2rem;
+    padding: 0 88px;
+}
+.QandAConli {
+    font-size: 1.2rem;
+    margin-top: .8rem;
+}
+.QandAConli span {
+    font-weight: bold;
+}
+

File diff suppressed because it is too large
+ 25 - 0
fhKeeper/formulahousekeeper/inva_4_tivo/index.html


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

@@ -1163,8 +1163,8 @@ public class ProjectController {
     }
 
     @RequestMapping("/exportSubProjectTimeCost")
-    public HttpRespMsg exportSubProjectTimeCost(HttpServletRequest request,Integer projectId){
-        return projectService.exportSubProjectTimeCost(request,projectId);
+    public HttpRespMsg exportSubProjectTimeCost(HttpServletRequest request,String startDate,String endDate,Integer projectId){
+        return projectService.exportSubProjectTimeCost(request,startDate,endDate,projectId);
     }
 
 }

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

@@ -86,6 +86,8 @@ public class TaskController {
     private DepartmentService departmentService;
     @Resource
     private TaskGroupService taskGroupService;
+    @Resource
+    private TaskAddCtrlMapper taskAddCtrlMapper;
 
     @RequestMapping("/save")
     @Transactional
@@ -612,6 +614,7 @@ public class TaskController {
     public HttpRespMsg getTask(Integer id) {
         HttpRespMsg msg = new HttpRespMsg();
         String userId = request.getHeader("Token");
+        User user = userMapper.selectById(userId);
         Task t = taskService.getById(id);
         if (t == null) {
             //msg.setError("该任务已不存在");
@@ -637,6 +640,40 @@ public class TaskController {
         TaskGroup group = taskGroupService.getOne(new QueryWrapper<TaskGroup>().eq("id", t.getGroupId()));
         t.setProjectInchargerId(project.getInchargerId()==null?"":project.getInchargerId());
         t.setGroupInchargerId(group.getInchargerId()==null?"":group.getInchargerId());
+        //判断当前用户是否有权限创建任务: 有权限的包括管理全部项目,项目创建人,项目PM, 分组负责人,分组参与人
+        List<SysRichFunction> manageAllProjects = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "管理全部项目");
+        boolean canAddTask = false;
+        Integer companyId = user.getCompanyId();
+        TaskAddCtrl taskAddCtrl = taskAddCtrlMapper.selectById(companyId);
+        if (taskAddCtrl == null) {
+            //没有的话,默认生成一个
+            taskAddCtrl = new TaskAddCtrl();
+            taskAddCtrl.setCompanyId(companyId);
+            taskAddCtrl.setCtrlType(1);//0-普通项目参与人不可添加任务,1-项目参与人可添加,2-仅分组参与人可添加
+            taskAddCtrlMapper.insert(taskAddCtrl);
+        }
+        if (manageAllProjects.size() > 0 || userId.equals(project.getCreatorId()) || userId.equals(project.getInchargerId())) {
+            canAddTask = true;
+        }
+        if (!canAddTask) {
+            //进一步判断是否是分组的负责人,参与人
+            if (userId.equals(group.getInchargerId())) {
+                canAddTask = true;
+            }
+            if (!canAddTask) {
+                Integer ctrlType = taskAddCtrl.getCtrlType();
+                if (ctrlType == 1) {
+                    canAddTask = true;
+                } else if (ctrlType == 2) {
+                    //分组参与人可以创建任务
+                    int count = groupParticipatorMapper.selectCount(new QueryWrapper<GroupParticipator>().eq("user_id", userId).eq("group_id", group.getId()));
+                    if (count > 0) {
+                        canAddTask = true;
+                    }
+                }
+            }
+        }
+        t.setCanAddTask(canAddTask);
         msg.data = t;
         return msg;
     }

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/Task.java

@@ -218,6 +218,9 @@ public class Task extends Model<Task> {
     @TableField(exist = false)
     private String departmentName;
 
+    @TableField(exist = false)
+    private boolean canAddTask;
+
     @Override
     protected Serializable pkVal() {
         return this.id;

+ 17 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/User.java

@@ -21,7 +21,7 @@ import org.springframework.format.annotation.DateTimeFormat;
  * </p>
  *
  * @author Seyason
- * @since 2022-10-08
+ * @since 2023-01-05
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -43,7 +43,7 @@ public class User extends Model<User> {
     private String name;
 
     /**
-     * 手机号 登录账号
+     * 手机号 登录账号,全系统唯一
      */
     @TableField("phone")
     private String phone;
@@ -164,7 +164,7 @@ public class User extends Model<User> {
     private String dingdingUnionid;
 
     /**
-     * 企业微信用户id
+     * 企业微信用户openuserid
      */
     @TableField("corpwx_userid")
     private String corpwxUserid;
@@ -197,6 +197,9 @@ public class User extends Model<User> {
     @TableField("report_status")
     private Integer reportStatus;
 
+    /**
+     * 直属上级
+     */
     @TableField("superior_id")
     private String superiorId;
 
@@ -220,7 +223,11 @@ public class User extends Model<User> {
 
     @TableField(exist = false)
     private double totalHours;
-
+    /**
+     * 是否可以登录八爪鱼系统
+     */
+    @TableField("is_ops")
+    private Integer isOps;
     /**
      * 员工工号,公司内唯一
      */
@@ -251,6 +258,12 @@ public class User extends Model<User> {
     @TableField("corpwx_real_userid")
     private String corpwxRealUserid;
 
+    /**
+     * 0-否 1-是
+     */
+    @TableField("is_first_login")
+    private Integer isFirstLogin;
+
 
     @Override
     protected Serializable pkVal() {

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/UserVO.java

@@ -26,4 +26,6 @@ public class UserVO extends User {
 
     private boolean hasAuditDept;
 
+    private boolean isManager;
+
 }

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

@@ -220,5 +220,5 @@ public interface ProjectService extends IService<Project> {
 
     HttpRespMsg getSubProjectTimeCost(HttpServletRequest request, String startDate, String endDate, Integer projectId,Integer pageIndex,Integer pageSize);
 
-    HttpRespMsg exportSubProjectTimeCost(HttpServletRequest request, Integer projectId);
+    HttpRespMsg exportSubProjectTimeCost(HttpServletRequest request,String startDate,String endDate, Integer projectId);
 }

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

@@ -30,6 +30,9 @@ public interface WxCorpInfoService extends IService<WxCorpInfo> {
 
     public String testDownloadFile();
 
+    //获取企业管理员列表
+    List<User> getAdminList(Integer companyId)throws Exception;
+
     public HttpRespMsg getUserCheckInDayData(int companyId, String userId, LocalDateTime startDateTime, LocalDateTime endDateTime, boolean showLog);
 
     HttpRespMsg syncMembByCardTime(WxCorpInfo wxCorpInfo);

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

@@ -124,10 +124,10 @@ public class ContractTypeServiceImpl extends ServiceImpl<ContractTypeMapper, Con
         List<Contract> types = contractMapper.selectList(new QueryWrapper<Contract>().eq("type_id", deleteId));
         if (types.size() > 0){
             //该类型尚有合同在使用,无法删除!
-            httpRespMsg.msg = MessageUtils.message("Contract.typeDelError");
+            httpRespMsg.setError(MessageUtils.message("Contract.typeDelError"));
         }else {
             contractTypeMapper.deleteById(deleteId);
-            httpRespMsg.msg = MessageUtils.message("file.deleteSuc");
+            httpRespMsg.setError(MessageUtils.message("file.deleteSuc"));
         }
         return httpRespMsg;
     }

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

@@ -8979,7 +8979,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
     }
 
     @Override
-    public HttpRespMsg exportSubProjectTimeCost(HttpServletRequest request, Integer projectId) {
+    public HttpRespMsg exportSubProjectTimeCost(HttpServletRequest request,String startDate,String endDate, Integer projectId) {
         HttpRespMsg msg=new HttpRespMsg();
         User user = userMapper.selectById(request.getHeader("token"));
         Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
@@ -9000,15 +9000,15 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 inchagerIds.add(-1);
             }
         }
-        List<Map<String,Object>> list=projectMapper.getSubProjectTimeCost(companyId,null,null,projectId,null,null,inchagerIds);
+        List<Map<String,Object>> list=projectMapper.getSubProjectTimeCost(companyId,startDate,endDate,projectId,null,null,inchagerIds);
         List<List<String>> dataList=new ArrayList<>();
         List<String> titleList=new ArrayList<>();
         titleList.add("项目编号");
         titleList.add("项目名称");
         titleList.add("子项目编号");
         titleList.add("子项目名称");
-        titleList.add("子项目工时");
-        titleList.add("子项目成本");
+        titleList.add("子项目工时/h");
+        titleList.add("子项目成本/元");
         dataList.add(titleList);
         for (Map<String, Object> map : list) {
             List<String> item=new ArrayList<>();
@@ -9016,8 +9016,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             item.add(String.valueOf(map.get("projectName")==null?"":map.get("projectName")));
             item.add(String.valueOf(map.get("subProjectCode")==null?"":map.get("subProjectCode")));
             item.add(String.valueOf(map.get("subProjectName")==null?"":map.get("subProjectName")));
-            item.add(String.valueOf(map.get("cost")==null?"0":map.get("cost"))+"(元)");
-            item.add(String.valueOf(map.get("workingTime")==null?"0":map.get("workingTime"))+"(小时)");
+            item.add(String.valueOf(map.get("workingTime")==null?"0":map.get("workingTime")));
+            item.add(String.valueOf(map.get("cost")==null?"0":map.get("cost")));
             dataList.add(item);
         }
         String fileName = "子项目工时成本表"+System.currentTimeMillis();

+ 15 - 8
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -2222,14 +2222,21 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             user.put("name", u.getName());
             user.put("departmentId", u.getDepartmentId());
             Optional<Map<String, Object>> first = reportNameByDate.stream().filter(r -> r.get("id").equals(u.getId())).findFirst();
-            //获取角色请假情况
-            Optional<LeaveSheet> leaveSheet = leaveSheetList.stream().filter(ls -> ls.getOwnerId().equals(u.getId()) &&
-                    ((localDate.isAfter(ls.getStartDate()) || localDate.isEqual(ls.getStartDate())) && (localDate.isBefore(ls.getEndDate()) || localDate.isEqual(ls.getEndDate())))).findFirst();
-            if(leaveSheet.isPresent()){
-                user.put("leaveType",leaveSheet.get().getLeaveType());
-                if(leaveSheet.get().getTimeType()==0){
-                    user.put("leaveDays",leaveSheet.get().getTimeDays());
-                }else user.put("leaveTimes",leaveSheet.get().getTimeHours());
+            //获取角色请假情况 存在同条件下多条请假记录
+            List<LeaveSheet> leaveSheets = leaveSheetList.stream().filter(ls -> ls.getOwnerId().equals(u.getId()) &&
+                    ((localDate.isAfter(ls.getStartDate()) || localDate.isEqual(ls.getStartDate())) && (localDate.isBefore(ls.getEndDate()) || localDate.isEqual(ls.getEndDate())))).collect(Collectors.toList());
+            if(leaveSheets.size()>0){
+                Integer leaveType=leaveSheets.get(0).getLeaveType();
+                BigDecimal leaveDays=new BigDecimal(0);
+                BigDecimal leaveTimes=new BigDecimal(0);
+                for (LeaveSheet leaveSheet : leaveSheets) {
+                    leaveDays=leaveDays.add(new BigDecimal(leaveSheet.getTimeDays()));
+                    leaveTimes=leaveTimes.add(new BigDecimal(leaveSheet.getTimeHours()));
+                }
+                user.put("leaveType",leaveType);
+                if(leaveSheets.stream().anyMatch(ls->ls.getTimeType()==0)){
+                    user.put("leaveDays",leaveDays);
+                }else user.put("leaveTimes",leaveTimes);
             }
             if (first.isPresent()) {
                 user.put("state", first.get().get("state"));

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

@@ -167,7 +167,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
     public static long providerTokenExpireTime = 0L;
     //登录网页端
     @Override
-    public HttpRespMsg loginAdmin(String username, String password) {
+    public HttpRespMsg loginAdmin(String username, String password){
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         //根据电话号码获取账号信息
         List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("phone", username));
@@ -199,6 +199,13 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
                     }
                 }
             }
+            //获取所在企业管理员列表
+            List<User> adminList=new ArrayList<>();
+            try {
+                adminList = wxCorpInfoService.getAdminList(company.getId());
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
             //检测密码正确时
             UserVO userVO = new UserVO().setCompanyName(company.getCompanyName());
             userVO.setCompany(company);
@@ -227,10 +234,14 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
                 num = auditWorkflowTimeSettingMapper.selectCount(new QueryWrapper<AuditWorkflowTimeSetting>().in("audit_dept_id", deptIds));
             }
             userVO.setHasAuditDept(num>0);
+            boolean match = adminList.stream().anyMatch(al -> al.getCorpwxUserid().equals(userVO.getCorpwxUserid()));
+            userVO.setManager(match);
             //获取当前角色的权限菜单
             setUserRoleMenu(userVO);
-
             httpRespMsg.data = userVO;
+            //记录第一次登录
+            userList.get(0).setIsFirstLogin(0);
+            userMapper.updateById(userList.get(0));
         } else {
             httpRespMsg.setError(MessageUtils.message("user.pwdError"));
         }
@@ -2328,7 +2339,13 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         if (info != null) {
             user.setUserNameNeedTranslate(info.getSaasSyncContact());
         }
-
+        //获取所在企业管理员列表
+        List<User> adminList=new ArrayList<>();
+        try {
+            adminList = wxCorpInfoService.getAdminList(company.getId());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
 
         UserVO userVO = new UserVO().setCompanyName(company.getCompanyName());
         userVO.setCompany(company);
@@ -2348,9 +2365,14 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
             num = auditWorkflowTimeSettingMapper.selectCount(new QueryWrapper<AuditWorkflowTimeSetting>().in("audit_dept_id", deptIds));
         }
         userVO.setHasAuditDept(num>0);
+        boolean match = adminList.stream().anyMatch(al -> al.getCorpwxUserid().equals(userVO.getCorpwxUserid()));
+        userVO.setManager(match);
         //获取当前角色的权限菜单
         setUserRoleMenu(userVO);
         httpRespMsg.data = userVO;
+        //记录第一次登录
+        user.setIsFirstLogin(0);
+        userMapper.updateById(user);
         return httpRespMsg;
     }
 

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

@@ -70,6 +70,9 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
 
     public static final String GET_BATCH_SEARCH_USER_INFO = "https://qyapi.weixin.qq.com/cgi-bin/service/contact/batchsearch?provider_access_token=ACCESS_TOKEN";
 
+    //获取企业管理员列表
+    public static final String GET_ADMIN_LIST = "https://qyapi.weixin.qq.com/cgi-bin/service/get_admin_list?suite_access_token=SUITE_ACCESS_TOKEN";
+
     public static final int TEXT_CARD_MSG_BUSTRIP_WAITING_AUDIT = 0;//出差待审核
     public static final int TEXT_CARD_MSG_BUSTRIP_AGREE = 1;//出差审核通过
     public static final int TEXT_CARD_MSG_BUSTRIP_DENY = 2;//出差审核驳回
@@ -469,6 +472,38 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
         return WeiXinCorpController.SUITE_ACCESS_TOKEN;
     }
 
+    //获取企业管理员列表
+    @Override
+    public List<User> getAdminList(Integer companyId)throws Exception{
+        List<User> userList=new ArrayList<>();
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", companyId));
+        String url=GET_ADMIN_LIST.replaceAll("SUITE_ACCESS_TOKEN",getSuiteAccessToken());
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        JSONObject reqParam = new JSONObject();
+        reqParam.put("auth_corpid",  wxCorpInfo.getCorpid());
+        reqParam.put("agentid",  wxCorpInfo.getAgentid());
+        HttpEntity<String> requestEntity = new HttpEntity<String>(reqParam.toJSONString(), headers);
+        ResponseEntity<String> responseEntity = this.restTemplate.exchange(url,
+                HttpMethod.POST, requestEntity, String.class);
+        if (responseEntity.getStatusCode() == HttpStatus.OK) {
+            String resp = responseEntity.getBody();
+            JSONObject json = JSONObject.parseObject(resp);
+            if (json.getIntValue("errcode") == 0) {
+                JSONArray adminList = json.getJSONArray("admin");
+                for (int i = 0; i < adminList.size(); i++) {
+                    JSONObject object = adminList.getJSONObject(i);
+                    String userid = String.valueOf(object.get("userid"));
+                    User user = userMapper.selectOne(new QueryWrapper<User>().eq("corpwx_userid", userid));
+                    userList.add(user);
+                }
+            } else {
+                throw new Exception(json.toJSONString());
+            }
+        }
+        return userList;
+    }
+
     //获取企业AccessToken
     private String getCorpAccessToken(WxCorpInfo corpInfo) throws Exception {
         if (corpInfo.getExpireTime().isBefore(LocalDateTime.now())) {

+ 96 - 57
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -278,11 +278,11 @@ public class TimingTask {
     }
 
 
-    //每天2:11 同步钉钉用户前2天到未来30天时间段的打卡,请假,出差数据
+    //每天2:11 同步泛微用户前2天到未来30天时间段的打卡,请假,出差数据
     @Scheduled(cron = "0 11 2 ? * *")
     private void synFanWeiWorkData() {
-        if (isDev) return;
-        if(!isPrivateDeploy) return;
+        /*if (isDev) return;
+        if(!isPrivateDeploy) return;*/
         List<TimeType> timeTypeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("sync_fanwei", 1));
         List<Integer> compIds = timeTypeList.stream().map(TimeType::getCompanyId).collect(Collectors.toList());
         if(compIds.isEmpty()){
@@ -294,85 +294,113 @@ public class TimingTask {
             DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
             DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
             DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("HH:mm");
-            LocalDateTime yesterday = LocalDateTime.now().minusDays(2);
+            //需要修改************************************************  日期
+            LocalDateTime yesterday = LocalDateTime.now().minusDays(100);
             String startDate = dtf.format(yesterday);
-            String endDate = dtf.format(yesterday.plusDays(32));
+            String endDate = dtf.format(yesterday.plusDays(30));
             List<UserFvTime> oldUserFvTimeList = userFvTimeService.list(new QueryWrapper<UserFvTime>().eq("company_id", compId));
             List<LeaveSheet> oldLeaveSheetList = leaveSheetService.list(new QueryWrapper<LeaveSheet>().eq("company_id", compId));
             List<BusinessTrip> oldBusinessTripList = businessTripService.list(new QueryWrapper<BusinessTrip>().eq("company_id", compId));
-            jsonObject.put("startDate",startDate);
+            /*jsonObject.put("startDate",startDate);
             jsonObject.put("endDate",endDate);
+            jsonObject.put("workDate",startDate);*/
             String jsonString = jsonObject.toJSONString();
             List<UserFvTime> userFvTimeList=new ArrayList<>();
             List<LeaveSheet> leaveSheetList=new ArrayList<>();
             List<BusinessTrip> businessTripList=new ArrayList<>();
             TimeType allDay = timeTypeMapper.selectOne(new QueryWrapper<TimeType>().eq("company_id", compId));
+            List<User> allUserList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", compId));
             //获取休息设置
             TimeAutoExclude timeAutoExclude = timeAutoExcludeMapper.selectOne(new QueryWrapper<TimeAutoExclude>().eq("company_id", compId));
-            //Todo: 获取打卡数据
+            //Todo: 获取考勤打卡数据
             HttpRespMsg workDataMsg = dockWithMLD.getResult("http://10.1.10.51:20175/api/cube/restful/interface/getModeDataPageList/getWorkData", jsonString);
             List<Map<String,Object>> workDataList= (List<Map<String, Object>>) workDataMsg.data;
-            List<String> userIds = workDataList.stream().map(map -> String.valueOf(map.get("userId"))).collect(Collectors.toList());
+            //Todo: 获取外出打卡数据
+            HttpRespMsg outWorkDataMsg = dockWithMLD.getResult("http://10.1.10.51:20175/api/cube/restful/interface/getModeDataPageList/getOutRecord", jsonString);
+            List<Map<String,Object>> outWorkDataList= (List<Map<String, Object>>) outWorkDataMsg.data;
+            //Todo: 获取考勤补卡数据
+            HttpRespMsg replaceWorkDataMsg = dockWithMLD.getResult("http://10.1.10.51:20175/api/cube/restful/interface/getModeDataPageList/getReplaceRecord", jsonString);
+            List<Map<String,Object>> replaceWorkDataList= (List<Map<String, Object>>) replaceWorkDataMsg.data;
+            List<String> userIds = workDataList.stream().map(map -> String.valueOf(map.get("userId"))).distinct().collect(Collectors.toList());
             List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("job_number", userIds));
+            List<LocalDateTime> dateTimeList = getDays(yesterday, yesterday.plusDays(132));
             for (User user : userList) {
-                System.out.println("需要同步的用户列表-----"+userList);
-                LocalTime startTime=null;
-                LocalTime endTime=null;
-                LocalDate workDate=null;
-                for (Map<String, Object> map : workDataList) {
-                    if (map.get("userId").equals(user.getJobNumber())) {
-                        if(String.valueOf(map.get("signtype")).equals("签到")){
+                for (LocalDateTime localDateTime : dateTimeList) {
+                    LocalDate workDate=localDateTime.toLocalDate();
+                    //当天的考勤记录
+                    List<Map<String, Object>> list = workDataList.stream().filter(wl -> wl.get("userId").equals(user.getJobNumber())&&wl.get("workDate").equals(workDate.format(dtf))).collect(Collectors.toList());
+                    UserFvTime userFvTime=new UserFvTime();
+                    userFvTime.setWorkDate(workDate);
+                    LocalTime startTime=null;
+                    LocalTime endTime=null;
+                    for (Map<String, Object> map : list) {
+                        if(String.valueOf(map.get("signtype")).equals("签到")&&!map.get("signtime").equals("")){
                             startTime=LocalTime.parse(String.valueOf(map.get("signtime")), dtf2);
-                            workDate= LocalDate.parse(String.valueOf(map.get("workDate")), dtf);
                         }
-                        if(String.valueOf(map.get("signtype")).equals("签退")){
+                        if(String.valueOf(map.get("signtype")).equals("签退")&&!map.get("signtime").equals("")){
                             endTime=LocalTime.parse(String.valueOf(map.get("signtime")), dtf2);
-                            workDate=LocalDate.parse(String.valueOf(map.get("workDate")),dtf);
                         }
+                        //处理外出记录 有外出记录默认以默认规则作为考勤数据来源
+                        Optional<Map<String, Object>> outFirst = outWorkDataList.stream().filter(ol -> ol.get("ycbgkssj").equals(map.get("workDate")) && ol.get("rybh").equals(map.get("userId"))).findFirst();
+                        if(outFirst.isPresent()){
+                            if(startTime==null||LocalTime.parse(String.valueOf(outFirst.get().get("kssj")), dtf2).isBefore(startTime)){
+                                startTime=LocalTime.parse(String.valueOf(outFirst.get().get("kssj")), dtf2);
+                            }
+                            if(endTime==null||LocalTime.parse(String.valueOf(outFirst.get().get("jssj")), dtf2).isBefore(endTime)){
+                                endTime=LocalTime.parse(String.valueOf(outFirst.get().get("jssj")), dtf2);
+                            }
+                        }
+                        //处理补卡记录 有补卡记录以补卡记录作为考勤数据来源
+                        Optional<Map<String, Object>> replaceFirst = replaceWorkDataList.stream().filter(rl -> rl.get("kqrq").equals(map.get("workDate")) && rl.get("rybh").equals(map.get("userId"))).findFirst();
+                        if(replaceFirst.isPresent()){
+                            if(startTime==null||replaceFirst.get().get("bklx").equals("上班")){
+                                startTime=LocalTime.parse(String.valueOf(replaceFirst.get().get("bksj")), dtf2);
+                            }
+                            if(endTime==null||replaceFirst.get().get("bklx").equals("下班")){
+                                endTime=LocalTime.parse(String.valueOf(replaceFirst.get().get("bksj")), dtf2);
+                            }
+                        }
+                        }
+                    if(compIds.contains(user.getCompanyId())){
+                        if(startTime==null||endTime==null){
+                            continue;
+                        }
+                        Duration between = Duration.between(startTime, endTime);
+                        userFvTime.setStartTime(startTime.format(dtf2));
+                        userFvTime.setEndTime(endTime.format(dtf2));
+                        userFvTime.setCompanyId(user.getCompanyId());
+                        userFvTime.setUserId(user.getId());
+                        long workHours = between.toHours();
+                        long restHours;
+                        if(startTime.isBefore(LocalTime.parse(timeAutoExclude.getStartTime(),dtf2))
+                                &&endTime.isAfter(LocalTime.parse(timeAutoExclude.getEndTime(),dtf2))){
+                            Duration bt = Duration.between(LocalTime.parse(timeAutoExclude.getStartTime(),dtf2), LocalTime.parse(timeAutoExclude.getEndTime(),dtf2));
+                            restHours=bt.toHours();
+                        }else {
+                            restHours=0;
+                        }
+                        userFvTime.setWorkHours(BigDecimal.valueOf(workHours).subtract(BigDecimal.valueOf(restHours)).floatValue());
+                        Optional<UserFvTime> first = oldUserFvTimeList.stream().filter(ol -> ol.getWorkDate().isEqual(userFvTime.getWorkDate()) && ol.getUserId().equals(userFvTime.getUserId())).findFirst();
+                        if(first.isPresent()){
+                            userFvTime.setId(first.get().getId());
+                        }
+                        userFvTimeList.add(userFvTime);
                     }
                 }
-                UserFvTime userFvTime=new UserFvTime();
-                System.out.println("泛微同步人员打卡数据----"+user.getName());
-                if(compIds.contains(user.getCompanyId())){
-                    if(startTime==null||endTime==null){
-                        System.out.println("缺少上班或者下班打卡时间----"+user.getName());
-                        continue;
-                    }
-                    userFvTime.setWorkDate(workDate);
-                    Duration between = Duration.between(startTime, endTime);
-                    userFvTime.setStartTime(startTime.format(dtf2));
-                    userFvTime.setEndTime(endTime.format(dtf2));
-                    userFvTime.setCompanyId(user.getCompanyId());
-                    userFvTime.setUserId(user.getId());
-                    long workHours = between.toHours();
-                    long restHours;
-                    if(startTime.isBefore(LocalTime.parse(timeAutoExclude.getStartTime(),dtf2))
-                            &&endTime.isAfter(LocalTime.parse(timeAutoExclude.getEndTime(),dtf2))){
-                        Duration bt = Duration.between(LocalTime.parse(timeAutoExclude.getStartTime(),dtf2), LocalTime.parse(timeAutoExclude.getEndTime(),dtf2));
-                        restHours=bt.toHours();
-                    }else {
-                        restHours=0;
-                    }
-                    userFvTime.setWorkHours(BigDecimal.valueOf(workHours).subtract(BigDecimal.valueOf(restHours)).floatValue());
-                    Optional<UserFvTime> first = oldUserFvTimeList.stream().filter(ol -> ol.getWorkDate().isEqual(userFvTime.getWorkDate()) && ol.getUserId().equals(userFvTime.getUserId())).findFirst();
-                    if(first.isPresent()){
-                        userFvTime.setId(first.get().getId());
-                    }
-                    userFvTimeList.add(userFvTime);
-                }
             }
             if(userFvTimeList.size()>0){
                 userFvTimeService.saveOrUpdateBatch(userFvTimeList);
             }
-            System.out.println(workDataList);
+            System.out.println(userFvTimeList);
             //Todo: 获取请假数据
             HttpRespMsg leaveRecordMsg = dockWithMLD.getResult("http://10.1.10.51:20175/api/cube/restful/interface/getModeDataPageList/getLeaveRecord", jsonString);
             List<Map<String,Object>> leaveRecordList= (List<Map<String, Object>>) leaveRecordMsg.data;
             for (Map<String, Object> map : leaveRecordList) {
-                User user = userMapper.selectOne(new QueryWrapper<User>().eq("job_number", map.get("rybh")));
-                if(user==null){
+                Optional<User> optional=allUserList.stream().filter(al->al.getJobNumber()!=null&&al.getJobNumber().equals(map.get("rybh"))).findFirst();
+                if(!optional.isPresent()){
                     continue;
                 }
+                User user=optional.get();
                 System.out.println("泛微同步人员请假数据----"+user.getName());
                 if(compIds.contains(user.getCompanyId())){
                     LeaveSheet leaveSheet=new LeaveSheet();
@@ -396,7 +424,7 @@ public class TimingTask {
                     }else {
                         leaveSheet.setTimeHours(Float.parseFloat(((String) map.get("timeHours")).equals("")?"0.00":((String) map.get("timeHours"))));
                     }
-                    Integer leaveType=null;
+                    Integer leaveType;
                     switch (String.valueOf(map.get("leaveType"))){
                         case "事假":leaveType=0;
                             break;
@@ -419,7 +447,7 @@ public class TimingTask {
                     leaveSheet.setLeaveType(leaveType);
                     leaveSheet.setProcinstId(String.valueOf(map.get("procinstId")));
                     leaveSheet.setGmtFinished(String.valueOf(map.get("gmtFinished")));
-                    Optional<LeaveSheet> first = oldLeaveSheetList.stream().filter(ol -> ol.getStartDate().isEqual(leaveSheet.getStartDate())&&ol.getEndDate().isEqual(leaveSheet.getEndDate()) && ol.getOwnerId().equals(leaveSheet.getOwnerId())).findFirst();
+                    Optional<LeaveSheet> first = oldLeaveSheetList.stream().filter(ol -> ol.getStartDate().isEqual(leaveSheet.getStartDate())&&ol.getEndDate().isEqual(leaveSheet.getEndDate()) && ol.getOwnerId().equals(leaveSheet.getOwnerId())&&ol.getProcinstId().equals(leaveSheet.getProcinstId())).findFirst();
                     if(first.isPresent()){
                         leaveSheet.setId(first.get().getId());
                     }
@@ -434,11 +462,11 @@ public class TimingTask {
             HttpRespMsg travelRecordMsg = dockWithMLD.getResult("http://10.1.10.51:20175/api/cube/restful/interface/getModeDataPageList/getTravelRecord", jsonString);
             List<Map<String,Object>> travelRecordList= (List<Map<String, Object>>) travelRecordMsg.data;
             for (Map<String, Object> map : travelRecordList) {
-                User user = userMapper.selectOne(new QueryWrapper<User>().eq("job_number", map.get("rybh")));
-                if(user==null){
+                Optional<User> optional=allUserList.stream().filter(al->al.getJobNumber()!=null&&al.getJobNumber().equals(map.get("rybh"))).findFirst();
+                if(!optional.isPresent()){
                     continue;
                 }
-                System.out.println("泛微同步人员出差数据----"+user.getName());
+                User user=optional.get();
                 if(compIds.contains(user.getCompanyId())){
                     BusinessTrip businessTrip=new BusinessTrip();
                     businessTrip.setCompanyId(user.getCompanyId());
@@ -470,10 +498,11 @@ public class TimingTask {
                             break;
                     }
                     businessTrip.setGoBack(goBack);
-                    businessTrip.setDayCount(Integer.parseInt(String.valueOf(map.get("dayCount")).substring(0,1)));
+                    Double dayCount =Double.valueOf(String.valueOf(map.get("dayCount")));
+                    businessTrip.setDayCount(dayCount.intValue());
                     businessTrip.setProcinstId((String) map.get("procinstId"));
                     businessTrip.setGmtFinished((String)map.get("gmtFinished"));
-                    Optional<BusinessTrip> first = oldBusinessTripList.stream().filter(ol -> ol.getStartDate().isEqual(businessTrip.getStartDate())&&ol.getEndDate().isEqual(businessTrip.getEndDate()) && ol.getOwnerId().equals(businessTrip.getOwnerId())).findFirst();
+                    Optional<BusinessTrip> first = oldBusinessTripList.stream().filter(ol -> ol.getStartDate().isEqual(businessTrip.getStartDate())&&ol.getEndDate().isEqual(businessTrip.getEndDate()) && ol.getOwnerId().equals(businessTrip.getOwnerId())&&ol.getProcinstId().equals(businessTrip.getProcinstId())).findFirst();
                     if(first.isPresent()){
                         businessTrip.setId(first.get().getId());
                     }
@@ -486,6 +515,16 @@ public class TimingTask {
         }
     }
 
+    private  List<LocalDateTime> getDays(LocalDateTime start, LocalDateTime end) {
+        List<LocalDateTime> result = new ArrayList();
+        while (start.isBefore(end)) {
+            result.add(start);
+            start=start.plusDays(1);
+        }
+        result.add(start);
+        return result;
+    }
+
     //每天1:00 同步昨天的微信请假信息
     @Scheduled(cron = "0 0 1 ? * *")
     public void synWxLeave() throws Exception {

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/DockWithMLD.java

@@ -79,7 +79,7 @@ public class DockWithMLD {
         //分页参数 处理全部数据 不需要进行分页
         JSONObject pageInfo = new JSONObject();
         pageInfo.put("pageNo", 1);
-        pageInfo.put("pageSize",10000);
+        pageInfo.put("pageSize",99999);
         paramDatajson.put("pageInfo",pageInfo);
         //封装 mainTable 参数
         JSONObject mainTable  = JSON.parseObject(screenString);

+ 2 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserMapper.xml

@@ -41,6 +41,7 @@
         <result column="job_number" property="jobNumber" />
         <result column="corpwx_deptid" property="corpwxDeptid" />
         <result column="corpwx_real_userid" property="corpwxRealUserid" />
+        <result column="is_first_login" property="isFirstLogin" />
     </resultMap>
     <resultMap id="BaseResultMap2" type="com.management.platform.entity.User">
         <id column="id" property="id" />
@@ -50,7 +51,7 @@
     </resultMap>
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, name, phone, password, portrait_url, create_time, role, company_id, department_id, department_cascade, cost, month_cost, salary_type, manage_dept_id, color, is_active, wx_openid, role_id, role_name, cost_apply_date, dingding_userid, dingding_unionid, corpwx_userid, induction_date, inactive_date, position, report_status, superior_id, plate1, plate2, plate3, plate4, plate5, is_ops, job_number, corpwx_deptid, corpwx_real_userid
+        id, name, phone, password, portrait_url, create_time, role, company_id, department_id, department_cascade, cost, month_cost, salary_type, manage_dept_id, color, is_active, wx_openid, role_id, role_name, cost_apply_date, dingding_userid, dingding_unionid, corpwx_userid, induction_date, inactive_date, position, report_status, superior_id, plate1, plate2, plate3, plate4, plate5, is_ops, job_number, corpwx_deptid, corpwx_real_userid, is_first_login
     </sql>
     <!--单独分页获取人员-->
     <select id="getUserByDepartment" resultType="java.util.Map">

+ 5 - 1
fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/controller/OperationLogController.java

@@ -8,6 +8,7 @@ import com.management.platform.mapper.OperationLogMapper;
 import com.management.platform.util.HttpRespMsg;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
@@ -31,9 +32,12 @@ public class OperationLogController {
     获取操作日志
      */
     @RequestMapping("list")
-    public HttpRespMsg list(Integer pageIndex, Integer pageSize) {
+    public HttpRespMsg list(Integer pageIndex, Integer pageSize, @RequestParam(defaultValue = "0") Integer personKey) {
         HttpRespMsg msg = new HttpRespMsg();
         QueryWrapper<OperationLog> queryWrapper = new QueryWrapper<>();
+        if(personKey==1){
+            queryWrapper.like("operation_content","人数");
+        }
         queryWrapper.orderByDesc("id");
         msg.data = operationLogMapper.selectPage(new Page<>(pageIndex, pageSize), queryWrapper);
         return msg;

+ 19 - 1
fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/entity/TimeType.java

@@ -17,7 +17,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2022-10-17
+ * @since 2023-01-03
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -389,6 +389,24 @@ public class TimeType extends Model<TimeType> {
     @TableField("not_allowed_no_attendance")
     private Integer notAllowedNoAttendance;
 
+    /**
+     * 1为需要同步企业微信请假,0为不需要同步企业微信请假
+     */
+    @TableField("wx_leave")
+    private Integer wxLeave;
+
+    /**
+     * 是否开通【推送工时数据】 0-否 1-是
+     */
+    @TableField("push_report_data")
+    private Integer pushReportData;
+
+    /**
+     * 推送工时数据URL
+     */
+    @TableField("push_report_url")
+    private String pushReportUrl;
+
 
     @Override
     protected Serializable pkVal() {

File diff suppressed because it is too large
+ 4 - 1
fhKeeper/formulahousekeeper/ops-platform/src/main/resources/mapper/TimeTypeMapper.xml


+ 4 - 4
fhKeeper/formulahousekeeper/timesheet/config/index.js

@@ -1,10 +1,10 @@
 var path = require('path')
 
- var ip = '127.0.0.1'
-// var ip = '47.101.180.183'
+//  var ip = '192.168.2.12'
+var ip = '47.101.180.183'
 // var ip = '47.100.37.243'
-// var ip = '192.168.2.31'
-// var ip = '192.168.2.44'
+// var ip = '192.168.10.2'
+// var ip = '192.168.2.13' 
 
 // var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
 // for (var i in ifaces) {

File diff suppressed because it is too large
+ 10941 - 441
fhKeeper/formulahousekeeper/timesheet/package-lock.json


+ 1 - 0
fhKeeper/formulahousekeeper/timesheet/package.json

@@ -30,6 +30,7 @@
     "vue-pdf": "^4.2.0",
     "vue-quill-editor": "^3.0.6",
     "vue-router": "^2.3.0",
+    "vue-tour": "^2.0.0",
     "vuedraggable": "^2.24.3",
     "vuex": "^2.0.0-rc.6"
   },

+ 6 - 0
fhKeeper/formulahousekeeper/timesheet/src/App.vue

@@ -1,5 +1,6 @@
 <template>
 	<div id="app">
+        <v-tour name="myTour" :steps="steps" :options="myOptions" :callbacks="myCallbacks" v-if="tourFlg"></v-tour>
 		<transition name="fade" mode="out-in">
 			<!-- <keep-alive>
                 <router-view v-if='$route.meta != null && $route.meta.keepAlive'/>
@@ -34,6 +35,11 @@
 		}
     }
 </script>
+<style>
+    .v-tour__target--highlighted {
+        box-shadow: 0 0 0 99999px rgba(0,0,0,.4) !important;
+    }
+</style>
 
 <style lang="scss">
     body {

File diff suppressed because it is too large
+ 1333 - 28
fhKeeper/formulahousekeeper/timesheet/src/components/taskComponent.vue


+ 5 - 0
fhKeeper/formulahousekeeper/timesheet/src/main.js

@@ -65,6 +65,11 @@ import NProgress from 'nprogress'
 import 'nprogress/nprogress.css'
 import Vue from 'vue'
 
+// 新手指导
+import VueTour from 'vue-tour'
+require('vue-tour/dist/vue-tour.css')
+Vue.use(VueTour)
+
 var addRouFlag = false; 
 //角色权限对应关系
 var userModules = [{role:0, modules:["工时报告","专业审核","部门审核","自动计时","费用报销","待办任务", "项目管理", "请假管理", "审批流设置"]},

+ 152 - 6
fhKeeper/formulahousekeeper/timesheet/src/views/Home.vue

@@ -1,6 +1,9 @@
 <template>
     <el-row class="container">
+        <v-tour name="myTour" :steps="steps" :options="myOptions" :callbacks="myCallbacks" v-if="tourFlg"></v-tour>
+
         <el-col :span="24" class="header">
+            <div class="contentMask" v-if="vTourFlg"></div>
             <el-col :span="10" class="logo" :class="collapsed?'logo-collapse-width':'logo-width'" :style="collapsed?'padding:0':''">
                 <img v-if="collapsed" class="headImg" src="../assets/image/head_logo.png" />
                 <div v-else class="logo-sys">
@@ -125,9 +128,10 @@
             <aside :class="collapsed?'menu-collapsed':'menu-expanded'">
                 <el-scrollbar style="height:100%">
                 <!--导航菜单-->
-                <el-menu :default-active="$route.path" class="el-menu-vertical-demo" unique-opened router v-if="!collapsed">
+                <el-menu :default-active="$route.path" class="el-menu-vertical-demo" unique-opened router v-if="!collapsed" default-openeds="zhan">
                     <template v-for="(item, index) in $router.options.routes" v-if="!item.hidden">
-                        <el-submenu :index="index+''" v-if="!item.leaf">
+                        <!-- <el-submenu :index="index+''" v-if="!item.leaf"> -->
+                        <el-submenu :index="'zhan'" v-if="!item.leaf">
                             <template slot="title"> 
                                 <i :class="item.iconCls"></i>
                                 <!-- <span class="itemName">{{item.name}}</span> -->
@@ -136,7 +140,7 @@
                                     <span>{{$t(item.meta.text)}}</span>
                                 </el-tooltip>
                             </template>
-                            <el-menu-item v-for="child in item.children" :index="child.path" :key="child.path" v-if="!child.hidden"><i :class="child.iconCls"></i>
+                            <el-menu-item v-for="child in item.children" :index="child.path" :key="child.path" v-if="!child.hidden" :data-v-step="child.path"><i :class="child.iconCls"></i>
                                 <!-- {{child.name}} -->
                                 <span class="bosx" v-if="$t(child.meta.text).length < 16">{{$t(child.meta.text)}}</span>
                                 <el-tooltip class="bosx"  v-if="$t(child.meta.text).length > 16" effect="dark" :content="$t(child.meta.text)" placement="top">
@@ -144,7 +148,7 @@
                                 </el-tooltip>
                             </el-menu-item>
                         </el-submenu>
-                        <el-menu-item v-if="item.leaf && item.children.length > 0" :index="item.children[0].path">
+                        <el-menu-item v-if="item.leaf && item.children.length > 0" :index="item.children[0].path" :data-v-step="item.children[0].path">
                             <i :class="item.iconCls"></i> 
                             <!-- {{item.children[0].name}} -->
                             <span class="bosx" v-if="$t(item.meta.text).length < 16">{{$t(item.meta.text)}}</span>
@@ -184,6 +188,7 @@
             </aside>
 
             <section class="content-container">
+                <div class="contentMask" v-if="vTourFlg"></div>
                 <div class="grid-content bg-purple-light">
                     <el-col :span="24" class="content-wrapper">
                         <transition name="fade" mode="out-in">
@@ -237,6 +242,24 @@
         inject:['reloads'],
         data() {
             return {
+                tourFlg: false,
+                steps: [],
+                myOptions:{
+                    useKeyboardNavigation: false,    //不使用←、→和ESC键来导航tour
+                    startTimeout: 1000,   //1秒后执行
+                    highlight: true,
+                    labels: {
+                        buttonSkip: '跳过',
+                        buttonPrevious: '上一步',
+                        buttonNext: '下一步',
+                        buttonStop: '关闭'
+                    }
+                },
+                myCallbacks: {
+                    onSkip: this.onSkip,   //在data中定义两个回调
+                    onFinish: this.onFinish
+                },
+
                 isCorpWX: false,
                 // roleArray:["普通员工","超级管理员", "系统管理员", "公司高层","财务管理员", "项目管理员","公司领导"],
                 roleArray:[this.$t('role.ordinaryEmployees'),this.$t('role.superAdministrator'),this.$t('role.systemAdministrator'),this.$t('role.companyTop'),this.$t('role.financialAdministrator'),this.$t('role.projectManager'),this.$t('role.companyLeadership')],
@@ -280,10 +303,106 @@
                 num: 0,
 
                 language: '',
-                setTimeLoad: null
+                setTimeLoad: null,
+
+                // 遮罩
+                vTourFlg: false
             };
         },
+        created() {
+            var arr = []
+            var routers = JSON.parse(sessionStorage.getItem("user")).moduleList
+            for(var i in routers) {
+                if(routers[i].path == '/timetype') {
+                    let obj = {
+                        target: '[data-v-step="/timetype"]',
+                        content: `查看基础设置,按照企业情况进行调整`,
+                        params: {
+                            placement: 'right',
+                            highlight: true 
+                        }
+                    }
+                    arr.push(obj)
+                }
+                if(routers[i].path == '/list') {
+                    let obj = {
+                        target: '[data-v-step="/list"]',
+                        content: `创建项目和任务`,
+                        params: {
+                            placement: 'right',
+                            highlight: true 
+                        }
+                    }
+                    arr.push(obj)
+                }
+                if(routers[i].path == '/daily') {
+                    let obj = {
+                        target: '[data-v-step="/daily"]',
+                        content: `填写每日工时报告`,
+                        params: {
+                            placement: 'right',
+                            highlight: true 
+                        }
+                    }
+                    arr.push(obj)
+                }
+                if(routers[i].path == '/review') {
+                    let obj = {
+                        target: '[data-v-step="/review"]',
+                        content: `审核人审核日报`,
+                        params: {
+                            placement: 'right',
+                            highlight: true 
+                        }
+                    }
+                    arr.push(obj)
+                }
+                if(routers[i].path == '/cost') {
+                    let obj = {
+                        target: '[data-v-step="/cost"]',
+                        content: `查看工时成本统计结果`,
+                        params: {
+                            placement: 'right',
+                            highlight: true 
+                        }
+                    }
+                    arr.push(obj)
+                }
+                if(routers[i].path == '/finance') {
+                    let obj = {
+                        target: '[data-v-step="/finance"]',
+                        content: `导入薪资,校准成本并生成财务报表`,
+                        params: {
+                            placement: 'right',
+                            highlight: true 
+                        }
+                    }
+                    arr.push(obj)
+                }
+                if(routers[i].path == '/team') {
+                    let obj = {
+                        target: '[data-v-step="/team"]',
+                        content: `编辑员工信息,分配角色`,
+                        params: {
+                            placement: 'right',
+                            highlight: true 
+                        }
+                    }
+                    arr.push(obj)
+                }
+            }
+            this.steps = arr
+            console.log(this.steps, '数据', routers)
+        },
         methods: {
+            onSkip(currentStep) {
+                console.log('看看')
+                this.vTourFlg = false
+            },
+            onFinish(currentStep) {
+                console.log('数据')
+                this.vTourFlg = false
+            },
 
             // 中英文切换
             langChange(command) {
@@ -567,7 +686,7 @@
                         timestamp: res.data.timestamp, // 必填,生成签名的时间戳 
                         nonceStr: res.data.noncestr, // 必填,生成签名的随机串 
                         signature: res.data.sign, // 必填,签名,见附录1 
-                        jsApiList: ['chooseImage','previewImage','uploadImage','downloadImage','previewFile','getLocation','agentConfig'] 
+                        jsApiList: ['chooseImage','previewImage','uploadImage','downloadImage','previewFile','getLocation','agentConfig','openAppManage'] 
                         });
                         var that = this;
                         wx.ready(function(){
@@ -656,11 +775,35 @@
             if(this.user.userNameNeedTranslate == '1') {
                 this.agentConfig()
             }
+
+            // 判断是否为新用户
+            if(this.user.isFirstLogin == 1) {
+                var thats = this
+                this.tourFlg = true
+                setTimeout(() => {
+                    thats.$tours['myTour'].start()
+                    setTimeout(() => {
+                        thats.vTourFlg = true
+                    }, 1000)
+                }, 200)
+            }
         },
     };
 </script>
 
 <style scoped lang="scss">
+.contentMask {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    top: 0;
+    left: 0;
+    background: #000;
+    opacity: .4;
+    z-index: 99;
+    // box-shadow: 0 0 0 99999px rgba(0,0,0,.4) !important;
+}
+
 .gongshimingz {
     width: 100%;
     position: absolute;
@@ -686,6 +829,7 @@
             line-height: 60px;
             background: #20a0ff;
             color: #fff;
+            position: relative;
             .userinfo {
                 text-align: right;
                 padding-right: 35px;
@@ -806,6 +950,7 @@
                 width: 80%;
                 overflow-y: auto;
                 overflow-x: hidden;
+                position: relative;
                 .breadcrumb-container {
                     .title {
                         width: 200px;
@@ -819,6 +964,7 @@
                 .content-wrapper {
                     background-color: #fff;
                     box-sizing: border-box;
+                    position: relative;
                 }
             }
         }

File diff suppressed because it is too large
+ 608 - 541
fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue


+ 93 - 40
fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue

@@ -1,5 +1,7 @@
 <template>
     <section >
+        <v-tour name="myTour" :steps="steps" :options="myOptions" :callbacks="myCallbacks"></v-tour>
+
         <el-col :span="24" class="toolbar" style="padding-bottom: 0px;position:sticky;top:0;z-index:1002">
             <el-form :inline="true">
                 <el-form-item :label="$t('navigation.basicSystemSettings')">
@@ -10,46 +12,48 @@
             </el-form>
         </el-col>
         <p style="padding-top:80px;margin: 0 0 10px 10px;color:#666;">{{ $t('employeehourlywage') }}</p>
-        <div class="panel clearfix" style="height:auto;margin-left:20px;margin-right:20px;">
-            <div style="width:100%;float:left">
-                <el-radio v-model="timeType.hourCostInputType" :label="0" style="width:100%;margin-left:10px;">{{ $t('methodsa') }}<span class="tip">{{ $t('suitableforfulltimeemployees') }}</span></el-radio>
-            </div>
-            <div style="width:100%;float:left"> 
-                <el-form ref="form0" :inline="true" :model="timeType" label-width="150px" style="margin-top:10px">
-                    <el-form-item :label="$t('workingdayspermonth')" prop="monthDays">
-                    <el-input v-model="timeType.monthDays"  type="number" style="width:120px;"></el-input>
-                    {{ $t('time.day') }} 
-                    </el-form-item>    
-                    <el-form-item :label="$t('dailyworkinghours')" prop="allday">
-                        <el-select v-model="timeType.allday" :placeholder="$t('defaultText.pleaseSelectWorkingHours')" style="width:120px;" @change="timeAlldayChange">
-                            <el-option v-for="item in times" :key="item" :label="item.toFixed(1)" :value="item"></el-option>
-                        </el-select>
-                        {{ $t('time.hour') }} 
-                    </el-form-item>
-                    <el-form-item>
-                        <span class="lockworktime"><el-checkbox v-model="timeType.lockWorktime" @change="lockChange" :label="$t('lockingworkinghours')" />
-                        <el-tooltip effect="dark" :content="$t('hoursreporteperday')" placement="top-start">
-                            <i class="el-icon-question" style="color:#606266"></i>
-                        </el-tooltip>
-                        </span>
-                    </el-form-item>
-                    <el-form-item :label="$t('imitillingtime')">
-                        <el-select :disabled="timeType.lockWorktime" v-model="timeType.maxReportTime" type="number" style="width:120px;">
-                            <el-option v-for="item in maxReportTimeRange" :key="item" :label="item.toFixed(1)" :value="item"></el-option>
-                        </el-select><span style="margin-left:5px;color:#409eff">{{ $t('time.hour') }}</span>
-                    </el-form-item><br>
-                    <el-form-item :label="$t('workSettings')" prop="allday" v-if="!timeType.lockWorktime">
-                        <el-checkbox v-model="timeType.fillOvertime" :label="$t('hourscanbereported')" />
-                        <template v-if="timeType.fillOvertime">
-                        <el-checkbox v-model="timeType.payOvertime" :label="$t('chargedtocost')" />
-                        <!-- <el-checkbox v-model="timeType.doubleOvertime" label="加班双倍成本" :disabled="!timeType.payOvertime"/> -->
-                        <el-input v-model="timeType.overtimeRatio" placeholder="" clearable style="width: 100px;margin: 0 10px 0 20px" v-if="timeType.payOvertime" @keyup.native="timeType.overtimeRatio = oninput(timeType.overtimeRatio, 1)"></el-input> <span v-if="timeType.payOvertime">{{ $t('bei-gong-zi') }}</span>
-                        </template>
-                    </el-form-item>
-                </el-form>
-            </div>
-            <div style="width:100%;float:left">
-                <el-radio v-model="timeType.hourCostInputType" :label="1" style="width:100%;margin-left:10px;">{{ $t('visittwo') }}<span class="tip">{{ $t('timeemployees') }}</span></el-radio>
+        <div data-v-step="timetypeBox">
+            <div class="panel clearfix" style="height:auto;margin-left:20px;margin-right:20px;">
+                <div style="width:100%;float:left">
+                    <el-radio v-model="timeType.hourCostInputType" :label="0" style="width:100%;margin-left:10px;">{{ $t('methodsa') }}<span class="tip">{{ $t('suitableforfulltimeemployees') }}</span></el-radio>
+                </div>
+                <div style="width:100%;float:left"> 
+                    <el-form ref="form0" :inline="true" :model="timeType" label-width="150px" style="margin-top:10px">
+                        <el-form-item :label="$t('workingdayspermonth')" prop="monthDays">
+                        <el-input v-model="timeType.monthDays"  type="number" style="width:120px;"></el-input>
+                        {{ $t('time.day') }} 
+                        </el-form-item>    
+                        <el-form-item :label="$t('dailyworkinghours')" prop="allday">
+                            <el-select v-model="timeType.allday" :placeholder="$t('defaultText.pleaseSelectWorkingHours')" style="width:120px;" @change="timeAlldayChange">
+                                <el-option v-for="item in times" :key="item" :label="item.toFixed(1)" :value="item"></el-option>
+                            </el-select>
+                            {{ $t('time.hour') }} 
+                        </el-form-item>
+                        <el-form-item>
+                            <span class="lockworktime"><el-checkbox v-model="timeType.lockWorktime" @change="lockChange" :label="$t('lockingworkinghours')" />
+                            <el-tooltip effect="dark" :content="$t('hoursreporteperday')" placement="top-start">
+                                <i class="el-icon-question" style="color:#606266"></i>
+                            </el-tooltip>
+                            </span>
+                        </el-form-item>
+                        <el-form-item :label="$t('imitillingtime')">
+                            <el-select :disabled="timeType.lockWorktime" v-model="timeType.maxReportTime" type="number" style="width:120px;">
+                                <el-option v-for="item in maxReportTimeRange" :key="item" :label="item.toFixed(1)" :value="item"></el-option>
+                            </el-select><span style="margin-left:5px;color:#409eff">{{ $t('time.hour') }}</span>
+                        </el-form-item><br>
+                        <el-form-item :label="$t('workSettings')" prop="allday" v-if="!timeType.lockWorktime">
+                            <el-checkbox v-model="timeType.fillOvertime" :label="$t('hourscanbereported')" />
+                            <template v-if="timeType.fillOvertime">
+                            <el-checkbox v-model="timeType.payOvertime" :label="$t('chargedtocost')" />
+                            <!-- <el-checkbox v-model="timeType.doubleOvertime" label="加班双倍成本" :disabled="!timeType.payOvertime"/> -->
+                            <el-input v-model="timeType.overtimeRatio" placeholder="" clearable style="width: 100px;margin: 0 10px 0 20px" v-if="timeType.payOvertime" @keyup.native="timeType.overtimeRatio = oninput(timeType.overtimeRatio, 1)"></el-input> <span v-if="timeType.payOvertime">{{ $t('bei-gong-zi') }}</span>
+                            </template>
+                        </el-form-item>
+                    </el-form>
+                </div>
+                <div style="width:100%;float:left">
+                    <el-radio v-model="timeType.hourCostInputType" :label="1" style="width:100%;margin-left:10px;">{{ $t('visittwo') }}<span class="tip">{{ $t('timeemployees') }}</span></el-radio>
+                </div>
             </div>
         </div>
         <!--设置时长样式内容-->
@@ -485,6 +489,38 @@
     export default {
         data() {
             return {
+                tourFlg: false,
+                steps: [{
+                        target: '[data-v-step="timetypeBox"]',
+                        content: `按照企业情况调整`,
+                        params: {
+                            placement: 'left',
+                            highlight: true 
+                        }
+                    },{
+                        target: '[data-v-step="/xinshozhidao1"]',
+                        content: `请先点击系统基础设置`,
+                        params: {
+                            placement: 'right',
+                            highlight: true 
+                        }
+                    }],
+                myOptions:{
+                    useKeyboardNavigation: false,    //不使用←、→和ESC键来导航tour
+                    startTimeout: 1000,   //1秒后执行
+                    highlight: true,
+                    labels: {
+                        buttonSkip: '跳过',
+                        buttonPrevious: '上一步',
+                        buttonNext: '下一步',
+                        buttonStop: '关闭'
+                    }
+                },
+                myCallbacks: {
+                    onPreviousStep: this.myCustomPreviousStepCallback,   //在data中定义两个回调
+                    onNextStep: this.myCustomNextStepCallback
+                },
+
                 pushParam:{
                     day:'05',
                     hour:'01',
@@ -573,8 +609,25 @@
             this.initTime();
             this.getCompanyTimeSetting();
             this.getRestList()
+
+            var thats = this
+            setTimeout(() => {
+                // thats.$tours['myTour'].start()
+            }, 1000)
         },
          methods: {
+             myCustomNextStepCallback(currentStep) {
+                console.log(currentStep, '看看')
+                if(currentStep == '0') {    
+                    this.$router.push("/timetype")
+                }
+            },
+            myCustomPreviousStepCallback(currentStep) {
+                if(currentStep == '1') {
+                    console.log('上一步')
+                }
+            },
+
             timePicker(e){
                 // console.log('timePicker',this.startTime,this.endTime);
                 if(this.startTime && this.endTime){

+ 423 - 372
fhKeeper/formulahousekeeper/timesheet/src/views/task/list.vue

@@ -216,405 +216,413 @@
 
         <!-- 任务详情信息弹出框 -->
         <el-dialog :class="addForm.id==null?'':'jm'" :title="title" v-if="addFormVisible" :visible.sync="addFormVisible" 
-        :close-on-click-modal="false" customClass="customWidth" width="800px" :top="'6vh'">
+        :close-on-click-modal="false" customClass="customWidth" width="840px" :top="'6vh'">
         <!-- <div style="width: 200%;height:80%;position: absolute;right:-100%;top:0;background:#000;opacity: 0;" @click="sss"></div> -->
-            <div style="height: 72vh;overflow: auto;">
-                <el-form ref="form1" :model="addForm" :rules="taskRules" label-width="100px">
-                    <!--子任务需要选择任务列表 -->
-                    <el-form-item :label="$t('tasklist')" prop="stages" v-if="addForm.parentTid != null">
-                        <el-select v-model="addForm.stagesId" style="width:100%;" >
-                            <el-option v-for="item in stageList" :key="item.id" :label="item.stagesName" :value="item.id"></el-option>
-                        </el-select>
-                    </el-form-item>
-                    <el-form-item :label="$t('types')">
-                        <el-select v-model="addForm.taskType" style="width:100%;" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement">
-                            <el-option v-for="item in taskTypeList" :key="item.id" :label="item.name" :value="item.id">
-                                <i :class="item.icon" ></i>
-                                <span>{{item.name}}</span>
-                            </el-option>
-                        </el-select>
-                    </el-form-item>
-                    <el-form-item :label="$t('taskdefinition')" prop="name">
-                        <el-input v-model="addForm.name" :maxlength="40" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement" :placeholder="$t('enterthetaskcontent')" clearable></el-input>
-                    </el-form-item>
-                    
-                    <el-form-item :label="addForm.taskType == 1 ? $t('deadline') : $t('starttimes')" :prop="addForm.taskType == 1 ? 'endDate' : 'startDate'">
-                        <el-date-picker v-model="addForm.startDate" type="date" style="width:40%;" value-format="yyyy-MM-dd"  
-                        :placeholder="$t('pleaseselectadate')" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement" v-if="addForm.taskType != 1"></el-date-picker>
-                        <span style="margin-left:30px;margin-right:10px;" v-if="addForm.taskType != 1">{{ $t('deadline') }}</span>
-                        <el-date-picker v-model="addForm.endDate" type="date" value-format="yyyy-MM-dd"  
-                        :placeholder="$t('pleaseselectadate')" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement"></el-date-picker>
+            <!-- 整合 -->
+            <taskComponent ref="thskComponents" :integrationTask="integrationTask" @closeBounced="closeBounced"></taskComponent>
+            <div slot="title" v-if="addForm.parentTid != null">
+                <el-page-header  @back="backToParentTask" :title="$t('parenttask')" :content="addForm.parentTname"></el-page-header>
+            </div>
+            <!-- 未整合 -->
+            <div v-if="false">
+                <div style="height: 72vh;overflow: auto;">
+                    <el-form ref="form1" :model="addForm" :rules="taskRules" label-width="100px">
+                        <!--子任务需要选择任务列表 -->
+                        <el-form-item :label="$t('tasklist')" prop="stages" v-if="addForm.parentTid != null">
+                            <el-select v-model="addForm.stagesId" style="width:100%;" >
+                                <el-option v-for="item in stageList" :key="item.id" :label="item.stagesName" :value="item.id"></el-option>
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item :label="$t('types')">
+                            <el-select v-model="addForm.taskType" style="width:100%;" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement">
+                                <el-option v-for="item in taskTypeList" :key="item.id" :label="item.name" :value="item.id">
+                                    <i :class="item.icon" ></i>
+                                    <span>{{item.name}}</span>
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item :label="$t('taskdefinition')" prop="name">
+                            <el-input v-model="addForm.name" :maxlength="40" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement" :placeholder="$t('enterthetaskcontent')" clearable></el-input>
                         </el-form-item>
-                    <div style="border: 1px solid #ddd;margin:5px 0;padding:5px 0;">
-                    <el-form-item :label="$t('zhi-hang-ren')+(index+1)" v-for="(executorItem, index) in addForm.executorListFront" :key="index">
-
-                        <el-select v-if="user.userNameNeedTranslate != '1'" v-model="executorItem.executorId" :disabled="(addForm.id != null && user.id != addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement" size="small" filterable clearable :placeholder="$t('pleaseselectanexecutor')" style="width:40%;" @change="$forceUpdate()">
-                            <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id">
-                                <span style="float: left">{{ item.name }}</span>
-                                <span style="float: right; color: #8492a6; font-size: 13px;margin-left: 20px" v-if="item.jobNumber">{{ item.jobNumber }}</span>
-                            </el-option>
-                        </el-select>
                         
-                        <selectCat :subject="users" :subjectId="executorItem.executorId" :filterable="true" :index="index" @selectCal="selectCal" :size="'mini'" v-if="user.userNameNeedTranslate == '1'"></selectCat>
+                        <el-form-item :label="addForm.taskType == 1 ? $t('deadline') : $t('starttimes')" :prop="addForm.taskType == 1 ? 'endDate' : 'startDate'">
+                            <el-date-picker v-model="addForm.startDate" type="date" style="width:40%;" value-format="yyyy-MM-dd"  
+                            :placeholder="$t('pleaseselectadate')" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement" v-if="addForm.taskType != 1"></el-date-picker>
+                            <span style="margin-left:30px;margin-right:10px;" v-if="addForm.taskType != 1">{{ $t('deadline') }}</span>
+                            <el-date-picker v-model="addForm.endDate" type="date" value-format="yyyy-MM-dd"  
+                            :placeholder="$t('pleaseselectadate')" :disabled="(this.addForm.id != null && user.id != this.addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement"></el-date-picker>
+                            </el-form-item>
+                        <div style="border: 1px solid #ddd;margin:5px 0;padding:5px 0;">
+                        <el-form-item :label="$t('zhi-hang-ren')+(index+1)" v-for="(executorItem, index) in addForm.executorListFront" :key="index">
 
-                        <span style="margin-left:30px;margin-right:10px;">{{ $t('plantime') }}</span>
-                        <el-input-number size="small" :disabled="(addForm.id != null && user.id != addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement" v-model="executorItem.planHours" style="width:30%;" :min="1" :max="100"  :placeholder="$t('pleaseentertheplannedworking')" ></el-input-number ><span style="margin-left:10px;">{{ $t('time.hour') }}</span>
-                        <!--移除执行人 -->
-                        <i class="el-icon-delete" v-if="index>0 && (addForm.id == null|| user.id == addForm.createrId || currentProject.inchargerId == user.id|| permissions.projectManagement)" style="margin-left:5px" @click="removeExecutorLine(index)"></i>
-                    </el-form-item>
-                    <el-link type="primary" v-if="(addForm.executorListFront == null || addForm.executorListFront.length<10)&& (addForm.id == null|| user.id == addForm.createrId || currentProject.inchargerId == user.id || permissions.projectManagement)" style="margin-left:35px;" @click="addExecutorLine">{{ $t('addinganexecutor') }}</el-link>
-                    </div>
-                    
-                    <el-form-item :label="$t('priority')">
-                        <el-select v-model="addForm.taskLevel" style="width:100%;" >
-                            <el-option v-for="item in importanceList" :key="item.id" :label="item.name" :value="item.id"></el-option>
-                        </el-select>
-                    </el-form-item>
-                    <!-- 富文本 -->
-                    <el-form-item :label="$t('detaileddescription')" style="height: 200px">
-                        <!-- <Editor id="tinymce" v-model="tinymceHtml" :init="editorInit"></Editor> -->
-                        <!-- <el-input type="textarea" v-model="addForm.taskDesc" :rows="3"></el-input> -->
-                        <!-- <quill-edito v-model="addForm.taskDesc"></quill-edito> -->
-                        <quill-editor style="height: 150px" ref="text" v-model="addForm.taskDesc" class="myQuillEditor" :options="editorOption" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)"/>
-                    </el-form-item>
-                    <!-- 富文本 -->
-                    <div v-if="addForm.id != null">
-                        <el-divider ></el-divider>
-                        <!-- 任务进展 -->
-                        <p ><i class="iconfont firerock-icontree" style="color:#20A0ff;margin-left:10px;">{{ $t('taskprogress') }}</i>
-                            <span ref="addPro" style="display: block; float:right;"><el-link @click="addprogress">{{ $t('addtaskprogress') }}</el-link></span>
-                        </p>
-                        <!-- 任务进展展示 -->
-                        <div style="display: none;" ref="proBox" class="progress">
-                            <!-- <el-form :model="> -->
-                            <el-radio-group v-model="radio">
-                                <el-radio :label="0" class="rala1">{{ $t('normals') }}</el-radio>
-                                <el-radio :label="1" class="rala2">{{ $t('atrisk') }}</el-radio>
-                                <el-radio :label="2" class="rala3">{{ $t('withinthetimelimit') }}</el-radio>
-                            </el-radio-group>
+                            <el-select v-if="user.userNameNeedTranslate != '1'" v-model="executorItem.executorId" :disabled="(addForm.id != null && user.id != addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement" size="small" filterable clearable :placeholder="$t('pleaseselectanexecutor')" style="width:40%;" @change="$forceUpdate()">
+                                <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id">
+                                    <span style="float: left">{{ item.name }}</span>
+                                    <span style="float: right; color: #8492a6; font-size: 13px;margin-left: 20px" v-if="item.jobNumber">{{ item.jobNumber }}</span>
+                                </el-option>
+                            </el-select>
+                            
+                            <selectCat :subject="users" :subjectId="executorItem.executorId" :filterable="true" :index="index" @selectCal="selectCal" :size="'mini'" v-if="user.userNameNeedTranslate == '1'"></selectCat>
 
-                            <el-input
-                            type="textarea"
-                            border="0"
-                            :autosize="{ minRows: 2, maxRows: 6}"
-                            :placeholder="$t('detailedprogressdescription')"
-                            v-model="text2"
-                            style="margin:10px 0 0 0">
-                            </el-input>
+                            <span style="margin-left:30px;margin-right:10px;">{{ $t('plantime') }}</span>
+                            <el-input-number size="small" :disabled="(addForm.id != null && user.id != addForm.createrId && currentProject.inchargerId != user.id) && !permissions.projectManagement" v-model="executorItem.planHours" style="width:30%;" :min="1" :max="100"  :placeholder="$t('pleaseentertheplannedworking')" ></el-input-number ><span style="margin-left:10px;">{{ $t('time.hour') }}</span>
+                            <!--移除执行人 -->
+                            <i class="el-icon-delete" v-if="index>0 && (addForm.id == null|| user.id == addForm.createrId || currentProject.inchargerId == user.id|| permissions.projectManagement)" style="margin-left:5px" @click="removeExecutorLine(index)"></i>
+                        </el-form-item>
+                        <el-link type="primary" v-if="(addForm.executorListFront == null || addForm.executorListFront.length<10)&& (addForm.id == null|| user.id == addForm.createrId || currentProject.inchargerId == user.id || permissions.projectManagement)" style="margin-left:35px;" @click="addExecutorLine">{{ $t('addinganexecutor') }}</el-link>
+                        </div>
+                        
+                        <el-form-item :label="$t('priority')">
+                            <el-select v-model="addForm.taskLevel" style="width:100%;" >
+                                <el-option v-for="item in importanceList" :key="item.id" :label="item.name" :value="item.id"></el-option>
+                            </el-select>
+                        </el-form-item>
+                        <!-- 富文本 -->
+                        <el-form-item :label="$t('detaileddescription')" style="height: 200px">
+                            <!-- <Editor id="tinymce" v-model="tinymceHtml" :init="editorInit"></Editor> -->
+                            <!-- <el-input type="textarea" v-model="addForm.taskDesc" :rows="3"></el-input> -->
+                            <!-- <quill-edito v-model="addForm.taskDesc"></quill-edito> -->
+                            <quill-editor style="height: 150px" ref="text" v-model="addForm.taskDesc" class="myQuillEditor" :options="editorOption" @blur="onEditorBlur($event)" @focus="onEditorFocus($event)"/>
+                        </el-form-item>
+                        <!-- 富文本 -->
+                        <div v-if="addForm.id != null">
+                            <el-divider ></el-divider>
+                            <!-- 任务进展 -->
+                            <p ><i class="iconfont firerock-icontree" style="color:#20A0ff;margin-left:10px;">{{ $t('taskprogress') }}</i>
+                                <span ref="addPro" style="display: block; float:right;"><el-link @click="addprogress">{{ $t('addtaskprogress') }}</el-link></span>
+                            </p>
+                            <!-- 任务进展展示 -->
+                            <div style="display: none;" ref="proBox" class="progress">
+                                <!-- <el-form :model="> -->
+                                <el-radio-group v-model="radio">
+                                    <el-radio :label="0" class="rala1">{{ $t('normals') }}</el-radio>
+                                    <el-radio :label="1" class="rala2">{{ $t('atrisk') }}</el-radio>
+                                    <el-radio :label="2" class="rala3">{{ $t('withinthetimelimit') }}</el-radio>
+                                </el-radio-group>
 
-                            <h4 style="font-weight: normal;">{{ $t('whotoremindtocheck') +':'}}{{checkLists.length}}</h4>
+                                <el-input
+                                type="textarea"
+                                border="0"
+                                :autosize="{ minRows: 2, maxRows: 6}"
+                                :placeholder="$t('detailedprogressdescription')"
+                                v-model="text2"
+                                style="margin:10px 0 0 0">
+                                </el-input>
 
-                            <i class="el-icon-circle-plus pron_i" style="font-size: 28px;color: #409EFF;" @click="addI(0)"></i>
+                                <h4 style="font-weight: normal;">{{ $t('whotoremindtocheck') +':'}}{{checkLists.length}}</h4>
 
-                            <div class="remind" ref="addRem" style="display: none">
-                                <el-checkbox-group v-model="checkboxGrounp" v-for="item in users" :key="item.id">
-                                    <p>
-                                        <el-checkbox :label="item.name" @change="kkk(item)">
-                                            <span>
-                                                <span v-if="user.userNameNeedTranslate != '1'">
-                                                    {{item.name}}
-                                                </span>
-                                                <span v-if="user.userNameNeedTranslate == '1'">
-                                                    <ww-open-data type='userName' :openid='item.name'></ww-open-data>
+                                <i class="el-icon-circle-plus pron_i" style="font-size: 28px;color: #409EFF;" @click="addI(0)"></i>
+
+                                <div class="remind" ref="addRem" style="display: none">
+                                    <el-checkbox-group v-model="checkboxGrounp" v-for="item in users" :key="item.id">
+                                        <p>
+                                            <el-checkbox :label="item.name" @change="kkk(item)">
+                                                <span>
+                                                    <span v-if="user.userNameNeedTranslate != '1'">
+                                                        {{item.name}}
+                                                    </span>
+                                                    <span v-if="user.userNameNeedTranslate == '1'">
+                                                        <ww-open-data type='userName' :openid='item.name'></ww-open-data>
+                                                    </span>
                                                 </span>
-                                            </span>
-                                        </el-checkbox>
-                                    </p>
-                                </el-checkbox-group>
-                            </div>
-                            <div class="ssp" @click="sss"></div>
-                            <!-- </el-form> -->
-                            <div class="pro_btn">
-                                <el-button size="mini" @click="shutPro">{{ $t('btn.cancel') }}</el-button>
-                                <el-button size="mini" type="primary" @click="addTaskProgress">{{ $t('fa-bu') }}</el-button>
-                            </div>
+                                            </el-checkbox>
+                                        </p>
+                                    </el-checkbox-group>
+                                </div>
+                                <div class="ssp" @click="sss"></div>
+                                <!-- </el-form> -->
+                                <div class="pro_btn">
+                                    <el-button size="mini" @click="shutPro">{{ $t('btn.cancel') }}</el-button>
+                                    <el-button size="mini" type="primary" @click="addTaskProgress">{{ $t('fa-bu') }}</el-button>
+                                </div>
 
-                        </div>
+                            </div>
 
-                        <div class="ddl" v-if="recentProgressInfo != null && recentProgressInfo.id != null">
-                            <div class="elCard" style="margin-bottom: 10px; height:" >
-                                <i class="el-icon-success" style="color: #43d14f;" v-if="recentProgressInfo.status == 0"></i>
-                                <i class="el-icon-success" style="color: #fd7624;" v-else-if="recentProgressInfo.status == 1"></i>
-                                <i class="el-icon-success" style="color: #fd4d47;" v-else></i>
-                                <span v-if="recentProgressInfo.status == 0">{{ $t('normals') }}</span>
-                                <span v-else-if="recentProgressInfo.status == 1">{{ $t('normals') }}</span>
-                                <span v-else>{{ $t('withinthetimelimit') }}</span>
+                            <div class="ddl" v-if="recentProgressInfo != null && recentProgressInfo.id != null">
+                                <div class="elCard" style="margin-bottom: 10px; height:" >
+                                    <i class="el-icon-success" style="color: #43d14f;" v-if="recentProgressInfo.status == 0"></i>
+                                    <i class="el-icon-success" style="color: #fd7624;" v-else-if="recentProgressInfo.status == 1"></i>
+                                    <i class="el-icon-success" style="color: #fd4d47;" v-else></i>
+                                    <span v-if="recentProgressInfo.status == 0">{{ $t('normals') }}</span>
+                                    <span v-else-if="recentProgressInfo.status == 1">{{ $t('normals') }}</span>
+                                    <span v-else>{{ $t('withinthetimelimit') }}</span>
 
-                                <el-dropdown trigger="click" style="float:right;cursor:pointer; float: right;">
-                                        <i class="el-icon-more" ></i>
-                                        <el-dropdown-menu slot="dropdown">
+                                    <el-dropdown trigger="click" style="float:right;cursor:pointer; float: right;">
+                                            <i class="el-icon-more" ></i>
+                                            <el-dropdown-menu slot="dropdown">
 
-                                            <el-dropdown-item divided>
-                                                <span @click="deleteTaskProgress(recentProgressInfo.id)"><i class="el-icon-delete"></i>{{ $t('deleteList ') }}</span></el-dropdown-item>
-                                        </el-dropdown-menu>
-                                </el-dropdown>
-                                <div class="elCard_qu">
-                                    <span>
-                                        <span v-if="user.userNameNeedTranslate != '1'">
-                                            {{recentProgressInfo.creatorName}}
-                                        </span>
-                                        <span v-if="user.userNameNeedTranslate == '1'">
-                                            <ww-open-data type='userName' :openid='recentProgressInfo.creatorName'></ww-open-data>
+                                                <el-dropdown-item divided>
+                                                    <span @click="deleteTaskProgress(recentProgressInfo.id)"><i class="el-icon-delete"></i>{{ $t('deleteList ') }}</span></el-dropdown-item>
+                                            </el-dropdown-menu>
+                                    </el-dropdown>
+                                    <div class="elCard_qu">
+                                        <span>
+                                            <span v-if="user.userNameNeedTranslate != '1'">
+                                                {{recentProgressInfo.creatorName}}
+                                            </span>
+                                            <span v-if="user.userNameNeedTranslate == '1'">
+                                                <ww-open-data type='userName' :openid='recentProgressInfo.creatorName'></ww-open-data>
+                                            </span>
                                         </span>
-                                    </span>
-                                    {{ $t('geng-xin-yu') }}{{recentProgressInfo.indate | relativeTime}}
+                                        {{ $t('geng-xin-yu') }}{{recentProgressInfo.indate | relativeTime}}
+                                    </div>
+                                    <p style="padding-left: 20px;">{{recentProgressInfo.content}}</p>
+                                    <div class="examine"><el-button type="text" @click="innerVisibless = true" style="color: #8F87A3;">{{ $t('viewingHistory') }}</el-button></div>
                                 </div>
-                                <p style="padding-left: 20px;">{{recentProgressInfo.content}}</p>
-                                <div class="examine"><el-button type="text" @click="innerVisibless = true" style="color: #8F87A3;">{{ $t('viewingHistory') }}</el-button></div>
                             </div>
-                        </div>
 
-                        <!-- 任务列表没有数据的时候展示 -->
-                        <div class="nones" v-if="ProgressList.length <= 0">
-                            {{ $t('nodata') }} 
-                        </div>
+                            <!-- 任务列表没有数据的时候展示 -->
+                            <div class="nones" v-if="ProgressList.length <= 0">
+                                {{ $t('nodata') }} 
+                            </div>
 
-                        <!-- 任务进展完整状态 -->
-                        <el-dialog :title="$t('other.prompts')" :visible.sync="innerVisibless" append-to-body width="500px">
-                        <div class="integrity">
-                            <h3 style="font-weight: normal;display: inline-block;margin: 0 0 20px 0;">{{ $t('taskprogress') }}:{{ProgressList.length}}</h3>
-                            <!-- <span class="write"><i class="el-icon-circle-plus"></i>填写进展</span> -->
-                            <el-divider></el-divider>
+                            <!-- 任务进展完整状态 -->
+                            <el-dialog :title="$t('other.prompts')" :visible.sync="innerVisibless" append-to-body width="500px">
+                            <div class="integrity">
+                                <h3 style="font-weight: normal;display: inline-block;margin: 0 0 20px 0;">{{ $t('taskprogress') }}:{{ProgressList.length}}</h3>
+                                <!-- <span class="write"><i class="el-icon-circle-plus"></i>填写进展</span> -->
+                                <el-divider></el-divider>
 
-                            <!--  -->
-                                <div class="block" style="height: 200px;">
-                                    <el-timeline style="padding:20px 0 0 0;">
-                                        <el-timeline-item
-                                        v-for="(activity, index) in ProgressList"
-                                        :key="index">
-                                        <div class="tb">
-                                            <span v-if="activity.status == 0" style="color: #43D14F" class="icon"></span>
-                                            <span v-if="activity.status == 1" style="color: #FD7624" class="icon"></span>
-                                            <span v-if="activity.status == 2" style="color: red" class="icon"></span>
-                                            <div>
-                                                <span v-if="activity.status == 0" style="color: #43D14F">{{ $t('normals') }}</span>
-                                                <span v-if="activity.status == 1" style="color: #FD7624">{{ $t('atrisk') }}</span>
-                                                <span v-if="activity.status == 2" style="color: red">{{ $t('withinthetimelimit') }}</span>
-                                                <span style="display: inline-block; float: right; color: #8C8C8C">{{activity.indate | relativeTime}}</span>
+                                <!--  -->
+                                    <div class="block" style="height: 200px;">
+                                        <el-timeline style="padding:20px 0 0 0;">
+                                            <el-timeline-item
+                                            v-for="(activity, index) in ProgressList"
+                                            :key="index">
+                                            <div class="tb">
+                                                <span v-if="activity.status == 0" style="color: #43D14F" class="icon"></span>
+                                                <span v-if="activity.status == 1" style="color: #FD7624" class="icon"></span>
+                                                <span v-if="activity.status == 2" style="color: red" class="icon"></span>
+                                                <div>
+                                                    <span v-if="activity.status == 0" style="color: #43D14F">{{ $t('normals') }}</span>
+                                                    <span v-if="activity.status == 1" style="color: #FD7624">{{ $t('atrisk') }}</span>
+                                                    <span v-if="activity.status == 2" style="color: red">{{ $t('withinthetimelimit') }}</span>
+                                                    <span style="display: inline-block; float: right; color: #8C8C8C">{{activity.indate | relativeTime}}</span>
+                                                </div>
+                                                <p style="color: #8C8C8C">{{activity.content}}</p>
+                                                
                                             </div>
-                                            <p style="color: #8C8C8C">{{activity.content}}</p>
-                                            
-                                        </div>
-                                        </el-timeline-item>
-                                    </el-timeline>
-                                </div>
-                            <!--  -->
-                        </div>
-                        <span slot="footer" class="dialog-footer">
-                            <el-button type="primary" @click="innerVisibless = false">{{ $t('Shutdown') }}</el-button>
-                        </span>
-                        </el-dialog>
-                        </div>
-                </el-form>
-            </div>
-            <div slot="footer" class="dialog-footer">
-                <el-button v-if="user.id == addForm.createrId || currentProject.inchargerId == user.id || currentProject.creatorId == user.id || permissions.projectManagement" @click.native="deleteTask" style="float:left;">{{ $t('btn.delete') }}</el-button>
-                <el-button @click.native="addFormVisible = false">{{ $t('btn.cancel') }}</el-button>
-                <el-button type="primary" @click="submitInsert" :loading="addLoading">{{ $t('btn.submit') }}</el-button>
-            </div>
-            <div slot="title" v-if="addForm.parentTid != null" >
-                <!-- <el-link @click="backToParentTask"><i class="el-icon-arrow-left single_line">返回父级任务</i> | {{addForm.parentTname}}</el-link> -->
-                <el-page-header  @back="backToParentTask" :title="$t('parenttask')" :content="addForm.parentTname"></el-page-header>
-            </div>
-            <!-- 评论 -->
-            <div class="remark" v-show="addForm.id != null">
-                <span class="zh">
-                    <!-- <span  v-for="(pl, i) in critic" :key="i"> -->
-                        <!-- <div class="player" v-if="pl"> -->
-                        <div class="player">
-                            <p @click="chan">{{ $t('participantin') }}</p>
-                            <span  v-for="(pl, i) in critic" :key="i">
-                            <div class="bj" style="width: 14%;overflow: hidden;">
-                                <span style="background: #778899" v-if="user.userNameNeedTranslate != '1'">{{pl.length > 2 ? pl.substring(pl.length - 2, pl.length) : pl}}</span>
-                                <span style="background: #778899" v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName' :openid='pl'></ww-open-data></span>
+                                            </el-timeline-item>
+                                        </el-timeline>
+                                    </div>
+                                <!--  -->
                             </div>
+                            <span slot="footer" class="dialog-footer">
+                                <el-button type="primary" @click="innerVisibless = false">{{ $t('Shutdown') }}</el-button>
                             </span>
-                        </div>
-                    <!-- </span> -->
-                    <div class="subject">
-                        <div class="sub-all">
-                            <div :class="dynamicTab ? 'subOn' : ''" @click="dynamicTab = true">{{ $t('alldynamic') }}</div>
-                            <div :class="dynamicTab ? '' : 'subOn'" @click="dynamicTab = false">{{ $t('xiang-guan-ri-bao') }}</div>
-                        </div>
-                        <div class="sub-details" ref="main" v-if="dynamicTab">
-                            <ul class="infinite-list" v-infinite-scroll="load" ref="contRoll">
-                                <div style="width: 100%" v-if="commentList.length <= 0">
-                                    <img src="../../assets/image/xiao.png" alt="">
+                            </el-dialog>
+                            </div>
+                    </el-form>
+                </div>
+                <div slot="footer" class="dialog-footer">
+                    <el-button v-if="user.id == addForm.createrId || currentProject.inchargerId == user.id || currentProject.creatorId == user.id || permissions.projectManagement" @click.native="deleteTask" style="float:left;">{{ $t('btn.delete') }}</el-button>
+                    <el-button @click.native="addFormVisible = false">{{ $t('btn.cancel') }}</el-button>
+                    <el-button type="primary" @click="submitInsert" :loading="addLoading">{{ $t('btn.submit') }}</el-button>
+                </div>
+                <div slot="title" v-if="addForm.parentTid != null" >
+                    <!-- <el-link @click="backToParentTask"><i class="el-icon-arrow-left single_line">返回父级任务</i> | {{addForm.parentTname}}</el-link> -->
+                    <el-page-header  @back="backToParentTask" :title="$t('parenttask')" :content="addForm.parentTname"></el-page-header>
+                </div>
+                <!-- 评论 -->
+                <div class="remark" v-show="addForm.id != null">
+                    <span class="zh">
+                        <!-- <span  v-for="(pl, i) in critic" :key="i"> -->
+                            <!-- <div class="player" v-if="pl"> -->
+                            <div class="player">
+                                <p @click="chan">{{ $t('participantin') }}</p>
+                                <span  v-for="(pl, i) in critic" :key="i">
+                                <div class="bj" style="width: 14%;overflow: hidden;">
+                                    <span style="background: #778899" v-if="user.userNameNeedTranslate != '1'">{{pl.length > 2 ? pl.substring(pl.length - 2, pl.length) : pl}}</span>
+                                    <span style="background: #778899" v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName' :openid='pl'></ww-open-data></span>
                                 </div>
-                                <li v-for="i in count" class="infinite-list-item counli" :key="i">
-                                    <p><i class="el-icon-s-fold"></i> <em>{{ $t('managerQucompletedthedependencytask') }}</em><span>{{ $t('onApril20') }}</span></p>
-                                </li>
-                                <li class="carts" v-for="item in commentList" :key="item.id">
-                                    <!-- <el-image style="width: 30px; height: 30px" :src="url" :fit="fit"></el-image> -->
-                                    <!-- <i :style="'background' + item.userColor"> -->
-                                    <i :style="'background' + item.userColor">
-                                        <i v-if="user.userNameNeedTranslate != '1'">
-                                            {{item.userName.length > 2 ? item.userName.substring(item.userName.length - 2, item.userName.length) : item.userName}}
-                                        </i>
-                                        <i v-if="user.userNameNeedTranslate == '1'">
-                                            <ww-open-data type='userName' :openid='item.userName'></ww-open-data>
-                                        </i>
-                                    </i>
-                                    <div>
-                                        <!-- <p>{{item.userName}}</p> -->
-                                        <p v-if="user.userNameNeedTranslate != '1'">{{item.userName}}</p>
-                                        <p v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName' :openid='item.userName'></ww-open-data></p>
-                                        <em>
-                                            <!-- {{item.content}} -->
-                                            <p style="display: inline-block;padding: 0;margin: 0;" v-if="user.userNameNeedTranslate == 1">
-                                                {{item.content.msg1}}
-                                                <ww-open-data type='userName' :openid='item.content.msg2'></ww-open-data>
-                                                {{item.content.msg3}}
-                                            </p>
-                                            <p style="display: inline-block;padding: 0;margin: 0;" v-if="user.userNameNeedTranslate != 1">{{item.content}}</p>
-                                        </em>
+                                </span>
+                            </div>
+                        <!-- </span> -->
+                        <div class="subject">
+                            <div class="sub-all">
+                                <div :class="dynamicTab ? 'subOn' : ''" @click="dynamicTab = true">{{ $t('alldynamic') }}</div>
+                                <div :class="dynamicTab ? '' : 'subOn'" @click="dynamicTab = false">{{ $t('xiang-guan-ri-bao') }}</div>
+                            </div>
+                            <div class="sub-details" ref="main" v-if="dynamicTab">
+                                <ul class="infinite-list" v-infinite-scroll="load" ref="contRoll">
+                                    <div style="width: 100%" v-if="commentList.length <= 0">
+                                        <img src="../../assets/image/xiao.png" alt="">
                                     </div>
-                                    <span>{{item.createTime | relativeTime}}</span>
-                                </li>
-                            </ul>
-                        </div>
+                                    <li v-for="i in count" class="infinite-list-item counli" :key="i">
+                                        <p><i class="el-icon-s-fold"></i> <em>{{ $t('managerQucompletedthedependencytask') }}</em><span>{{ $t('onApril20') }}</span></p>
+                                    </li>
+                                    <li class="carts" v-for="item in commentList" :key="item.id">
+                                        <!-- <el-image style="width: 30px; height: 30px" :src="url" :fit="fit"></el-image> -->
+                                        <!-- <i :style="'background' + item.userColor"> -->
+                                        <i :style="'background' + item.userColor">
+                                            <i v-if="user.userNameNeedTranslate != '1'">
+                                                {{item.userName.length > 2 ? item.userName.substring(item.userName.length - 2, item.userName.length) : item.userName}}
+                                            </i>
+                                            <i v-if="user.userNameNeedTranslate == '1'">
+                                                <ww-open-data type='userName' :openid='item.userName'></ww-open-data>
+                                            </i>
+                                        </i>
+                                        <div>
+                                            <!-- <p>{{item.userName}}</p> -->
+                                            <p v-if="user.userNameNeedTranslate != '1'">{{item.userName}}</p>
+                                            <p v-if="user.userNameNeedTranslate == '1'"><ww-open-data type='userName' :openid='item.userName'></ww-open-data></p>
+                                            <em>
+                                                <!-- {{item.content}} -->
+                                                <p style="display: inline-block;padding: 0;margin: 0;" v-if="user.userNameNeedTranslate == 1">
+                                                    {{item.content.msg1}}
+                                                    <ww-open-data type='userName' :openid='item.content.msg2'></ww-open-data>
+                                                    {{item.content.msg3}}
+                                                </p>
+                                                <p style="display: inline-block;padding: 0;margin: 0;" v-if="user.userNameNeedTranslate != 1">{{item.content}}</p>
+                                            </em>
+                                        </div>
+                                        <span>{{item.createTime | relativeTime}}</span>
+                                    </li>
+                                </ul>
+                            </div>
 
-                        <div class="Daily" v-if="!dynamicTab">
-                            <div class="one_daily_body DailyBody">
-                                <el-card shadow="never" v-for="(item2,index2) in dailyList" :key="index2" style="margin-bottom: 20px;">
-                                    <p>
-                                        {{ $t('tian-bao-ren') }}: <span v-if="user.userNameNeedTranslate != 1">{{item2.userName}}</span>
-                                        <span v-if="user.userNameNeedTranslate == 1">
-                                            <ww-open-data type='userName' :openid='item2.userName'></ww-open-data>
-                                        </span>
-                                        <span style="float: right;">{{item2.createDate}}</span>
-                                    </p>
-                                    <p>{{ $t('other.approvalStatus') }}:
-                                        <span v-if="user.company.packageEngineering == 0">
-                                            <span style="margin-left:15px;color:#DAA520;"  v-if="item2.state == 0">
-                                                <span v-if="item2.isDeptAudit==0">
-                                                    <span v-if="item2.projectAuditState==0">
-                                                        <!-- 待项目审核人 --> {{$t('other.waitForTheProjectReviewer')}}
-                                                        <span v-if="item2.projectAuditorName != null">(
-                                                            <span v-if="user.userNameNeedTranslate == '1'">
-                                                                <ww-open-data type='userName' :openid='item2.projectAuditorName'></ww-open-data>
-                                                            </span>
-                                                            <span v-if="user.userNameNeedTranslate != '1'">{{item2.projectAuditorName}}</span>
-                                                            )</span> 
-                                                        <!-- 审核 --> {{$t('other.audit')}}
-                                                    </span>
-                                                    <span style="color:#32CD32;" v-else-if="item2.projectAuditState==1">
-                                                        <!-- 项目审核人 --> {{$t('other.projectAuditor')}}
-                                                        <span v-if="item2.projectAuditorName != null">(
-                                                            <!-- {{item2.projectAuditorName}} -->
-                                                            <span v-if="user.userNameNeedTranslate == '1'">
-                                                                <ww-open-data type='userName' :openid='item2.projectAuditorName'></ww-open-data>
-                                                            </span>
-                                                            <span v-if="user.userNameNeedTranslate != '1'">{{item2.projectAuditorName}}</span>
-                                                            )</span>
-                                                        <!-- 审核通过 --> {{$t('state.approved')}}
+                            <div class="Daily" v-if="!dynamicTab">
+                                <div class="one_daily_body DailyBody">
+                                    <el-card shadow="never" v-for="(item2,index2) in dailyList" :key="index2" style="margin-bottom: 20px;">
+                                        <p>
+                                            {{ $t('tian-bao-ren') }}: <span v-if="user.userNameNeedTranslate != 1">{{item2.userName}}</span>
+                                            <span v-if="user.userNameNeedTranslate == 1">
+                                                <ww-open-data type='userName' :openid='item2.userName'></ww-open-data>
+                                            </span>
+                                            <span style="float: right;">{{item2.createDate}}</span>
+                                        </p>
+                                        <p>{{ $t('other.approvalStatus') }}:
+                                            <span v-if="user.company.packageEngineering == 0">
+                                                <span style="margin-left:15px;color:#DAA520;"  v-if="item2.state == 0">
+                                                    <span v-if="item2.isDeptAudit==0">
+                                                        <span v-if="item2.projectAuditState==0">
+                                                            <!-- 待项目审核人 --> {{$t('other.waitForTheProjectReviewer')}}
+                                                            <span v-if="item2.projectAuditorName != null">(
+                                                                <span v-if="user.userNameNeedTranslate == '1'">
+                                                                    <ww-open-data type='userName' :openid='item2.projectAuditorName'></ww-open-data>
+                                                                </span>
+                                                                <span v-if="user.userNameNeedTranslate != '1'">{{item2.projectAuditorName}}</span>
+                                                                )</span> 
+                                                            <!-- 审核 --> {{$t('other.audit')}}
+                                                        </span>
+                                                        <span style="color:#32CD32;" v-else-if="item2.projectAuditState==1">
+                                                            <!-- 项目审核人 --> {{$t('other.projectAuditor')}}
+                                                            <span v-if="item2.projectAuditorName != null">(
+                                                                <!-- {{item2.projectAuditorName}} -->
+                                                                <span v-if="user.userNameNeedTranslate == '1'">
+                                                                    <ww-open-data type='userName' :openid='item2.projectAuditorName'></ww-open-data>
+                                                                </span>
+                                                                <span v-if="user.userNameNeedTranslate != '1'">{{item2.projectAuditorName}}</span>
+                                                                )</span>
+                                                            <!-- 审核通过 --> {{$t('state.approved')}}
+                                                        </span>
                                                     </span>
-                                                </span>
-                                                <span v-else-if="item2.isDeptAudit==1">
-                                                    ({{$t('other.await')}}
-                                                    <span v-if="user.userNameNeedTranslate == '1'">
-                                                        <ww-open-data type='departmentName' :openid='item2.auditDeptName'></ww-open-data>
+                                                    <span v-else-if="item2.isDeptAudit==1">
+                                                        ({{$t('other.await')}}
+                                                        <span v-if="user.userNameNeedTranslate == '1'">
+                                                            <ww-open-data type='departmentName' :openid='item2.auditDeptName'></ww-open-data>
+                                                        </span>
+                                                        <span v-if="user.userNameNeedTranslate != '1'">{{item2.auditDeptName}}</span>
+                                                        {{$t('other.audit')}})
                                                     </span>
-                                                    <span v-if="user.userNameNeedTranslate != '1'">{{item2.auditDeptName}}</span>
-                                                    {{$t('other.audit')}})
+                                                    </span> 
+                                                <span style="margin-left:15px;color:#DAA520;" v-else-if="item2.state == -1">{{$t('other.importWaitingForReview')}}</span>
+                                                <span style="margin-left:15px;color:#32CD32;" v-else-if="item2.state == 1">{{$t('state.alreadyPassed')}}
+                                                    <span style="color:#c7e944" v-if="item2.reportAutoApprove == 1">{{$t('other.automaticReview')}}</span>
                                                 </span>
-                                                </span> 
-                                            <span style="margin-left:15px;color:#DAA520;" v-else-if="item2.state == -1">{{$t('other.importWaitingForReview')}}</span>
-                                            <span style="margin-left:15px;color:#32CD32;" v-else-if="item2.state == 1">{{$t('state.alreadyPassed')}}
-                                                <span style="color:#c7e944" v-if="item2.reportAutoApprove == 1">{{$t('other.automaticReview')}}</span>
+                                                
+                                                <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 2">{{$t('state.rejected')}} {{$t('other.reason')}}:{{item2.rejectReason}}</span>
+                                                <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 3">{{$t('state.waitingsubmit')}}</span>
                                             </span>
-                                            
-                                            <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 2">{{$t('state.rejected')}} {{$t('other.reason')}}:{{item2.rejectReason}}</span>
-                                            <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 3">{{$t('state.waitingsubmit')}}</span>
-                                        </span>
-                                        <span v-if="user.company.packageEngineering == 1">
-                                            <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == -1">{{$t('other.importWaitingForReview')}}</span>
-                                            <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == 0 && item2.departmentAuditState == -1">{{$t('other.waitingForProfessionalReview')}}</span>
-                                            <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == 0 && item2.departmentAuditState == 0">{{$t('other.waitingForDepartmentReview')}}</span>
-                                            <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == 0 && item2.departmentAuditState == 1">{{$t('other.waitForTheProjectReviewer')}}<span v-if="item2.projectAuditorName != null">
-                                                (
-                                                    <span v-if="user.userNameNeedTranslate != 1">
-                                                        {{item2.projectAuditorName}}
-                                                    </span>
-                                                    <span v-if="user.userNameNeedTranslate == 1">
-                                                        <ww-open-data type='userName' :openid='item2.projectAuditorName'></ww-open-data>
-                                                    </span>
-                                                )
-                                            </span>{{$t('other.audit')}}</span>
-                                            <span style="margin-left:15px;color:#32CD32;" v-else-if="item2.state == 1">{{$t('state.alreadyPassed')}}</span>
-                                            <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 2">{{$t('state.rejected')}} {{$t('other.reason')}}:{{item2.rejectReason}}</span>
-                                            <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 3">{{$t('state.waitingsubmit')}}</span>
-                                        </span>
-                                    </p>
-                                    <p v-if="user.timeType.customDegreeActive==1 && item2.degree_id != null && item2.degree_id != -1">{{user.timeType.customDegreeName}}:{{item2.degreeName}}</p>
-                                    <p v-if="user.timeType.customDataActive==1">{{user.timeType.customDataName}}:{{item2.customData}}</p>
-                                    <!-- 自定义日报文本 -->
-                                    <p v-if="user.timeType.customTextActive==1">{{user.timeType.customTextName}}:{{item2.customText}}</p>
-                                    <p v-if="user.company.packageEngineering == 1">
-                                        {{$t('other.professionalProgress')}}:
-                                        <span style="margin-right:10px;" v-for="progressItem in item2.professionProgress" :key="progressItem.id">{{progressItem.professionName}}({{progressItem.progress}}%) 
-                                            <el-tooltip v-if="progressItem.auditState == 0"  :content="$t('state.WaitingAudit')" effect="light" placement="top">
-                                            <i class="iconfont firerock-icondaibandengdaishenhe"></i>
-                                            </el-tooltip>
-                                            <el-tooltip v-if="progressItem.auditState == 1" :content="$t('state.alreadyPassed')" effect="light" placement="top">
-                                            <i  class="iconfont firerock-iconshenhetongguo"></i>
-                                            </el-tooltip>
-                                            <el-tooltip v-if="progressItem.auditState == 2" :content="$t('state.notThrough')" effect="light" placement="top">
-                                            <i  class="iconfont firerock-iconshenhebohui"></i>
-                                            </el-tooltip>
+                                            <span v-if="user.company.packageEngineering == 1">
+                                                <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == -1">{{$t('other.importWaitingForReview')}}</span>
+                                                <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == 0 && item2.departmentAuditState == -1">{{$t('other.waitingForProfessionalReview')}}</span>
+                                                <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == 0 && item2.departmentAuditState == 0">{{$t('other.waitingForDepartmentReview')}}</span>
+                                                <span style="margin-left:15px;color:#DAA520;" v-if="item2.state == 0 && item2.departmentAuditState == 1">{{$t('other.waitForTheProjectReviewer')}}<span v-if="item2.projectAuditorName != null">
+                                                    (
+                                                        <span v-if="user.userNameNeedTranslate != 1">
+                                                            {{item2.projectAuditorName}}
+                                                        </span>
+                                                        <span v-if="user.userNameNeedTranslate == 1">
+                                                            <ww-open-data type='userName' :openid='item2.projectAuditorName'></ww-open-data>
+                                                        </span>
+                                                    )
+                                                </span>{{$t('other.audit')}}</span>
+                                                <span style="margin-left:15px;color:#32CD32;" v-else-if="item2.state == 1">{{$t('state.alreadyPassed')}}</span>
+                                                <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 2">{{$t('state.rejected')}} {{$t('other.reason')}}:{{item2.rejectReason}}</span>
+                                                <span style="margin-left:15px;color:#FF0000;" v-else-if="item2.state == 3">{{$t('state.waitingsubmit')}}</span>
                                             </span>
-                                    </p>
-                                    <div v-if="item2.multiWorktime==0">
-                                    <p style="display: inline-block;">{{$t('time.duration')}}:
-                                        <span v-if="item2.reportTimeType == 0" style="margin-right:10px;">{{typeList[item2.timeType]}}</span>
-                                        <span v-if="item2.reportTimeType == 2" style="margin-right:10px;">{{item2.startTime+'-'+item2.endTime}}</span>
-                                    {{item2.time.toFixed(1)}}h  
-                                    <el-tag type="danger" size="mini" style="margin-left: 65px" v-if="item2.isOvertime === 1">{{$t('other.WorkOvertime')}}<span v-if="item2.overtimeHours">{{item2.overtimeHours.toFixed(1)}}h</span></el-tag>
-                                    </p>
-                                    <p>{{$t('other.matters')}}:<span v-html="item2.content"></span></p>
-                                    </div>
-                                    <div v-if="item2.multiWorktime==1" >
-                                        <p>{{$t('other.projectDuration')}}:{{item2.time.toFixed(1)}}h  <el-tag type="danger" size="mini" style="margin-left: 65px" v-if="item2.isOvertime === 1">{{ $t('other.WorkOvertime') }}<span v-if="item2.overtimeHours">{{item2.overtimeHours.toFixed(1)}}h</span></el-tag></p>
-                                        <div v-for="(timeItem, tIndex) in item2.worktimeList" :key="tIndex"
-                                            style="border: 0.5px #ddd solid;margin-bottom:5px;padding:5px;">
-                                            <p style="display: inline-block;">{{$t('time.duration')}}:
-                                                <span v-if="item2.reportTimeType == 2" style="margin-right:10px;">{{timeItem.startTime+'-'+timeItem.endTime}}</span>
-                                            {{timeItem.time.toFixed(1)}}h  
-                                            </p>
-                                            <p>{{$t('other.matters')}}:<span v-html="timeItem.content"></span></p>
+                                        </p>
+                                        <p v-if="user.timeType.customDegreeActive==1 && item2.degree_id != null && item2.degree_id != -1">{{user.timeType.customDegreeName}}:{{item2.degreeName}}</p>
+                                        <p v-if="user.timeType.customDataActive==1">{{user.timeType.customDataName}}:{{item2.customData}}</p>
+                                        <!-- 自定义日报文本 -->
+                                        <p v-if="user.timeType.customTextActive==1">{{user.timeType.customTextName}}:{{item2.customText}}</p>
+                                        <p v-if="user.company.packageEngineering == 1">
+                                            {{$t('other.professionalProgress')}}:
+                                            <span style="margin-right:10px;" v-for="progressItem in item2.professionProgress" :key="progressItem.id">{{progressItem.professionName}}({{progressItem.progress}}%) 
+                                                <el-tooltip v-if="progressItem.auditState == 0"  :content="$t('state.WaitingAudit')" effect="light" placement="top">
+                                                <i class="iconfont firerock-icondaibandengdaishenhe"></i>
+                                                </el-tooltip>
+                                                <el-tooltip v-if="progressItem.auditState == 1" :content="$t('state.alreadyPassed')" effect="light" placement="top">
+                                                <i  class="iconfont firerock-iconshenhetongguo"></i>
+                                                </el-tooltip>
+                                                <el-tooltip v-if="progressItem.auditState == 2" :content="$t('state.notThrough')" effect="light" placement="top">
+                                                <i  class="iconfont firerock-iconshenhebohui"></i>
+                                                </el-tooltip>
+                                                </span>
+                                        </p>
+                                        <div v-if="item2.multiWorktime==0">
+                                        <p style="display: inline-block;">{{$t('time.duration')}}:
+                                            <span v-if="item2.reportTimeType == 0" style="margin-right:10px;">{{typeList[item2.timeType]}}</span>
+                                            <span v-if="item2.reportTimeType == 2" style="margin-right:10px;">{{item2.startTime+'-'+item2.endTime}}</span>
+                                        {{item2.time.toFixed(1)}}h  
+                                        <el-tag type="danger" size="mini" style="margin-left: 65px" v-if="item2.isOvertime === 1">{{$t('other.WorkOvertime')}}<span v-if="item2.overtimeHours">{{item2.overtimeHours.toFixed(1)}}h</span></el-tag>
+                                        </p>
+                                        <p>{{$t('other.matters')}}:<span v-html="item2.content"></span></p>
                                         </div>
-                                    </div>
-                                    <p v-if="item2.state == 1 && user.timeType.needEvaluate == 1">{{$t('other.evaluation')}}:<span v-html="item2.evaluate"></span></p>
-                                    
-                                    <!--照片的显示 -->
-                                    <p v-if="item2.pics != null && item2.pics.length > 0"> 
-                                        <el-image v-for="(pic, index) in item2.pics" :key="index"
-                                            style="width: 100px; height: 100px; margin-right:10px;"
-                                            :src="pic" 
-                                            :preview-src-list="item2.pics">
-                                        </el-image>
-                                    </p>
-                                </el-card>
+                                        <div v-if="item2.multiWorktime==1" >
+                                            <p>{{$t('other.projectDuration')}}:{{item2.time.toFixed(1)}}h  <el-tag type="danger" size="mini" style="margin-left: 65px" v-if="item2.isOvertime === 1">{{ $t('other.WorkOvertime') }}<span v-if="item2.overtimeHours">{{item2.overtimeHours.toFixed(1)}}h</span></el-tag></p>
+                                            <div v-for="(timeItem, tIndex) in item2.worktimeList" :key="tIndex"
+                                                style="border: 0.5px #ddd solid;margin-bottom:5px;padding:5px;">
+                                                <p style="display: inline-block;">{{$t('time.duration')}}:
+                                                    <span v-if="item2.reportTimeType == 2" style="margin-right:10px;">{{timeItem.startTime+'-'+timeItem.endTime}}</span>
+                                                {{timeItem.time.toFixed(1)}}h  
+                                                </p>
+                                                <p>{{$t('other.matters')}}:<span v-html="timeItem.content"></span></p>
+                                            </div>
+                                        </div>
+                                        <p v-if="item2.state == 1 && user.timeType.needEvaluate == 1">{{$t('other.evaluation')}}:<span v-html="item2.evaluate"></span></p>
+                                        
+                                        <!--照片的显示 -->
+                                        <p v-if="item2.pics != null && item2.pics.length > 0"> 
+                                            <el-image v-for="(pic, index) in item2.pics" :key="index"
+                                                style="width: 100px; height: 100px; margin-right:10px;"
+                                                :src="pic" 
+                                                :preview-src-list="item2.pics">
+                                            </el-image>
+                                        </p>
+                                    </el-card>
+                                </div>
                             </div>
                         </div>
-                    </div>
-                    <div class="issue" v-if="dynamicTab">
-                        <!-- <el-input type="textarea" class="textareays" label-width="100%" label-height="140px"></el-input> -->
-                        <div class="issue_fixation">
-                            <div class="inputDeep"><el-input
-                            type="textarea"
-                            :placeholder="$t('pleaseentercontent')"
-                            :autosize="{ minRows: 6, maxRows: 6}"
-                            v-model="textarea2"
-                            class="inputDeeps"
-                            >
-                            </el-input></div>
-                            <el-button class="issue-button" type="primary" @click="release()">{{ $t('fa-bu') }}</el-button>
+                        <div class="issue" v-if="dynamicTab">
+                            <!-- <el-input type="textarea" class="textareays" label-width="100%" label-height="140px"></el-input> -->
+                            <div class="issue_fixation">
+                                <div class="inputDeep"><el-input
+                                type="textarea"
+                                :placeholder="$t('pleaseentercontent')"
+                                :autosize="{ minRows: 6, maxRows: 6}"
+                                v-model="textarea2"
+                                class="inputDeeps"
+                                >
+                                </el-input></div>
+                                <el-button class="issue-button" type="primary" @click="release()">{{ $t('fa-bu') }}</el-button>
+                            </div>
                         </div>
-                    </div>
-                </span>
+                    </span>
+                </div>
+                <!-- /评论 -->
             </div>
-            <!-- 评论 -->
         </el-dialog>
 
     </section>
@@ -790,7 +798,9 @@ import { error } from 'dingtalk-jsapi';
     // 引入自定义组件
     import selectCat from "@/components/select.vue"
 
-        // 富文本样式
+    import taskComponent from "@/components/taskComponent.vue"
+
+    // 富文本样式
     import 'quill/dist/quill.core.css'
     import 'quill/dist/quill.snow.css'
     import 'quill/dist/quill.bubble.css'
@@ -809,7 +819,8 @@ import { error } from 'dingtalk-jsapi';
             // Summary,
             // Earning,
             quillEditor, // 富文本
-            selectCat
+            selectCat,
+            taskComponent
         },
         data() {
             return {
@@ -933,10 +944,34 @@ import { error } from 'dingtalk-jsapi';
                 departmentList: [],
                 deptId: [],
                 dynamicTab: true,
-                dailyList: []
+                dailyList: [],
+
+                askComponentFlg: false,
+                integrationTask: {},
+                integrationTaskNingwai: {}
             };
         },
         methods: {
+            closeBounced(obj) {
+                if(!obj.backToParentTaskSub) {
+                    this.addFormVisible = false
+                    this.taskComponentFlg = false
+                    if(obj.addSubTask) {
+                        this.addSubTask()
+                    }
+
+                    if(obj.taskLineClickAbs) {
+                        this.taskLineClick(obj.items)
+                    }
+
+                    if(obj.deleteTask) {
+                        this.getList()
+                    }
+                } else {
+                    this.backToParentTask()
+                }
+            },
+
             // 获取来自日报
             getDailyList(id) {
                 this.http.post('/report/getTaskReportList',{ 
@@ -1396,12 +1431,26 @@ import { error } from 'dingtalk-jsapi';
                 this.addFormVisible = true;
                 // this.addLoading = false;
                 this.title = this.$t('editingtasks');
-                this.getTaskDetail(task.id);
-                this.getTaskProgressList(task.id); // 获取任务进展列表 
-                this.getUsers(); // 获取名单数据
-                this.gain(task); // 获取评论列表
                 this.dynamicTab = true
-                this.getDailyList(task.id) // 获取来自日报
+
+                // 自定义组件
+                this.integrationTask = {
+                    id: task.id,
+                    task: task,
+                    num: 1,
+                    curProjectId: this.curProjectId,
+                    create: false,
+                    integrationTaskNingwai: this.integrationTaskNingwai,
+                    taskVue: true
+                }
+                this.taskComponentFlg = true
+
+                this.getTaskDetail(task.id);
+                // this.getTaskProgressList(task.id); // 获取任务进展列表 
+                // this.getUsers(); // 获取名单数据
+                // this.gain(task); // 获取评论列表
+                // this.getDailyList(task.id) // 获取来自日报
+
                 // this.getStageList()
             }, 
             addExecutorLine() {
@@ -1722,7 +1771,9 @@ import { error } from 'dingtalk-jsapi';
                 this.textContent = true
             },
             backToParentTask() {
+                console.log('我是不是出发了')
                 this.getTaskDetail(this.addForm.parentTid);
+                this.$refs.thskComponents.backToParentTask()
             },
             // 点击发布
             release() {

+ 27 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue

@@ -119,6 +119,7 @@
                         <el-link type="primary" v-if="user.userNameNeedTranslate != '1'" :underline="false" @click="syncWithCorpWx">{{ $t('synchronizetheenterprisemicrodirectory') }}</el-link>
                         <el-link type="primary" v-if="user.userNameNeedTranslate == '1'" :underline="false" @click="newSyncWithCorpWxDayload = true">{{ $t('synchronizetheenterprisemicrodirectory') }}</el-link>
                     </el-form-item>
+
                     <el-form-item style="float:right;" v-if="user.dingdingUserid != null && permissions.structureImport">
                         <el-link type="primary" :underline="false" @click="syncWithCorpDingding">{{ $t('synchronizetheaddressbook') }}</el-link>
                     </el-form-item>
@@ -731,6 +732,7 @@
           路径:管理企业-应用管理-工时管家-可见范围
         </span>
         <span slot="footer" class="dialog-footer">
+          <el-button type="primary" @click="visibleRange" v-if="user.manager">可见范围设置</el-button>
           <el-button type="primary" @click="newSyncWithCorpWx">开始同步</el-button>
         </span>
       </el-dialog>
@@ -3336,6 +3338,31 @@ export default {
       } else if(obj.distinction == '12'){
         this.toUserId = obj.id
       }
+    },
+    // 企业微信可见范围设置
+    visibleRange() {
+      console.log('我点击可见范围设置')
+      wx.invoke('openAppManage', {}, function(res){
+        if(res.err_msg == "openAppManage:ok") {
+              // 调用成功              
+          }
+          if(res.err_msg == "openAppManage:fail:no permission") {
+              // 调用人身份不符合                 
+              this.$message({message: '调用人身份不符合',type: "error"});
+          }
+          if(res.err_msg == "openAppManage:fail:unknown app") {
+              // 应用信息获取失败
+              this.$message({message: '应用信息获取失败',type: "error"});
+          }
+          if(res.err_msg == "openAppManage:fail:unsupported app type") {
+              // 应用类型不符合要求
+              this.$message({message: '应用类型不符合要求',type: "error"});
+          }
+          if(res.err_msg == "openAppManage:fail") {
+              // 其它错误                  
+              this.$message({message: '其它错误',type: "error"});
+          }      
+       })
     }
   },
   mounted() {