Преглед на файлове

项目导入增加所属部门

seyason преди 1 година
родител
ревизия
2bfbc3e405

+ 33 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskController.java

@@ -132,6 +132,39 @@ public class TaskController {
             task.setExecutorColor(StringUtils.isEmpty(colors)?null:colors);
             //总时长
             task.setPlanHours(executorList.stream().filter(f->f.getPlanHours() != null).mapToInt(TaskExecutor::getPlanHours).sum());
+            //校验总计划工时不得超过父任务的计划工时
+            if (task.getParentTid() != null) {
+                Task pTask = taskService.getById(task.getParentTid());
+                if (pTask.getPlanHours() != null && task.getPlanHours() != null) {
+                    List<Task> subTaskList = taskMapper.selectList(new QueryWrapper<Task>().select("id, plan_hours").eq("parent_tid", pTask.getId()));
+                    if (task.getId() != null) {
+                        //过滤掉当前任务
+                        subTaskList = subTaskList.stream().filter(sub->!sub.getId().equals(task.getId())).collect(Collectors.toList());
+                    }
+                    Integer leftHours = pTask.getPlanHours() - subTaskList.stream().mapToInt(Task::getPlanHours).sum();
+                    if (leftHours == 0) {
+                        msg.setError("父任务计划工时已分配完,请调整。");
+                        return msg;
+                    } else if (task.getPlanHours().compareTo(leftHours) > 0) {
+                        msg.setError("父任务计划工时尚可剩余"+leftHours+"小时可分配,请调整。");
+                        return msg;
+                    }
+                }
+            }
+            //校验总计划工时不得小于全部子任务的计划工时之和
+            if (task.getId() != null) {
+                if (task.getPlanHours() != null) {
+                    List<Task> allSubTasks = taskMapper.selectList(new QueryWrapper<Task>().select("id, plan_hours").eq("parent_tid", task.getId()));
+                    if (allSubTasks.size() > 0) {
+                        int sum = allSubTasks.stream().mapToInt(Task::getPlanHours).sum();
+                        if (task.getPlanHours() < sum) {
+                            msg.setError("计划工时不得少于全部子任务计划工时总和("+sum+"小时),请调整。");
+                            return msg;
+                        }
+                    }
+                }
+            }
+
             //检查执行人是否在当前分组的参与人当中
             List<GroupParticipator> groupParticipatorList = groupParticipatorMapper.selectList(new QueryWrapper<GroupParticipator>().eq("group_id", task.getGroupId()));
             List<Participation> participationList = participationMapper.selectList(new QueryWrapper<Participation>().eq("project_id", task.getProjectId()));
@@ -224,9 +257,6 @@ public class TaskController {
                 needRecalculateProgress = true;
             }
         }
-        System.out.println(task.getStartDate());
-        System.out.println(task.getEndDate());
-        System.out.println(task.getFinishDate());
         taskService.saveOrUpdate(task);
         if (task.getExecutorId() == null) {
             //清空执行人

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

@@ -69,6 +69,8 @@ public interface WxCorpInfoService extends IService<WxCorpInfo> {
 
     HashMap<String, List> getOpenId(String corpId, String keyword, String cursor,Integer queryType,Integer limit) throws Exception;
 
+    Integer searchCorpWxDeptId(String corpId, String deptName) throws Exception;
+
     String operateMeeting(String userIds, String title, String description, String startTime, long duration, WxCorpInfo wxCorpInfo, String meetingType, String meetingId) throws Exception;
 
     List<Map<String, String>> getActiveInfoByUser(HttpServletRequest request) throws Exception;

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

@@ -1494,6 +1494,7 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
         }
     }
 
