Browse Source

师傅确认书

FengChaoYu 3 months ago
parent
commit
f6e14a4ec1

+ 6 - 0
mall-miniapp-service/pom.xml

@@ -361,6 +361,12 @@
                 </exclusion>
             </exclusions>
         </dependency>
+        <!-- 阿里云OCR识别 -->
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>alibabacloud-ocr_api20210707</artifactId>
+            <version>3.0.3</version>
+        </dependency>
     </dependencies>
 
 

+ 19 - 3
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/controller/user/WorkerController.java

@@ -8,13 +8,20 @@ import com.gree.mall.miniapp.bean.policy.PolicyOrderDetail;
 import com.gree.mall.miniapp.bean.policy.WorkerRemind;
 import com.gree.mall.miniapp.helper.ResponseHelper;
 import com.gree.mall.miniapp.logic.policy.WorkerLogic;
-import com.gree.mall.miniapp.plus.entity.*;
+import com.gree.mall.miniapp.plus.entity.AdminWebsit;
+import com.gree.mall.miniapp.plus.entity.Agreement;
+import com.gree.mall.miniapp.plus.entity.Policy;
+import com.gree.mall.miniapp.plus.entity.PolicyOrder;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import java.text.ParseException;
@@ -136,5 +143,14 @@ public class WorkerController {
         return ResponseHelper.success(payDetail);
     }
 
-
+    @PostMapping("/ocr/handwriting")
+    @ApiOperation(value = "师傅签名手写OCR识别")
+    public ResponseHelper<Boolean> ocrHandwriting(
+            @ApiParam(required = true, value = "拼接附件") @RequestParam MultipartFile file,
+            @ApiParam(required = true, value = "签名附件") @RequestParam MultipartFile signFile,
+            @ApiParam(required = true, value = "地区 gz=广州 fs=佛山") @RequestParam String type
+    ) throws Exception {
+        Boolean result = workerLogic.ocrHandwriting(file, signFile, type);
+        return ResponseHelper.success(result);
+    }
 }

+ 2 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/helper/ResponseHelper.java

