Kaynağa Gözat

修改生成二维码接口

yusm 1 hafta önce
ebeveyn
işleme
4f13af4e3f

+ 84 - 6
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/WechatAccountController.java

@@ -12,6 +12,7 @@ import com.management.platform.service.CompanyService;
 import com.management.platform.service.UserQrCodeService;
 import com.management.platform.service.UserService;
 import com.management.platform.service.WechatAccountService;
+import com.management.platform.service.impl.QRCodeService;
 import com.management.platform.service.impl.WechatApiService;
 import com.management.platform.util.FileZipUtil;
 import com.management.platform.util.HttpRespMsg;
@@ -37,10 +38,7 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.InetAddress;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
@@ -79,6 +77,9 @@ public class WechatAccountController {
     @Value(value ="${upload.path}")
     private String uploadPath;
 
+    @Resource
+    private QRCodeService qrCodeService;
+
     private final static String prefixUrl="https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=";
 
 
@@ -230,8 +231,8 @@ public class WechatAccountController {
     }
 
     //一键生成所有员工的二维码
-    @RequestMapping(value = "oneClickGeneration")
-    public HttpRespMsg oneClickGeneration(HttpServletRequest request) {
+    @RequestMapping(value = "oneClickGenerationOld")
+    public HttpRespMsg oneClickGenerationOld(HttpServletRequest request) {
         HttpRespMsg msg = new HttpRespMsg();
         String token = request.getHeader("Token");
         User user = userService.getById(token);
@@ -294,6 +295,83 @@ public class WechatAccountController {
     }
 
 
+    //一键生成所有员工的二维码
+    @RequestMapping(value = "oneClickGeneration")
+    public HttpRespMsg oneClickGeneration(HttpServletRequest request) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("Token");
+        User user = userService.getById(token);
+
+        // 检查公众号配置
+        WechatAccount wechatAccount = wechatAccountService.getOne(
+                new QueryWrapper<WechatAccount>().eq("company_id", user.getCompanyId()));
+        if (wechatAccount == null) {
+            msg.setError("该公司没有配置公众号相关的参数");
+            return msg;
+        }
+
+        // 获取微信access_token
+        String accessToken = wechatAccountService.getAccessToken(user.getCompanyId(), wechatAccount.getAppId());
+
+        // 查询已生成二维码的员工
+        List<UserQrCode> qrCodeList = userQrCodeService.list(
+                new QueryWrapper<UserQrCode>().eq("company_id", user.getCompanyId()));
+        List<String> userAlreadyIds = qrCodeList.stream()
+                .map(UserQrCode::getUserId)
+                .collect(Collectors.toList());
+        userAlreadyIds.add("-1"); // 避免空列表导致SQL异常
+
+        // 查询未生成二维码的员工
+        List<User> userList = userService.list(
+                new QueryWrapper<User>()
+                        .notIn("id", userAlreadyIds)
+                        .eq("company_id", user.getCompanyId()));
+
+        if (!userList.isEmpty()) {
+            List<CompletableFuture<String>> futures = new ArrayList<>();
+            List<String> failedUsers = new ArrayList<>();
+
+            for (User u : userList) {
+                try {
+                    // 异步生成二维码并保存
+                    CompletableFuture<String> future = qrCodeService.generateAndSaveQRCode(
+                            accessToken, u.getId(), u.getName());
+
+                    future.thenAccept(filePath -> {
+                        // 成功生成后,保存记录到数据库
+                        UserQrCode qrCode = new UserQrCode();
+                        qrCode.setCompanyId(user.getCompanyId());
+                        qrCode.setUserId(u.getId());
+                        qrCode.setImg(filePath); // 存储文件路径
+                        userQrCodeService.save(qrCode);
+                    }).exceptionally(e -> {
+                        // 记录失败用户
+                        failedUsers.add(u.getName());
+                        return null;
+                    });
+
+                    futures.add(future);
+                } catch (Exception e) {
+                    failedUsers.add(u.getName());
+                }
+            }
+
+            // 等待所有任务完成(可选)
+            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
+
+            if (!failedUsers.isEmpty()) {
+                msg.setError("部分员工二维码生成失败: " + String.join(", ", failedUsers));
+            } else {
+                msg.setData("所有员工二维码生成成功!");
+            }
+        } else {
+            msg.setData("没有需要生成二维码的员工。");
+        }
+
+        return msg;
+    }
+
+
 
 
     @Async("taskExecutor")

+ 2 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/WechatCallbackController.java

@@ -24,6 +24,7 @@ import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Arrays;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -180,6 +181,7 @@ public class WechatCallbackController {
                         custom.setCustomName(openId);//用户的openId
                         custom.setIsDelete(0);
                         custom.setInchargerId(miniBindUserList.get(0).getUserId());
+                        custom.setCreateTime(new Date());
                         if (StringUtils.isNotEmpty(miniBindUserList.get(0).getUserId())) {
                             User user = userService.getById(miniBindUserList.get(0).getUserId());
                             custom.setCompanyId(user != null ? user.getCompanyId() : null);

+ 51 - 43
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/QRCodeService.java

@@ -1,79 +1,87 @@
 package com.management.platform.service.impl;
 
-import lombok.extern.slf4j.Slf4j;
+
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.ByteArrayResource;
-import org.springframework.core.io.Resource;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.*;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
 
-import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 @Service
-@Slf4j
 public class QRCodeService {
 
-    private static final String QR_CODE_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit";
+    @Value(value = "upload.path")// 配置文件中的上传路径,例如:/data/uploads/
+    private String uploadPath;
 
+    private static final String QR_CODE_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit";
 
     @Autowired
     private RestTemplate restTemplate;
 
+    /**
+     * 生成二维码并保存到本地
+     * @param accessToken 微信access_token
+     * @param userId 用户ID(用于scene参数)
+     * @param userName 用户姓名(用于文件名)
+     * @return 文件保存路径(异步)
+     */
+    @Async("taskExecutor")
+    public CompletableFuture<String> generateAndSaveQRCode(String accessToken, String userId, String userName) {
+        try {
+            // 生成二维码字节数据
+            byte[] qrCodeBytes = generateQRCode(accessToken, userId);
+
+            // 创建上传目录(如果不存在)
+            Path uploadDir = Paths.get(uploadPath);
+            if (!Files.exists(uploadDir)) {
+                Files.createDirectories(uploadDir);
+            }
+
+            // 文件名:员工姓名 + .jpg
+            String fileName = userName + ".jpg";
+            Path filePath = uploadDir.resolve(fileName);
 
-    public byte[] generateQRCode(String accessToken) {
+            // 保存文件
+            Files.write(filePath, qrCodeBytes);
 
+            return CompletableFuture.completedFuture(filePath.toString());
+        } catch (Exception e) {
+            return CompletableFuture.completedFuture("");
+        }
+    }
+
+    /**
+     * 调用微信API生成二维码字节数据
+     */
+    private byte[] generateQRCode(String accessToken, String userId) {
         HttpHeaders headers = new HttpHeaders();
         headers.setContentType(MediaType.APPLICATION_JSON);
 
         Map<String, Object> body = new HashMap<>();
-        body.put("scene", "8453269023523102720");
+        body.put("scene", userId); // 使用用户ID作为scene参数
         body.put("page", "pages/index/index");
         body.put("width", 430);
         body.put("is_hyaline", true);
 
-        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body,headers);
+        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body, headers);
 
         ResponseEntity<byte[]> response = restTemplate.exchange(
                 QR_CODE_URL + "?access_token=" + accessToken,
                 HttpMethod.POST,
                 entity,
                 byte[].class);
-        // 验证响应
-        if (response.getStatusCode() != HttpStatus.OK) {
-            throw new RuntimeException("请求失败,状态码: " + response.getStatusCode());
-        }
-        log.info("QR code generation result: {}", response.getBody());
-        byte[] result = response.getBody();
-
-        // 简单验证是否是PNG文件 (PNG文件头)
-        if (result == null || result.length < 8 ||
-                result[0] != (byte) 0x89 || result[1] != 'P' ||
-                result[2] != 'N' || result[3] != 'G') {
-            String error = result != null ? new String(result, StandardCharsets.UTF_8) : "null";
-            throw new RuntimeException("无效的图片数据,可能是错误响应: " + error);
-        }
-
-        return result;
-    }
-
-    public ResponseEntity<Resource> generateQRCodeResponse(String accessToken) {
-        byte[] qrCode = generateQRCode(accessToken);
 
-        ByteArrayResource resource = new ByteArrayResource(qrCode) {
-            @Override
-            public String getFilename() {
-                return "qrcode_" + System.currentTimeMillis() + ".png";
-            }
-        };
-
-        return ResponseEntity.ok()
-                .contentType(MediaType.IMAGE_PNG)
-                .header(HttpHeaders.CONTENT_DISPOSITION,
-                        "inline; filename=\"" + resource.getFilename() + "\"")
-                .body(resource);
+        if (response.getStatusCode() != HttpStatus.OK || response.getBody() == null) {
+            throw new RuntimeException("生成二维码失败,状态码: " + response.getStatusCode());
+        }
+        return response.getBody();
     }
-}
-
+}