1
0

2 Ревизии ab9e6d561b ... 86fea54679

Автор SHA1 Съобщение Дата
  zhouyy 86fea54679 Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper преди 4 седмици
  zhouyy dc693f7e59 数据拉取定时任务、逻辑补充 преди 4 седмици

+ 43 - 13
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/QRCodeController.java

@@ -2,7 +2,6 @@ package com.management.platform.controller;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
-import com.google.zxing.WriterException;
 import com.management.platform.entity.ErpOrderInfo;
 import com.management.platform.mapper.ErpOrderInfoMapper;
 import com.management.platform.util.HttpRespMsg;
@@ -17,6 +16,9 @@ import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
 import java.io.*;
 import java.util.Arrays;
 import java.util.List;
@@ -53,21 +55,36 @@ public class QRCodeController {
             String data = JSON.toJSONString(erpOrderInfo);
             int width = 300; // 二维码宽度
             int height = 300; // 二维码高度
+
+            String titleText = erpOrderInfo.getProjectId();
+            String footerLine1 = String.format("工单号: %s",null == erpOrderInfo.getOrderId()?"":erpOrderInfo.getOrderId());
+            String footerLine2 = String.format("行号: %s",null == erpOrderInfo.getLine()?"":erpOrderInfo.getLine());
+
             String s = null != erpOrderInfo.getMoDId() ? erpOrderInfo.getMoDId() : "";
             String fileName = "项目二维码_"+s+System.currentTimeMillis()+".png";
+
             try {
-                QRCodeUtil.generateQRCodeImage(data, width, height, uploadPath+fileName);
-            } catch (WriterException e) {
-                e.printStackTrace();
-                msg.setError("二维码生成失败,请联系管理员");
-                return msg;
-            } catch (IOException e) {
+                BufferedImage qrImage = QRCodeUtil.generateQRCodeImage(data, width, height);
+                // 创建带标题和两行底部文字的完整图片
+                BufferedImage combinedImage = QRCodeUtil.createCompleteImage(
+                        qrImage,
+                        titleText,
+                        new String[]{footerLine1, footerLine2},
+                        new Color(70, 130, 180),  // 标题背景色(钢蓝色)
+                        new Color(220, 220, 220)   // 底部背景色(浅灰色)
+                );
+
+                // 保存最终图片
+                File outputFile = new File(uploadPath+fileName);
+                ImageIO.write(combinedImage, "png", outputFile);
+            } catch (Exception e) {
                 e.printStackTrace();
                 msg.setError("二维码生成失败,请联系管理员");
                 return msg;
             }
             filesToZip[index] = uploadPath+fileName;
             index++;
+
         }
         String zipFileName = System.currentTimeMillis()+".zip";
         String zipFile = uploadPath+zipFileName;
