Browse Source

二要素身份验证,以及其他bug修复

song 9 months ago
parent
commit
0ecdcc6d60
40 changed files with 732 additions and 97 deletions
  1. 3 1
      dbscripts/V1.0.0/init_strucure_1.0.7.sql
  2. 6 0
      pom.xml
  3. 5 0
      sanling-finance-biz/pom.xml
  4. 5 0
      sanling-finance-biz/src/main/java/org/spring/finance/biz/common/SysDictConstants.java
  5. 11 1
      sanling-finance-biz/src/main/java/org/spring/finance/biz/common/SystemConstants.java
  6. 40 0
      sanling-finance-biz/src/main/java/org/spring/finance/biz/config/business/IdVerifyConfig.java
  7. 8 1
      sanling-finance-biz/src/main/java/org/spring/finance/biz/crud/entity/bo/WithdrawalExaminePassBo.java
  8. 3 0
      sanling-finance-biz/src/main/java/org/spring/finance/biz/crud/entity/vo/AuditRechargeListVo.java
  9. 3 3
      sanling-finance-biz/src/main/java/org/spring/finance/biz/crud/entity/vo/ExamineRechargeDetailVo.java
  10. 3 0
      sanling-finance-biz/src/main/java/org/spring/finance/biz/crud/entity/vo/ExamineWithdrawalDetailVo.java
  11. 6 0
      sanling-finance-biz/src/main/java/org/spring/finance/biz/crud/entity/vo/ExamineWithdrawalVo.java
  12. 42 4
      sanling-finance-biz/src/main/java/org/spring/finance/biz/crud/service/app/WithdrawalAppService.java
  13. 82 0
      sanling-finance-biz/src/main/java/org/spring/finance/biz/idverify/HttpsApiClient.java
  14. 33 0
      sanling-finance-biz/src/main/java/org/spring/finance/biz/idverify/IdVerifyClientApi.java
  15. 121 0
      sanling-finance-biz/src/main/java/org/spring/finance/biz/idverify/handler/VerifyHandler.java
  16. 16 0
      sanling-finance-biz/src/main/java/org/spring/finance/biz/idverify/req/IdVerifyReq.java
  17. 3 3
      sanling-finance-biz/src/main/java/org/spring/finance/biz/sms/SmsClientApi.java
  18. 5 0
      sanling-finance-biz/src/main/java/org/spring/finance/biz/utils/FinanceDisableUtils.java
  19. 40 0
      sanling-finance-biz/src/main/java/org/spring/finance/biz/utils/SignatureUtils.java
  20. 25 7
      sanling-finance-cms/src/main/java/org/spring/finance/cms/controller/account/AccountController.java
  21. 2 2
      sanling-finance-cms/src/main/java/org/spring/finance/cms/controller/finance/RechargeController.java
  22. 60 32
      sanling-finance-cms/src/main/java/org/spring/finance/cms/controller/finance/WithdrawalController.java
  23. 16 0
      sanling-finance-cms/src/main/java/org/spring/finance/cms/entity/req/GlobalLimitReq.java
  24. 3 0
      sanling-finance-cms/src/main/java/org/spring/finance/cms/entity/req/UpdateAccountInfoReq.java
  25. 5 1
      sanling-finance-cms/src/main/java/org/spring/finance/cms/entity/req/WithdrawalExamineReq.java
  26. 2 2
      sanling-finance-cms/src/main/java/org/spring/finance/cms/entity/vo/AccountFinanceListVo.java
  27. 3 0
      sanling-finance-cms/src/main/java/org/spring/finance/cms/entity/vo/AccountFinanceVo.java
  28. 4 0
      sanling-finance-cms/src/main/java/org/spring/finance/cms/entity/vo/AccountInfoVo.java
  29. 6 0
      sanling-finance-cms/src/main/resources/application-dev.yml
  30. 6 0
      sanling-finance-cms/src/main/resources/application-prod.yml
  31. 6 0
      sanling-finance-job/src/main/resources/application-prod.yml
  32. 110 30
      sanling-finance-server/src/main/java/org/spring/finance/server/controller/account/AccountAuthController.java
  33. 9 0
      sanling-finance-server/src/main/java/org/spring/finance/server/controller/account/AccountInfoController.java
  34. 8 2
      sanling-finance-server/src/main/java/org/spring/finance/server/controller/account/RechargeAndWithdrawalController.java
  35. 3 1
      sanling-finance-server/src/main/java/org/spring/finance/server/controller/account/TransferController.java
  36. 0 5
      sanling-finance-server/src/main/java/org/spring/finance/server/entity/req/UpdatePwdReq.java
  37. 11 2
      sanling-finance-server/src/main/java/org/spring/finance/server/entity/vo/AccountInfoVo.java
  38. 6 0
      sanling-finance-server/src/main/resources/application-dev.yml
  39. 6 0
      sanling-finance-server/src/main/resources/application-prod.yml
  40. 6 0
      sanling-finance-server/src/main/resources/application-test.yml

+ 3 - 1
dbscripts/V1.0.0/init_strucure_1.0.7.sql