@@ -10,6 +10,8 @@ public class ResponseHelper<T> {
     public final static int ResponseCode_COMMON = 501;//通用拦截提示
     public final static int ResponseCode_AUTH_ERROR = 1001;//非法请求
     public final static int ResponseCode_NOT_PHONE = 4001;//未找到师傅手机号
+    public final static int ResponseCode_NOT_SIGN_G_PAY_CONFIRM = 40171;//未广州签支付确认书
+    public final static int ResponseCode_NOT_SIGN_F_PAY_CONFIRM = 40172;//未佛山签支付确认书
 
     //无权限访问
     public final static int NOT_PERMISSION = 2001;

+ 40 - 1
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/logic/policy/WorkerLogic.java

@@ -3,6 +3,7 @@ package com.gree.mall.miniapp.logic.policy;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.gree.mall.miniapp.bean.PayDetail;
@@ -11,9 +12,9 @@ import com.gree.mall.miniapp.bean.policy.PolicyOrderDetail;
 import com.gree.mall.miniapp.bean.policy.WorkerRemind;
 import com.gree.mall.miniapp.bean.user.CurrentCompanyWechat;
 import com.gree.mall.miniapp.enums.ExamineWorkerStatusEnum;
-import com.gree.mall.miniapp.enums.IsEnum;
 import com.gree.mall.miniapp.enums.IsYesNoEnum;
 import com.gree.mall.miniapp.enums.PolicyOrderStutasEnum;
+import com.gree.mall.miniapp.enums.UserTypeEnum;
 import com.gree.mall.miniapp.exception.RemoteServiceException;
 import com.gree.mall.miniapp.logic.common.CommonLogic;
 import com.gree.mall.miniapp.logic.common.outside.WechatLogic;
@@ -21,11 +22,16 @@ import com.gree.mall.miniapp.plus.entity.*;
 import com.gree.mall.miniapp.plus.service.*;
 import com.gree.mall.miniapp.utils.IpUtil;
 import com.gree.mall.miniapp.utils.StringUtil;
+import com.gree.mall.miniapp.utils.ocr.OCRUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Date;
@@ -75,6 +81,9 @@ public class WorkerLogic {
     @Autowired
     MailboxService mailboxService;
 
+    @Autowired
+    OCRUtil ocrUtil;
+
 
 
     public List<WorkerRemind> remind() {
@@ -604,4 +613,34 @@ public class WorkerLogic {
         }
         return new ArrayList<>();
     }
+
+    public Boolean ocrHandwriting(MultipartFile joinFile, MultipartFile signFile, String type) throws Exception {
+        CurrentCompanyWechat currentCompanyWechat = commonLogic.getCurrentCompanyWechat();
+        final User user = currentCompanyWechat.getUser();
+        if (!user.getType().equals(UserTypeEnum.WORKER.getKey())) {
+            throw new RemoteServiceException("非“师傅”类型账号, 操作失败");
+        }
+        final InputStream inputStream = signFile.getInputStream();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int length = 0;
+        while ((length = inputStream.read(buffer)) != -1) {
+            baos.write(buffer, 0, length);
+        }
+        inputStream.close();
+        baos.close();
+        final String name = ocrUtil.handwritingORC(new ByteArrayInputStream(baos.toByteArray()));
+        if (!StrUtil.equals(name, user.getNickName().replace(" ", ""))) {
+            return false;
+        }
+        final CommonFile commonFile = commonLogic.uploadFile(joinFile);
+
+        userService.lambdaUpdate()
+                .set(type.equals("gz"), User::getWorkerSignGz, commonFile.getUrl())
+                .set(type.equals("fs"), User::getWorkerSignFs, commonFile.getUrl())
+                .eq(User::getUserId, user.getUserId())
+                .update();
+
+        return true;
+    }
 }

+ 31 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/logic/user/UserLogic.java

@@ -1,6 +1,7 @@
 package com.gree.mall.miniapp.logic.user;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.date.DateUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -1007,6 +1008,36 @@ public class UserLogic {
         if (StringUtils.isNotBlank(user.getMobile())) {
             userTypeInit(user);
         }
+
+        // 检查师傅确认书
+        if (user.getType().equals(UserTypeEnum.WORKER.getKey())) {
+            final List<WebsitUser> websitUsers = websitUserService.lambdaQuery()
+                    .select(WebsitUser::getWebsitId)
+                    .eq(WebsitUser::getUserId, user.getUserId())
+                    .in(WebsitUser::getExamineStatus, ExamineWorkerStatusEnum.OK.getKey(), ExamineWorkerStatusEnum.EXPIRED.getKey())
+                    .list();
+
+            if (CollectionUtil.isNotEmpty(websitUsers)) {
+                final List<String> websitIds = websitUsers.stream().map(WebsitUser::getWebsitId).distinct().collect(Collectors.toList());
+                final List<String> companyCodeList = adminWebsitService.lambdaQuery()
+                        .select(AdminWebsit::getBelongCompanyCode)
+                        .in(AdminWebsit::getWebsitId, websitIds)
+                        .groupBy(AdminWebsit::getBelongCompanyCode)
+                        .list()
+                        .stream()
+                        .map(AdminWebsit::getBelongCompanyCode)
+                        .collect(Collectors.toList());
+                for (String code : companyCodeList) {
+                    if (code.equals("S9219801") && StringUtils.isBlank(user.getWorkerSignGz())) {
+                        throw new RemoteServiceException(ResponseHelper.ResponseCode_NOT_SIGN_G_PAY_CONFIRM, "未广州签支付确认书");
+                    }
+                    if (code.equals("S9219807") && StringUtils.isBlank(user.getWorkerSignFs())) {
+                        throw new RemoteServiceException(ResponseHelper.ResponseCode_NOT_SIGN_F_PAY_CONFIRM, "未佛山签支付确认书");
+                    }
+                }
+            }
+        }
+
         return userWxBean;
     }
 

+ 75 - 0
mall-miniapp-service/src/main/java/com/gree/mall/miniapp/utils/ocr/OCRUtil.java

@@ -0,0 +1,75 @@
+package com.gree.mall.miniapp.utils.ocr;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.aliyun.auth.credentials.Credential;
+import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
+import com.aliyun.sdk.service.ocr_api20210707.AsyncClient;
+import com.aliyun.sdk.service.ocr_api20210707.models.RecognizeHandwritingRequest;
+import com.aliyun.sdk.service.ocr_api20210707.models.RecognizeHandwritingResponse;
+import com.aliyun.sdk.service.ocr_api20210707.models.RecognizeHandwritingResponseBody;
+import com.gree.mall.miniapp.exception.RemoteServiceException;
+import darabonba.core.client.ClientOverrideConfiguration;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.io.ByteArrayInputStream;
+import java.util.concurrent.CompletableFuture;
+
+@Service
+@Slf4j
+public class OCRUtil {
+
+    @Value("${ali.access.key.id}")
+    private String ACCESS_KEY_ID;
+    @Value("${ali.access.key.secert}")
+    private String ACCESS_KEY_SECERT;
+
+    public AsyncClient buildClient() {
+        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
+                .accessKeyId(ACCESS_KEY_ID)
+                .accessKeySecret(ACCESS_KEY_SECERT)
+                .build());
+        return AsyncClient.builder()
+                //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
+                .credentialsProvider(provider)
+                //.serviceConfiguration(Configuration.create()) // Service-level configuration
+                // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
+                .overrideConfiguration(
+                        ClientOverrideConfiguration.create()
+                                // Endpoint 请参考 https://api.aliyun.com/product/ocr-api
+                                // 服务地址 ocr-api.cn-hangzhou.aliyuncs.com
+                                // VPC地址 ocr-api-vpc.cn-hangzhou.aliyuncs.com
+                                .setEndpointOverride("ocr-api-vpc.cn-hangzhou.aliyuncs.com")
+                        //.setConnectTimeout(Duration.ofSeconds(30))
+                )
+                .build();
+    }
+
+    public String handwritingORC(ByteArrayInputStream byteArrayInputStream) {
+        AsyncClient client = buildClient();
+        // Parameter settings for API request
+        RecognizeHandwritingRequest recognizeHandwritingRequest = RecognizeHandwritingRequest.builder()
+                .body(byteArrayInputStream)
+                .needRotate(false)
+                // Request-level configuration rewrite, can set Http request parameters, etc.
+                // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
+                .build();
+        CompletableFuture<RecognizeHandwritingResponse> response = client.recognizeHandwriting(recognizeHandwritingRequest);
+        String content = "";
+        try {
+            final RecognizeHandwritingResponse resp = response.get();
+            final RecognizeHandwritingResponseBody body = resp.getBody();
+            final JSONObject data = JSONUtil.parseObj(body.getData());
+            content = StrUtil.replace(data.get("content", String.class), " ", "");
+        } catch (Exception e) {
+            throw new RemoteServiceException("OCR服务异常");
+        } finally {
+            client.close();
+        }
+
+        return content;
+    }
+}