@@ -108,16 +125,29 @@ public class QRCodeController {
         HttpRespMsg msg = new HttpRespMsg();
         ErpOrderInfo erpOrderInfo = erpOrderInfoMapper.selectById(erpId);
         String data = JSON.toJSONString(erpOrderInfo);
+
+        String titleText = erpOrderInfo.getProjectId();
+        String footerLine1 = String.format("工单号: %s",null == erpOrderInfo.getOrderId()?"":erpOrderInfo.getOrderId());
+        String footerLine2 = String.format("行号: %s",null == erpOrderInfo.getLine()?"":erpOrderInfo.getLine());
+
         int width = 300; // 二维码宽度
         int height = 300; // 二维码高度
         String fileName = "项目二维码_"+System.currentTimeMillis()+".png";
         try {
-            QRCodeUtil.generateQRCodeImage(data, width, height, uploadPath+fileName);
-        } catch (WriterException e) {
-            e.printStackTrace();
-            msg.setError("二维码生成失败,请联系管理员");
-            return msg;
-        } catch (IOException e) {
+            BufferedImage qrImage = QRCodeUtil.generateQRCodeImage(data, width, height);
+            // 创建带标题和两行底部文字的完整图片
+            BufferedImage combinedImage = QRCodeUtil.createCompleteImage(
+                    qrImage,
+                    titleText,
+                    new String[]{footerLine1, footerLine2},
+                    new Color(70, 130, 180),  // 标题背景色(钢蓝色)
+                    new Color(220, 220, 220)   // 底部背景色(浅灰色)
+            );
+
+            // 保存最终图片
+            File outputFile = new File(uploadPath+fileName);
+            ImageIO.write(combinedImage, "png", outputFile);
+        } catch (Exception e) {
             e.printStackTrace();
             msg.setError("二维码生成失败,请联系管理员");
             return msg;

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/UserMapper.java

@@ -59,4 +59,6 @@ public interface UserMapper extends BaseMapper<User> {
     void updateActiveByIds(List<String> array, int isActive);
 
     void unbindCorpWX(String id);
+
+    List<User> getWithFunction(@Param("companyId") Integer companyId,@Param("functionName") String functionName);
 }

+ 8 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceMonthlyWorktimeServiceImpl.java

@@ -22,11 +22,10 @@ import org.springframework.web.client.RestTemplate;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
-import java.math.BigDecimal;
-import java.math.RoundingMode;
 
 /**
  * <p>
@@ -110,13 +109,19 @@ public class FinanceMonthlyWorktimeServiceImpl extends ServiceImpl<FinanceMonthl
                 ResponseEntity<String> tisResponse = restTemplate.exchange(insertUrl, HttpMethod.POST, insertEntity, String.class);
                 if (tisResponse.getStatusCode() == HttpStatus.OK) {
                     System.out.println("插入成功");
+                    financeMonthlyWorktimeMapper.update(null,new LambdaUpdateWrapper<FinanceMonthlyWorktime>()
+                            .eq(FinanceMonthlyWorktime::getId,fmwId)
+                            .set(FinanceMonthlyWorktime::getIsSend, 1)
+                            .set(FinanceMonthlyWorktime::getLastSendTime, LocalDateTime.now())
+                    );
                 }else{
                     System.out.println("插入失败");
                 }
             }
 
         }
-
+        financeMonthlyWorktime = financeMonthlyWorktimeMapper.selectById(fmwId);
+        httpRespMsg.setData(financeMonthlyWorktime);
         return httpRespMsg;
     }
 

+ 5 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/TaskGroupServiceImpl.java

@@ -2,11 +2,14 @@ package com.management.platform.service.impl;
 
 import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.entity.*;
 import com.management.platform.entity.vo.setTemplate;
 import com.management.platform.mapper.*;
-import com.management.platform.service.*;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.service.StagesService;
+import com.management.platform.service.TaskExecutorService;
+import com.management.platform.service.TaskGroupService;
+import com.management.platform.service.TaskService;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.ListUtil;
 import com.management.platform.util.MessageUtils;
@@ -20,7 +23,6 @@ import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * <p>

+ 87 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/DataCollectTask.java

@@ -1,9 +1,13 @@
 package com.management.platform.task;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.entity.*;
 import com.management.platform.entity.vo.TisTimeVO;
 import com.management.platform.mapper.*;
+import com.management.platform.service.StagesService;
+import com.management.platform.service.TaskService;
+import com.management.platform.util.MessageUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.ParameterizedTypeReference;
@@ -58,6 +62,8 @@ public class DataCollectTask {
     private FmwDetailMapper fmwDetailMapper;
     @Autowired
     private FinanceMonthlyWorktimeMapper financeMonthlyWorktimeMapper;
+    @Autowired
+    private CompanyMapper companyMapper;
 
 
 //    private static HikariDataSource sqlServerDataSource;
@@ -504,7 +510,7 @@ public class DataCollectTask {
         RestTemplate restTemplate = new RestTemplate();
         String sumUrl = PREFIX_URL+"/dataCollect/getSqlServerProjectDataSum";
         String listUrl = PREFIX_URL+"/dataCollect/getSqlServerProjectDataList";
-
+        Company company = companyMapper.selectById(specialCompanyId);
         try {
             ResponseEntity<String> sumResponse = restTemplate.exchange(
                     sumUrl,
@@ -548,7 +554,13 @@ public class DataCollectTask {
                                 toAddList.addAll(dataList);
                             }
                             if(!CollectionUtils.isEmpty(toAddList)){
-                                projectMapper.batchInsert(toAddList);
+                                for (Project project : toAddList) {
+                                    projectMapper.insert(project);
+                                    if (company.getPackageProject() == 1) {
+                                        initGroup(specialCompanyId,project.getId());
+                                    }
+                                }
+//                                projectMapper.batchInsert(toAddList);
                             }
                             if(!CollectionUtils.isEmpty(toUpdateList)){
                                 for (Project orderInfo : toUpdateList) {
@@ -569,6 +581,79 @@ public class DataCollectTask {
 
     }
 
+    @Resource
+    private GroupTemplateMapper groupTemplateMapper;
+
+    @Resource
+    private GroupTmpstagesMapper groupTmpstagesMapper;
+
+    @Resource
+    private StagesService stagesService;
+
+    @Resource
+    private GtemplateTaskMapper gtemplateTaskMapper;
+    @Resource
+    private TaskGroupMapper taskGroupMapper;
+
+    @Resource
+    private TaskService taskService;
+
+    public void initGroup(Integer companyId, Integer projectId) {
+        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
+                .eq(User::getRoleName, "超级管理员")
+                .last(" limit 1")
+        );
+        List<GroupTemplate> groupTemplates = groupTemplateMapper.selectList(new QueryWrapper<GroupTemplate>()
+                .eq("company_id", companyId).eq("cre_with_pro", true));
+        if (groupTemplates.size()==0){
+            //创建默认分组
+            TaskGroup group = new TaskGroup();
+            group.setProjectId(projectId);
+            //group.setName("项目阶段");
+            group.setName(MessageUtils.message("entry.projectStage"));
+            taskGroupMapper.insert(group);
+        }else{
+            for (GroupTemplate groupTemplate : groupTemplates) {
+                TaskGroup group = new TaskGroup();
+                group.setProjectId(projectId);
+                group.setName(groupTemplate.getName());
+                taskGroupMapper.insert(group);
+                //从模板创建任务列表
+                List<GroupTmpstages> stages = groupTmpstagesMapper.selectList(new QueryWrapper<GroupTmpstages>().eq("template_id", groupTemplate.getId()));
+                List<Stages> batchList = new ArrayList<>();
+                stages.forEach(s->{
+                    Stages stageItem = new Stages();
+                    stageItem.setGroupId(group.getId());
+                    stageItem.setStagesName(s.getStagesName());
+                    stageItem.setSequence(s.getSequence());
+                    stageItem.setProjectId(projectId);
+                    batchList.add(stageItem);
+                });
+                stagesService.saveBatch(batchList);
+                //阶段的任务,里程碑,风险
+                List<GtemplateTask> gtemplateTaskList = gtemplateTaskMapper.selectList(
+                        new QueryWrapper<GtemplateTask>().eq("gtemplate_id", groupTemplate.getId())
+                                .orderByAsc("seq"));
+                if (gtemplateTaskList.size() > 0) {
+                    List<Task> taskList = new ArrayList<>();
+                    gtemplateTaskList.forEach(gt->{
+                        Task task = gt.toTask();
+                        task.setProjectId(projectId);
+                        task.setGroupId(group.getId());
+                        String sName = stages.stream().filter(s->s.getId().equals(gt.getTstagesId())).findFirst().get().getStagesName();
+                        Integer realStageId = batchList.stream().filter(bat->bat.getStagesName().equals(sName)).findFirst().get().getId();
+                        task.setStagesId(realStageId);
+                        task.setCreaterId(user.getId());
+                        task.setCreaterName(user.getName());
+                        task.setCreatorColor(user.getColor());
+                        taskList.add(task);
+                    });
+                    taskService.saveBatch(taskList);
+                }
+            }
+        }
+    }
+
     @Scheduled(cron = "0 30 3 * * ?")
     @Async
     public void businessTripTask(){

+ 20 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -1255,6 +1255,14 @@ public class TimingTask {
             List<Integer> taskIds = taskList.stream().map(Task::getId).distinct().collect(Collectors.toList());
             taskIds.add(-1);
             List<TaskExecutor> taskExecutorList = taskExecutorMapper.selectList(new QueryWrapper<TaskExecutor>().in("task_id", taskIds));
+
+            List<User> functionUsers = userMapper.getWithFunction(wxCorpInfo.getCompanyId(),"接收所有超期任务提醒");
+            String sendWxIds = "";
+            if(CollectionUtils.isNotEmpty(functionUsers)){
+                sendWxIds = functionUsers.stream().filter(t -> org.apache.commons.lang3.StringUtils.isNotBlank(t.getCorpwxUserid()))
+                        .map(User::getCorpwxUserid).distinct().collect(Collectors.joining("|"));
+            }
+
             for (Task task : taskList) {
                 List<String> list = taskExecutorList.stream().filter(tl -> tl.getTaskId().equals(task.getId())).map(TaskExecutor::getExecutorId).distinct().collect(Collectors.toList());
                 String corpUserid = userList.stream().filter(ul -> list.contains(ul.getId())).map(User::getCorpwxUserid).distinct().collect(Collectors.joining(","));
@@ -1267,6 +1275,18 @@ public class TimingTask {
                 }
                 stringBuilder.append("截止,请抓紧时间完成!");
                 wxCorpInfoService.sendWXCorpMsg(wxCorpInfo,corpUserid,stringBuilder.toString(),"task",null);
+                if(org.apache.commons.lang3.StringUtils.isNotBlank(sendWxIds)){
+                    StringBuilder msg=new StringBuilder();
+                    msg.append("任务["+task.getName()+"]");
+                    if(task.getEndDate().isEqual(now)){
+                        msg.append("今天");
+                    }else if(task.getEndDate().isEqual(now.plusDays(1))){
+                        msg.append("一天后");
+                    }
+                    msg.append("截止,请抓紧时间完成!");
+                    wxCorpInfoService.sendWXCorpMsg(wxCorpInfo,sendWxIds,msg.toString(),"task",null);
+                }
+
             }
         }
     }

+ 100 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/QRCodeUtil.java

@@ -2,6 +2,7 @@ package com.management.platform.util;
 
 import com.google.zxing.*;
 import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
+import com.google.zxing.client.j2se.MatrixToImageWriter;
 import com.google.zxing.common.BitMatrix;
 import com.google.zxing.common.HybridBinarizer;
 import com.google.zxing.qrcode.QRCodeWriter;
@@ -19,6 +20,105 @@ import java.util.Map;
 
 public class QRCodeUtil {
 
+    public static BufferedImage createCompleteImage(
+            BufferedImage qrImage,
+            String titleText,
+            String[] footerLines,
+            Color titleBgColor,
+            Color footerBgColor) {
+
+        // 设置字体
+        Font titleFont = new Font("微软雅黑", Font.BOLD, 24);
+        Font footerFont = new Font("微软雅黑", Font.PLAIN, 16);
+        Color textColor = Color.WHITE; // 标题文字颜色
+        Color footerTextColor = Color.BLACK; // 底部文字颜色
+
+        // 计算各部分尺寸
+        BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D g2d = tempImage.createGraphics();
+
+        // 计算标题区域高度
+        g2d.setFont(titleFont);
+        FontMetrics titleMetrics = g2d.getFontMetrics();
+        int titleHeight = titleMetrics.getHeight() + 40; // 增加内边距
+
+        // 计算底部区域高度(基于两行文字)
+        g2d.setFont(footerFont);
+        FontMetrics footerMetrics = g2d.getFontMetrics();
+        int lineHeight = footerMetrics.getHeight();
+        int footerHeight = (lineHeight * footerLines.length) + 40; // 两行文字加上边距
+
+        g2d.dispose();
+
+        // 计算总高度和宽度
+        int padding = 20;
+        int totalWidth = qrImage.getWidth() + padding * 2;
+        int totalHeight = titleHeight + qrImage.getHeight() + footerHeight;
+
+        // 创建新图片
+        BufferedImage combinedImage = new BufferedImage(
+                totalWidth, totalHeight, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D graphics = combinedImage.createGraphics();
+
+        // 设置渲染质量
+        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
+
+        // 1. 绘制标题区域
+        graphics.setColor(titleBgColor);
+        graphics.fillRect(0, 0, totalWidth, titleHeight);
+
+        // 绘制标题文字(居中)
+        graphics.setFont(titleFont);
+        graphics.setColor(textColor);
+        int titleX = (totalWidth - titleMetrics.stringWidth(titleText)) / 2;
+        int titleY = titleHeight / 2 + titleMetrics.getAscent() / 2;
+        graphics.drawString(titleText, titleX, titleY);
+
+        // 2. 绘制二维码区域(居中)
+        int qrX = (totalWidth - qrImage.getWidth()) / 2;
+        graphics.drawImage(qrImage, qrX, titleHeight, null);
+
+        // 3. 绘制底部区域
+        graphics.setColor(footerBgColor);
+        graphics.fillRect(0, titleHeight + qrImage.getHeight(),
+                totalWidth, footerHeight);
+
+        // 绘制底部文字(两行,分别居中)
+        graphics.setFont(footerFont);
+        graphics.setColor(footerTextColor);
+
+        // 第一行文字位置
+        int line1Y = titleHeight + qrImage.getHeight() + 30;
+        int line1X = (totalWidth - footerMetrics.stringWidth(footerLines[0])) / 2;
+        graphics.drawString(footerLines[0], line1X, line1Y);
+
+        // 第二行文字位置
+        if (footerLines.length > 1) {
+            int line2Y = line1Y + lineHeight;
+            int line2X = (totalWidth - footerMetrics.stringWidth(footerLines[1])) / 2;
+            graphics.drawString(footerLines[1], line2X, line2Y);
+        }
+
+        // 添加细边框
+        graphics.setColor(new Color(200, 200, 200));
+        graphics.drawRect(0, 0, totalWidth - 1, totalHeight - 1);
+
+        graphics.dispose();
+        return combinedImage;
+    }
+
+    public static BufferedImage generateQRCodeImage(String text, int width, int height) throws Exception {
+        QRCodeWriter qrCodeWriter = new QRCodeWriter();
+        Map<EncodeHintType, Object> hints = new HashMap<>();
+        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
+        hints.put(EncodeHintType.MARGIN, 1);
+
+        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
+        return MatrixToImageWriter.toBufferedImage(bitMatrix);
+    }
+
+
     /**字符串生成二维码*/
     public static void generateQRCodeImage(String text, int width, int height, String filePath)
             throws WriterException, IOException {

+ 9 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserMapper.xml

@@ -286,6 +286,15 @@
         AND (induction_date &lt;= #{startDate} OR induction_date is NULL)
         AND id not IN (SELECT * from user_exclude)
     </select>
+    <select id="getWithFunction" resultType="com.management.platform.entity.User">
+        select user.*
+        from user
+                 left join sys_role_function srf on user.role_id = srf.role_id
+                 left join sys_function sf on srf.function_id = sf.id
+        where user.company_id = #{companyId}
+          and sf.name = #{functionName}
+          and user.is_active = 1
+    </select>
 
     <update id="updateActiveByIds">
         update user set is_active=1 WHERE id IN