Explorar el Código

职业技能迁移

wzy hace 5 meses
padre
commit
12f2fc5628

+ 1 - 1
pom.xml

@@ -49,7 +49,7 @@
         <dependency>
             <groupId>com.malk</groupId>
             <artifactId>base</artifactId>
-            <version>1.1-SNAPSHOT</version>
+            <version>1.2-SNAPSHOT</version>
         </dependency>
 
         <dependency>

+ 20 - 0
src/main/java/com/malk/pro/aspect/ControllerYdAspect.java

@@ -39,4 +39,24 @@ public class ControllerYdAspect {
     // demo ===============================谷元/能辉========================================================================== end
 
 
+    // ===============================职业技能========================================================================== start
+    // 定义切点:拦截所有Controller包下的方法
+    @Pointcut("execution(* com.malk.pro.zyjn.controller..*.*(..))")
+    public void zyjnControllerPointcut() {}
+    // 在方法执行前执行
+    @Before("zyjnControllerPointcut()")
+    public void zyjnBefore(JoinPoint joinPoint) {
+        // 项目编号 2002 每个项目一个编号,请勿重复
+        McProject.addYida("2002",new String[]{"APP_GKH227Q9PDQ2CYIIJSHJ","I5D66NB1S3JNGJBDEND4L78FN8CT34LMQVKZLRP"});
+        McProject.addDd("2002",new String[]{"dingn2nkwrrosmyjk9o2","t26NJ2TIHeQZAG17QPJAPoVgrVwPUZCLH0JLO955_c0BoAhdaAS5eNf9Fc6KAepo"});
+        MDC.put("MDC_KEY_PID","2002");
+    }
+    // 在方法执行后执行
+    @AfterReturning(pointcut = "zyjnControllerPointcut()", returning = "result")
+    public void zyjnAfterReturning(JoinPoint joinPoint, Object result) {
+        MDC.remove("MDC_KEY_PID");
+    }
+    // ===============================职业技能========================================================================== end
+
+
 }

+ 69 - 0
src/main/java/com/malk/pro/zyjn/controller/ZyjnController.java

@@ -0,0 +1,69 @@
+package com.malk.pro.zyjn.controller;
+
+import com.malk.server.common.McR;
+import com.malk.pro.zyjn.service.ZyjnService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+import java.util.Objects;
+
+@RestController
+@Slf4j
+public class ZyjnController {
+    @Autowired
+    private ZyjnService zyjnService;
+
+    @GetMapping("/test")
+    public McR test() {
+        return McR.success();
+    }
+
+    @PostMapping("/test2")
+    public McR test2(@RequestBody Map map) {
+        return McR.success();
+    }
+
+    /**
+     * 上传部门月度考勤表(审核前)
+     * @param map
+     * @return
+     */
+    @PostMapping("/getDeptAttendanceSheet")
+    public McR getDeptAttendanceSheet(@RequestBody Map map) {
+        if (Objects.isNull(map.get("userId")) || Objects.isNull(map.get("deptId"))
+                || Objects.isNull(map.get("date")) || Objects.isNull(map.get("deptName"))
+                || Objects.isNull(map.get("userName"))){
+            return McR.errorParam("缺少传参");
+        }
+        String userId = map.get("userId").toString();
+        String userName = map.get("userName").toString();
+        String deptId = map.get("deptId").toString();
+        String deptName = map.get("deptName").toString();
+        Long date = Long.valueOf(map.get("date").toString());
+        return zyjnService.getDeptAttendanceSheet(userId,userName,deptId,date,deptName);
+    }
+
+    /**
+     * 上传部门月度考勤表(审核后)
+     * @param map
+     * @return
+     */
+    @PostMapping("/updateDeptAttendanceSheet")
+    public McR updateDeptAttendanceSheet(@RequestBody Map map) {
+        if (Objects.isNull(map.get("formInstId"))){
+            return McR.errorParam("缺少传参");
+        }
+        String formInstId = map.get("formInstId").toString();
+        zyjnService.updateDeptAttendanceSheet(formInstId);
+        return McR.success();
+    }
+
+    @GetMapping("/download/{fileName}")
+    public void download(@PathVariable("fileName") String fileName, HttpServletResponse response) {
+        zyjnService.download(fileName, response);
+    }
+
+}

