Pārlūkot izejas kodu

add:OCR-二手委托人接口

lyx 3 nedēļas atpakaļ
vecāks
revīzija
87b5632edb

+ 68 - 49
alien-store/src/main/java/shop/alien/store/controller/AliController.java

@@ -1,13 +1,17 @@
 package shop.alien.store.controller;
 
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import io.swagger.annotations.*;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 import shop.alien.entity.result.R;
+import shop.alien.entity.store.LifeUser;
 import shop.alien.entity.store.StoreAliPayLog;
+import shop.alien.entity.store.StoreInfo;
+import shop.alien.entity.store.StoreUser;
 import shop.alien.store.service.AliService;
 import shop.alien.store.service.LifeUserService;
 import shop.alien.store.service.StoreInfoService;
@@ -22,8 +26,10 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.text.SimpleDateFormat;
 import java.util.Date;
-import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * @author ssk
@@ -67,17 +73,51 @@ public class AliController {
 
     @ApiOperation("身份证二要素核验")
     @ApiOperationSupport(order = 2)
-    @ApiImplicitParams({@ApiImplicitParam(name = "name", value = "姓名", dataType = "String", paramType = "query", required = true),
-            @ApiImplicitParam(name = "idCard", value = "身份证号", dataType = "String", paramType = "query", required = true)})
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "name", value = "姓名", dataType = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "idCard", value = "身份证号", dataType = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "appType", value = "端区分(0:用户, 1:商家)", dataType = "Integer", paramType = "query", required = true, defaultValue = "0")
+    })
     @GetMapping("/getIdInfo")
-    public R getIdInfo(String name, String idCard) {
+    public R getIdInfo(@RequestParam("name") String name, @RequestParam("idCard") String idCard, @RequestParam("appType") Integer appType) {
         log.info("AliController.getIdInfo?name={}&idCard={}", name, idCard);
+        int size = 0;
+        if (appType == 0) {
+            //根据身份查询未注销的用户
+            size = lifeUserService
+                    .list(new LambdaQueryWrapper<LifeUser>()
+                            .eq(LifeUser::getIdCard, idCard)
+                            .eq(LifeUser::getRealName, name)
+                            .eq(LifeUser::getLogoutFlag, 0))
+                    .size();
+        } else {
+            //根据身份查询已入住或审核中的商家
+            List<StoreUser> storeUserList = storeUserService
+                    .list(new LambdaQueryWrapper<StoreUser>()
+                            .eq(StoreUser::getIdCard, idCard)
+                            .eq(StoreUser::getName, name));
+            List<Integer> storeIds = storeUserList.stream()
+                    .map(StoreUser::getStoreId)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toList());
+            if (!storeIds.isEmpty()) {
+                size = storeInfoService
+                        .list(new LambdaQueryWrapper<StoreInfo>()
+                                .in(StoreInfo::getId, storeIds)
+                                .notIn(StoreInfo::getStoreApplicationStatus, 2))
+                        .size();
+            }
+        }
+        if (size > 0) {
+            return R.fail("该身份证已实名认证过");
+        }
         if (aliPayConfig.getIdInfo(name, idCard)) {
             return R.success("身份验证成功");
         }
-        Map map = new HashMap();
-        map.put("msg","身份验证失败");
-        return R.data(map,"身份验证失败");
+//        Map map = new HashMap();
+//        map.put("msg","身份验证失败");
+//        return R.data(map,"身份验证失败");
+        return R.fail("身份证号与姓名不一致,请检查后重新填写");
     }
 
     @ApiOperation("单笔转账接口")
@@ -225,63 +265,42 @@ public class AliController {
         return R.data(aliApi.promotionPackagePay(price, subject));
     }
 
