Jelajahi Sumber

feat(ocr): 集成图片OCR识别和伪造检测功能

- 配置文件中更新数据库连接信息,修改MySQL驱动和连接URL
- 添加图片OCR识别相关常量配置,包括属性键和Python服务配置
- 新增ImageConfig类用于存储OCR和伪造检测请求URL配置
- 创建ImageRecognizeConfigRepository接口和对应的数据库表结构
- 在OcrServiceImpl中集成AES解密和Python服务调用逻辑
- 更新TruForServiceImpl实现伪造检测功能的Python服务调用
- 移除已废弃的Vaultody相关服务代码和交易记录功能
- 添加获取Python服务地址和密钥的安全验证机制
kongxiangyang 2 minggu lalu
induk
melakukan
8d6f7b1fbb

+ 9 - 0
crm-manager/src/main/java/com/crm/manager/config/ImageConfig.java

@@ -0,0 +1,9 @@
+package com.crm.manager.config;
+
+import lombok.Data;
+
+@Data
+public class ImageConfig {
+    private String ocrRequestUrl;
+    private String forgeryRequestUrl;
+}

+ 2 - 0
crm-manager/src/main/java/com/crm/manager/controller/OcrController.java

@@ -3,6 +3,8 @@ package com.crm.manager.controller;
 import com.crm.manager.service.OcrService;
 import com.crm.rely.backend.core.dto.base.BaseResultDto;
 import com.crm.rely.backend.model.entity.ocr.OcrCheckEntity;
+import com.crm.rely.backend.util.AESUtil;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;

+ 0 - 15
crm-manager/src/main/java/com/crm/manager/dao/mapper/TransactionItemMapper.java

@@ -1,15 +0,0 @@
-package com.crm.manager.dao.mapper;
-
-import com.crm.rely.backend.model.entity.vaultody.vaults.VaultTransactionsSearchEntity;
-import com.crm.rely.backend.model.pojo.table.TransactionItemTable;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
-
-@Mapper
-public interface TransactionItemMapper {
-    Integer countList(@Param("entity") VaultTransactionsSearchEntity entity, @Param("startSecond") Long startSecond, @Param("endSecond") Long endSecond);
-
-    List<TransactionItemTable> pageList(@Param("entity") VaultTransactionsSearchEntity entity, @Param("startSecond") Long startSecond, @Param("endSecond") Long endSecond);
-}

+ 11 - 0
crm-manager/src/main/java/com/crm/manager/repository/ImageRecognizeConfigRepository.java

@@ -0,0 +1,11 @@
+package com.crm.manager.repository;
+
+import com.crm.rely.backend.dao.repository.BaseRepository;
+import com.crm.rely.backend.model.pojo.table.ImageRecognizeConfigTable;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ImageRecognizeConfigRepository extends BaseRepository<ImageRecognizeConfigTable> {
+
+    ImageRecognizeConfigTable getByCode(String code);
+}

+ 0 - 28
crm-manager/src/main/java/com/crm/manager/service/VaultodyService.java

@@ -1,28 +0,0 @@
-package com.crm.manager.service;
-
-import com.crm.rely.backend.core.dto.base.BaseResultDto;
-import com.crm.rely.backend.model.config.VaultodyConfig;
-import com.crm.rely.backend.model.dto.vaultody.vaults.TransactionItemDto;
-import com.crm.rely.backend.model.dto.vaultody.vaults.VaultTransaction;
-import com.crm.rely.backend.model.entity.vaultody.vaults.VaultTransactionsEntity;
-import com.crm.rely.backend.model.entity.vaultody.vaults.VaultTransactionsSearchEntity;
-import com.crm.rely.backend.model.pojo.table.TransactionItemTable;
-
-import java.util.List;
-
-public interface VaultodyService {
-
-    BaseResultDto vaultsList() throws Exception;
-
-    void batchSave(List<TransactionItemTable> tables);
-
-    List<TransactionItemTable> finAllByVaultId(String vaultId);
-
-    BaseResultDto searchList(VaultTransactionsSearchEntity entity) throws Exception;
-
-    List<TransactionItemDto> queryWithFilter(VaultodyConfig config) throws Exception;
-
-    VaultTransaction query3Items(VaultTransactionsEntity entity, VaultodyConfig config) throws Exception;
-
-    VaultodyConfig getVaultodyConfig();
-}

+ 54 - 3
crm-manager/src/main/java/com/crm/manager/service/impl/OcrServiceImpl.java

@@ -1,12 +1,23 @@
 package com.crm.manager.service.impl;
 
 import com.alibaba.fastjson2.JSON;
+import com.crm.manager.config.ImageConfig;
+import com.crm.manager.repository.ImageRecognizeConfigRepository;
 import com.crm.manager.service.OcrService;
+import com.crm.manager.service.SysConfigService;
+import com.crm.rely.backend.core.constant.Constants;
 import com.crm.rely.backend.core.dto.base.BaseResultDto;