+ 54 - 0
src/main/java/com/malk/pro/zyjn/entity/Attendance.java

@@ -0,0 +1,54 @@
+package com.malk.pro.zyjn.entity;
+
+import lombok.Data;
+
+@Data
+public class Attendance {
+    private int id;
+
+    private String name;
+
+    private String situation1;
+    private String situation2;
+    private String situation3;
+    private String situation4;
+    private String situation5;
+    private String situation6;
+    private String situation7;
+    private String situation8;
+    private String situation9;
+    private String situation10;
+    private String situation11;
+    private String situation12;
+    private String situation13;
+    private String situation14;
+    private String situation15;
+    private String situation16;
+    private String situation17;
+    private String situation18;
+    private String situation19;
+    private String situation20;
+    private String situation21;
+    private String situation22;
+    private String situation23;
+    private String situation24;
+    private String situation25;
+    private String situation26;
+    private String situation27;
+    private String situation28;
+    private String situation29;
+    private String situation30;
+    private String situation31;
+
+    private String remark;
+
+    public Attendance() {
+    }
+
+    public Attendance(int id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    
+}

+ 15 - 0
src/main/java/com/malk/pro/zyjn/service/ZyjnService.java

@@ -0,0 +1,15 @@
+package com.malk.pro.zyjn.service;
+
+import com.malk.server.common.McR;
+import org.springframework.scheduling.annotation.Async;
+
+import javax.servlet.http.HttpServletResponse;
+
+public interface ZyjnService {
+    McR getDeptAttendanceSheet(String userId, String userName, String deptId, Long date,String deptName);
+
+    void download(String fileName, HttpServletResponse response);
+
+    @Async
+    void updateDeptAttendanceSheet(String formInstId);
+}

+ 540 - 0
src/main/java/com/malk/pro/zyjn/service/impl/ZyjnServiceImpl.java

@@ -0,0 +1,540 @@
+package com.malk.pro.zyjn.service.impl;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ReflectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.malk.core.McProject;
+import com.malk.pro.zyjn.entity.Attendance;
+import com.malk.pro.zyjn.service.ZyjnService;
+import com.malk.pro.zyjn.utils.UtilExcel;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.common.McR;
+import com.malk.server.dingtalk.DDConf;
+import com.malk.server.dingtalk.DDR_New;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.dingtalk.DDClient;
+import com.malk.utils.UtilHttp;
+import lombok.extern.slf4j.Slf4j;
+import okio.BufferedSink;
+import okio.Okio;
+import okio.Source;
+import org.apache.poi.EncryptedDocumentException;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.ss.usermodel.*;
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Slf4j
+@Service
+public class ZyjnServiceImpl implements ZyjnService {
+    private final String tableFilePath = "/home/server/zhiyejineng/file/";
+
+    private final String downloadUrl = "https://mc.cloudpure.cn/zyjn/download/";
+
+    @Autowired
+    private DDClient ddClient;
+
+    @Autowired
+    private DDConf ddConf;
+
+    @Autowired
+    private YDClient ydClient;
+
+    private static final String COLUM_ATTENDANCE_RESULTS = "995157155";//考勤结果列id
+
+    private static final String SPACE_ID = "24768523387";//钉盘考勤报表空间id
+
+
+    private static final String ADMIN_USERID = "253434204020308091";//管理员-任欢欢userid
+
+    private static final String ADMIN_UNION_ID = "oqzo73xXs9EdIiSatosDYqgiEiE";//管理员-任欢欢union_id
+
+    private static final String DEPT_ID = "161860966";//综合办公室部门id
+
+
+    @Override
+    public McR getDeptAttendanceSheet(String userId, String userName,String deptId, Long date, String deptName) {
+        //获取发起人所属最上层部门
+        Map<String,Object> params = new HashMap<>();
+        params.put("access_token",ddClient.getAccessToken());
+        Map<String,Object> body = new HashMap<>();
+        body.put("dept_id",deptId);
+        DDR_New deptDDR = (DDR_New) UtilHttp.doPost("https://oapi.dingtalk.com/topapi/v2/department/listparentbydept", null, params, body, DDR_New.class);
+        Map deptDDRResult = (Map) deptDDR.getResult();
+        List<String> parentDeptIdList = (List<String>) deptDDRResult.get("parent_id_list");
+        String topDeptId = deptId;
+        if (parentDeptIdList.size() >= 2){
+            topDeptId = String.valueOf(parentDeptIdList.get(parentDeptIdList.size()-2));
+        }
+
+        //获取发起人所属最上层部门下所有成员
+        Map body2 = new HashMap();
+        body2.put("dept_id",topDeptId);
+        body2.put("cursor",0);
+        body2.put("size",100);
+
+        DDR_New employeeDDR = (DDR_New) UtilHttp.doPost("https://oapi.dingtalk.com/topapi/user/listsimple", null, params, body2, DDR_New.class);
+        Map employeeResult = (Map) employeeDDR.getResult();
+        List<Map> userList = (List<Map>) employeeResult.get("list");
+
+        //遍历获取每个成员考勤记录
+        List<Attendance> employeeAttendanceList = new ArrayList<>();
+        if (!userList.isEmpty()){
+            DateTime startDate = DateUtil.date(date);
+            DateTime endDate = DateUtil.endOfMonth(startDate);
+
+            int id = 1;
+            for (Map user : userList) {
+                //查询用户当月请假情况
+                Map<String,Object> param3 = new HashMap<>();
+                param3.put("access_token",ddClient.getAccessToken());
+                Map body3 = new HashMap<>();
+                body3.put("userid_list",userId);
+                body3.put("start_time",startDate.getTime());
+                body3.put("end_time",endDate.getTime());
+                body3.put("offset",0);
+                body3.put("size",20);
+
+                DDR_New ddrNew3 = (DDR_New) UtilHttp.doPost("https://oapi.dingtalk.com/topapi/attendance/getleavestatus", null, param3, body3, DDR_New.class);
+                Map result3 = (Map) ddrNew3.getResult();
+                List<Map> leaveStatus = (List<Map>) result3.get("leave_status");
+
+                int index = 1;
+                String userid = user.get("userid").toString();
+                String name = user.get("name").toString();
+                Map map = new HashMap();
+                map.put("column_id_list",COLUM_ATTENDANCE_RESULTS);
+                map.put("from_date",startDate.toString());
+                map.put("to_date",endDate.toString());
+                map.put("userid",userid);
+                DDR_New attendanceDDR = (DDR_New) UtilHttp.doPost("https://oapi.dingtalk.com/topapi/attendance/getcolumnval", null, params, map, DDR_New.class);
+                Map attendanceResult = (Map) attendanceDDR.getResult();
+                Map columnVals = ((List<Map>) attendanceResult.get("column_vals")).get(0);
+                List<Map> attendanceList = (List<Map>) columnVals.get("column_vals");
+                Attendance attendance = new Attendance(id,name);
+                /*List<Map> filterAttendanceList = attendanceList.stream()
+                        .filter(item -> DateUtil.parse(item.get("date").toString()).isBefore(DateTime.now()))
+                        .collect(Collectors.toList());*/
+                for (Map attendanceMap : attendanceList) {
+                    String situation = attendanceMap.get("value").toString();
+                    if (situation.contains("休息")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"假");
+                    }else if (situation.contains("旷工")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"工");
+                        if (!leaveStatus.isEmpty()){
+                            long time = DateUtil.parse(attendanceMap.get("date").toString()).getTime();
+                            for (Map leaveState : leaveStatus) {
+                                long startTime = DateUtil.beginOfDay(new Date((long) leaveState.get("start_time"))).getTime();
+                                long endTime = DateUtil.endOfDay(new Date((long) leaveState.get("end_time"))).getTime();
+                                if (time >= startTime && time <= endTime){
+                                    //请假未审批
+                                    ReflectUtil.invoke(attendance,"setSituation"+index,"?");
+                                }
+                            }
+                        }
+                    }else if (situation.contains("公休假")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"公");
+                    }else if (situation.contains("调休")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"调");
+                    }else if (situation.contains("病假")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"病");
+                    }else if (situation.contains("事假")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"事");
+                    }else if (situation.contains("丧假")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"丧");
+                    }else if (situation.contains("婚假")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"婚");
+                    }else if (situation.contains("产假")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"产");
+                    }else if (situation.contains("探亲假")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"探");
+                    }else if (situation.contains("哺乳假")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"哺");
+                    }else if (situation.contains("产前假")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"前");
+                    }else if (situation.contains("育儿假")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"育");
+                    }else if (situation.contains("未打卡")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"工");
+                        if (!leaveStatus.isEmpty()){
+                            long time = DateUtil.parse(attendanceMap.get("date").toString()).getTime();
+                            for (Map leaveState : leaveStatus) {
+                                long startTime = DateUtil.beginOfDay(new Date((long) leaveState.get("start_time"))).getTime();
+                                long endTime = DateUtil.endOfDay(new Date((long) leaveState.get("end_time"))).getTime();
+                                if (time >= startTime && time <= endTime){
+                                    //请假未审批
+                                    ReflectUtil.invoke(attendance,"setSituation"+index,"?");
+                                }
+                            }
+                        }
+                    }else if (situation.contains("正常")){
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"工");
+                    }else {
+                        ReflectUtil.invoke(attendance,"setSituation"+index,"工");
+                    }
+                    index++;
+                }
+                employeeAttendanceList.add(attendance);
+                id++;
+            }
+        }
+
+        //生成报表
+        Map mainData = new HashMap();
+        mainData.put("department",deptName);
+        mainData.put("date",DateUtil.format(DateTime.of(date),"yyyy年MM月"));
+        mainData.put("subName",userName);
+
+        UtilExcel.exportAllSheetByTemplate(mainData,employeeAttendanceList,deptName+mainData.get("date")+"考勤表(未审核)",tableFilePath,"template.xlsx");
+
+        //上传至钉盘
+        String fileName = deptName + mainData.get("date") + "考勤表(未审核).xlsx";
+        uploadToDingTalk(tableFilePath + fileName,userId);
+
+        Map result = new HashMap<>();
+        result.put("downloadUrl",downloadUrl + fileName);
+        result.put("fileName",fileName);
+        result.put("ext","xlsx");
+
+        //返回下载文件url
+        return McR.success(result);
+    }
+
+
+
+    @Override
+    public void download(String fileName, HttpServletResponse response) {
+        File file = new File(tableFilePath + fileName);
+        if (!file.exists()) {
+            return; //文件不存在
+        }
+
+        try {
+            fileName = URLEncoder.encode(file.getName(), "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+        response.setHeader("Content-disposition", "attachment;filename="+fileName+";"+"filename*=utf-8''"+fileName);
+        response.setContentType("application/octet-stream");
+
+        try (BufferedSink sink = Okio.buffer(Okio.sink(response.getOutputStream()))) {
+            Source source = Okio.source(file);
+            sink.writeAll(source);
+            source.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void downloadFile(String fileURL, String savePath) throws IOException {
+        //如果fileUrl中包含中文,则需要对其进行编码
+        Pattern pattern = Pattern.compile("[\u4E00-\u9FA5]");
+        Matcher matcher = pattern.matcher(fileURL);
+        if (matcher.find()){
+            String encodeFileName = URLEncoder.encode(fileURL.substring(fileURL.lastIndexOf("/") + 1), "UTF-8");
+            fileURL = fileURL.substring(0,fileURL.lastIndexOf("/") + 1) + encodeFileName;
+        }
+        //若是宜搭附件url 则需获得附件临时免登地址
+        if (fileURL.contains("aliwork")){
+            String pid= MDC.get("MDC_KEY_PID");
+            String[] yida= McProject.getYida(pid);
+
+            Map<String,Object> param = new HashMap<>();
+            param.put("systemToken",yida[1]);
+            param.put("userId",ADMIN_USERID);//任欢欢
+            param.put("fileUrl",fileURL);
+
+            fileURL = ((DDR_New) UtilHttp.doGet("https://api.dingtalk.com/v1.0/yida/apps/temporaryUrls/" + yida[0], ddClient.initTokenHeader(), param, DDR_New.class)).getResult().toString();
+        }
+
+        URL url = new URL(fileURL);
+        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
+        int responseCode = httpConn.getResponseCode();
+
+        // 检查HTTP响应代码是否为200
+        if (responseCode == HttpURLConnection.HTTP_OK) {
+            InputStream inputStream = httpConn.getInputStream();
+            FileOutputStream outputStream = new FileOutputStream(savePath);
+
+            byte[] buffer = new byte[4096];
+            int bytesRead = -1;
+
+            while ((bytesRead = inputStream.read(buffer)) != -1) {
+                outputStream.write(buffer, 0, bytesRead);
+            }
+
+            outputStream.close();
+            inputStream.close();
+        } else {
+            System.out.println("无法下载文件。HTTP响应代码: " + responseCode);
+        }
+        httpConn.disconnect();
+    }
+
+    @Async
+    @Override
+    public void updateDeptAttendanceSheet(String formInstId) {
+        //获取文件下载链接
+        DDR_New ddrNew = ydClient.queryData(YDParam.builder()
+                .formInstId(formInstId)
+                .build(), YDConf.FORM_QUERY.retrieve_id);
+        Map formData = ddrNew.getFormData();
+        String userId = ddrNew.getOriginator().get("userId").toString();
+        List<Map> fileList = (List<Map>) JSONArray.parse(String.valueOf(formData.get("attachmentField_lzkvrlcl")));
+        String ydDownloadUrl = fileList.get(0).get("downloadUrl").toString();
+        String fileName = fileList.get(0).get("name").toString();
+        //将downloadurl下载到本地
+        try {
+            downloadFile(ydDownloadUrl, tableFilePath + fileName);
+            System.out.println("文件下载成功!");
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        //获取审批记录
+        Map param = new HashMap<>();
+        String pid= MDC.get("MDC_KEY_PID");
+        String[] yida= McProject.getYida(pid);
+
+        param.put("appType",yida[0]);
+        param.put("systemToken",yida[1]);
+        param.put("userId",userId);
+        param.put("processInstanceId",formInstId);
+
+        DDR_New ddrNew2 = (DDR_New) UtilHttp.doGet("https://api.dingtalk.com/v1.0/yida/processes/operationRecords", ddClient.initTokenHeader(), param, DDR_New.class);
+        List<Map> result = (List<Map>) ddrNew2.getResult();
+
+        String startTime = result.get(0).get("operateTimeGMT").toString().replace("T"," ").replace("Z","");
+        String endTime = result.get(result.size() - 2).get("operateTimeGMT").toString().replace("T", " ").replace("Z", "");
+        String operatorName = result.get(result.size() - 2).get("operatorName").toString();
+
+        //更新部门考勤表审批人信息
+        try {
+            Workbook workbook = WorkbookFactory.create(new FileInputStream(tableFilePath + fileName));
+            Sheet sheet = workbook.getSheetAt(0);
+            List<Integer> rowsToBeRemoved = new ArrayList<>();
+            for (int i = 0; i <= sheet.getLastRowNum(); i++) {
+                Row row = sheet.getRow(i);
+
+                if (isRowEmpty(row)) {
+                    rowsToBeRemoved.add(i);
+                    continue;
+                }
+                for (int j = 0; j <= row.getLastCellNum(); j++) {
+                    Cell cell = row.getCell(j);
+                    if (Objects.nonNull(cell)){
+                        if (cell.getCellTypeEnum() == CellType.STRING){
+                            String cellValue = cell.getStringCellValue();
+                            if (cellValue.equals("部门考勤员")){
+                                Cell cell1 = row.createCell(29);
+                                cell1.setCellValue("提交");
+                                Cell cell2 = row.createCell(31);
+                                cell2.setCellValue(startTime);
+                                break;
+                            }else if (cellValue.equals("部门负责人")){
+                                Cell cell3 = row.createCell(27);
+                                cell3.setCellValue(operatorName);
+                                Cell cell4 = row.createCell(29);
+                                cell4.setCellValue("审核通过");
+                                Cell cell5 = row.createCell(31);
+                                cell5.setCellValue(endTime);
+                                break;
+                            }
+                        }
+                    }
+                }
+
+            }
+
+            //删除空行
+            rowsToBeRemoved.remove(0);
+            rowsToBeRemoved.remove(rowsToBeRemoved.size() - 1);
+            for (int rowNum : rowsToBeRemoved) {
+                sheet.shiftRows(rowsToBeRemoved.get(0) + 1, sheet.getLastRowNum(), -1);
+            }
+
+            // 保存修改后的Excel文件
+            FileOutputStream fileOut = new FileOutputStream(tableFilePath + fileName.replace("(未审核)",""));
+            workbook.write(fileOut);
+            fileOut.close();
+
+            workbook.close();
+        } catch (IOException | EncryptedDocumentException e) {
+            e.printStackTrace();
+        } catch (InvalidFormatException e) {
+            throw new RuntimeException(e);
+        }
+
+        //更新宜搭考勤表
+        Map attachment = new HashMap();
+        String newDownloadUrl = downloadUrl + fileName.replace("(未审核)", "");
+        attachment.put("downloadUrl", newDownloadUrl);
+        attachment.put("name",fileName.replace("(未审核)",""));
+        attachment.put("previewUrl", newDownloadUrl);
+        attachment.put("url",newDownloadUrl);
+        Map map = new HashMap();
+        map.put("attachmentField_lzkvrlcl",new Map[]{attachment});
+
+        ydClient.operateData(YDParam.builder()
+                .formInstId(formInstId)
+                .updateFormDataJson(JSONArray.toJSONString(map))
+                .build(), YDConf.FORM_OPERATION.update);
+
+        //上传钉盘
+        Map dentry = uploadToDingTalk(tableFilePath + fileName.replace("(未审核)",""), userId);
+        String dentryUuid = dentry.get("uuid").toString();
+
+        //设置权限 发起人及综办可下载
+        Map<String,Object> param3 = new HashMap<>();
+        param3.put("unionId",ADMIN_UNION_ID);//管理员-任欢欢
+
+        List<Map> dentryPermissionList = new ArrayList<>();
+        dentryPermissionList.add(new HashMap<String,Object>(){{
+            put("type","USER");
+            put("id",userId);//发起人userid
+        }});
+        dentryPermissionList.add(new HashMap<String,Object>(){{
+            put("type","DEPT");
+            put("id",DEPT_ID);//综办部门id
+        }});
+        Map body3 = new HashMap();
+        body3.put("roleId","DOWNLOADER");//查看下载者
+        body3.put("members",dentryPermissionList);
+
+        DDR_New ddrNew3 = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v2.0/storage/spaces/dentries/" + dentryUuid + "/permissions", ddClient.initTokenHeader(), param3, body3, DDR_New.class);
+        if (ddrNew3.isSuccess()){
+            log.info("权限设置成功!");
+        }else {
+            log.error("权限设置失败!" + ddrNew3.getCode() + " " + ddrNew3.getMessage());
+        }
+
+        //查询未审核考勤表
+        Map<String,Object> param4 = new HashMap<>();
+        param4.put("unionId",ADMIN_UNION_ID);//管理员-任欢欢
+        param4.put("parentId",0);
+        DDR_New ddrNew4 = (DDR_New) UtilHttp.doGet("https://api.dingtalk.com/v1.0/storage/spaces/"+SPACE_ID+"/dentries", ddClient.initTokenHeader(), param4, DDR_New.class);
+        List<Map> dentries = ddrNew4.getDentries();
+        for (Map dentry2 : dentries) {
+            if (dentry2.get("name").toString().equals(fileName)) {
+                String dentryId = dentry2.get("id").toString();
+                //删除未审核考勤表
+                Map param5 = new HashMap();
+                param5.put("unionId",ADMIN_UNION_ID);//管理员-任欢欢
+                UtilHttp.doDelete("https://api.dingtalk.com/v1.0/storage/spaces/"+SPACE_ID+"/dentries/"+dentryId,ddClient.initTokenHeader(),param5, DDR_New.class);
+                break;
+            }
+        }
+
+
+    }
+
+    private static boolean isRowEmpty(Row row) {
+        if (row == null) return true;
+        for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
+            Cell cell = row.getCell(c);
+
+            if (cell != null){
+                CellType cellTypeEnum = cell.getCellTypeEnum();
+
+                if (cellTypeEnum == CellType.STRING){
+                    String stringCellValue = cell.getStringCellValue();
+                    if (!stringCellValue.isEmpty()){
+                        return false;
+                    }
+                } else if (cellTypeEnum != CellType.BLANK){
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    private Map uploadToDingTalk(String filePath, String userId) {
+        //获取当前时间戳
+        long beginTimestamp = System.currentTimeMillis();
+        System.out.println("开始上传部门考勤表:" + DateUtil.format(new Date(beginTimestamp), "yyyy-MM-dd HH:mm:ss"));
+
+        //文件
+        File file = new File(filePath);
+
+        //获取文件上传信息
+        String spaceId = SPACE_ID;//考勤报表-空间id
+        Map param = new HashMap();
+        param.put("unionId",ADMIN_UNION_ID);//任欢欢
+        Map body = new HashMap();
+        body.put("protocol","HEADER_SIGNATURE");
+        body.put("multipart",false);
+
+        DDR_New ddr = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/storage/spaces/" + spaceId + "/files/uploadInfos/query", ddConf.initTokenHeader(ddClient.getAccessToken()), param, body, DDR_New.class);
+        String uploadKey = ddr.getUploadKey();
+        Map headerSignatureInfo = ddr.getHeaderSignatureInfo();
+        Map<String,String> headers = (Map<String,String>) headerSignatureInfo.get("headers");
+        List<String> resourceUrls = (List<String>) headerSignatureInfo.get("resourceUrls");
+        String resourceUrl = resourceUrls.get(0);
+
+        Map dentry = new HashMap();
+        //使用OSS的header加签方式上传文件
+        try {
+            URL url = new URL(resourceUrl);
+            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
+            if (headers != null) {
+                for (Map.Entry<String, String> entry : headers.entrySet()) {
+                    connection.setRequestProperty(entry.getKey(), entry.getValue());
+                }
+            }
+            connection.setDoOutput(true);
+            connection.setRequestMethod("PUT");
+            connection.setUseCaches(false);
+            connection.setReadTimeout(10000);
+            connection.setConnectTimeout(10000);
+            connection.connect();
+            OutputStream out = connection.getOutputStream();
+            InputStream is = new FileInputStream(file);
+            byte[] b =new byte[1024];
+            int temp;
+            while ((temp=is.read(b))!=-1){
+                out.write(b,0,temp);
+            }
+            out.flush();
+            out.close();
+            int responseCode = connection.getResponseCode();
+            connection.disconnect();
+            if (responseCode == 200) {
+                System.out.println("上传成功");
+            } else {
+                System.out.println("上传失败");
+            }
+            //提交文件
+            Map body2 = new HashMap();
+            Map option = new HashMap();
+            option.put("conflictStrategy","OVERWRITE");
+            body2.put("uploadKey",uploadKey);
+            body2.put("name",file.getName());
+            body2.put("parentId","0");
+            body2.put("option",option);
+            DDR_New ddrNew = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/storage/spaces/" + spaceId + "/files/commit", ddClient.initTokenHeader(), param, body2, DDR_New.class);
+            dentry = ddrNew.getDentry();
+
+        }catch (IOException e){
+            log.info("上传文件异常:{}",e);
+        }
+
+        long endTimestamp = System.currentTimeMillis();
+        System.out.println("上传文件结束:" + DateUtil.format(new Date(endTimestamp), "yyyy-MM-dd HH:mm:ss"));
+        System.out.println("上传文件耗时:" + (endTimestamp - beginTimestamp)/1000.0 + "s");
+        return dentry;
+    }
+}

+ 42 - 0
src/main/java/com/malk/pro/zyjn/utils/UtilExcel.java

@@ -0,0 +1,42 @@
+package com.malk.pro.zyjn.utils;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.write.metadata.WriteSheet;
+import com.malk.utils.UtilFile;
+import lombok.Builder;
+import lombok.Data;
+import lombok.SneakyThrows;
+
+import javax.annotation.Nullable;
+import java.io.File;
+import java.io.InputStream;
+import java.util.List;
+
+@Builder
+@Data
+public class UtilExcel {
+    /**
+     * 列表与主表进行填充 [格式: 模板主表 {字段}, 列表 {.字段}]
+     */
+    @SneakyThrows
+    public static void exportAllSheetByTemplate(Object dataMain, List dataList, @Nullable String fileName, String tableFilePath, String templateName) {
+        InputStream inputStream = UtilFile.readPackageResource("templates/" + templateName);
+
+        File file = new File(tableFilePath + fileName + ".xlsx");
+        if (file.exists()) {
+            file.delete();
+        }
+
+        ExcelWriter workBook = EasyExcel.write(tableFilePath + fileName + ".xlsx").withTemplate(inputStream).build();
+
+        WriteSheet sheet = EasyExcel.writerSheet(0).build();
+        // 先单组数据填充,再多组数据填充
+        workBook.fill(dataMain, sheet);
+        workBook.fill(dataList, sheet);
+
+        workBook.finish();
+
+    }
+
+}