-    @ApiOperation("退款")
+    @ApiOperation("处理退款")
     @ApiOperationSupport(order = 13)
     @ApiImplicitParams({
-            @ApiImplicitParam(name = "outTradeNo", value = "订单号", dataType = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "outTradeNo", value = "订单号", dataType = "String", paramType = "query", required = true),
             @ApiImplicitParam(name = "refundAmount", value = "退款金额", dataType = "String", paramType = "query", required = true),
             @ApiImplicitParam(name = "refundReason", value = "退款原因", dataType = "String", paramType = "query", required = true),
-            @ApiImplicitParam(name = "partialRefundCode", value = "部分退款编码", dataType = "String", paramType = "query", required = false)
+            @ApiImplicitParam(name = "partialRefundCode", value = "部分退款编号", dataType = "String", paramType = "query")
     })
     @GetMapping("/processRefund")
-    public String processRefund(@RequestParam(value = "outTradeNo") String outTradeNo,
-                                       @RequestParam(value = "refundAmount") String refundAmount,
-                                       @RequestParam(value = "refundReason") String refundReason,
-                                       @RequestParam(value = "partialRefundCode") String partialRefundCode) {
+    public String processRefund(@RequestParam("outTradeNo") String outTradeNo,
+                                @RequestParam("refundAmount") String refundAmount,
+                                @RequestParam("refundReason") String refundReason,
+                                @RequestParam(value = "partialRefundCode", required = false) String partialRefundCode) {
+        log.info("AliController.processRefund?outTradeNo={}, refundAmount={}, refundReason={}, partialRefundCode={}",
+                outTradeNo, refundAmount, refundReason, partialRefundCode);
         return aliApi.processRefund(outTradeNo, refundAmount, refundReason, partialRefundCode);
     }
 
     /**
-     * 支付宝OCR识别
-     *
-     * @param imageId 图片id
-     * @param ocrType OCR识别类型
-     * @return OCR识别结果
-     * @throws Exception 识别异常
-     */
-    @ApiOperation("支付宝OCR识别方式一")
-    @ApiOperationSupport(order = 14)
-    @ApiImplicitParams({
-            @ApiImplicitParam(name = "imageId", value = "图片id", dataType = "String", paramType = "query", required = true),
-            @ApiImplicitParam(name = "ocrType", value = "OCR识别类型", dataType = "String", paramType = "query", required = true)
-    })
-    @GetMapping("/ocrRequest")
-    public R<JSONObject> ocrRequest(@RequestParam(value = "imageId") String imageId, @RequestParam(value = "ocrType") String ocrType) {
-        try {
-            return aliApi.ocrRequest(imageId, ocrType);
-        } catch (Exception e) {
-            return R.fail("OCR识别异常:"+e.getMessage());
-        }
-    }
-
-    /**
-     * 支付宝OCR识别
-     *
-     * @return OCR识别结果
-     * @throws Exception 识别异常
+     * 二手委托人识别(底层调用IDcard识别)
      */
-    @ApiOperation("支付宝OCR识别方式二")
-    @ApiOperationSupport(order = 15)
+    @ApiOperation("二手委托人识别(底层调用IDcard识别)")
+    @ApiOperationSupport(order = 16)
     @ApiImplicitParams({
-            @ApiImplicitParam(name = "ocrType", value = "OCR识别类型", dataType = "String", paramType = "query", required = true)
+            @ApiImplicitParam(name = "imageUrl", value = "图片文件", dataType = "File", paramType = "query", required = true),
+            @ApiImplicitParam(name = "ocrType", value = "OCR识别类型", dataType = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "userName", value = "委托人姓名", dataType = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "idCard", value = "委托人身份证号", dataType = "String", paramType = "query", required = true)
     })
-    @PostMapping("/ocrRequestByBase64")
-    public R ocrRequestByBase64(MultipartFile imageFile,
-                                @RequestParam("ocrType") String ocrType) {
+    @PostMapping("/secondClient")
+    public R secondClient(@RequestBody Map<String, String> params)
+    {
         try {
-            return aliApi.ocrRequestByBase64(imageFile, ocrType);
+            return aliApi.secondClient(params.get("imageUrl"), params.get("ocrType"), params.get("userName"), params.get("idCard"));
         } catch (Exception e) {
-            return R.fail("OCR识别异常:"+e.getMessage());
+            return R.fail(e.getMessage());
         }
     }
 }

+ 44 - 3
alien-store/src/main/java/shop/alien/store/util/ali/AliApi.java

@@ -212,7 +212,7 @@ public class AliApi {
                 // 保存退款信息进入到退款记录表
                 JSONObject responseBody = JSONObject.parseObject(response.getBody());
                 JSONObject refundResponse = responseBody.getJSONObject("alipay_trade_refund_response");
-                
+
                 StoreAliPayRefundLog refundLog = new StoreAliPayRefundLog();
                 // 响应基本信息
                 refundLog.setResponseCode(refundResponse.getString("code"));
@@ -254,7 +254,7 @@ public class AliApi {
                 // 标准字段
                 refundLog.setDeleteFlag(0);
                 refundLog.setCreatedTime(new Date());
-                
+
                 storeAliPayRefundLogService.save(refundLog);
 
             } else {
@@ -752,7 +752,7 @@ public class AliApi {
     }
 
     /**
-     * 支付宝OCR识别(使用策略工厂模式)
+     * 支付宝OCR识别
      *
      * @param imageId 图片id
      * @param ocrType OCR识别类型
@@ -765,6 +765,19 @@ public class AliApi {
     }
 
     /**
+     * 支付宝OCR识别
+     *
+     * @param imageUrl 图片url
+     * @param ocrType OCR识别类型
+     * @return OCR识别结果
+     * @throws Exception 识别异常
+     */
+    public R ocrRequestUrl(String imageUrl, String ocrType) throws Exception {
+        OcrStrategy strategy = ocrStrategyFactory.getStrategy(ocrType);
+        return strategy.recognizeUrl(imageUrl);
+    }
+
+    /**
      * 支付宝OCR识别(Base64方式,使用策略工厂模式)
      * 目前没用w
      * @param imageFile 图片文件
@@ -818,4 +831,32 @@ public class AliApi {
         return "支付宝请求错误";
     }
 
+    public R secondClient(String imageUrl, String ocrType, String userName, String idCard) {
+        try {
+            R r = this.ocrRequestUrl(imageUrl, ocrType);
+            r.getCode();
+            if(200 == r.getCode()) {
+                if(!JSONObject.parseObject(r.getData().toString()).containsKey("face")) {
+                    return R.fail("OCR识别异常:请上传身份证正面照片");
+                }
+                JSONObject jsonObject = JSONObject.parseObject(r.getData().toString()).getJSONObject("face").getJSONObject("data");
+                String name = jsonObject.getString("name");
+                String idCardNo = jsonObject.getString("idNumber");
+                if(userName.equals(name) && idCard.equals(idCardNo)) {
+                    return R.success("验证成功");
+                } else {
+                    return R.fail("委托人姓名或身份证号错误");
+                }
+            }
+        } catch (IllegalArgumentException e) {
+            // 7. 细化异常类型(JSON 解析失败,比如数据格式不匹配)
+            log.error("OCR 结果解析失败(数据格式异常):{}", e.getMessage(), e);
+            return R.fail("OCR识别异常:返回数据格式错误");
+        } catch (Exception e) {
+            // 8. 兜底异常(记录详细日志,便于排查)
+            log.error("委托人身份验证未知异常:{}", e.getMessage(), e);
+            return R.fail("委托人身份验证未知异常:"+e.getMessage());
+        }
+        return R.fail("OCR识别异常");
+    }
 }

+ 15 - 6
alien-store/src/main/java/shop/alien/store/util/ali/ocr/OcrStrategy.java

@@ -9,28 +9,37 @@ import shop.alien.entity.result.R;
  * @date 2025/11/18
  */
 public interface OcrStrategy {
-    
+
     /**
      * 执行OCR识别
-     * 
+     *
      * @param imageId 图片id
      * @return OCR识别结果(JSON格式)
      * @throws Exception 识别异常
      */
     R recognize(String imageId) throws Exception;
-    
+
+    /**
+     * 执行OCR识别
+     *
+     * @param imageUrl 图片url
+     * @return OCR识别结果(JSON格式)
+     * @throws Exception 识别异常
+     */
+    R recognizeUrl(String imageUrl) throws Exception;
+
     /**
      * 执行OCR识别(Base64方式)
-     * 
+     *
      * @param imageBase64 图片Base64编码
      * @return OCR识别结果(JSON格式)
      * @throws Exception 识别异常
      */
     R recognizeByBase64(String imageBase64) throws Exception;
-    
+
     /**
      * 获取策略类型字符串
-     * 
+     *
      * @return 策略类型字符串
      */
     String getType();

+ 18 - 12
alien-store/src/main/java/shop/alien/store/util/ali/ocr/strategy/BusinessLicenseOcrStrategy.java

@@ -31,26 +31,32 @@ public class BusinessLicenseOcrStrategy extends AbstractOcrStrategy {
 
     @Override
     public R recognize(String imageId) throws Exception {
-        Client client = createOcrClient();
+
         // 从数据库中获取图片URL
         StoreImg storeImage = storeImgService.getById(imageId);
         String imageUrl = storeImage.getImgUrl();
+        return recognizeUrl(imageUrl);
+    }
+
+    @Override
+    public R recognizeUrl(String imageUrl) throws Exception {
+        Client client = createOcrClient();
         RecognizeBusinessLicenseRequest request = new RecognizeBusinessLicenseRequest()
                 .setUrl(imageUrl);
-        
+
         try {
             RecognizeBusinessLicenseResponse response = client.recognizeBusinessLicenseWithOptions(
                     request, new RuntimeOptions());
             RecognizeBusinessLicenseResponseBody body = response.getBody();
-            
+
             if (body == null || body.getData() == null) {
                 throw new Exception("OCR识别返回结果为空");
             }
-            
+
             JSONObject jsonObject = JSONObject.parseObject(body.getData());
             log.info("营业执照OCR识别成功: {}", jsonObject.getJSONObject("data"));
             return R.data(jsonObject.getJSONObject("data"));
-            
+
         } catch (TeaException error) {
             handleOcrException(error, "营业执照识别失败");
             return R.fail("营业执照识别失败");
@@ -59,30 +65,30 @@ public class BusinessLicenseOcrStrategy extends AbstractOcrStrategy {
             return R.fail("营业执照识别异常");
         }
     }
-    
+
     @Override
     public R recognizeByBase64(String imageBase64) throws Exception {
         Client client = createOcrClient();
         // 将Base64字符串转换为字节数组,然后创建InputStream
         byte[] imageBytes = java.util.Base64.getDecoder().decode(imageBase64);
         java.io.InputStream imageInputStream = new java.io.ByteArrayInputStream(imageBytes);
-        
+
         RecognizeBusinessLicenseRequest request = new RecognizeBusinessLicenseRequest()
                 .setBody(imageInputStream);
-        
+
         try {
             RecognizeBusinessLicenseResponse response = client.recognizeBusinessLicenseWithOptions(
                     request, new RuntimeOptions());
             RecognizeBusinessLicenseResponseBody body = response.getBody();
-            
+
             if (body == null || body.getData() == null) {
                 throw new Exception("OCR识别返回结果为空");
             }
-            
+
             JSONObject jsonObject = JSONObject.parseObject(body.getData());
             log.info("营业执照OCR识别成功: {}", jsonObject.getJSONObject("data"));
             return R.data(jsonObject.getJSONObject("data"));
-            
+
         } catch (TeaException error) {
             handleOcrException(error, "营业执照识别失败");
             return R.fail("营业执照识别失败");
@@ -100,7 +106,7 @@ public class BusinessLicenseOcrStrategy extends AbstractOcrStrategy {
             }
         }
     }
-    
+
     @Override
     public String getType() {
         return OcrTypeEnum.BUSINESS_LICENSE.getCode();

+ 7 - 1
alien-store/src/main/java/shop/alien/store/util/ali/ocr/strategy/FoodManageLicenseOcrStrategy.java

@@ -29,10 +29,16 @@ public class FoodManageLicenseOcrStrategy extends AbstractOcrStrategy {
 
     @Override
     public R recognize(String imageId) throws Exception {
-        Client client = createOcrClient();
+
         // 从数据库中获取图片URL
         StoreImg storeImage = storeImgService.getById(imageId);
         String imageUrl = storeImage.getImgUrl();
+        return recognizeUrl(imageUrl);
+    }
+
+    @Override
+    public R recognizeUrl(String imageUrl) throws Exception {
+        Client client = createOcrClient();
         RecognizeFoodManageLicenseRequest request = new RecognizeFoodManageLicenseRequest()
                 .setUrl(imageUrl);
 

+ 17 - 11
alien-store/src/main/java/shop/alien/store/util/ali/ocr/strategy/IdCardOcrStrategy.java

@@ -29,26 +29,32 @@ public class IdCardOcrStrategy extends AbstractOcrStrategy {
 
     @Override
     public R recognize(String imageId) throws Exception {
-        Client client = createOcrClient();
+
         // 从数据库中获取图片URL
         StoreImg storeImage = storeImgService.getById(imageId);
         String imageUrl = storeImage.getImgUrl();
+        return recognizeUrl(imageUrl);
+    }
+
+    @Override
+    public R recognizeUrl(String imageUrl) throws Exception {
+        Client client = createOcrClient();
         RecognizeIdcardRequest request = new RecognizeIdcardRequest()
                 .setUrl(imageUrl); // 默认识别正面,可根据需要修改为 "back" 识别反面
-        
+
         try {
             RecognizeIdcardResponse response = client.recognizeIdcardWithOptions(
                     request, new RuntimeOptions());
             RecognizeIdcardResponseBody body = response.getBody();
-            
+
             if (body == null || body.getData() == null) {
                 throw new Exception("OCR识别返回结果为空");
             }
-            
+
             JSONObject jsonObject = JSONObject.parseObject(body.getData());
             log.info("身份证OCR识别成功: {}", jsonObject.getJSONObject("data"));
             return R.data(jsonObject.getJSONObject("data"));
-            
+
         } catch (TeaException error) {
             handleOcrException(error, "身份证识别失败");
             return R.fail("身份证识别失败");
@@ -57,7 +63,7 @@ public class IdCardOcrStrategy extends AbstractOcrStrategy {
             return R.fail("身份证识别异常");
         }
     }
-    
+
     @Override
     public R recognizeByBase64(String imageBase64) throws Exception {
         Client client = createOcrClient();
@@ -67,20 +73,20 @@ public class IdCardOcrStrategy extends AbstractOcrStrategy {
 
         RecognizeIdcardRequest request = new RecognizeIdcardRequest()
                 .setBody(imageInputStream); // 默认识别正面,可根据需要修改为 "back" 识别反面
-        
+
         try {
             RecognizeIdcardResponse response = client.recognizeIdcardWithOptions(
                     request, new RuntimeOptions());
             RecognizeIdcardResponseBody body = response.getBody();
-            
+
             if (body == null || body.getData() == null) {
                 throw new Exception("OCR识别返回结果为空");
             }
-            
+
             JSONObject jsonObject = JSONObject.parseObject(body.getData());
             log.info("身份证OCR识别成功: {}", jsonObject.getJSONObject("data"));
             return R.data(jsonObject.getJSONObject("data"));
-            
+
         } catch (TeaException error) {
             handleOcrException(error, "身份证识别失败");
             return R.fail("身份证识别失败");
@@ -98,7 +104,7 @@ public class IdCardOcrStrategy extends AbstractOcrStrategy {
             }
         }
     }
-    
+
     @Override
     public String getType() {
         return OcrTypeEnum.ID_CARD.getCode();