@@ -31,4 +31,6 @@ UPDATE `t_mgr_menu_info` SET `sort` = 13 WHERE `id` = 38;
 INSERT INTO `t_sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `dict_status`, `create_by`, `update_by`, `remark`, `update_time`, `create_time`) VALUES (42, 0, 'data_proxy_interest_rate', '0.3', 'type_system_config', NULL, NULL, 0, 0, '1', '1', '代理抽成比例', '2025-02-21 10:59:43', '2025-02-20 19:04:52');
 -- 增加充值审核表待审核金额
 ALTER TABLE `t_examine_recharge`
-    ADD COLUMN `pending_amount` decimal(15, 2) NULL COMMENT '待审核金额' AFTER `account_id`
+    ADD COLUMN `pending_amount` decimal(15, 2) NULL COMMENT '待审核金额' AFTER `account_id`
+-- 字典表中加入提现起步金额
+INSERT INTO `finance_center`.`t_sys_dict_data` (`dict_label`, `dict_value`, `dict_type`, `create_by`, `remark`) VALUES ('data_minimum_withdrawal_amount', '1000', 'type_system_config', '1', '提现起步金额')

+ 6 - 0
pom.xml

@@ -59,6 +59,12 @@
                 <artifactId>javase</artifactId>
                 <version>3.4.1</version>
             </dependency>
+<!--            SDK核心-->
+            <dependency>
+                <groupId>com.aliyun.api.gateway</groupId>
+                <artifactId>sdk-core-java</artifactId>
+                <version>1.1.7</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 

+ 5 - 0
sanling-finance-biz/pom.xml

@@ -80,6 +80,11 @@
             <groupId>com.google.zxing</groupId>
             <artifactId>javase</artifactId>
         </dependency>
+<!--        核心库阿里sdk-->
+        <dependency>
+            <groupId>com.aliyun.api.gateway</groupId>
+            <artifactId>sdk-core-java</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 5 - 0
sanling-finance-biz/src/main/java/org/spring/finance/biz/common/SysDictConstants.java

@@ -33,6 +33,11 @@ public class SysDictConstants {
      */
     public final static String DATA_PROXY_INTEREST_RATE = "data_proxy_interest_rate";
 
+    /**
+     * 数据-提现起步金额
+     */
+    public final static String DATA_MINIMUM_WITHDRAWAL_AMOUNT = "data_minimum_withdrawal_amount";
+
     /**
      * 数据-代理结息金额
      */

+ 11 - 1
sanling-finance-biz/src/main/java/org/spring/finance/biz/common/SystemConstants.java

@@ -27,7 +27,17 @@ public class SystemConstants {
     /**
      * 每日提现操作结束开始时间
      */
-    public final static LocalTime WITHDRAWAL_END_TIME = LocalTime.of(22, 0);
+    public final static LocalTime WITHDRAWAL_END_TIME = LocalTime.of(21, 0);
+
+    /**
+     * 每日充值操作限制开始时间
+     */
+    public final static LocalTime RECHARGE_START_TIME = LocalTime.of(6, 0);
+
+    /**
+     * 每日充值操作限制结束时间
+     */
+    public final static LocalTime RECHARGE_END_TIME = LocalTime.of(22, 0);
 
     /**
      * 每日资金禁止操作开始时间

+ 40 - 0
sanling-finance-biz/src/main/java/org/spring/finance/biz/config/business/IdVerifyConfig.java

@@ -0,0 +1,40 @@
+package org.spring.finance.biz.config.business;
+
+import lombok.Data;
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+@Getter
+public class IdVerifyConfig {
+    /**
+     * host
+     */
+    @Value("${sanling.id_verify.host}")
+    private String host;
+
+    /**
+     * path
+     */
+    @Value("${sanling.id_verify.path}")
+    private String path;
+
+    /**
+     * App_key
+     */
+    @Value("${sanling.id_verify.app_key}")
+    private String app_key;
+
+    /**
+     * App_secret
+     */
+    @Value("${sanling.id_verify.app_secret}")
+    private String app_secret;
+
+    /**
+     * App_Code
+     */
+    @Value("${sanling.id_verify.app_code}")
+    private String app_code;
+}

+ 8 - 1
sanling-finance-biz/src/main/java/org/spring/finance/biz/crud/entity/bo/WithdrawalExaminePassBo.java

@@ -1,7 +1,9 @@
 package org.spring.finance.biz.crud.entity.bo;
 
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 import org.spring.finance.biz.crud.entity.AccountFinance;
 import org.spring.finance.biz.crud.entity.ExamineWithdrawal;
 
@@ -12,7 +14,7 @@ import org.spring.finance.biz.crud.entity.ExamineWithdrawal;
  * @Version: 1.0
  */
 @Data
-@AllArgsConstructor
+@Builder
 public class WithdrawalExaminePassBo {
 
     /**
@@ -35,4 +37,9 @@ public class WithdrawalExaminePassBo {
      * 财务凭证
      */
     private String certificate;
+
+    /**
+     * 拒绝原因
+     */
+    private String reason;
 }

+ 3 - 0
sanling-finance-biz/src/main/java/org/spring/finance/biz/crud/entity/vo/AuditRechargeListVo.java

@@ -39,6 +39,9 @@ public class  AuditRechargeListVo {
     @ApiModelProperty(value = "财务凭证")
     private String certificate;
 
+    @ApiModelProperty(value = "拒绝原因")
+    private String reason;
+
     @ApiModelProperty(value = "充值时间")
     @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
     private LocalDateTime createTime;

+ 3 - 3
sanling-finance-biz/src/main/java/org/spring/finance/biz/crud/entity/vo/ExamineRechargeDetailVo.java

@@ -34,12 +34,12 @@ public class ExamineRechargeDetailVo extends ExamineRechargeVo {
     @ApiModelProperty(value = "拒绝原因")
     private String reason;
 
+    @ApiModelProperty(value = "审核状态")
+    private Integer examineStatus;
+
     @ApiModelProperty(value = "公司名称")
     private String companyName;
 
-    @ApiModelProperty(value = "备注")
-    private String remark;
-    
     @ApiModelProperty(value = "银行卡号码")
     private String cardNumber;
 

+ 3 - 0
sanling-finance-biz/src/main/java/org/spring/finance/biz/crud/entity/vo/ExamineWithdrawalDetailVo.java

@@ -35,6 +35,9 @@ public class ExamineWithdrawalDetailVo extends ExamineWithdrawalVo {
     @ApiModelProperty(value = "财务凭证")
     private String certificate;
 
+    @ApiModelProperty(value = "拒绝原因")
+    private String reason;
+
     @ApiModelProperty(value = "打款时间")
     @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
     private LocalDateTime paymentTime;

+ 6 - 0
sanling-finance-biz/src/main/java/org/spring/finance/biz/crud/entity/vo/ExamineWithdrawalVo.java

@@ -30,6 +30,9 @@ public class ExamineWithdrawalVo {
     @ApiModelProperty(value = "金额")
     private BigDecimal amount;
 
+    @ApiModelProperty(value = "卡号")
+    private String cardNumber;
+
     @ApiModelProperty(value = "审核状态")
     private String examineStatusStr;
 
@@ -39,6 +42,9 @@ public class ExamineWithdrawalVo {
     @ApiModelProperty(value = "开户支行名称")
     private String bankBranchName;
 
+    @ApiModelProperty(value = "拒绝原因")
+    private String reason;
+
     @ApiModelProperty(value = "提现时间")
     @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
     private LocalDateTime createTime;

+ 42 - 4
sanling-finance-biz/src/main/java/org/spring/finance/biz/crud/service/app/WithdrawalAppService.java

@@ -56,8 +56,8 @@ public class WithdrawalAppService {
         //更新金融账户余额
         LambdaUpdateWrapper<AccountFinance> updateWrapper = Wrappers.lambdaUpdate();
         updateWrapper.eq(AccountFinance::getId, accountFinance.getId())
-                .setSql("auction_amount=auction_amount-" + amount)
-                .setSql("auction_frozen_amount=auction_frozen_amount+" + amount)
+                .setSql("agile_amount=agile_amount-" + amount)
+                .setSql("agile_frozen_amount=agile_frozen_amount+" + amount)
                 .setSql("withdrawal_amount=withdrawal_amount+" + amount);
         boolean result = accountFinanceService.update(updateWrapper);
         ExamineWithdrawal examineWithdrawal = new ExamineWithdrawal();
@@ -94,7 +94,13 @@ public class WithdrawalAppService {
         examineWithdrawal.setAmount(amount);
         boolean result = examineWithdrawalService.create(examineWithdrawal);
         if (result) {
-            WithdrawalExaminePassBo withdrawalExaminePassBo = new WithdrawalExaminePassBo(withdrawalAccount, examineWithdrawal, adminId, certificate);
+            WithdrawalExaminePassBo withdrawalExaminePassBo = WithdrawalExaminePassBo.builder()
+                    .withdrawalAccount(withdrawalAccount)
+                    .examineWithdrawal(examineWithdrawal)
+                    .adminId(adminId)
+                    .certificate(certificate)
+                    .reason(null)
+                    .build();
             this.withdrawalExaminePass(withdrawalExaminePassBo);
         }
     }
@@ -116,7 +122,7 @@ public class WithdrawalAppService {
         //修改金融账户
         LambdaUpdateWrapper<AccountFinance> updateWrapperFinance = Wrappers.lambdaUpdate();
         updateWrapperFinance.eq(AccountFinance::getId, withdrawalAccount.getId())
-                .setSql("agile_amount=agile_amount-" + amount);
+                .setSql("agile_frozen_amount=agile_frozen_amount-" + amount);
         boolean result = accountFinanceService.update(updateWrapperFinance);
         if (result) {
             //生成资金流水
@@ -146,4 +152,36 @@ public class WithdrawalAppService {
         }
     }
 
+    /**
+     * 提现审核拒绝
+     *
+     * @param withdrawalExaminePassBo
+     * @Author: zhangxuesong
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void withdrawalExamineRefuse(WithdrawalExaminePassBo withdrawalExaminePassBo) {
+        AccountFinance withdrawalAccount = withdrawalExaminePassBo.getWithdrawalAccount();
+        ExamineWithdrawal examineWithdrawal = withdrawalExaminePassBo.getExamineWithdrawal();
+        BigDecimal amount = examineWithdrawal.getAmount();
+        //修改金融账户
+        LambdaUpdateWrapper<AccountFinance> updateWrapperFinance = Wrappers.lambdaUpdate();
+        updateWrapperFinance.eq(AccountFinance::getId, withdrawalAccount.getId())
+                .setSql("agile_amount=agile_amount+" + amount)
+                .setSql("agile_frozen_amount=agile_frozen_amount-" + amount);
+        boolean result = accountFinanceService.update(updateWrapperFinance);
+        if (result) {
+            //更新审核单
+            LambdaUpdateWrapper<ExamineWithdrawal> updateWrapper = Wrappers.lambdaUpdate();
+            updateWrapper.eq(ExamineWithdrawal::getId, examineWithdrawal.getId())
+                    .set(ExamineWithdrawal::getExamineStatus, ExamineStatusEnum.REFUSE.getCode())
+                    .set(ExamineWithdrawal::getReason, withdrawalExaminePassBo.getReason())
+                    .set(ExamineWithdrawal::getOperatorId, withdrawalExaminePassBo.getAdminId())
+                    .set(ExamineWithdrawal::getPaymentTime, LocalDateTime.now());
+            result = examineWithdrawalService.update(updateWrapper);
+        }
+        if (!result) {
+            throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "数据库更新失败");
+        }
+    }
+
 }

+ 82 - 0
sanling-finance-biz/src/main/java/org/spring/finance/biz/idverify/HttpsApiClient.java

@@ -0,0 +1,82 @@
+//
+//  Created by  fred on 2017/1/12.
+//  Copyright © 2016年 Alibaba. All rights reserved.
+//
+
+package org.spring.finance.biz.idverify;
+
+import com.alibaba.cloudapi.sdk.client.ApacheHttpClient;
+import com.alibaba.cloudapi.sdk.enums.HttpMethod;
+import com.alibaba.cloudapi.sdk.enums.ParamPosition;
+import com.alibaba.cloudapi.sdk.enums.Scheme;
+import com.alibaba.cloudapi.sdk.model.ApiCallback;
+import com.alibaba.cloudapi.sdk.model.ApiRequest;
+import com.alibaba.cloudapi.sdk.model.ApiResponse;
+import com.alibaba.cloudapi.sdk.model.HttpClientBuilderParams;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+
+@Service
+public class HttpsApiClient extends ApacheHttpClient{
+    public final static String HOST = "sinocheck2.market.alicloudapi.com";
+    static HttpsApiClient instance = new HttpsApiClient();
+    public static HttpsApiClient getInstance(){return instance;}
+
+    public void init(HttpClientBuilderParams httpClientBuilderParams){
+        httpClientBuilderParams.setScheme(Scheme.HTTPS);
+        httpClientBuilderParams.setHost(HOST);
+        super.init(httpClientBuilderParams);
+    }
+
+
+
+    public void 身份证二要素API_请求体(String name , String id_number , ApiCallback callback) {
+        String path = "/verify/identity";
+        ApiRequest request = new ApiRequest(HttpMethod.POST_FORM , path);
+        request.addParam("name" , name , ParamPosition.BODY , true);
+        request.addParam("id_number" , id_number , ParamPosition.BODY , true);
+
+
+
+        sendAsyncRequest(request , callback);
+    }
+
+    public ApiResponse idVerifyApiSyncMode(String name , String id_number) {
+        String path = "/verify/identity";
+        ApiRequest request = new ApiRequest(HttpMethod.POST_FORM , path);
+        request.addParam("name" , name , ParamPosition.BODY , true);
+        request.addParam("id_number" , id_number , ParamPosition.BODY , true);
+
+
+
+        return sendSyncRequest(request);
+    }
+    public void 身份证二要素API_查询参数(String name , String id_number , byte[] body , ApiCallback callback) {
+        String path = "/getapilist/verify_id_name";
+        ApiRequest request = new ApiRequest(HttpMethod.POST_BODY , path, body);
+        request.addParam("name" , name , ParamPosition.QUERY , true);
+        request.addParam("id_number" , id_number , ParamPosition.QUERY , true);
+
+
+
+        sendAsyncRequest(request , callback);
+    }
+
+    public ApiResponse 身份证二要素API_查询参数SyncMode(String name , String id_number , byte[] body) {
+        String path = "/getapilist/verify_id_name";
+        ApiRequest request = new ApiRequest(HttpMethod.POST_BODY , path, body);
+        request.addParam("name" , name , ParamPosition.QUERY , true);
+        request.addParam("id_number" , id_number , ParamPosition.QUERY , true);
+
+
+
+        return sendSyncRequest(request);
+    }
+
+}

+ 33 - 0
sanling-finance-biz/src/main/java/org/spring/finance/biz/idverify/IdVerifyClientApi.java

@@ -0,0 +1,33 @@
+package org.spring.finance.biz.idverify;
+
+import com.alibaba.cloudapi.sdk.model.HttpClientBuilderParams;
+import lombok.extern.slf4j.Slf4j;
+import org.spring.finance.biz.config.business.IdVerifyConfig;
+import org.spring.finance.biz.crud.entity.AccountFinance;
+import org.spring.finance.biz.idverify.handler.VerifyHandler;
+import org.spring.finance.biz.idverify.req.IdVerifyReq;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.concurrent.Executors;
+
+@Service
+public class IdVerifyClientApi {
+    @Resource
+    private IdVerifyConfig idVerifyConfig;
+    @Resource
+    private HttpsApiClient httpsApiClient;
+    @Resource
+    private VerifyHandler verifyHandler;
+    public String verifyId(String idNumber, String name) {
+        IdVerifyReq idVerifyReq = new IdVerifyReq();
+        idVerifyReq.setIdNumber(idNumber);
+        idVerifyReq.setName(name);
+        HttpClientBuilderParams httpClientBuilderParams = new HttpClientBuilderParams();
+        httpClientBuilderParams.setAppKey(idVerifyConfig.getApp_key());
+        httpClientBuilderParams.setAppSecret(idVerifyConfig.getApp_secret());
+        HttpsApiClient.getInstance().init(httpClientBuilderParams);
+        String  result = VerifyHandler.verifyHandler(idVerifyReq);
+        return result;
+    }
+}

+ 121 - 0
sanling-finance-biz/src/main/java/org/spring/finance/biz/idverify/handler/VerifyHandler.java

@@ -0,0 +1,121 @@
+package org.spring.finance.biz.idverify.handler;
+
+
+import com.alibaba.cloudapi.sdk.constant.SdkConstant;
+import com.alibaba.cloudapi.sdk.model.ApiCallback;
+import com.alibaba.cloudapi.sdk.model.ApiRequest;
+import com.alibaba.cloudapi.sdk.model.ApiResponse;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.http.ssl.TrustStrategy;
+import org.spring.finance.biz.idverify.HttpsApiClient;
+import org.spring.finance.biz.idverify.req.IdVerifyReq;
+import org.springframework.stereotype.Service;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+@Service
+public class VerifyHandler {
+    public static String verifyHandler(IdVerifyReq idVerifyReq) {
+        String resultString = null;
+       try {
+           ApiResponse apiResponse = HttpsApiClient.getInstance().idVerifyApiSyncMode(idVerifyReq.getName(), idVerifyReq.getIdNumber());
+           resultString = getResultString(apiResponse);
+           System.out.println(resultString);
+       } catch (Exception e) {
+           e.printStackTrace();
+       }
+       return resultString;
+    }
+
+    private static String getResultString(ApiResponse response) throws IOException {
+        StringBuilder result = new StringBuilder();
+        result.append("Response from backend server").append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF);
+        result.append("ResultCode:").append(SdkConstant.CLOUDAPI_LF).append(response.getCode()).append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF);
+        if(response.getCode() != 200){
+            result.append("Error description:").append(response.getHeaders().get("X-Ca-Error-Message")).append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF);
+        }
+
+        result.append("ResultBody:").append(SdkConstant.CLOUDAPI_LF).append(new String(response.getBody() , SdkConstant.CLOUDAPI_ENCODING));
+
+        return result.toString();
+    }
+
+    private static Registry<ConnectionSocketFactory> getNoVerifyRegistry() {
+        RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
+        try {
+            registryBuilder.register("http", PlainConnectionSocketFactory.INSTANCE).build();
+            registryBuilder.register(
+                    "https",
+                    new SSLConnectionSocketFactory(new SSLContextBuilder().loadTrustMaterial(
+                            KeyStore.getInstance(KeyStore.getDefaultType()), new TrustStrategy() {
+                                @Override
+                                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+                                    return true;
+                                }
+                            }).build(),
+                            new HostnameVerifier() {
+                                @Override
+                                public boolean verify(String paramString, SSLSession paramSSLSession) {
+                                    return true;
+                                }
+                            }));
+
+        } catch (Exception e) {
+            throw new RuntimeException("HttpClientUtil init failure !", e);
+        }
+        return registryBuilder.build();
+    }
+
+
+    private static void trustAllHttpsCertificates() throws Exception {
+        javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
+        javax.net.ssl.TrustManager tm = new miTM();
+        trustAllCerts[0] = tm;
+        javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
+                .getInstance("SSL");
+        sc.init(null, trustAllCerts, null);
+        javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
+                .getSocketFactory());
+    }
+
+    static class miTM implements javax.net.ssl.TrustManager,
+            javax.net.ssl.X509TrustManager {
+        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+            return null;
+        }
+
+        public boolean isServerTrusted(
+                java.security.cert.X509Certificate[] certs) {
+            return true;
+        }
+
+        public boolean isClientTrusted(
+                java.security.cert.X509Certificate[] certs) {
+            return true;
+        }
+
+        public void checkServerTrusted(
+                java.security.cert.X509Certificate[] certs, String authType)
+                throws java.security.cert.CertificateException {
+            return;
+        }
+
+        public void checkClientTrusted(
+                java.security.cert.X509Certificate[] certs, String authType)
+                throws java.security.cert.CertificateException {
+            return;
+        }
+    }
+
+}

+ 16 - 0
sanling-finance-biz/src/main/java/org/spring/finance/biz/idverify/req/IdVerifyReq.java

@@ -0,0 +1,16 @@
+package org.spring.finance.biz.idverify.req;
+
+import lombok.Data;
+
+@Data
+public class IdVerifyReq {
+    /**
+     * 身份证号
+     */
+    private String idNumber;
+
+    /**
+     * 姓名
+     */
+    private String name;
+}

+ 3 - 3
sanling-finance-biz/src/main/java/org/spring/finance/biz/sms/SmsClientApi.java

@@ -74,12 +74,12 @@ public class SmsClientApi {
      */
     public boolean verification(int smsCode, String phoneNum, int optType) {
         String activeProfile = applicationContext.getEnvironment().getActiveProfiles()[0];
-//        if (!PROD_PROFILE.equals(activeProfile)) {
-//            //测试环境万能验证码
+        if (!PROD_PROFILE.equals(activeProfile)) {
+            //测试环境万能验证码
             if (smsCode == UNIVERSAL_CODE) {
                 return true;
             }
-//        }
+        }
         //获取缓存中验证码
         String cacheCode = redisUtils.get(getCodeCacheKey(phoneNum, optType));
         if (ObjectUtil.equals(cacheCode, Convert.toStr(smsCode))) {

+ 5 - 0
sanling-finance-biz/src/main/java/org/spring/finance/biz/utils/FinanceDisableUtils.java

@@ -26,6 +26,11 @@ public class FinanceDisableUtils {
         return now.isAfter(SystemConstants.WITHDRAWAL_START_TIME) && now.isBefore(SystemConstants.WITHDRAWAL_END_TIME);
     }
 
+    public static boolean isEnableRecharge() {
+        LocalTime now = LocalTime.now();
+        return now.isAfter(SystemConstants.RECHARGE_START_TIME) && now.isBefore(SystemConstants.RECHARGE_END_TIME);
+    }
+
     /**
      * 资金操作是否开启
      *

+ 40 - 0
sanling-finance-biz/src/main/java/org/spring/finance/biz/utils/SignatureUtils.java

@@ -0,0 +1,40 @@
+package org.spring.finance.biz.utils;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.util.Base64;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class SignatureUtils {
+    /**
+     * 生成签名
+     *
+     * @param params 请求参数
+     * @param appSecret AppSecret
+     * @return 签名字符串
+     */
+    public static String generateSignature(Map<String, String> params, String appSecret) {
+        try {
+            // 按参数名升序排序
+            Map<String, String> sortedParams = new TreeMap<>(params);
+
+            // 拼接待签名字符串
+            StringBuilder signStrBuilder = new StringBuilder();
+            for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
+                signStrBuilder.append(entry.getKey()).append(entry.getValue());
+            }
+
+            // 使用HMAC-SHA256算法生成签名
+            Mac sha256Hmac = Mac.getInstance("HmacSHA256");
+            SecretKeySpec secretKeySpec = new SecretKeySpec(appSecret.getBytes(), "HmacSHA256");
+            sha256Hmac.init(secretKeySpec);
+            byte[] signatureBytes = sha256Hmac.doFinal(signStrBuilder.toString().getBytes());
+
+            // 将签名转换为Base64字符串
+            return Base64.getEncoder().encodeToString(signatureBytes);
+        } catch (Exception e) {
+            throw new RuntimeException("签名生成失败", e);
+        }
+    }
+}

+ 25 - 7
sanling-finance-cms/src/main/java/org/spring/finance/cms/controller/account/AccountController.java

@@ -3,11 +3,9 @@ package org.spring.finance.cms.controller.account;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.convert.Convert;
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.PhoneUtil;
-import cn.hutool.core.util.RandomUtil;
-import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.*;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -184,6 +182,7 @@ public class AccountController {
         accountFinanceVo.setTotalIntegralIncome(accountFinanceService.getAccountAmount("agile_interest"));
         accountFinanceVo.setTotalGratitudeIncome(accountFinanceService.getAccountAmount("gratitude_interest"));
         accountFinanceVo.setGeneralProxyIncome(accountFinanceService.getAccountAmount("general_proxy_account"));
+        accountFinanceVo.setTotalFrozenAmount(accountFinanceService.getAccountAmount("agile_frozen_amount"));
         return Result.success(accountFinanceVo);
 
     }
@@ -270,6 +269,7 @@ public class AccountController {
             accountFinance.setPassword(passwordAes);
             accountFinance.setSalt(salt);
         }
+        accountFinance.setTransferLimit(updateAccountInfoReq.getTransferLimit());
         accountFinanceService.updateAccountInfo(accountFinance, adminId);
         return Result.success();
     }
@@ -412,9 +412,9 @@ public class AccountController {
             throw new BusinessException(ErrorCodeEnum.INPUT_PARAMETER_ERROR.getCode(), "手机号格式不正确");
         }
         //校验身份证号码
-//        if (!IdcardUtil.isValidCard(addAccountReq.getIdNumber())) {
-//            throw new BusinessException(ErrorCodeEnum.INPUT_PARAMETER_ERROR.getCode(), "身份证号格式不正确");
-//        }
+        if (!IdcardUtil.isValidCard(addAccountReq.getIdNumber())) {
+            throw new BusinessException(ErrorCodeEnum.INPUT_PARAMETER_ERROR.getCode(), "身份证号格式不正确");
+        }
         AccountFinance accountFinance = accountFinanceService.getOneByPhone(addAccountReq.getAccount());
         if (accountFinance != null) {
             throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "该账号已存在");
@@ -493,4 +493,22 @@ public class AccountController {
         }
         return Result.success();
     }
+
+    @ApiOperation(value = "全局转账限额设置")
+    @PostMapping(value = "global_transfer_limit")
+    public Result<?> globalTransferLimit (@RequestBody @Valid BaseSimpleReq<GlobalLimitReq> req) {
+        GlobalLimitReq globalLimitReq = req.getData();
+        if (globalLimitReq == null) {
+            throw new BusinessException(ErrorCodeEnum.INPUT_PARAMETER_ERROR.getCode(), ErrorCodeEnum.INPUT_PARAMETER_ERROR.getDesc());
+        }
+         //更新全局转账限额
+        QueryWrapper<AccountFinance> queryWrapper = Wrappers.query();
+        AccountFinance accountFinance = new AccountFinance();
+        accountFinance.setTransferLimit(globalLimitReq.getTransferLimit());
+        boolean result = accountFinanceService.update(accountFinance, queryWrapper);
+        if (!result) {
+            throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "更新全局转账限额失败");
+        }
+        return Result.success();
+    }
 }

+ 2 - 2
sanling-finance-cms/src/main/java/org/spring/finance/cms/controller/finance/RechargeController.java

@@ -142,7 +142,7 @@ public class RechargeController {
                     //查询会员转账短信模板id
                     String templateCode = sysDictDataService.findValueByKey(SysDictConstants.DATA_TEMPLATE_RECHARGE_PASS, SysDictConstants.TYPE_SMS_CONFIG);
                     if (StrUtil.isBlank(templateCode)) {
-                        log.error("----------------提现成功短信模板未配置");
+                        log.error("----------------充值审核模板未配置");
                         return;
                     }
                     JSONObject jsonObject = new JSONObject();
@@ -186,7 +186,7 @@ public class RechargeController {
                 //查询会员转账短信模板id
                 String templateCode = sysDictDataService.findValueByKey(SysDictConstants.DATA_TEMPLATE_RECHARGE_REFUSE, SysDictConstants.TYPE_SMS_CONFIG);
                 if (StrUtil.isBlank(templateCode)) {
-                    log.error("----------------提现成功短信模板未配置");
+                    log.error("----------------充值失败短信模板未配置");
                     return;
                 }
                 AccountFinance rechargeAccount = accountFinanceService.getById(examineRecharge.getAccountId());

+ 60 - 32
sanling-finance-cms/src/main/java/org/spring/finance/cms/controller/finance/WithdrawalController.java

@@ -3,6 +3,7 @@ package org.spring.finance.cms.controller.finance;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.thread.ThreadUtil;
+import cn.hutool.core.util.DesensitizedUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson2.JSONObject;
@@ -104,39 +105,67 @@ public class WithdrawalController {
         if (examineWithdrawal == null || ObjectUtil.notEqual(examineWithdrawal.getExamineStatus(), ExamineStatusEnum.EXAMINE.getCode())) {
             throw new BusinessException(ErrorCodeEnum.MISSING_KEY_INFORMATION.getCode(), "充值审核单不存在或不是审核中状态");
         }
-        //上用户锁
         AccountFinance withdrawalAccount = accountFinanceService.getById(examineWithdrawal.getAccountId());
         if (withdrawalAccount == null) {
             throw new BusinessException(ErrorCodeEnum.MISSING_KEY_INFORMATION.getCode(), "提现用户不存在");
         }
-        String withdrawalKey = LockKey.ACCOUNT_FINANCE_LOCK + withdrawalAccount.getId();
-        int withdrawalLock = distributedLockUtils.lock(withdrawalKey);
-        if (withdrawalLock == 0) {
-            throw new BusinessException(ErrorCodeEnum.DONT_OFTEN_OPERATOR.getCode(), ErrorCodeEnum.DONT_OFTEN_OPERATOR.getDesc());
-        }
-        try {
-            WithdrawalExaminePassBo withdrawalExaminePassBo = new WithdrawalExaminePassBo(withdrawalAccount, examineWithdrawal, adminId, withdrawalExamineReq.getCertificate());
-            withdrawalAppService.withdrawalExaminePass(withdrawalExaminePassBo);
-            //异步发送短信通知
-            ThreadUtil.execute(() -> {
-                //查询会员转账短信模板id
-                String templateCode = sysDictDataService.findValueByKey(SysDictConstants.DATA_TEMPLATE_WITHDRAWAL_SUCCESS, SysDictConstants.TYPE_SMS_CONFIG);
-                if (StrUtil.isBlank(templateCode)) {
-                    log.error("----------------提现成功短信模板未配置");
-                    return;
-                }
-                JSONObject jsonObject = new JSONObject();
-                jsonObject.put("realName", withdrawalAccount.getRealName());
-                SmsNoticeBo smsNoticeBo = new SmsNoticeBo(NumberUtils.LONG_ONE, withdrawalAccount.getAccount(), jsonObject, templateCode);
-                smsClientApi.smsNotice(smsNoticeBo);
-            });
-        } catch (BusinessException e) {
-            return Result.error(e.getErrCode(), e.getErrMsg());
-        } catch (Exception e) {
-            log.error("-------------------提现审核通过报错:", e);
-            return Result.error(e.getMessage());
-        } finally {
-            distributedLockUtils.unlock(withdrawalKey);
+        if (ObjectUtil.equals(withdrawalExamineReq.getExamineStatus(), ExamineStatusEnum.PASS.getCode())){
+            //上用户锁
+            String withdrawalKey = LockKey.ACCOUNT_FINANCE_LOCK + withdrawalAccount.getId();
+            int withdrawalLock = distributedLockUtils.lock(withdrawalKey);
+            if (withdrawalLock == 0) {
+                throw new BusinessException(ErrorCodeEnum.DONT_OFTEN_OPERATOR.getCode(), ErrorCodeEnum.DONT_OFTEN_OPERATOR.getDesc());
+            }
+            try {
+                WithdrawalExaminePassBo withdrawalExaminePassBo = WithdrawalExaminePassBo.builder()
+                        .withdrawalAccount(withdrawalAccount)
+                        .examineWithdrawal(examineWithdrawal)
+                        .adminId(adminId)
+                        .certificate(withdrawalExamineReq.getCertificate())
+                        .reason(withdrawalExamineReq.getReason())
+                        .build();
+                withdrawalAppService.withdrawalExaminePass(withdrawalExaminePassBo);
+                //异步发送短信通知
+                ThreadUtil.execute(() -> {
+                    //查询会员转账短信模板id
+                    String templateCode = sysDictDataService.findValueByKey(SysDictConstants.DATA_TEMPLATE_WITHDRAWAL_SUCCESS, SysDictConstants.TYPE_SMS_CONFIG);
+                    if (StrUtil.isBlank(templateCode)) {
+                        log.error("----------------提现成功短信模板未配置");
+                        return;
+                    }
+                    JSONObject jsonObject = new JSONObject();
+                    jsonObject.put("realName", withdrawalAccount.getRealName());
+                    SmsNoticeBo smsNoticeBo = new SmsNoticeBo(NumberUtils.LONG_ONE, withdrawalAccount.getAccount(), jsonObject, templateCode);
+                    smsClientApi.smsNotice(smsNoticeBo);
+                });
+            } catch (BusinessException e) {
+                return Result.error(e.getErrCode(), e.getErrMsg());
+            } catch (Exception e) {
+                log.error("-------------------提现审核通过报错:", e);
+                return Result.error(e.getMessage());
+            } finally {
+                distributedLockUtils.unlock(withdrawalKey);
+            }
+        } else if (ObjectUtil.equals(withdrawalExamineReq.getExamineStatus(), ExamineStatusEnum.REFUSE.getCode())) {
+            String withdrawalKey = LockKey.ACCOUNT_FINANCE_LOCK + withdrawalAccount.getId();
+            int withdrawalLock = distributedLockUtils.lock(withdrawalKey);
+            if (withdrawalLock == 0) {
+                throw new BusinessException(ErrorCodeEnum.DONT_OFTEN_OPERATOR.getCode(), ErrorCodeEnum.DONT_OFTEN_OPERATOR.getDesc());
+            }
+            try {
+                WithdrawalExaminePassBo withdrawalExaminePassBo = WithdrawalExaminePassBo.builder()
+                        .withdrawalAccount(withdrawalAccount)
+                        .examineWithdrawal(examineWithdrawal)
+                        .adminId(adminId)
+                        .certificate(withdrawalExamineReq.getCertificate())
+                        .reason(withdrawalExamineReq.getReason())
+                        .build();
+                withdrawalAppService.withdrawalExamineRefuse(withdrawalExaminePassBo);
+            } catch (BusinessException e) {
+                return Result.error(e.getErrCode(), e.getErrMsg());
+            } finally {
+                distributedLockUtils.unlock(withdrawalKey);
+            }
         }
         return Result.success();
     }
@@ -153,7 +182,7 @@ public class WithdrawalController {
 //        }
 //        ExamineWithdrawal examineWithdrawal = examineWithdrawalService.getById(withdrawalExamineFailReq.getId());
 //        if (examineWithdrawal == null || ObjectUtil.notEqual(examineWithdrawal.getExamineStatus(), ExamineStatusEnum.EXAMINE.getCode())) {
-//            throw new BusinessException(ErrorCodeEnum.MISSING_KEY_INFORMATION.getCode(), "充值审核单不存在或不是审核中状态");
+//            throw new BusinessException(ErrorCodeEnum.MISSING_KEY_INFORMATION.getCode(), "提现审核单不存在或不是审核中状态");
 //        }
 //        LambdaUpdateWrapper<ExamineWithdrawal> updateWrapper = Wrappers.lambdaUpdate();
 //        updateWrapper.eq(ExamineWithdrawal::getId, withdrawalExamineFailReq.getId())
@@ -186,7 +215,6 @@ public class WithdrawalController {
         queryWrapper.orderByAsc("t1.examine_status");
         IPage<ExamineWithdrawalVo> iPage = examineWithdrawalService.pageToCondition(new Page<>(req.getPage(), req.getPageSize()), queryWrapper);
         if (CollUtil.isNotEmpty(iPage.getRecords())) {
-
             for (ExamineWithdrawalVo examineWithdrawalVo : iPage.getRecords()) {
                 convertList(examineWithdrawalVo);
             }
@@ -220,7 +248,7 @@ public class WithdrawalController {
     /**
      * 列表转换
      *
-     * @param examineRechargeVo
+     * @param  examineRechargeVo
      * @Author: yanzesheng
      * @Date: 2023/6/14 20:46
      * @return: void

+ 16 - 0
sanling-finance-cms/src/main/java/org/spring/finance/cms/entity/req/GlobalLimitReq.java

@@ -0,0 +1,16 @@
+package org.spring.finance.cms.entity.req;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.math.BigDecimal;
+
+@ApiModel(value = "GlobalLimitReq", description = "全局限制参数")
+@Data
+public class GlobalLimitReq {
+
+    @ApiModelProperty(value = "转账限制额度")
+    private BigDecimal transferLimit;
+}

+ 3 - 0
sanling-finance-cms/src/main/java/org/spring/finance/cms/entity/req/UpdateAccountInfoReq.java

@@ -7,6 +7,7 @@ import org.spring.finance.biz.crud.entity.req.AddOrUpdateBankReq;
 
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -37,4 +38,6 @@ public class UpdateAccountInfoReq {
     @ApiModelProperty(value = "银行卡更新列表")
     private List<AddOrUpdateBankReq> bankList;
 
+    @ApiModelProperty(value = "转账限额")
+    private BigDecimal transferLimit;
 }

+ 5 - 1
sanling-finance-cms/src/main/java/org/spring/finance/cms/entity/req/WithdrawalExamineReq.java

@@ -19,7 +19,11 @@ public class WithdrawalExamineReq {
     private Integer id;
 
     @ApiModelProperty(value = "财务凭证", required = true)
-    @NotBlank(message = "财务凭证不能为空")
     private String certificate;
 
+    @ApiModelProperty(value = "审核状态,详见枚举ExamineStatusEnum")
+    private Integer examineStatus;
+
+    @ApiModelProperty(value = "拒绝原因")
+    private String reason;
 }

+ 2 - 2
sanling-finance-cms/src/main/java/org/spring/finance/cms/entity/vo/AccountFinanceListVo.java

@@ -31,8 +31,8 @@ public class AccountFinanceListVo extends AccountBaseVo {
     @ApiModelProperty(value = "拍卖保证金账户")
     private BigDecimal agileInterest;
 
-    @ApiModelProperty(value = "股权账户")
-    private BigDecimal shareholderAmount;
+    @ApiModelProperty(value = "账户冻结金额")
+    private BigDecimal agileFrozenAmount;
 
     @ApiModelProperty(value = "是否财务账号")
     private Integer isTreasurer;

+ 3 - 0
sanling-finance-cms/src/main/java/org/spring/finance/cms/entity/vo/AccountFinanceVo.java

@@ -32,4 +32,7 @@ public class AccountFinanceVo {
 
     @ApiModelProperty(value = "总代理抽成")
     private BigDecimal generalProxyIncome;
+
+    @ApiModelProperty(value = "总冻结账户金额")
+    private BigDecimal totalFrozenAmount;
 }

+ 4 - 0
sanling-finance-cms/src/main/java/org/spring/finance/cms/entity/vo/AccountInfoVo.java

@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import org.spring.finance.biz.crud.entity.vo.AccountBankVo;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -26,6 +27,9 @@ public class AccountInfoVo {
     @ApiModelProperty(value = "身份证号")
     private String idNumber;
 
+    @ApiModelProperty(value = "转账限额")
+    private BigDecimal transferLimit;
+
     @ApiModelProperty(value = "银行卡列表")
     private List<AccountBankVo> bankList;
 

+ 6 - 0
sanling-finance-cms/src/main/resources/application-dev.yml

@@ -68,6 +68,12 @@ sanling:
     bucket_name: yanzesheng-test
     upload_file: sanling-img/
     access_address: https://yanzesheng-test.oss-cn-fuzhou.aliyuncs.com/
+  id_verify:
+    host: https://sinocheck2.market.alicloudapi.com
+    path: /getapilist/verify_id_name
+    app_key: 204825904
+    app_secret: m8QalxDEd3LbsZDZgqbl7VjJPC6jK9ln
+    app_code: 42536b7ee3714a1581cf1ace58b5cedf
   redisson:
     address: 192.168.101.188:6379
     password: 123456

+ 6 - 0
sanling-finance-cms/src/main/resources/application-prod.yml

@@ -80,3 +80,9 @@ sanling:
     send_url: https://smsapi.cn-south-1.myhuaweicloud.com:443/sms/batchSendSms/v1
     app_key: Q56m40pPijc9lRF1Lf7HfxHIYFRv
     app_secret: vHpgnRE85yX8cG4kfXOgdXrxCYFb
+  id_verify:
+    host: https://sinocheck2.market.alicloudapi.com
+    path: /getapilist/verify_id_name
+    app_key: 204825904
+    app_secret: m8QalxDEd3LbsZDZgqbl7VjJPC6jK9ln
+    app_code: 42536b7ee3714a1581cf1ace58b5cedf

+ 6 - 0
sanling-finance-job/src/main/resources/application-prod.yml

@@ -89,3 +89,9 @@ sanling:
     send_url: https://smsapi.cn-south-1.myhuaweicloud.com:443/sms/batchSendSms/v1
     app_key: Q56m40pPijc9lRF1Lf7HfxHIYFRv
     app_secret: vHpgnRE85yX8cG4kfXOgdXrxCYFb
+  id_verify:
+    host: https://sinocheck2.market.alicloudapi.com
+    path: /getapilist/verify_id_name
+    app_key: 204825904
+    app_secret: m8QalxDEd3LbsZDZgqbl7VjJPC6jK9ln
+    app_code: 42536b7ee3714a1581cf1ace58b5cedf

+ 110 - 30
sanling-finance-server/src/main/java/org/spring/finance/server/controller/account/AccountAuthController.java

@@ -4,6 +4,8 @@ import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.PhoneUtil;
 import cn.hutool.core.util.RandomUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
@@ -11,14 +13,18 @@ import org.spring.base.common.enums.ErrorCodeEnum;
 import org.spring.base.common.exception.BusinessException;
 import org.spring.base.common.req.BaseReq;
 import org.spring.base.common.rsp.Result;
+import org.spring.finance.biz.common.SysDictConstants;
 import org.spring.finance.biz.crud.entity.AccountFinance;
 import org.spring.finance.biz.crud.entity.bo.AccountRegisterBo;
 import org.spring.finance.biz.crud.entity.req.StrReq;
 import org.spring.finance.biz.crud.service.AccountFinanceService;
 import org.spring.finance.biz.crud.service.PromotionService;
+import org.spring.finance.biz.crud.service.SysDictDataService;
 import org.spring.finance.biz.crud.service.app.AccountAppService;
 import org.spring.finance.biz.crud.service.cache.UserSessionRedisCache;
 import org.spring.finance.biz.enums.sms.SmsOptTypeEnum;
+import org.spring.finance.biz.idverify.IdVerifyClientApi;
+import org.spring.finance.biz.idverify.req.IdVerifyReq;
 import org.spring.finance.biz.sms.SmsClientApi;
 import org.spring.finance.biz.utils.AesUtils;
 import org.spring.finance.server.common.annotation.LoginRequired;
@@ -46,6 +52,10 @@ public class AccountAuthController {
     @Resource
     private UserSessionRedisCache userSessionRedisCache;
     @Resource
+    private IdVerifyClientApi idVerifyClientApi;
+    @Resource
+    private SysDictDataService sysDictDataService;
+    @Resource
     private PromotionService promotionService;
     //转账额度每日
     private final static BigDecimal TRANSFER_AMOUNT = BigDecimal.valueOf(50000);
@@ -94,6 +104,16 @@ public class AccountAuthController {
         accountRegisterBo.setSalt(salt);
         accountRegisterBo.setPassword(AesUtils.encrypt(password, salt));
         accountRegisterBo.setRealName(realName);
+        //字典查询转账限额额度
+        String transferLimit = sysDictDataService.findValueByKey(SysDictConstants.DATA_TRANSFER_LIMIT, SysDictConstants.TYPE_SYSTEM_CONFIG);
+        BigDecimal transferLimitAmount = new BigDecimal(transferLimit);
+        //设置用户每日限额
+        accountRegisterBo.setTransferLimit(transferLimitAmount);
+        //字典查询提现限额额度
+        String withdrawalLimit = sysDictDataService.findValueByKey(SysDictConstants.DATA_WITHDRAWAL_LIMIT, SysDictConstants.TYPE_SYSTEM_CONFIG);
+        BigDecimal withdrawalLimitAmount = new BigDecimal(withdrawalLimit);
+        //设置每日提现额度
+        accountRegisterBo.setWithdrawalLimit(withdrawalLimitAmount);
         //生成推荐码
         accountRegisterBo.setPromotionCode(accountAppService.getPromotionCode());
         accountFinance = accountFinanceService.register(accountRegisterBo);
@@ -187,23 +207,43 @@ public class AccountAuthController {
 //        LoginVo loginVo = new LoginVo();
 //        loginVo.setAccessToken(accessToken);
 //        return Result.success(loginVo);
+//    }
+
+//    @ResponseBody
+//    @ApiOperation(value = "修改登录密码")
+//    @LoginRequired
+//    @PostMapping(value = "update_pwd")
+//    public Result<?> updatePwd(@RequestBody @Valid BaseReq<UpdatePwdReq> req) {
+//        Integer userId = userSessionRedisCache.getLoginUserId(req.getAccessToken());
+//        AccountFinance accountFinance = accountFinanceService.getById(userId);
+//        if (accountFinance == null) {
+//            throw new BusinessException(ErrorCodeEnum.MISSING_KEY_INFORMATION.getCode(), ErrorCodeEnum.MISSING_KEY_INFORMATION.getDesc());
+//        }
+//        //校验旧密码
+//        String pwdEncryption = AesUtils.encrypt(req.getData().getOldPwd(), accountFinance.getSalt());
+//        if (ObjectUtil.notEqual(pwdEncryption, accountFinance.getPassword())) {
+//            throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "旧密码错误");
+//        }
+//        String salt = RandomUtil.randomString(16);
+//        AccountFinance update = new AccountFinance();
+//        update.setId(userId);
+//        update.setSalt(salt);
+//        update.setPassword(AesUtils.encrypt(req.getData().getPassword(), salt));
+//        boolean result = accountFinanceService.updateById(update);
+//        return result ? Result.success() : Result.error("修改密码失败");
 //    }
 
     @ResponseBody
-    @ApiOperation(value = "修改密码")
+    @ApiOperation(value = "修改登录密码")
     @LoginRequired
-    @PostMapping(value = "update_pwd")
-    public Result<?> updatePwd(@RequestBody @Valid BaseReq<UpdatePwdReq> req) {
+    @PostMapping(value = "update_login_pwd")
+    public Result<?> UpdateLoginPwd (@RequestBody @Valid BaseReq<UpdatePwdReq> req) {
         Integer userId = userSessionRedisCache.getLoginUserId(req.getAccessToken());
         AccountFinance accountFinance = accountFinanceService.getById(userId);
         if (accountFinance == null) {
             throw new BusinessException(ErrorCodeEnum.MISSING_KEY_INFORMATION.getCode(), ErrorCodeEnum.MISSING_KEY_INFORMATION.getDesc());
         }
-        //校验旧密码
-        String pwdEncryption = AesUtils.encrypt(req.getData().getOldPwd(), accountFinance.getSalt());
-        if (ObjectUtil.notEqual(pwdEncryption, accountFinance.getPassword())) {
-            throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "旧密码错误");
-        }
+        //生成登陆密码盐值
         String salt = RandomUtil.randomString(16);
         AccountFinance update = new AccountFinance();
         update.setId(userId);
@@ -235,29 +275,32 @@ public class AccountAuthController {
             if (!verification) {
                 throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "验证码不正确");
             }
-        } else {
-            //注册
-            if (!verification) {
-                throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "验证码不正确");
-            }
-            AccountRegisterBo accountRegisterBo = new AccountRegisterBo();
-            accountRegisterBo.setAccount(account);
-            if (req.getData().getPromotionCode() != null && !req.getData().getPromotionCode().isEmpty()) {
-                if (accountAppService.checkPromotion(req.getData().getPromotionId(), req.getData().getPromotionCode())) {
-                    throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "请输入有效的邀请码");
-                }else {
-                    AccountFinance promotionAccount = accountFinanceService.getByCode(req.getData().getPromotionCode());
-                    accountRegisterBo.setPromotionId(promotionAccount.getId());
-                }
-            }
-            //设置用户每日限额
-            accountRegisterBo.setTransferLimit(TRANSFER_AMOUNT);
-            //设置每日提现额度
-            accountRegisterBo.setWithdrawalLimit(WITHDRAWAL_AMOUNT);
-            //生成推荐码
-            accountRegisterBo.setPromotionCode(accountAppService.getPromotionCode());
-            accountFinance = accountFinanceService.register(accountRegisterBo);
+        }else {
+            throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "手机号未注册");
         }
+//        } else {
+//            //注册
+//            if (!verification) {
+//                throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "验证码不正确");
+//            }
+//            AccountRegisterBo accountRegisterBo = new AccountRegisterBo();
+//            accountRegisterBo.setAccount(account);
+//            if (req.getData().getPromotionCode() != null && !req.getData().getPromotionCode().isEmpty()) {
+//                if (accountAppService.checkPromotion(req.getData().getPromotionId(), req.getData().getPromotionCode())) {
+//                    throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "请输入有效的邀请码");
+//                }else {
+//                    AccountFinance promotionAccount = accountFinanceService.getByCode(req.getData().getPromotionCode());
+//                    accountRegisterBo.setPromotionId(promotionAccount.getId());
+//                }
+//            }
+//            //设置用户每日限额
+//            accountRegisterBo.setTransferLimit(TRANSFER_AMOUNT);
+//            //设置每日提现额度
+//            accountRegisterBo.setWithdrawalLimit(WITHDRAWAL_AMOUNT);
+//            //生成推荐码
+//            accountRegisterBo.setPromotionCode(accountAppService.getPromotionCode());
+//            accountFinance = accountFinanceService.register(accountRegisterBo);
+//        }
         //生成token
         String accessToken = IdUtil.simpleUUID();
         //登录
@@ -325,4 +368,41 @@ public class AccountAuthController {
         boolean result = accountFinanceService.updatePayPwd(userId, payPwd, salt);
         return result ? Result.success() : Result.error("设置支付密码失败");
     }
+
+
+    @ApiOperation(value = "实名认证")
+    @PostMapping(value = "real_name_auth")
+    public Result<?> realNameAuth(@RequestBody @Valid BaseReq<IdVerifyReq> req) {
+        if (req.getData() == null) {
+            throw new BusinessException(ErrorCodeEnum.INPUT_PARAMETER_ERROR.getCode(), ErrorCodeEnum.INPUT_PARAMETER_ERROR.getDesc());
+        }
+        IdVerifyReq idVerifyReq = req.getData();
+        String result = idVerifyClientApi.verifyId(idVerifyReq.getIdNumber(),idVerifyReq.getName());
+        //处理逻辑业务
+        AccountFinance accountFinance = new AccountFinance();
+        accountFinance.setIdNumber(idVerifyReq.getIdNumber());
+        accountFinance.setRealName(idVerifyReq.getName());
+        Integer userId = userSessionRedisCache.getLoginUserId(req.getAccessToken());
+        accountFinance.setId(userId);
+        try {
+            String resultBody = result.split("ResultBody:")[1].trim();
+            JSONObject jsonObject = JSON.parseObject(resultBody);
+            int checkresult = jsonObject.getJSONObject("result").getIntValue("checkresult");
+            String message = jsonObject.getJSONObject("result").getString("message");
+            if (checkresult == 1) {
+                accountFinanceService.updateById(accountFinance);
+                return Result.success(message);
+            } else if(checkresult == 2) {
+                return Result.error(message);
+            } else if(checkresult == 3) {
+                return Result.error(message);
+            } else {
+                return Result.error("实名认证失败");
+            }
+        } catch (Exception e) {
+            throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "实名认证失败");
+        }
+    }
+
+
 }

+ 9 - 0
sanling-finance-server/src/main/java/org/spring/finance/server/controller/account/AccountInfoController.java

@@ -111,6 +111,15 @@ public class AccountInfoController {
         accountInfoVo.setYesterdayAgileInterest(agileInterest);
         //获取账户定租金额
         accountInfoVo.setConsumerInterest(accountFinance.getConsumerInterest());
+        //获取用户提现额度
+        accountInfoVo.setWithdrawalLimit(accountFinance.getWithdrawalLimit());
+        //获取用户当日已提现金额
+        accountInfoVo.setWithdrawalAmount(accountFinance.getWithdrawalAmount());
+        //对用户身份证进行**处理
+        accountInfoVo.setIdNumber(DesensitizedUtil.bankCard(accountFinance.getIdNumber()));
+        //获取用户每日提现最低额度
+        String withdrawalLimitStr = sysDictDataService.findValueByKey(SysDictConstants.DATA_MINIMUM_WITHDRAWAL_AMOUNT, SysDictConstants.TYPE_SYSTEM_CONFIG);
+        accountInfoVo.setMinimumWithdrawalLimit(new BigDecimal(withdrawalLimitStr));
         //获取用户代理Id
         Promotion promotion = promotionService.getOne(Wrappers.<Promotion>lambdaQuery().eq(Promotion::getAccountId, accountId));
         accountInfoVo.setProxyId(promotion.getProxyId());

+ 8 - 2
sanling-finance-server/src/main/java/org/spring/finance/server/controller/account/RechargeAndWithdrawalController.java

@@ -87,7 +87,7 @@ public class RechargeAndWithdrawalController {
         if (accountAppService.isFinanceAccount(accountId)) {
             throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "财务账号不可充值");
         }
-        if (!FinanceDisableUtils.isEnableWithdrawal()) {
+        if (!FinanceDisableUtils.isEnableRecharge()) {
             throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "充值时间为每天6:00-22:00");
         }
         ExamineRecharge examineRecharge = new ExamineRecharge();
@@ -105,6 +105,12 @@ public class RechargeAndWithdrawalController {
     public Result<?> withdrawalApplication(@RequestBody @Valid BaseReq<WithdrawalApplicationReq> req) {
 //        throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "暂时关闭");
         WithdrawalApplicationReq withdrawalApplicationReq = req.getData();
+        //获取最小提现金额
+        String minWithdrawalAmountStr = sysDictDataService.findValueByKey(SysDictConstants.DATA_MINIMUM_WITHDRAWAL_AMOUNT, SysDictConstants.TYPE_SYSTEM_CONFIG);
+        BigDecimal minWithdrawalAmount = new BigDecimal(minWithdrawalAmountStr);
+        if (withdrawalApplicationReq.getAmount().compareTo(minWithdrawalAmount) < 0) {
+            throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "提现金额不能小于" + minWithdrawalAmountStr);
+        }
         Integer accountId = userSessionRedisCache.getLoginUserId(req.getAccessToken());
         if (withdrawalApplicationReq == null || accountId == null) {
             throw new BusinessException(ErrorCodeEnum.INPUT_PARAMETER_ERROR.getCode(), ErrorCodeEnum.INPUT_PARAMETER_ERROR.getDesc());
@@ -113,7 +119,7 @@ public class RechargeAndWithdrawalController {
             throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "财务账号不可提现申请");
         }
         if (!FinanceDisableUtils.isEnableWithdrawal()) {
-            throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "提现时间为每天6:00-22:00");
+            throw new BusinessException(ErrorCodeEnum.FAIL.getCode(), "提现时间为每天6:00-21:00");
         }
         //获取银行卡配置信息
         AccountBank accountBank = accountBankService.getById(withdrawalApplicationReq.getAccountBankId());

+ 3 - 1
sanling-finance-server/src/main/java/org/spring/finance/server/controller/account/TransferController.java

@@ -269,7 +269,9 @@ public class TransferController {
         }
         QueryWrapper<FinanceBill> queryWrapper = Wrappers.query();
         queryWrapper.eq("t1.account_id", accountId);
-        queryWrapper.eq("t1.type", FinanceTypeEnum.TRANSFER_OUT.getCode());
+        queryWrapper.and(wrapper -> wrapper.eq("t1.type", FinanceTypeEnum.TRANSFER_OUT.getCode())
+                .or()
+                .eq("t1.type", FinanceTypeEnum.TRANSFER_IN.getCode()));
         queryWrapper.orderByDesc("t1.create_time");
         IPage<FinanceBillDto> iPage = financeBillService.financeDtoList(new Page<>(req.getPage(), req.getPageSize()), queryWrapper, true);
         return BasePageQueryRsp.success(BeanUtil.copyToList(iPage.getRecords(), AccountTransferListVo.class), iPage.getTotal());

+ 0 - 5
sanling-finance-server/src/main/java/org/spring/finance/server/entity/req/UpdatePwdReq.java

@@ -12,11 +12,6 @@ import javax.validation.constraints.NotBlank;
 @ApiModel(value = "UpdatePwdReq", description = "修改登录密码请求")
 @Data
 public class UpdatePwdReq {
-
-    @ApiModelProperty(value = "旧密码", required = true)
-    @NotBlank(message = "旧密码不能为空")
-    private String oldPwd;
-
     @ApiModelProperty(value = "新密码", required = true)
     @NotBlank(message = "新密码不能为空")
     private String password;

+ 11 - 2
sanling-finance-server/src/main/java/org/spring/finance/server/entity/vo/AccountInfoVo.java

@@ -39,8 +39,8 @@ public class AccountInfoVo {
     @ApiModelProperty(value = "总资产")
     private BigDecimal totalAmount;
 
-    @ApiModelProperty(value = "拍卖保证金冻结金额")
-    private BigDecimal auctionFrozenAmount;
+    @ApiModelProperty(value = "账户冻结金额")
+    private BigDecimal agileFrozenAmount;
 
     @ApiModelProperty(value = "昨日天租收益")
     private BigDecimal yesterdayAgileInterest;
@@ -75,6 +75,15 @@ public class AccountInfoVo {
     @ApiModelProperty(value = "已转账金额")
     private BigDecimal transferAmount;
 
+    @ApiModelProperty(value = "最低提现额度")
+    private BigDecimal minimumWithdrawalLimit;
+
     @ApiModelProperty(value = "总代理ID")
     private Integer proxyId;
+
+    @ApiModelProperty(value = "提现额度")
+    private BigDecimal withdrawalLimit;
+
+    @ApiModelProperty(value = "已提现金额")
+    private BigDecimal withdrawalAmount;
 }

+ 6 - 0
sanling-finance-server/src/main/resources/application-dev.yml

@@ -73,6 +73,12 @@ sanling:
     bucket_name: yanzesheng-test
     upload_file: sanling-img/
     access_address: https://yanzesheng-test.oss-cn-fuzhou.aliyuncs.com/
+  id_verify:
+    host: https://sinocheck2.market.alicloudapi.com
+    path: /getapilist/verify_id_name
+    app_key: 204825904
+    app_secret: m8QalxDEd3LbsZDZgqbl7VjJPC6jK9ln
+    app_code: 42536b7ee3714a1581cf1ace58b5cedf
   redisson:
     address: 192.168.101.188:6379
     password: 123456

+ 6 - 0
sanling-finance-server/src/main/resources/application-prod.yml

@@ -64,6 +64,12 @@ sanling:
     bucket_name: yanzesheng-test
     upload_file: sanling-img/
     access_address: https://yanzesheng-test.oss-cn-fuzhou.aliyuncs.com/
+  id_verify:
+    host: https://sinocheck2.market.alicloudapi.com
+    path: /getapilist/verify_id_name
+    app_key: 204825904
+    app_secret: m8QalxDEd3LbsZDZgqbl7VjJPC6jK9ln
+    app_code: 42536b7ee3714a1581cf1ace58b5cedf
   redisson:
     address: 127.0.0.1:6379
     password: jnb!@34$#@

+ 6 - 0
sanling-finance-server/src/main/resources/application-test.yml

@@ -64,6 +64,12 @@ sanling:
     bucket_name: yanzesheng-test
     upload_file: sanling-img/
     access_address: https://yanzesheng-test.oss-cn-fuzhou.aliyuncs.com/
+  id_verify:
+    host: https://sinocheck2.market.alicloudapi.com
+    path: /getapilist/verify_id_name
+    app_key: 204825904
+    app_secret: m8QalxDEd3LbsZDZgqbl7VjJPC6jK9ln
+    app_code: 42536b7ee3714a1581cf1ace58b5cedf
   redisson:
     address: 118.178.121.151:6379
     password: 123456