+ 6 - 0
mall-server-api/pom.xml

@@ -436,6 +436,12 @@
             <version>1.6.2</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>alibabacloud-ocr_api20210707</artifactId>
+            <version>3.0.3</version>
+        </dependency>
+
 
     </dependencies>
 

+ 3 - 0
mall-server-api/sql/20241226-师傅收款手写签名.sql

@@ -0,0 +1,3 @@
+ALTER TABLE `user`
+    ADD COLUMN `worker_sign_gz` varchar(500) NULL COMMENT '师傅广州签确认书url' AFTER `is_buy`,
+    ADD COLUMN `worker_sign_fs` varchar(500) NULL COMMENT '师傅佛山签确认书url' AFTER `worker_sign_gz`;

+ 75 - 0
mall-server-api/src/main/java/com/gree/mall/manager/utils/ocr/OCRUtil.java

@@ -0,0 +1,75 @@
+package com.gree.mall.manager.utils.ocr;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.aliyun.auth.credentials.Credential;
+import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
+import com.aliyun.sdk.service.ocr_api20210707.AsyncClient;
+import com.aliyun.sdk.service.ocr_api20210707.models.RecognizeHandwritingRequest;
+import com.aliyun.sdk.service.ocr_api20210707.models.RecognizeHandwritingResponse;
+import com.aliyun.sdk.service.ocr_api20210707.models.RecognizeHandwritingResponseBody;
+import com.gree.mall.manager.exception.RemoteServiceException;
+import darabonba.core.client.ClientOverrideConfiguration;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.io.ByteArrayInputStream;
+import java.util.concurrent.CompletableFuture;
+
+@Service
+@Slf4j
+public class OCRUtil {
+
+    @Value("${ali.access.key.id}")
+    private String ACCESS_KEY_ID;
+    @Value("${ali.access.key.secert}")
+    private String ACCESS_KEY_SECERT;
+
+    public AsyncClient buildClient() {
+        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
+                .accessKeyId(ACCESS_KEY_ID)
+                .accessKeySecret(ACCESS_KEY_SECERT)
+                .build());
+        return AsyncClient.builder()
+                //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
+                .credentialsProvider(provider)
+                //.serviceConfiguration(Configuration.create()) // Service-level configuration
+                // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
+                .overrideConfiguration(
+                        ClientOverrideConfiguration.create()
+                                // Endpoint 请参考 https://api.aliyun.com/product/ocr-api
+                                // 服务地址 ocr-api.cn-hangzhou.aliyuncs.com
+                                // VPC地址 ocr-api-vpc.cn-hangzhou.aliyuncs.com
+                                .setEndpointOverride("ocr-api-vpc.cn-hangzhou.aliyuncs.com")
+                        //.setConnectTimeout(Duration.ofSeconds(30))
+                )
+                .build();
+    }
+
+    public String handwritingORC(ByteArrayInputStream byteArrayInputStream) {
+        AsyncClient client = buildClient();
+        // Parameter settings for API request
+        RecognizeHandwritingRequest recognizeHandwritingRequest = RecognizeHandwritingRequest.builder()
+                .body(byteArrayInputStream)
+                .needRotate(false)
+                // Request-level configuration rewrite, can set Http request parameters, etc.
+                // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
+                .build();
+        CompletableFuture<RecognizeHandwritingResponse> response = client.recognizeHandwriting(recognizeHandwritingRequest);
+        String content = "";
+        try {
+            final RecognizeHandwritingResponse resp = response.get();
+            final RecognizeHandwritingResponseBody body = resp.getBody();
+            final JSONObject data = JSONUtil.parseObj(body.getData());
+            content = StrUtil.replace(data.get("content", String.class), " ", "");
+        } catch (Exception e) {
+            throw new RemoteServiceException("OCR服务异常");
+        } finally {
+            client.close();
+        }
+
+        return content;
+    }
+}