Selaa lähdekoodia

上海职业技能鉴定

wzy 10 kuukautta sitten
vanhempi
commit
5159c20159

+ 73 - 0
mjava-zhiyejineng/pom.xml

@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.2.0.RELEASE</version> <!-- 使用最新的稳定版或其他适用版本 -->
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+
+    <groupId>com.malk.zyjn</groupId>
+    <artifactId>mjava-zhiyejineng</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.malk</groupId>
+            <artifactId>base</artifactId>
+            <version>1.1-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>3.14.9</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>zhiyejineng</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <executable>true</executable>
+                    <includeSystemScope>true</includeSystemScope>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 17 - 0
mjava-zhiyejineng/src/main/java/com/malk/zyjn/ZyjnApplication.java

@@ -0,0 +1,17 @@
+package com.malk.zyjn;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication(scanBasePackages = {"com.malk"})
+@EnableScheduling
+public class ZyjnApplication {
+    public static void main(String[] args) {
+        try {
+            SpringApplication.run(ZyjnApplication.class,args);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+}

+ 72 - 0
mjava-zhiyejineng/src/main/java/com/malk/zyjn/controller/ZyjnController.java

@@ -0,0 +1,72 @@
+package com.malk.zyjn.controller;
+
+import com.malk.server.common.McR;
+import com.malk.service.dingtalk.DDClient;
+import com.malk.zyjn.service.ZyjnService;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.RequestBody;
+
+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
mjava-zhiyejineng/src/main/java/com/malk/zyjn/entity/Attendance.java

@@ -0,0 +1,54 @@
+package com.malk.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
mjava-zhiyejineng/src/main/java/com/malk/zyjn/service/ZyjnService.java

@@ -0,0 +1,15 @@
+package com.malk.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);
+}

+ 536 - 0
mjava-zhiyejineng/src/main/java/com/malk/zyjn/service/impl/ZyjnServiceImpl.java

@@ -0,0 +1,536 @@
+package com.malk.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.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.google.common.base.Strings;
+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 com.malk.utils.UtilMap;
+import com.malk.zyjn.entity.Attendance;
+import com.malk.zyjn.service.ZyjnService;
+import com.malk.zyjn.utils.UtilExcel;
+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.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+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;
+import java.util.stream.Collectors;
+@Slf4j
+@Service
+public class ZyjnServiceImpl implements ZyjnService {
+    @Value(value = "${tableFile.path}")
+    private String tableFilePath;
+
+    @Value(value = "${download.url}")
+    private String downloadUrl;
+
+    @Autowired
+    private DDClient ddClient;
+
+    @Autowired
+    private DDConf ddConf;
+
+    @Autowired
+    private YDClient ydClient;
+
+    @Autowired
+    private YDConf ydConf;
+
+    private static final String COLUM_ATTENDANCE_RESULTS = "995157155";//考勤结果列id
+
+    private static final String SPACE_ID = "24768523387";//钉盘考勤报表空间id
+
+    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,"假");
+                    }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,"工");
+                        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 {
+                        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")){
+            Map<String,Object> param = new HashMap<>();
+            param.put("systemToken",ydConf.getSystemToken());
+            param.put("userId","253434204020308091");//任欢欢
+            param.put("fileUrl",fileURL);
+
+            fileURL = ((DDR_New) UtilHttp.doGet("https://api.dingtalk.com/v1.0/yida/apps/temporaryUrls/" + ydConf.getAppType(), 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 downloadUrl = fileList.get(0).get("downloadUrl").toString();
+        String fileName = fileList.get(0).get("name").toString();
+        //将downloadurl下载到本地
+        try {
+            downloadFile(downloadUrl, tableFilePath + fileName);
+            System.out.println("文件下载成功!");
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        //获取审批记录
+        Map param = new HashMap<>();
+        param.put("appType",ydConf.getAppType());
+        param.put("systemToken",ydConf.getSystemToken());
+        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() - 1).get("operateTimeGMT").toString().replace("T", " ").replace("Z", "");
+        String operatorName = result.get(result.size() - 1).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.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;
+    }
+}

+ 44 - 0
mjava-zhiyejineng/src/main/java/com/malk/zyjn/utils/UtilExcel.java

@@ -0,0 +1,44 @@
+package com.malk.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 org.springframework.beans.factory.annotation.Value;
+
+import javax.annotation.Nullable;
+import javax.servlet.http.HttpServletResponse;
+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();
+
+    }
+
+}

+ 37 - 0
mjava-zhiyejineng/src/main/resources/application-dev.yml