+
     //用于报表展示:递归获取企业微信所有上级部门字符串,格式:"上级部门/上级部门/部门"
     public String getWxDepartment(Department department,List<Department> departmentList) {
         if (department == null || department.getCorpwxDeptid() == null){

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

@@ -3707,6 +3707,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         User user = userMapper.selectById(userId);
         TimeType timeType = timeTypeMapper.selectById(user.getCompanyId());
         WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id",user.getCompanyId()));
+        List<Department> allDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", user.getCompanyId()));
         //然后处理文件
         String fileName = multipartFile.getOriginalFilename();
         File file = new File(fileName == null ? "file" : fileName);
@@ -3723,6 +3724,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             inputStream.close();
             outputStream.close();
             if(fileName.endsWith(".xlsx")){
+                //部门
+                boolean projectWithDept = false;
                 //然后解析表格
                 XSSFWorkbook workbook = new XSSFWorkbook(file);
                 //我们只需要第一个sheet
@@ -3756,6 +3759,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                 projectLevelMap.put(MessageUtils.message("excel.highRisk"), 7);
                 List<String> existCodeList = new ArrayList<>();
                 List<String> userNameList=new ArrayList<>();
+
                 for (int rowIndex = 0; rowIndex <= rowNum; rowIndex++) {
                     XSSFRow row = sheet.getRow(rowIndex);
                     if (row == null) {
@@ -3765,8 +3769,19 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     if (ExcelUtil.isRowEmpty(row)) {
                         continue;
                     }
-                    XSSFCell participatorCell = row.getCell(5);
-                    XSSFCell inchargerCell = row.getCell(6);
+                    //检测是否有所属部门列
+                    if (rowIndex == 0) {
+                        XSSFCell cell = row.getCell(0);
+                        if (cell != null) {
+                            String cellValue = cell.getStringCellValue();
+                            if (cellValue.equals("所属部门")) {
+                                //第一列是所属部门
+                                projectWithDept = true;
+                            }
+                        }
+                    }
+                    XSSFCell participatorCell = row.getCell(6+(projectWithDept?1:0));
+                    XSSFCell inchargerCell = row.getCell(7+(projectWithDept?1:0));
                     if (participatorCell!=null)participatorCell.setCellType(CellType.STRING);
                     if (inchargerCell != null)inchargerCell.setCellType(CellType.STRING);
                     String part = participatorCell.getStringCellValue().trim();
@@ -3804,30 +3819,31 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     if (ExcelUtil.isRowEmpty(row)) {
                         continue;
                     }
-                    //项目编号	项目名称 参与人 负责人 级别 开始日期 截止日期 合同金额
-                    XSSFCell codeCell = row.getCell(0);
-                    XSSFCell categoryCell = row.getCell(1);
-                    XSSFCell isPublicCell = row.getCell(2);
-                    XSSFCell nameCell = row.getCell(3);
-                    XSSFCell descCell = row.getCell(4);
-                    XSSFCell subNameCell = row.getCell(5);
-                    XSSFCell participatorCell = row.getCell(6);
-                    XSSFCell inchargerCell = row.getCell(7);
+                    //项目编号 项目分类	项目名称 参与人 负责人 级别 开始日期 截止日期 合同金额
+                    XSSFCell deptCell = projectWithDept?row.getCell(0):null;
+                    XSSFCell codeCell = row.getCell(0+(projectWithDept?1:0));
+                    XSSFCell categoryCell = row.getCell(1+(projectWithDept?1:0));
+                    XSSFCell isPublicCell = row.getCell(2+(projectWithDept?1:0));
+                    XSSFCell nameCell = row.getCell(3+(projectWithDept?1:0));
+                    XSSFCell descCell = row.getCell(4+(projectWithDept?1:0));
+                    XSSFCell subNameCell = row.getCell(5+(projectWithDept?1:0));
+                    XSSFCell participatorCell = row.getCell(6+(projectWithDept?1:0));
+                    XSSFCell inchargerCell = row.getCell(7+(projectWithDept?1:0));
                     XSSFCell reportAuditorsCell=null;
                     XSSFCell reportCcCell=null;
                     int i=0;
                     if(timeType.getReportAuditType()==0||timeType.getReportAuditType()==4||timeType.getReportAuditType()==6){
                         i++;
-                        reportAuditorsCell = row.getCell(7+i);
+                        reportAuditorsCell = row.getCell(7+(projectWithDept?1:0)+i);
                     }
                     if(timeType.getReportAuditType()==7){
                         i++;
-                        reportCcCell=row.getCell(7+i);
+                        reportCcCell=row.getCell(7+(projectWithDept?1:0)+i);
                     }
-                    XSSFCell levelCell = row.getCell(8+i);
-                    XSSFCell startDateCell = row.getCell(9+i);
-                    XSSFCell endDateCell = row.getCell(10+i);
-                    XSSFCell amountCell = row.getCell(11+i);
+                    XSSFCell levelCell = row.getCell(8+(projectWithDept?1:0)+i);
+                    XSSFCell startDateCell = row.getCell(9+(projectWithDept?1:0)+i);
+                    XSSFCell endDateCell = row.getCell(10+(projectWithDept?1:0)+i);
+                    XSSFCell amountCell = row.getCell(11+(projectWithDept?1:0)+i);
 
 
                     if (codeCell != null)codeCell.setCellType(CellType.STRING);
@@ -3892,6 +3908,32 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                     project.setCreatorName(user.getName());
                     project.setProjectName(name);
                     project.setCreateDate(LocalDate.now());
+                    if (projectWithDept) {
+                        if (!StringUtils.isEmpty(deptCell.getStringCellValue())) {
+                            Department targetDept = null;
+                            if (wxCorpInfo != null && wxCorpInfo.getSaasSyncContact() == 1) {
+                                //通过企业微信接口搜索部门
+                                Integer wxDeptId = wxCorpInfoService.searchCorpWxDeptId(wxCorpInfo.getCorpid(), deptCell.getStringCellValue());
+                                if (wxDeptId != null) {
+                                    targetDept = allDeptList.stream().filter(d -> wxDeptId.equals(d.getCorpwxDeptid())).findFirst().get();
+                                }
+                            } else {
+                                //直接搜索数据库
+                                Optional<Department> first = allDeptList.stream().filter(d -> d.getDepartmentName().equals(deptCell.getStringCellValue())).findFirst();
+                                if (first.isPresent()) {
+                                    targetDept = first.get();
+                                }
+                            }
+                            if (targetDept != null) {
+                                //设置所属部门
+                                Integer deptId = targetDept.getDepartmentId();
+                                project.setDeptId(deptId);
+                                project.setDeptCascade(convertDepartmentIdToCascade(deptId));
+                            } else {
+                                throw new Exception("部门[" + deptCell.getStringCellValue() + "]不存在");
+                            }
+                        }
+                    }
 
                     //处理人员
                     if (inchargerCell != null) {
@@ -8177,9 +8219,11 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             inchagerIds=new ArrayList<>();
             if(functionInchargeList.size()>0){
                 List<Project> list = projectList.stream().filter(pl -> (pl.getInchargerId()==null?0:pl.getInchargerId()).equals(user.getId())).collect(Collectors.toList());
-                if(list!=null){
+                if(list.size() > 0){
                     List<Integer> collect = list.stream().map(li -> li.getId()).collect(Collectors.toList());
                     inchagerIds.addAll(collect);
+                } else {
+                    inchagerIds.add(-1);
                 }
             }else {
                 inchagerIds.add(-1);
@@ -8217,9 +8261,11 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             inchagerIds=new ArrayList<>();
             if(functionInchargeList.size()>0){
                 List<Project> list = projectList.stream().filter(pl -> (pl.getInchargerId()==null?0:pl.getInchargerId()).equals(user.getId())).collect(Collectors.toList());
-                if(list!=null){
+                if(list.size() > 0){
                     List<Integer> collect = list.stream().map(li -> li.getId()).collect(Collectors.toList());
                     inchagerIds.addAll(collect);
+                } else {
+                    inchagerIds.add(-1);
                 }
             }else {
                 inchagerIds.add(-1);

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

@@ -48,6 +48,8 @@ import java.util.stream.Collectors;
 @Slf4j
 public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpInfo> implements WxCorpInfoService {
 
+    public static final String URL_SEARCH_CONTACT = "https://qyapi.weixin.qq.com/cgi-bin/service/contact/search?provider_access_token=ACCESS_TOKEN";
+
     public static String URL_SEND_WXCORP_MSG = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN";
     //获取临时素材url
     public static String URL_GET_MEDIA = "https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
@@ -1990,7 +1992,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
         List<Object> user = new ArrayList<>();
         List<Object> dept = new ArrayList<>();
         String itemCursor = "";
-        String url = "https://qyapi.weixin.qq.com/cgi-bin/service/contact/search?provider_access_token=ACCESS_TOKEN";
+        String url = URL_SEARCH_CONTACT;
         HttpHeaders headers = new HttpHeaders();
         RestTemplate restTemplate = new RestTemplate();
         MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
@@ -2056,6 +2058,67 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
         return result;
     }
 
+    @Override
+    public Integer searchCorpWxDeptId(String corpId, String deptName) throws Exception {
+        HashMap<String, List> result = new HashMap<>();
+        List<Object> user = new ArrayList<>();
+        List<Object> dept = new ArrayList<>();
+        String itemCursor = "";
+        String url = URL_SEARCH_CONTACT;
+        HttpHeaders headers = new HttpHeaders();
+        RestTemplate restTemplate = new RestTemplate();
+        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
+        headers.setContentType(type);
+        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
+        String providerToken = getProviderAccessToken();
+        if (providerToken!=null){
+            //搜索通讯录名单
+            url = url.replace("ACCESS_TOKEN", providerToken);
+            JSONObject requestMap = new JSONObject();
+            requestMap.put("auth_corpid", corpId);
+            requestMap.put("query_word", deptName);
+            requestMap.put("query_type", 2);//2表示查询部门
+            HttpEntity<JSONObject> entity = new HttpEntity<>(requestMap, headers);
+            ResponseEntity<String> ResponseEntity = restTemplate.postForEntity(url, entity, String.class);
+            if (ResponseEntity.getStatusCode() == HttpStatus.OK) {
+                String resp = ResponseEntity.getBody();
+                JSONObject respJson = JSONObject.parseObject(resp);
+                if (respJson.getInteger("errcode")==0){
+                    JSONObject queryResult = respJson.getJSONObject("query_result");
+                    System.out.println(queryResult.toJSONString());
+                    if (!queryResult.isEmpty()){
+                        if(queryResult.getJSONObject("party")!=null){
+                            JSONArray deptJsonArray = queryResult.getJSONObject("party").getJSONArray("department_id");
+                            if (deptJsonArray!=null){
+                                Object[] objects = deptJsonArray.toArray();
+                                for (Object object : objects) {
+                                    dept.add(object);
+                                }
+                            }
+                        }
+                    }else{
+                        System.err.println("==================通讯录查询请求无userid列表===================");
+                    }
+                    System.err.println(respJson.toString());
+                    Boolean is_last = respJson.getBoolean("is_last");
+                    if (!is_last){
+                        itemCursor = respJson.getString("next_cursor");
+                    }
+                }else {
+                    System.err.println("===================通讯录查询请求失败=================");
+                }
+            }
+        }else {
+            System.out.println("=============token查询失败=================");
+        }
+        if (dept.size() >0) {
+            //TODO: 先取第一个,后面再改进;
+            return (Integer)dept.get(0);
+        } else {
+            return null;
+        }
+    }
+
     public String addCalendar(WxCorpInfo wxCorpInfo,String targetUsers, String description) throws Exception {
         String result="";
         String url = ADD_CALENDAR.replace("ACCESS_TOKEN",getCorpAccessToken(wxCorpInfo));

+ 7 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserCorpwxTimeMapper.xml

@@ -28,10 +28,12 @@
 
     <select id="getUserDataList" resultType="java.util.HashMap" >
         SELECT user.id as userId, department.department_name as departmentName, DATE_FORMAT(a.create_date, '%Y/%m/%d') as createDate,a.start_time as startTime, a.end_time as endTime, a.work_hours as workHours, user.name as username,user.corpwx_userid as corpwxUserid,a.week_day as weekDay,
-        week_day_txt as weekDayTxt,card_time as cardTime, outdoor_time as outdoorTime, ask_leave_time as askLeaveTime FROM user_corpwx_time a LEFT JOIN user ON  user.name = a.name AND a.`company_id` = user.`company_id`
+        week_day_txt as weekDayTxt,card_time as cardTime, outdoor_time as outdoorTime, ask_leave_time as askLeaveTime FROM user_corpwx_time a
+            LEFT JOIN user ON  user.name = a.name AND a.`company_id` = user.`company_id`
         left join department on department.department_id = user.department_id
         WHERE a.create_date BETWEEN #{startDate} AND #{endDate}
         AND a.company_id = #{companyId}
+        and (a.`create_date` &gt;= user.`induction_date` OR user.`induction_date` IS NULL)
         <if test="deptId != null">
             AND user.`department_id` = #{deptId}
         </if>
@@ -42,7 +44,10 @@
         SELECT user.id AS userId, user.`name` as username,department.department_name as departmentName, user.`corpwx_userid` as corpwxUserid, IFNULL(card_time.workHours, 0) as workHours, IFNULL(report_time.projectTime, 0)  AS projectTime FROM
         user left join department on department.department_id = user.department_id
             LEFT JOIN
-        (SELECT a.corpwx_userid,a.name, SUM(a.work_hours) AS workHours FROM user_corpwx_time a WHERE a.company_id = #{companyId} AND  a.create_date in
+        (SELECT a.corpwx_userid,a.name, SUM(a.work_hours) AS workHours FROM user_corpwx_time a, user b WHERE a.company_id = #{companyId}
+        AND a.`corpwx_userid` = b.`corpwx_userid`
+            AND (a.`create_date` &gt;= b.`induction_date` OR b.`induction_date` IS NULL)
+            AND  a.create_date in
            <foreach collection="dateList" item="date" open="(" separator="," close=")">
                 #{date}
             </foreach>

BIN
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/项目导入模板_部门.xlsx


+ 4 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue

@@ -57,7 +57,10 @@
                             </el-dropdown-item>
                             <el-dropdown-item v-if="permissions.projectImport">
                                 <el-link type="primary" :underline="false" @click="downloadmb" v-if="user.company.packageCustomer == 1 || user.company.packageProvider == 1 || user.timeType.mainProjectState == 1 || user.companyId == '936' || user.timeType.reportCc == 1">{{ $t('Downloadthetemplate') }}</el-link>
-                                <el-link type="primary" :underline="false" href="./upload/项目导入模板.xlsx" :download="$t('importtemplateproject') + '.xlsx'" v-else>{{ $t('Downloadthetemplate') }}</el-link>
+                                <el-link type="primary" :underline="false" href="./upload/项目导入模板.xlsx" :download="$t('importtemplateproject') + '.xlsx'" v-else-if="user.timeType.projectWithDept==0">{{ $t('Downloadthetemplate') }}</el-link>
+                                <!--项目带所属部门的-->
+                                <el-link type="primary" :underline="false" href="./upload/项目导入模板_部门.xlsx" download="项目导入模板+部门.xlsx" v-else>{{ $t('Downloadthetemplate') }}</el-link>
+                                
                             </el-dropdown-item>
                             <el-dropdown-item v-if="permissions.projectExport" :disabled="exportDisabled">
                                 <el-link type="primary" :underline="false" @click="exportProjectData" :download="$t('exportProject') + '.xlsx'">{{ $t('exportProject') }}</el-link>