+import com.crm.rely.backend.core.exception.ServiceException;
+import com.crm.rely.backend.core.pojo.table.SysConfigTable;
+import com.crm.rely.backend.model.constant.ConfigConstants;
 import com.crm.rely.backend.model.entity.ocr.IdCardData;
 import com.crm.rely.backend.model.entity.ocr.OcrCheckEntity;
 import com.crm.rely.backend.model.entity.ocr.OcrResult;
+import com.crm.rely.backend.model.pojo.table.ImageRecognizeConfigTable;
+import com.crm.rely.backend.util.AESUtil;
+import org.apache.commons.lang3.StringUtils;
 import org.jsoup.Connection;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.HashMap;
@@ -17,6 +28,12 @@ import static com.crm.rely.backend.util.HttpUtil.post;
 @Service
 public class OcrServiceImpl implements OcrService {
 
+    @Autowired
+    private SysConfigService sysConfigService;
+
+    @Autowired
+    private ImageRecognizeConfigRepository imageRecognizeConfigRepository;
+
 
     /**
      * 获取OCR识别结果
@@ -26,7 +43,41 @@ public class OcrServiceImpl implements OcrService {
      */
     @Override
     public BaseResultDto result(OcrCheckEntity entity) {
-        return BaseResultDto.success(idCardOcr(entity.getImageBase64()));
+        entity.setImageBase64(AESUtil.decrypt(entity.getImageBase64(),getPropertyKey()));
+        // 这里开始调用 python 接口
+        ImageConfig imageConfig = getImagePythonConfig();
+        return BaseResultDto.success(idCardOcr(entity.getImageBase64(),imageConfig.getOcrRequestUrl()));
+    }
+
+    /**
+     * 获取密钥
+     * @return
+     * @throws ServiceException
+     */
+    private String getPropertyKey() throws ServiceException {
+        SysConfigTable table = sysConfigService.getByCode(ConfigConstants.IMAGE_CONFIG_PROPERTY_KEY);
+        if (table == null) {
+            throw ServiceException.exception(Constants.SYSTEM_ERROR);
+        }
+        return table.getValue();
+    }
+
+    /**
+     * 获取python服务地址
+     * @return
+     * @throws ServiceException
+     */
+    public ImageConfig getImagePythonConfig() throws ServiceException{
+        ImageRecognizeConfigTable configTable = imageRecognizeConfigRepository.getByCode(ConfigConstants.CUSTOMER_IMAGE_PYTHON_CONFIG);
+        if (configTable == null) {
+            throw ServiceException.exception(Constants.SYSTEM_ERROR);
+        }
+        // 获取md5密钥
+        String aesKey = getPropertyKey();
+
+        String property = AESUtil.decrypt(configTable.getValue(), aesKey);
+        ImageConfig imageConfig = JSON.parseObject(property, ImageConfig.class);
+        return imageConfig;
     }
 
 
@@ -36,10 +87,10 @@ public class OcrServiceImpl implements OcrService {
      * @param base64Image 图片 base64 字符串(不带前缀 data:image/png;base64,)
      * @return IdCardData 识别后的身份证实体
      */
-    public static IdCardData idCardOcr(String base64Image) {
+    public static IdCardData idCardOcr(String base64Image,String url) {
         try {
             // 1. 接口地址
-            String url = "http://103.214.175.29:5000/ocr/idcard/base64";
+//            String url = "http://103.214.175.29:5000/ocr/idcard/base64";
 
             // 2. 请求头
             Map<String, String> headers = new HashMap<>();

+ 53 - 3
crm-manager/src/main/java/com/crm/manager/service/impl/TruForServiceImpl.java

@@ -1,11 +1,21 @@
 package com.crm.manager.service.impl;
 
 import com.alibaba.fastjson2.JSON;
+import com.crm.manager.config.ImageConfig;
+import com.crm.manager.repository.ImageRecognizeConfigRepository;
+import com.crm.manager.service.SysConfigService;
 import com.crm.manager.service.TruForService;
+import com.crm.rely.backend.core.constant.Constants;
 import com.crm.rely.backend.core.dto.base.BaseResultDto;
+import com.crm.rely.backend.core.exception.ServiceException;
+import com.crm.rely.backend.core.pojo.table.SysConfigTable;
+import com.crm.rely.backend.model.constant.ConfigConstants;
 import com.crm.rely.backend.model.entity.trufor.ImageDetectResult;
 import com.crm.rely.backend.model.entity.trufor.TruForCheckEntity;
+import com.crm.rely.backend.model.pojo.table.ImageRecognizeConfigTable;
+import com.crm.rely.backend.util.AESUtil;
 import org.jsoup.Connection;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.HashMap;
@@ -16,17 +26,57 @@ import static com.crm.rely.backend.util.HttpUtil.post;
 @Service
 public class TruForServiceImpl implements TruForService {
 
+    @Autowired
+    private SysConfigService sysConfigService;
+
+    @Autowired
+    private ImageRecognizeConfigRepository imageRecognizeConfigRepository;
+
     @Override
     public BaseResultDto result(TruForCheckEntity entity) {
-        return BaseResultDto.success(imageForgedDetect(entity.getImageBase64()));
+        entity.setImageBase64(AESUtil.decrypt(entity.getImageBase64(),getPropertyKey()));
+        // 这里开始调用 python 接口
+        ImageConfig imageConfig = getImagePythonConfig();
+        return BaseResultDto.success(imageForgedDetect(entity.getImageBase64(),imageConfig.getForgeryRequestUrl()));
+    }
+
+    /**
+     * 获取python服务地址
+     * @return
+     * @throws ServiceException
+     */
+    public ImageConfig getImagePythonConfig() throws ServiceException{
+        ImageRecognizeConfigTable configTable = imageRecognizeConfigRepository.getByCode(ConfigConstants.CUSTOMER_IMAGE_PYTHON_CONFIG);
+        if (configTable == null) {
+            throw ServiceException.exception(Constants.SYSTEM_ERROR);
+        }
+        // 获取md5密钥
+        String aesKey = getPropertyKey();
+
+        String property = AESUtil.decrypt(configTable.getValue(), aesKey);
+        ImageConfig imageConfig = JSON.parseObject(property, ImageConfig.class);
+        return imageConfig;
+    }
+
+    /**
+     * 获取密钥
+     * @return
+     * @throws ServiceException
+     */
+    private String getPropertyKey() throws ServiceException {
+        SysConfigTable table = sysConfigService.getByCode(ConfigConstants.IMAGE_CONFIG_PROPERTY_KEY);
+        if (table == null) {
+            throw ServiceException.exception(Constants.SYSTEM_ERROR);
+        }
+        return table.getValue();
     }
 
 
     // ======================== 【图像伪造检测】调用方法 ========================
-    public static ImageDetectResult imageForgedDetect(String base64Image) {
+    public static ImageDetectResult imageForgedDetect(String base64Image,String url) {
         try {
             // 1. 你的API接口地址
-            String url = "http://103.214.175.29:9527/detect";
+//            String url = "http://103.214.175.29:9527/detect";
 
             // 2. 请求头
             Map<String, String> headers = new HashMap<>();

+ 0 - 473
crm-manager/src/main/java/com/crm/manager/service/impl/VaultodyServiceImpl.java

@@ -1,473 +0,0 @@
-package com.crm.manager.service.impl;
-
-import com.alibaba.fastjson2.JSON;
-import com.crm.manager.dao.mapper.TransactionItemMapper;
-import com.crm.manager.repository.TransactionItemRepository;
-import com.crm.manager.service.SysConfigService;
-import com.crm.manager.service.SysVaultodyConfigService;
-import com.crm.manager.service.VaultodyService;
-import com.crm.manager.util.DateUtils;
-import com.crm.rely.backend.core.constant.Constants;
-import com.crm.rely.backend.core.dto.base.BaseResultDto;
-import com.crm.rely.backend.core.dto.base.PageDto;
-import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
-import com.crm.rely.backend.core.exception.ServiceException;
-import com.crm.rely.backend.core.pojo.table.SysConfigTable;
-import com.crm.rely.backend.model.config.VaultodyConfig;
-import com.crm.rely.backend.model.constant.ConfigConstants;
-import com.crm.rely.backend.model.dto.vaultody.vaults.TransactionItemDto;
-import com.crm.rely.backend.model.dto.vaultody.vaults.VaultTransaction;
-import com.crm.rely.backend.model.dto.vaultody.vaults.VaultodyVaultsListDto;
-import com.crm.rely.backend.model.dto.vaultody.vaults.response.ResponseData;
-import com.crm.rely.backend.model.dto.vaultody.vaults.response.TransactionItem;
-import com.crm.rely.backend.model.dto.vaultody.vaults.response.TransactionResponse;
-import com.crm.rely.backend.model.dto.vaultody.vaults.response.VaultsListResponseDto;
-import com.crm.rely.backend.model.entity.vaultody.vaults.VaultTransactionsEntity;
-import com.crm.rely.backend.model.entity.vaultody.vaults.VaultTransactionsSearchEntity;
-import com.crm.rely.backend.model.pojo.table.SysVaultodyConfigTable;
-import com.crm.rely.backend.model.pojo.table.TransactionItemTable;
-import com.crm.rely.backend.util.AESUtil;
-import com.crm.rely.backend.util.HttpUtil;
-import com.crm.rely.backend.util.UUIDUtil;
-import com.google.common.collect.Lists;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
-import org.jsoup.Connection;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.ObjectUtils;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-import java.util.stream.Collectors;
-
-@Slf4j
-@Service
-public class VaultodyServiceImpl implements VaultodyService {
-
-    @Autowired
-    private SysVaultodyConfigService vaultodyConfigService;
-    @Autowired
-    private SysConfigService sysConfigService;
-    @Autowired
-    private TransactionItemRepository transactionItemRepository;
-    @Autowired
-    private TransactionItemMapper transactionItemMapper;
-
-    public static String getSignature(String message, String apiSecret) {
-        try {
-            byte[] decodedSecret = Base64.getDecoder().decode(apiSecret);
-            Mac mac = Mac.getInstance("HmacSHA256");
-            SecretKeySpec secretKeySpec = new SecretKeySpec(decodedSecret, "HmacSHA256");
-            mac.init(secretKeySpec);
-            byte[] hash = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
-
-            return Base64.getEncoder().encodeToString(hash);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
-
-    public static void main2(String[] args) {
-        String s = "{\n" +
-                "  \"apiKey\": \"6f3cc6caf513a5cde2df5d3ed805e3703d4d43b2\",\n" +
-                "  \"apiSecret\": \"MLjTUAYgxSM2dg==\",\n" +
-                "  \"passphrase\": \"7UGMi2*t0h\",\n" +
-                "  \"vaultId\": \"\",\n" +
-                "  \"baseUrl\": \"https://rest.vaultody.com\",\n" +
-                "  \"vaultsListUrl\": \"/vaults/test\",\n" +
-                "  \"network\": \"\",\n" +
-                "  \"vaultsTransactionsPathTemplate\": \"/vaults/%s/transactions\",\n" +
-                "  \"webhooksPassphrase\": \"\"\n" +
-                "}";
-        System.out.println(AESUtil.encrypt(s, "bfa5559109f94c78af615bcf00d52060"));
-        System.out.println(AESUtil.decrypt(AESUtil.encrypt(s, "bfa5559109f94c78af615bcf00d52060"), "bfa5559109f94c78af615bcf00d52060"));
-    }
-
-    public static void main(String[] args) {
-        String s = "{\n" +
-                "    \"apiKey\": \"6f3cc6caf513a5cde2df5d3ed805e3703d4d43b2\",\n" +
-                "    \"apiSecret\": \"MLjTUAYgxSM2dg==\",\n" +
-                "    \"passphrase\": \"7UGMi2*t0h\",\n" +
-                "    \"vaultId\": \"\",\n" +
-                "    \"baseUrl\": \"https://rest.vaultody.com\",\n" +
-                "    \"vaultsListUrl\": \"/vaults/%s\",\n" +
-                "    \"networkType\": \"test\",\n" +
-                "    \"vaultsTransactionsPathTemplate\": \"/vaults/%s/transactions\",\n" +
-                "    \"webhooksPassphrase\": \"\",\n" +
-                "    \"vaultodyList\": [\n" +
-                "        {\n" +
-                "            \"apiKey\": \"6f3cc6caf513a5cde2df5d3ed805e3703d4d43b2\",\n" +
-                "            \"apiSecret\": \"MLjTUAYgxSM2dg==\",\n" +
-                "            \"passphrase\": \"7UGMi2*t0h\",\n" +
-                "            \"vaultId\": \"69cb34038d64830006453c0c\",\n" +
-                "            \"baseUrl\": \"https://rest.vaultody.com\",\n" +
-                "            \"vaultsListUrl\": \"/vaults/%s\",\n" +
-                "            \"networkType\": \"test\",\n" +
-                "            \"vaultsTransactionsPathTemplate\": \"/vaults/%s/transactions\",\n" +
-                "            \"webhooksPassphrase\": \"\"\n" +
-                "        },\n" +
-                "        {\n" +
-                "            \"apiKey\": \"002key\",\n" +
-                "            \"apiSecret\": \"002pwd\",\n" +
-                "            \"passphrase\": \"7UGMi2*t0h\",\n" +
-                "            \"vaultId\": \"002\",\n" +
-                "            \"baseUrl\": \"https://rest.vaultody.com\",\n" +
-                "            \"vaultsListUrl\": \"/vaults/%s\",\n" +
-                "            \"networkType\": \"test\",\n" +
-                "            \"vaultsTransactionsPathTemplate\": \"/vaults/%s/transactions\",\n" +
-                "            \"webhooksPassphrase\": \"\"\n" +
-                "        }\n" +
-                "    ]\n" +
-                "}";
-        System.out.println(AESUtil.encrypt(s, "bfa5559109f94c78af615bcf00d52060"));
-        System.out.println(AESUtil.decrypt(AESUtil.encrypt(s, "bfa5559109f94c78af615bcf00d52060"), "bfa5559109f94c78af615bcf00d52060"));
-    }
-
-    /**
-     * Coin
-     */
-    public static void main1(String[] args) {
-        try {
-            List<VaultodyVaultsListDto> dtos = new ArrayList<>();
-            // ------------------ 配置 ------------------
-            String apiKey = "6f3cc6caf513a5cde2df5d3ed805e3703d4d43b2";
-            String apiSecret = "MLjTUAYgxSM2dg==";        // Base64编码的secret
-            String passphrase = "7UGMi2*t0h";
-            String method = "GET";
-            String requestPath = "/vaults/test";
-            String baseUrl = "https://rest.vaultody.com";
-
-            String query = "{}"; // POST 时 query 通常为空,否则按接口要求填写
-            String body = "{}"; // POST 时 query 通常为空,否则按接口要求填写
-
-            // ------------------ 时间戳(秒) ------------------
-            String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
-
-            // ------------------ 构建消息用于签名 ------------------
-            String message = timestamp + method + requestPath + body + query;
-            System.out.println("Message: " + message);
-
-            String signature = getSignature(message, apiSecret);
-            System.out.println("Signature: " + signature);
-            Map<String, String> headers = new HashMap<>();
-            headers.put("x-api-key", apiKey);
-            headers.put("x-api-sign", signature);
-            headers.put("x-api-timestamp", timestamp);
-            headers.put("x-api-passphrase", passphrase);
-            headers.put("Content-Type", "application/json");
-
-            try {
-                Connection.Response response = HttpUtil.get(baseUrl + requestPath, headers);
-                if (response.statusCode() != 200){
-                    System.out.println("Error: " + response.statusMessage());
-                }
-                VaultsListResponseDto responseDto = JSON.parseObject(response.body(), VaultsListResponseDto.class);
-                List<VaultsListResponseDto.Item> items = responseDto.getData().getItems();
-                for (VaultsListResponseDto.Item item : items){
-                    VaultodyVaultsListDto dto = new VaultodyVaultsListDto();
-                    BeanUtils.copyProperties(item, dto);
-                    dtos.add(dto);
-                }
-                System.out.println(JSON.toJSONString(dtos));
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * 交易记录接口拼接url
-     */
-    public String getPath(String pathTemplate, String vaultId) {
-//        String pathTemplate = "/vaults/%s/transactions";
-        String actualPath = String.format(pathTemplate, vaultId);
-        return actualPath;
-    }
-    /**
-     * 交易记录接口拼接url
-     */
-    public String getVaultsPath(String pathTemplate, String networkType) {
-//        String pathTemplate = "/vaults/{networkType}";
-        String actualPath = String.format(pathTemplate, networkType);
-        return actualPath;
-    }
-
-    public VaultodyConfig getVaultodyConfig() {
-        SysVaultodyConfigTable configTable = vaultodyConfigService.getByCode(ConfigConstants.VAULTODY_MANAGER_CONFIG);
-        if (configTable == null) {
-            throw ServiceException.exception(Constants.SYSTEM_ERROR);
-        }
-        String aesKey = getPropertyKey();
-
-        String property = AESUtil.decrypt(configTable.getValue(), aesKey);
-        VaultodyConfig vaultodyConfig = JSON.parseObject(property, VaultodyConfig.class);
-        return vaultodyConfig;
-    }
-
-    public VaultodyConfig getVaultodyConfig(String vaultId) {
-        SysVaultodyConfigTable configTable = vaultodyConfigService.getByCode(ConfigConstants.VAULTODY_MANAGER_CONFIG);
-        if (configTable == null) {
-            throw ServiceException.exception(Constants.SYSTEM_ERROR);
-        }
-        String aesKey = getPropertyKey();
-
-        String property = AESUtil.decrypt(configTable.getValue(), aesKey);
-        VaultodyConfig vaultodyConfig = JSON.parseObject(property, VaultodyConfig.class);
-        List<VaultodyConfig> vaultodyList = vaultodyConfig.getVaultodyList();
-        if(CollectionUtils.isEmpty(vaultodyList)){
-            throw ServiceException.exception(Constants.NOT_PERMIT);
-        }
-
-        Map<String, VaultodyConfig> list = vaultodyList.stream().collect(Collectors.toMap(VaultodyConfig::getVaultId, v -> v));
-        VaultodyConfig config = new VaultodyConfig();
-        if(!list.containsKey(vaultId)){
-            throw ServiceException.exception(Constants.NOT_PERMIT);
-        }
-        config = list.get(vaultId);
-        return config;
-    }
-
-    private String getPropertyKey() throws ServiceException {
-        SysConfigTable table = sysConfigService.getByCode(ConfigConstants.VAULTODY_FINANCE_PROPERTY_KEY);
-        if (table == null) {
-            throw ServiceException.exception(Constants.SYSTEM_ERROR);
-        }
-        return table.getValue();
-    }
-
-
-    @Override
-    public BaseResultDto vaultsList() throws Exception {
-        List<VaultodyVaultsListDto> dtos = new ArrayList<>();
-        VaultodyConfig config = getVaultodyConfig();
-
-        String apiKey = config.getApiKey();
-        String apiSecret = config.getApiSecret();
-        String passphrase = config.getPassphrase();
-        String method = "GET";
-        String requestPath = getVaultsPath(config.getVaultsListUrl(), config.getNetworkType());
-        String baseUrl = config.getBaseUrl();
-
-        String query = "{}"; // POST 时 query 通常为空,否则按接口要求填写
-        String body = "{}";
-
-        // ------------------ 时间戳(秒) ------------------
-        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
-
-        // ------------------ 构建消息用于签名 ------------------
-        String message = timestamp + method + requestPath + body + query;
-
-        String signature = getSignature(message, apiSecret);
-        System.out.println("Signature: " + signature);
-        Map<String, String> headers = new HashMap<>();
-        headers.put("x-api-key", apiKey);
-        headers.put("x-api-sign", signature);
-        headers.put("x-api-timestamp", timestamp);
-        headers.put("x-api-passphrase", passphrase);
-        headers.put("Content-Type", "application/json");
-
-        Connection.Response response = HttpUtil.get(baseUrl + requestPath, headers);
-        if (response.statusCode() != 200){
-            return BaseResultDto.error(response.statusMessage());
-        }
-        VaultsListResponseDto responseDto = JSON.parseObject(response.body(), VaultsListResponseDto.class);
-        List<VaultsListResponseDto.Item> items = responseDto.getData().getItems();
-        for (VaultsListResponseDto.Item item : items){
-            VaultodyVaultsListDto dto = new VaultodyVaultsListDto();
-            BeanUtils.copyProperties(item, dto);
-            dtos.add(dto);
-        }
-        return BaseResultDto.success(dtos);
-    }
-
-    public VaultTransaction query3Items(VaultTransactionsEntity entity,VaultodyConfig config) throws Exception{
-        String apiKey = config.getApiKey();
-        String apiSecret = config.getApiSecret();       // Base64编码的secret
-        String passphrase = config.getPassphrase();
-        String method = "GET";
-//        String requestPath = "/vaults/"+entity.getVaultId()+"/transactions";
-        String requestPath = getPath(config.getVaultsTransactionsPathTemplate(), entity.getVaultId());
-        String baseUrl = config.getBaseUrl();
-        String query = "{}";
-        Map<String, String> params = new HashMap();
-        if(!ObjectUtils.isEmpty(entity.getLimit())){
-            params.put("limit", String.valueOf(entity.getLimit()));
-        }
-        if(StringUtils.isNotBlank(entity.getStartingAfter())){
-            params.put("startingAfter", entity.getStartingAfter());
-        }
-        if (StringUtils.isNotBlank(entity.getContext())){
-            params.put("context", entity.getContext());
-        }
-        // ------------------ 时间戳(秒) ------------------
-        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
-        // ------------------ 构建消息用于签名 ------------------
-        String message = timestamp + method + requestPath + query + JSON.toJSONString(params);
-        String signature = getSignature(message, apiSecret);
-        log.info("Signature: {}",signature);
-        Map<String, String> headers = new HashMap<>();
-        headers.put("x-api-key", apiKey);
-        headers.put("x-api-sign", signature);
-        headers.put("x-api-timestamp", timestamp);
-        headers.put("x-api-passphrase", passphrase);
-        headers.put("Content-Type", "application/json");
-        Connection.Response response = HttpUtil.get(baseUrl + requestPath, headers, params);
-        log.info("response.statusCode: {} , response.body: {}",response.statusCode() , response.body());
-        if (response.statusCode() != 200) {
-            log.error("response.statusCode() != 200,{}","3Item Error!");
-            throw ServiceException.exception(Constants.SYSTEM_ERROR);
-        }
-        TransactionResponse responseDto = JSON.parseObject(response.body(), TransactionResponse.class);
-        ResponseData data = responseDto.getData();
-        VaultTransaction vaultTransaction = getVaultTransaction(data);
-        return vaultTransaction;
-    }
-
-    private VaultTransaction getVaultTransaction(ResponseData data) {
-        VaultTransaction vaultTransaction = new VaultTransaction();
-        vaultTransaction.setHasMore(data.getHasMore());
-        vaultTransaction.setLimit(data.getLimit());
-        vaultTransaction.setStartingAfter(data.getStartingAfter());
-        List<TransactionItemDto> list = Lists.newArrayList();
-        for (TransactionItem item : data.getItems()) {
-            TransactionItemDto dto = new TransactionItemDto();
-            dto.setRequestId(UUIDUtil.getUUID());
-            dto.setId(item.getId());
-            dto.setTransactionId(item.getTransactionId());
-            dto.setStatus(item.getStatus());
-            dto.setCreatedTimestamp(item.getCreatedTimestamp());
-            dto.setSenderAddress(item.getSenders().get(0).getAddress());
-            dto.setSenderIsVaultAddress(item.getSenders().get(0).getIsVaultAddress());
-            dto.setSenderAmountUnit(item.getSenders().get(0).getAmountUnit());
-            dto.setSenderAmount(item.getSenders().get(0).getAmount());
-            dto.setRecipientAddress(item.getRecipients().get(0).getAddress());
-            dto.setRecipientIsVaultAddress(item.getRecipients().get(0).getIsVaultAddress());
-            dto.setRecipientAmountUnit(item.getRecipients().get(0).getAmountUnit());
-            dto.setRecipientAmount(item.getRecipients().get(0).getAmount());
-            dto.setBlockchain(item.getBlockchain());
-            dto.setMinedInBlockHeight(item.getMinedInBlockHeight());
-            dto.setFeeAmount(item.getTransactionFee().getAmount());
-            dto.setFeeAmountUnit(item.getTransactionFee().getAmountUnit());
-            dto.setSenderLabel(item.getSenders().get(0).getLabel());
-            dto.setRecipientLabel(item.getRecipients().get(0).getLabel());
-            list.add(dto);
-        }
-        vaultTransaction.setList(list);
-        return vaultTransaction;
-    }
-
-    @Override
-    public void batchSave(List<TransactionItemTable> tables) {
-        transactionItemRepository.saveAll(tables);
-    }
-
-    @Override
-    public List<TransactionItemTable> finAllByVaultId(String vaultId) {
-        return transactionItemRepository.findAllByVaultId(vaultId);
-    }
-
-    @Override
-    public BaseResultDto searchList(VaultTransactionsSearchEntity entity) throws Exception {
-        List<TransactionItemTable> tables = new LinkedList<>();
-        VaultodyConfig vaultodyConfig = getVaultodyConfig(entity.getVaultId());
-        List<TransactionItemDto> list = queryWithFilter(vaultodyConfig);
-        if(!CollectionUtils.isEmpty(list)){
-            for (TransactionItemDto transactionItemDto : list) {
-                TransactionItemTable table = new TransactionItemTable() ;
-                BeanUtils.copyProperties(transactionItemDto, table);
-                table.setVaultId(entity.getVaultId());
-                table.setItemId(transactionItemDto.getId());
-                tables.add(table);
-            }
-            batchSave(tables);
-        }
-
-        Long startSecond = null;
-        Long endSecond = null;
-
-        if(entity.getStartTime() != null){
-            startSecond = DateUtils.dateToSecondTimestamp(entity.getStartTime());
-        }
-        if (entity.getEndTime() != null){
-            endSecond = DateUtils.dateToSecondTimestamp(entity.getEndTime());
-        }
-
-        Integer count = transactionItemMapper.countList(entity,startSecond,endSecond);
-        if (count == null || count <= 0) {
-            return ResultWithPagerDto.success(new PageDto(), new ArrayList<>());
-        }
-        PageDto pageDto = PageDto.format(entity, count);
-        List<TransactionItemTable> dtos = transactionItemMapper.pageList(entity,startSecond,endSecond);
-
-        if (dtos == null || dtos.size() <= 0) {
-            throw new ServiceException(Constants.SYSTEM_ERROR);
-        }
-
-        return ResultWithPagerDto.success(pageDto, dtos);
-    }
-
-    public List<TransactionItemDto> queryWithFilter(VaultodyConfig config) throws Exception {
-        VaultTransactionsEntity entity = new VaultTransactionsEntity();
-        entity.setVaultId(config.getVaultId());
-        List<TransactionItemDto> result = new ArrayList<>();
-
-        // 先获取数据库中已存在的item ID列表
-        List<String> existingItemIds = recordByVaultId(config.getVaultId());
-        Set<String> existingIdSet = new HashSet<>(existingItemIds);
-        VaultTransaction vaultTransaction = query3Items(entity,config);
-
-        // 处理第一页数据
-        if (vaultTransaction.getList() != null && !vaultTransaction.getList().isEmpty()) {
-            List<TransactionItemDto> filteredList = filterExistingItems(vaultTransaction.getList(), existingIdSet);
-            result.addAll(filteredList);
-        }
-
-        // 分页查询剩余数据
-        while (Boolean.TRUE.equals(vaultTransaction.getHasMore())
-                && vaultTransaction.getList() != null
-                && !vaultTransaction.getList().isEmpty()) {
-
-            String lastId = vaultTransaction.getList().get(vaultTransaction.getList().size() - 1).getId();
-            entity.setStartingAfter(lastId);
-
-            vaultTransaction = query3Items(entity,config);
-
-            if (vaultTransaction.getList() != null && !vaultTransaction.getList().isEmpty()) {
-                List<TransactionItemDto> filteredList = filterExistingItems(vaultTransaction.getList(), existingIdSet);
-                result.addAll(filteredList);
-            } else {
-                break;
-            }
-        }
-
-        return result;
-    }
-
-    private List<TransactionItemDto> filterExistingItems(List<TransactionItemDto> items, Set<String> existingIdSet) {
-        if (items == null || items.isEmpty()) {
-            return Collections.emptyList();
-        }
-
-        return items.stream()
-                .filter(item -> item != null && item.getId() != null)
-                .filter(item -> !existingIdSet.contains(item.getId()))
-                .collect(Collectors.toList());
-    }
-
-    private List<String> recordByVaultId(String vaultId){
-        List<TransactionItemTable> list = finAllByVaultId(vaultId);
-        if(CollectionUtils.isEmpty(list)){
-            return new ArrayList<>();
-        }
-        return list.stream().map(TransactionItemTable::getItemId).toList();
-    }
-}

+ 2 - 2
crm-manager/src/main/resources/application-dev.yml

@@ -1,7 +1,7 @@
 spring:
   datasource:
-    driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://103.214.175.29:28571/cwg_vaultody?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&useSSL=false
+    driver-class-name: com.mysql.jdbc.Driver
+    url: jdbc:mysql://103.158.191.66:28571/cwg_crm?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&allowMultiQueries=true&useSSL=false
     username: root
     password: NSH01Y0GTmUNjgg6xw80qg==
 #  cloud:

+ 7 - 2
crm-model/src/main/java/com/crm/rely/backend/model/constant/ConfigConstants.java

@@ -2,8 +2,13 @@ package com.crm.rely.backend.model.constant;
 
 public class ConfigConstants {
 
-    public static final String VAULTODY_MANAGER_CONFIG = "VAULTODY_MANAGER_CONFIG";
+    // 图片OCR识别+伪造识别配置
+    public static final String IMAGE_CONFIG_PROPERTY_KEY = "IMAGE_CONFIG_PROPERTY_KEY";
 
-    public static final String VAULTODY_FINANCE_PROPERTY_KEY = "VAULTODY_FINANCE_PROPERTY_KEY";
+    // 图片OCR识别+伪造识别配置 python
+    public static final String IMAGE_CONFIG_PROPERTY_PYTHON_KEY = "IMAGE_CONFIG_PROPERTY_PYTHON_KEY";
+
+    // 获取python服务地址
+    public static final String CUSTOMER_IMAGE_PYTHON_CONFIG = "CUSTOMER_IMAGE_PYTHON_CONFIG";
 
 }

+ 0 - 51
crm-model/src/main/java/com/crm/rely/backend/model/entity/vaultody/vaults/VaultTransactionsEntity.java

@@ -1,51 +0,0 @@
-package com.crm.rely.backend.model.entity.vaultody.vaults;
-
-import lombok.Data;
-
-import java.util.Date;
-
-/**
- * 获取保险箱交易记录入参
- */
-@Data
-public class VaultTransactionsEntity {
-    /**
-     * 保险箱ID
-     */
-    private String vaultId;
-
-    private Long limit;
-
-    private String startingAfter;
-
-    private String context;
-
-    /**
-     * 发送方保险库地址
-     */
-    private String senderAddress;
-
-    /**
-     * 接收方保险库地址
-     */
-    private String recipientAddress;
-
-    /**
-     * 转出钱包名称
-     */
-    private String senderLabel;
-
-    /**
-     * 收款钱包名称
-     */
-    private String recipientLabel;
-
-    /**
-     * 开始时间
-     */
-    private Date startTime;
-    /**
-     * 结束时间
-     */
-    private Date endTime;
-}

+ 0 - 57
crm-model/src/main/java/com/crm/rely/backend/model/entity/vaultody/vaults/VaultTransactionsSearchEntity.java

@@ -1,57 +0,0 @@
-package com.crm.rely.backend.model.entity.vaultody.vaults;
-
-import com.crm.rely.backend.core.entity.base.BaseSearchPageEntity;
-import lombok.Data;
-
-import java.util.Date;
-
-@Data
-public class VaultTransactionsSearchEntity extends BaseSearchPageEntity {
-    /**
-     * 保险箱ID
-     */
-    private String vaultId;
-
-    /**
-     * 发送方保险库地址
-     */
-    private String senderAddress;
-
-    /**
-     * 接收方保险库地址
-     */
-    private String recipientAddress;
-
-    /**
-     * 转出钱包名称
-     */
-    private String senderLabel;
-
-    /**
-     * 收款钱包名称
-     */
-    private String recipientLabel;
-    /**
-     * 开始时间
-     */
-    private Date startTime;
-    /**
-     * 结束时间
-     */
-    private Date endTime;
-
-    /**
-     * 交易状态
-     */
-    private String status;
-
-    /**
-     * 所属区块链
-     */
-    private String blockchain;
-
-    /**
-     * 币种
-     */
-    private String unit;
-}

+ 16 - 0
crm-model/src/main/java/com/crm/rely/backend/model/pojo/table/ImageRecognizeConfigTable.java

@@ -0,0 +1,16 @@
+package com.crm.rely.backend.model.pojo.table;
+
+import com.crm.rely.backend.core.pojo.BaseTable;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import lombok.Data;
+
+
+@Data
+@Entity
+@Table(name = "image_recognize_config")
+public class ImageRecognizeConfigTable extends BaseTable {
+    private String code;
+
+    private String value;
+}