@@ -0,0 +1,37 @@
+server:
+  port: 9021
+  servlet:
+    context-path: /zyjn
+
+spring:
+  datasource:
+    url: jdbc:mysql://localhost:3306/floe?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
+    username: root
+    password: 111111
+enable:
+  scheduling: false
+logging:
+  config: classpath:logback-spring.xml
+  path: /home/server/zyjn/log/
+  level:
+    com.malk.*: debug
+
+# dingtalk
+dingtalk:
+  agentId: 3191553633
+  appKey: dingn2nkwrrosmyjk9o2
+  appSecret: t26NJ2TIHeQZAG17QPJAPoVgrVwPUZCLH0JLO955_c0BoAhdaAS5eNf9Fc6KAepo
+  corpId:
+  aesKey:
+  token:
+
+# aliwork
+aliwork:
+  appType: APP_GKH227Q9PDQ2CYIIJSHJ
+  systemToken: I5D66NB1S3JNGJBDEND4L78FN8CT34LMQVKZLRP
+
+tableFile:
+  path: d:\\
+
+download:
+  url: https://887x6302o8.vicp.fun/zyjn/download/

+ 37 - 0
mjava-zhiyejineng/src/main/resources/application-prod.yml

@@ -0,0 +1,37 @@
+server:
+  port: 9021
+  servlet:
+    context-path: /zyjn
+
+spring:
+  datasource:
+    url: jdbc:mysql://localhost:3306/floe?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
+    username: root
+    password: 111111
+enable:
+  scheduling: false
+logging:
+  config: classpath:logback-spring.xml
+  path: /home/server/zhiyejineng/log/
+  level:
+    com.malk.*: debug
+
+# dingtalk
+dingtalk:
+  agentId: 3191553633
+  appKey: dingn2nkwrrosmyjk9o2
+  appSecret: t26NJ2TIHeQZAG17QPJAPoVgrVwPUZCLH0JLO955_c0BoAhdaAS5eNf9Fc6KAepo
+  corpId:
+  aesKey:
+  token:
+
+# aliwork
+aliwork:
+  appType: APP_GKH227Q9PDQ2CYIIJSHJ
+  systemToken: I5D66NB1S3JNGJBDEND4L78FN8CT34LMQVKZLRP
+
+tableFile:
+  path: /home/server/zhiyejineng/file/
+
+download:
+  url: https://mc.cloudpure.cn/zyjn/download/

+ 15 - 0
mjava-zhiyejineng/src/main/resources/application.yml

@@ -0,0 +1,15 @@
+spring:
+  profiles:
+    active: prod
+  servlet:
+    multipart:
+      max-file-size: 100MB
+      max-request-size: 100MB
+  http:
+    enabled: false
+
+#  configuration:
+#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+  global-config:
+    db-config:
+      id-type: auto

+ 61 - 0
mjava-zhiyejineng/src/main/resources/logback-spring.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false" scan="false" scanPeriod="60 seconds">
+    <springProperty scope="context" name="LOG_HOME" source="logging.path" defaultValue="/home/server/log/"/>
+    <property name="FileNamePattern" value="${LOG_HOME}%d{yyyyMM}/%d{dd}"/>
+
+    <!-- 定义控制台输出 -->
+    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - [%thread] - %-5level - %logger{50} - %msg%n</pattern>
+        </layout>
+    </appender>
+
+    <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 指定日志文件的名称 -->
+        <!--<file>${FileNamePattern}/info.log</file>-->
+
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${FileNamePattern}/info-%i.log</fileNamePattern>
+            <MaxHistory>30</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <MaxFileSize>30MB</MaxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern>
+        </layout>
+    </appender>
+
+    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
+        <discriminator>
+            <Key>processid</Key>
+            <DefaultValue>sys</DefaultValue>
+        </discriminator>
+        <sift>
+            <appender name="FILE-${processid}"
+                      class="ch.qos.logback.core.rolling.RollingFileAppender">
+                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                    <FileNamePattern>
+                        ${FileNamePattern}/${processid}.log
+                    </FileNamePattern>
+                </rollingPolicy>
+                <layout class="ch.qos.logback.classic.PatternLayout">
+                    <Pattern>
+                        %d{yyyyMMdd:HH:mm:ss.SSS} [%thread] %-5level %msg%n
+                    </Pattern>
+                </layout>
+            </appender>
+        </sift>
+    </appender>
+
+
+    <!-- 日志输出级别 -->
+    <logger name="org.springframework" level="debug"  additivity="false"/>
+    <logger name="com.zitoo.connecter" level="debug"/>
+    <root level="INFO">
+        <appender-ref ref="stdout"/>
+        <appender-ref ref="appLogAppender"/>
+        <appender-ref ref="SIFT"/>
+    </root>
+</configuration>

BIN
mjava-zhiyejineng/src/main/resources/templates/template.xlsx