瀏覽代碼

Merge remote-tracking branch 'origin/master'

huangjunling 1 周之前
父節點
當前提交
ed801c912c
共有 100 個文件被更改,包括 2541 次插入604 次删除
  1. 14 1
      qnfhq-api/pom.xml
  2. 62 0
      qnfhq-api/src/main/java/com/qnfhq/aliyun/CaptchaConfig.java
  3. 28 0
      qnfhq-api/src/main/java/com/qnfhq/common/BigDecimalSerialize.java
  4. 29 0
      qnfhq-api/src/main/java/com/qnfhq/common/BigDecimalSerialize2.java
  5. 4 4
      qnfhq-api/src/main/java/com/qnfhq/config/SaTokenConfigure.java
  6. 1 1
      qnfhq-api/src/main/java/com/qnfhq/config/SwaggerConfig.java
  7. 16 38
      qnfhq-api/src/main/java/com/qnfhq/constant/CacheConstants.java
  8. 62 0
      qnfhq-api/src/main/java/com/qnfhq/modules/business/controller/TMingOrderController.java
  9. 17 0
      qnfhq-api/src/main/java/com/qnfhq/modules/business/dao/TMingOrderMapper.java
  10. 17 0
      qnfhq-api/src/main/java/com/qnfhq/modules/business/dao/TMingProductMapper.java
  11. 9 0
      qnfhq-api/src/main/java/com/qnfhq/modules/business/dao/TMingProductUserMapper.java
  12. 16 0
      qnfhq-api/src/main/java/com/qnfhq/modules/business/entity/AddMosaicSetting.java
  13. 128 0
      qnfhq-api/src/main/java/com/qnfhq/modules/business/entity/MingProduct.java
  14. 59 0
      qnfhq-api/src/main/java/com/qnfhq/modules/business/entity/MingProductUser.java
  15. 126 0
      qnfhq-api/src/main/java/com/qnfhq/modules/business/entity/TMingOrder.java
  16. 26 0
      qnfhq-api/src/main/java/com/qnfhq/modules/business/service/ITMingOrderService.java
  17. 18 0
      qnfhq-api/src/main/java/com/qnfhq/modules/business/service/ITMingProductService.java
  18. 200 0
      qnfhq-api/src/main/java/com/qnfhq/modules/business/service/impl/TMingOrderServiceImpl.java
  19. 27 0
      qnfhq-api/src/main/java/com/qnfhq/modules/business/service/impl/TMingProductServiceImpl.java
  20. 11 11
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/C2cAdController.java
  21. 137 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/C2cMsgContentController.java
  22. 97 51
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/C2cOrderController.java
  23. 16 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/C2cMsgContactDao.java
  24. 16 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/C2cMsgContentDao.java
  25. 16 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/C2cMsgRelationDao.java
  26. 5 2
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cAdViewDTO.java
  27. 27 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cMsgContactDTO.java
  28. 50 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cMsgContentDTO.java
  29. 35 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cMsgRelationDTO.java
  30. 2 3
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderComplainVoucherDTO.java
  31. 5 6
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderCreateDTO.java
  32. 24 5
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderDTO.java
  33. 0 2
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderIdDTO.java
  34. 0 3
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderListDTO.java
  35. 0 2
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cPaymentVoucherIdDTO.java
  36. 14 1
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cAdEntity.java
  37. 33 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cMerchantEntity.java
  38. 53 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cMsgContactEntity.java
  39. 49 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cMsgContentEntity.java
  40. 42 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cMsgRelationEntity.java
  41. 22 11
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cOrderEntity.java
  42. 32 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/enums/MsgRelationEnum.java
  43. 35 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/enums/MsgStatusEnum.java
  44. 20 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/enums/MsgTypeEnum.java
  45. 3 3
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cAdService.java
  46. 38 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cMsgContactService.java
  47. 23 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cMsgContentService.java
  48. 31 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cMsgRelationService.java
  49. 0 2
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cOrderComplainVoucherService.java
  50. 4 7
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cOrderService.java
  51. 88 139
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cAdServiceImpl.java
  52. 104 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cMsgContactServiceImpl.java
  53. 62 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cMsgContentServiceImpl.java
  54. 64 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cMsgRelationServiceImpl.java
  55. 0 13
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cOrderComplainVoucherServiceImpl.java
  56. 31 59
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cOrderServiceImpl.java
  57. 14 54
      qnfhq-api/src/main/java/com/qnfhq/modules/user/controller/ApiAppUserController.java
  58. 7 1
      qnfhq-api/src/main/java/com/qnfhq/modules/user/dao/AppAssetDao.java
  59. 3 1
      qnfhq-api/src/main/java/com/qnfhq/modules/user/dto/SendEmailCodeDTO.java
  60. 3 1
      qnfhq-api/src/main/java/com/qnfhq/modules/user/dto/SendPhoneCodeDTO.java
  61. 17 0
      qnfhq-api/src/main/java/com/qnfhq/modules/user/dto/VerifyIntelligentCaptchaDTO.java
  62. 17 0
      qnfhq-api/src/main/java/com/qnfhq/modules/user/dto/setting/CaptchaSetting.java
  63. 1 1
      qnfhq-api/src/main/java/com/qnfhq/modules/user/entity/AppUserDetailEntity.java
  64. 10 4
      qnfhq-api/src/main/java/com/qnfhq/modules/user/enums/RecordEnum.java
  65. 2 0
      qnfhq-api/src/main/java/com/qnfhq/modules/user/enums/SettingEnum.java
  66. 3 0
      qnfhq-api/src/main/java/com/qnfhq/modules/user/service/AppUserDetailService.java
  67. 40 12
      qnfhq-api/src/main/java/com/qnfhq/modules/user/service/AppUserService.java
  68. 3 0
      qnfhq-api/src/main/java/com/qnfhq/modules/user/service/SettingService.java
  69. 5 0
      qnfhq-api/src/main/java/com/qnfhq/modules/user/service/impl/AppUserDetailServiceImpl.java
  70. 79 94
      qnfhq-api/src/main/java/com/qnfhq/modules/user/service/impl/AppUserServiceImpl.java
  71. 2 0
      qnfhq-api/src/main/java/com/qnfhq/modules/user/service/impl/SettingServiceImpl.java
  72. 2 2
      qnfhq-api/src/main/resources/application.yml
  73. 8 3
      qnfhq-api/src/main/resources/i18n/messages.properties
  74. 9 4
      qnfhq-api/src/main/resources/i18n/messages_de.properties
  75. 9 3
      qnfhq-api/src/main/resources/i18n/messages_en.properties
  76. 9 4
      qnfhq-api/src/main/resources/i18n/messages_es.properties
  77. 9 4
      qnfhq-api/src/main/resources/i18n/messages_fr.properties
  78. 8 2
      qnfhq-api/src/main/resources/i18n/messages_ja.properties
  79. 8 3
      qnfhq-api/src/main/resources/i18n/messages_ko.properties
  80. 9 4
      qnfhq-api/src/main/resources/i18n/messages_th.properties
  81. 8 3
      qnfhq-api/src/main/resources/i18n/messages_tw.properties
  82. 9 4
      qnfhq-api/src/main/resources/i18n/messages_vi.properties
  83. 8 3
      qnfhq-api/src/main/resources/i18n/messages_zh.properties
  84. 12 3
      qnfhq-api/src/main/resources/i18n/validation.properties
  85. 12 3
      qnfhq-api/src/main/resources/i18n/validation_de.properties
  86. 12 2
      qnfhq-api/src/main/resources/i18n/validation_en.properties
  87. 12 3
      qnfhq-api/src/main/resources/i18n/validation_es.properties
  88. 12 3
      qnfhq-api/src/main/resources/i18n/validation_fr.properties
  89. 11 2
      qnfhq-api/src/main/resources/i18n/validation_ja.properties
  90. 12 3
      qnfhq-api/src/main/resources/i18n/validation_ko.properties
  91. 10 1
      qnfhq-api/src/main/resources/i18n/validation_th.properties
  92. 11 2
      qnfhq-api/src/main/resources/i18n/validation_tw.properties
  93. 10 1
      qnfhq-api/src/main/resources/i18n/validation_vi.properties
  94. 12 2
      qnfhq-api/src/main/resources/i18n/validation_zh.properties
  95. 2 0
      qnfhq-api/src/main/resources/mapper/c2c/C2cAdDao.xml
  96. 6 0
      qnfhq-api/src/main/resources/mapper/c2c/C2cMerchantDao.xml
  97. 17 0
      qnfhq-api/src/main/resources/mapper/c2c/C2cMsgContactDao.xml
  98. 17 0
      qnfhq-api/src/main/resources/mapper/c2c/C2cMsgContentDao.xml
  99. 15 0
      qnfhq-api/src/main/resources/mapper/c2c/C2cMsgRelationDao.xml
  100. 8 8
      qnfhq-api/src/main/resources/mapper/c2c/C2cOrderDao.xml

+ 14 - 1
qnfhq-api/pom.xml

@@ -15,6 +15,8 @@
         <freemarker.version>2.3.34</freemarker.version>
         <aliyun.sms.version>4.1.1</aliyun.sms.version>
         <redisson.version>3.52.0</redisson.version>
+        <fastjson.version>2.0.60</fastjson.version>
+        <aliyun.captcha.version>1.1.4</aliyun.captcha.version>
     </properties>
 	<dependencies>
 		<dependency>
@@ -75,8 +77,19 @@
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
-            <version>2.0.60</version>
+            <version>${fastjson.version}</version>
         </dependency>
+        <!-- 阿里云 智能验证码 -->
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>captcha20230305</artifactId>
+            <version>${aliyun.captcha.version}</version>
+        </dependency>
+
+        <!--        <dependency>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-websocket</artifactId>
+                </dependency>-->
 	</dependencies>
 
 	<build>

+ 62 - 0
qnfhq-api/src/main/java/com/qnfhq/aliyun/CaptchaConfig.java

@@ -0,0 +1,62 @@
+package com.qnfhq.aliyun;
+
+import com.alibaba.fastjson2.JSON;
+import com.aliyun.captcha20230305.models.VerifyIntelligentCaptchaResponse;
+import com.aliyun.tea.TeaException;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class CaptchaConfig {
+
+    public static com.aliyun.captcha20230305.Client createClient(String accessKeyId, String accessKeySecret, String endpoint) throws Exception {
+
+        com.aliyun.credentials.Client credential = new com.aliyun.credentials.Client();
+        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
+                .setCredential(credential)
+                .setAccessKeyId(accessKeyId)
+                .setAccessKeySecret(accessKeySecret)
+                .setType("access_key");
+
+        config.endpoint = endpoint;
+        return new com.aliyun.captcha20230305.Client(config);
+    }
+
+
+    /**
+     * 智能验证
+     * @param accessKeyId
+     * @param accessKeySecret
+     * @param sceneId
+     * @param verifyParam
+     * @return
+     */
+    public static VerifyIntelligentCaptchaResponse verifyIntelligentCaptcha(String accessKeyId, String accessKeySecret, String sceneId,
+                                                  String endpoint, String verifyParam) {
+        com.aliyun.captcha20230305.Client client = null;
+        try {
+            client = createClient(accessKeyId, accessKeySecret, endpoint);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        com.aliyun.captcha20230305.models.VerifyIntelligentCaptchaRequest verifyIntelligentCaptchaRequest = new com.aliyun.captcha20230305.models.VerifyIntelligentCaptchaRequest()
+                .setCaptchaVerifyParam(verifyParam)
+                .setSceneId(sceneId);
+        try {
+             return client.verifyIntelligentCaptchaWithOptions(verifyIntelligentCaptchaRequest,
+                    new com.aliyun.teautil.models.RuntimeOptions());
+        } catch (TeaException error) {
+            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
+            // 错误 message
+            log.error(error.getMessage(),error);
+            com.aliyun.teautil.Common.assertAsString(error.message);
+        } catch (Exception _error) {
+            TeaException error = new TeaException(_error.getMessage(), _error);
+            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
+            // 错误 message
+            log.error(error.getMessage(), error);
+            com.aliyun.teautil.Common.assertAsString(error.message);
+        }
+        return null;
+    }
+
+}

+ 28 - 0
qnfhq-api/src/main/java/com/qnfhq/common/BigDecimalSerialize.java

@@ -0,0 +1,28 @@
+package com.qnfhq.common;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import lombok.SneakyThrows;
+
+import java.math.BigDecimal;
+
+/**
+ * 一句话描述
+ *
+ * @Author: Yelz 30262728@qq.com
+ * @Date: 2025/11/24 14:21
+ * @Description:
+ */
+public class BigDecimalSerialize extends JsonSerializer<BigDecimal> {
+    @SneakyThrows
+    @Override
+    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializerProvider) {
+        if (value != null) {
+            String plainStr = value.stripTrailingZeros().toPlainString();
+            gen.writeString(plainStr);
+        } else {
+            gen.writeString(BigDecimal.ZERO.toPlainString());
+        }
+    }
+}

+ 29 - 0
qnfhq-api/src/main/java/com/qnfhq/common/BigDecimalSerialize2.java

@@ -0,0 +1,29 @@
+package com.qnfhq.common;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import lombok.SneakyThrows;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+ * 一句话描述
+ *
+ * @Author: Yelz 30262728@qq.com
+ * @Date: 2025/11/24 14:21
+ * @Description:
+ */
+public class BigDecimalSerialize2 extends JsonSerializer<BigDecimal> {
+    @SneakyThrows
+    @Override
+    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializerProvider) {
+        if (value != null) {
+            String plainStr = value.setScale(2, RoundingMode.DOWN).toPlainString();
+            gen.writeString(plainStr);
+        } else {
+            gen.writeString(BigDecimal.ZERO.toPlainString());
+        }
+    }
+}

+ 4 - 4
qnfhq-api/src/main/java/com/qnfhq/config/SaTokenConfigure.java

@@ -28,20 +28,20 @@ public class SaTokenConfigure {
     public SaServletFilter getSaServletFilter() {
         return new SaServletFilter()
 
-                // 指定 拦截路由 与 放行路由 todo 测试过鉴权
+                // 指定 拦截路由 与 放行路由
                 .addInclude("/**")
 //                .addExclude("/**")
                 .addExclude(
                         "/user/register",
                         "/user/login",
-                        "/user/captcha",
-                        "/user/checkCaptcha",
+                        "/user/verifyIntelligentCaptcha",
                         "/user/sendEmailCode",
                         "/user/sendMobileCode",
                         "/user/resetPwdPhone",
                         "/user/resetPwdEmail",
                         "/user/checkPhoneCode",
-                        "/user/checkEmailCode"
+                        "/user/checkEmailCode",
+                        "/swagger-ui.html","/swagger-ui/**","/v3/api-docs/**"
 
                 )
                 // 认证函数: 每次请求执行

+ 1 - 1
qnfhq-api/src/main/java/com/qnfhq/config/SwaggerConfig.java

@@ -22,7 +22,7 @@ public class SwaggerConfig {
 
     private Info apiInfo() {
         return new Info()
-                .title("区块链改造")
+                .title("交易所改造")
                 .description("接口文档")
                 .version("v1.0.0");
     }

+ 16 - 38
qnfhq-api/src/main/java/com/qnfhq/constant/CacheConstants.java

@@ -104,19 +104,9 @@ public class CacheConstants
         return new StringBuilder("c2c_ad_h").append(adId).toString();
     }
 
-//    /**
-//     * 用户待支付数
-//     */
-//    public static final String C2C_UNPAY_COUNTS ="c2c-unpay-counts:{}";
-//
-//    /**
-//     * 用户待放币订单数
-//     */
-//    public static final String C2C_RELEASE_COUNTS ="c2c-release-counts:{}";
-//
-//    /**
-//     * 商家待支付数统计
-//     */
+    /**
+     * 商家待支付数统计
+     */
     public static String getC2cMertUnPayKey(String mertUid) {
         return new StringBuilder("c2c-mtunpay-counts:").append(mertUid).toString();
     }
@@ -129,31 +119,19 @@ public class CacheConstants
         return new StringBuilder("c2c-mtrelease-counts:").append(mertUid).toString();
     }
 
+    /**
+     * 聊天未读数key
+     */
+    public static String getChatUnreadKey(Long uid) {
+        return new StringBuilder("c2c-c-unread:").append(uid.toString()).toString();
+    }
+
+    /**
+     * 用户总未读数key
+     */
+    public static String getTotalUnreadKey(Long uid) {
+        return new StringBuilder("c2c-t-unread:").append(uid.toString()).toString();
+    }
 
 
-//    public static final BigDecimal AD_AVAIL_NUM_TOINT = new BigDecimal(100000000);
-//
-//    /**
-//     * 客服按会话数排序
-//     */
-//    public static final String KEFU_ZSET_KEY = "kefu_uids";
-//
-//    /**
-//     * 客服对应的会话
-//     */
-//    public static final String KEFU_SESSION_KEY = "session_";
-//
-//    /**
-//     * 客服信息
-//     */
-//    public static final String KEFU_INFO_KEY = "kefu_info_";
-//
-//    /**
-//     * 排队等待的用户
-//     */
-//    public static final String ONLINE_CUST_UID = "kefu_wait_uid";
-//    /**
-//     * 聊天的用户id
-//     */
-//    public static final String KEFU_UID_KEY = "im_uid_";
 }

+ 62 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/business/controller/TMingOrderController.java

@@ -0,0 +1,62 @@
+package com.qnfhq.modules.business.controller;
+
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.qnfhq.common.ApiBaseController;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.common.utils.StringUtils;
+import com.qnfhq.common.utils.cache.RedisCache;
+import com.qnfhq.modules.business.entity.TMingOrder;
+import com.qnfhq.modules.business.service.ITMingOrderService;
+import com.qnfhq.modules.user.service.SettingService;
+import jakarta.annotation.Resource;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import org.springframework.web.bind.annotation.*;
+
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * 挖矿Controller
+ * 
+ * @author ruoyi
+ * @date 2023-07-17
+ */
+@RestController
+@RequestMapping("/api/mingOrder")
+public class TMingOrderController extends ApiBaseController
+{
+    @Autowired
+     private SettingService settingService;
+    @Autowired
+    private ITMingOrderService itMingOrderService;
+    @Resource
+    private RedisCache redisCache;
+
+
+
+    @PostMapping("/submit")
+     public Result submit(@RequestBody  TMingOrder mingOrder) {
+        Result result = new Result();
+        String keyCache = StringUtils.format("api-currency-submit:{}", StpUtil.getLoginIdAsLong());
+        if(StringUtils.isNotNull(redisCache.getCacheObject(keyCache))) {
+            return error("请勿重复操作");
+        }
+        redisCache.setCacheObject(keyCache, "1", 30, TimeUnit.SECONDS);
+
+        String msg = itMingOrderService.bugMingOrder(mingOrder.getPlanId(),mingOrder.getAmount(),getStpUserId());
+        if(!"success".equals(msg)){
+            redisCache.deleteObject(keyCache);
+
+            return result.error(msg);
+        }
+        redisCache.deleteObject(keyCache);
+        return  null;
+    }
+
+
+
+
+
+}

+ 17 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/business/dao/TMingOrderMapper.java

@@ -0,0 +1,17 @@
+package com.qnfhq.modules.business.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qnfhq.modules.business.entity.TMingOrder;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * mingMapper接口
+ * 
+ * @author table
+ * @date 2023-08-18
+ */
+@Mapper
+public interface TMingOrderMapper extends BaseMapper<TMingOrder>
+{
+
+}

+ 17 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/business/dao/TMingProductMapper.java

@@ -0,0 +1,17 @@
+package com.qnfhq.modules.business.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qnfhq.modules.business.entity.MingProduct;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * mingProductMapper接口
+ * 
+ * @author table
+ * @date 2023-08-18
+ */
+@Mapper
+public interface TMingProductMapper extends BaseMapper<MingProduct>
+{
+
+}

+ 9 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/business/dao/TMingProductUserMapper.java

@@ -0,0 +1,9 @@
+package com.qnfhq.modules.business.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qnfhq.modules.business.entity.MingProductUser;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface TMingProductUserMapper extends BaseMapper<MingProductUser> {
+}

+ 16 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/business/entity/AddMosaicSetting.java

@@ -0,0 +1,16 @@
+package com.qnfhq.modules.business.entity;
+
+import lombok.Data;
+
+/**
+ * 底部菜单
+ */
+@Data
+public class AddMosaicSetting {
+    private Boolean isOpen; //总开关
+    private Boolean sencordIsOpen; //秒合约开关
+    private Boolean currencyIsOpen; //币币开关
+    private Boolean contractIsOpen; //u本位开关
+    private Boolean financialIsOpen; //理财开关
+    private Boolean pledgeIsOpen; //质押开关
+}

+ 128 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/business/entity/MingProduct.java

@@ -0,0 +1,128 @@
+package com.qnfhq.modules.business.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * mingProduct对象 t_ming_product
+ *
+ * @author table
+ * @date 2023-08-18
+ */
+@Data
+@TableName("t_ming_product")
+public class MingProduct {
+
+private static final long serialVersionUID=1L;
+
+    /**
+     * $column.columnComment
+     */
+        @TableId(value = "id",type = IdType.AUTO)
+    private Long id;
+    /**
+     * 标题
+     */
+    private String title;
+    /**
+     * 图标
+     */
+    private String icon;
+    /**
+     * 启用禁用(展示在前端)1开0关
+     */
+    private Long status;
+    /**
+     * 天数(如 7,10,30)
+     */
+    private String days;
+
+    /**
+     * 结算时间
+     */
+    private String settleDay;
+
+    /**
+     * 违约利率
+     */
+    private BigDecimal defaultOdds;
+    /**
+     * 最小日利率百分比
+     */
+    private BigDecimal minOdds;
+    /**
+     * 最大日利率百分比
+     */
+    private BigDecimal maxOdds;
+    /**
+     * 每人限购次数,0表示不限
+     */
+    private Long timeLimit;
+    /**
+     * 最小金额
+     */
+    private BigDecimal limitMin;
+    /**
+     * 最大金额
+     */
+    private BigDecimal limitMax;
+    /**
+     * 排序
+     */
+    private Long sort;
+    /**
+     *  购买次数
+     */
+    private Long buyPurchase;
+    /**
+     * 币种 
+     */
+    private String coin;
+
+    /**
+     * 汇率
+     */
+    @TableField(exist = false)
+    private BigDecimal rate;
+
+    @CreatedBy
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
+
+    @CreatedDate
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+    @LastModifiedBy
+    @TableField(fill = FieldFill.UPDATE)
+    private String updateBy;
+
+    @LastModifiedDate
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Date updateTime;
+    /** 备注 */
+    private String remark;
+
+    /**
+     * 用户的项目进度
+     * @throws
+     * @author master
+     * @date 2025/6/26
+     */
+    @TableField(exist = false)
+    private String userProcess;
+
+}

+ 59 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/business/entity/MingProductUser.java

@@ -0,0 +1,59 @@
+package com.qnfhq.modules.business.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.qnfhq.common.entity.BaseEntity;
+import com.qnfhq.modules.user.entity.AppAssetEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 用户购买质押限制对象 t_ming_product_user
+ *
+ * @author table
+ * @date 2023-10-11
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("t_ming_product_user")
+public class MingProductUser extends BaseEntity {
+
+private static final long serialVersionUID=1L;
+
+    /**
+     * $column.columnComment
+     */
+        @TableId(value = "id",type = IdType.AUTO)
+    private Long id;
+    /**
+     * 产品id
+     */
+    private Long productId;
+    /**
+     * 玩家用户id
+     */
+    private Long appUserId;
+    /**
+     * 限购次数
+     */
+    private Long pledgeNum;
+    /**
+     *
+     */
+    private String searchValue;
+
+    @TableField(exist = false)
+    private AppAssetEntity tAppUser;
+
+    @TableField(exist = false)
+    private String coin;
+
+    @TableField(exist = false)
+    private String icon;
+
+    @TableField(exist = false)
+    private String title;
+
+}

+ 126 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/business/entity/TMingOrder.java

@@ -0,0 +1,126 @@
+package com.qnfhq.modules.business.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Data;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * ming对象 t_ming_order
+ *
+ * @author table
+ * @date 2023-08-18
+ */
+@Data
+@TableName("t_ming_order")
+public class TMingOrder {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * $column.columnComment
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+    /**
+     * 投资金额(分)
+     */
+    private BigDecimal amount;
+    /**
+     * 投资期限(天)
+     */
+    private Integer days;
+    /**
+     * 0 收益  1 结算 3 赎回
+     */
+    private Integer status;
+    /**
+     * 项目id
+     */
+    private Long planId;
+    /**
+     * 项目名称
+     */
+    private String planTitle;
+    /**
+     * 订单编号
+     */
+    private String orderNo;
+    /**
+     * 到期时间
+     */
+    private Date endTime;
+    /**
+     * 结算时间
+     */
+    private Date settleTime;
+    /**
+     * 累计收益
+     */
+    private BigDecimal accumulaEarn;
+    /**
+     * 最小利率
+     */
+    private BigDecimal minOdds;
+    /**
+     * 最大利率
+     */
+    private BigDecimal maxOdds;
+    /**
+     * 后台用户id
+     */
+    private String adminUserIds;
+    /**
+     * $column.columnComment
+     */
+    private String collectionOrder;
+    /**
+     * $column.columnComment
+     */
+    private Long userId;
+    /**
+     * $column.columnComment
+     */
+    private BigDecimal orderAmount;
+
+
+    private String coin;
+
+
+    @TableField(exist = false)
+    private Integer settlementType;
+    /**
+     * 结算日期 1-31
+     */
+    @TableField(exist = false)
+    private Integer settlementDay;
+
+
+    @CreatedDate
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+
+    @LastModifiedDate
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Date updateTime;
+
+
+    @TableField(exist = false)
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    private Map<String, Object> params;
+
+    @TableField(exist = false)
+    private String logo;
+}

+ 26 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/business/service/ITMingOrderService.java

@@ -0,0 +1,26 @@
+package com.qnfhq.modules.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qnfhq.modules.business.entity.TMingOrder;
+
+
+import java.math.BigDecimal;
+
+/**
+ * mingService接口
+ * 
+ * @author table
+ * @date 2023-08-18
+ */
+public interface ITMingOrderService extends IService<TMingOrder>
+{
+    /**
+     * 购买挖矿
+     * @param planId
+     * @param amount
+     * @param userId
+     * @return
+     */
+    String bugMingOrder(Long planId, BigDecimal amount,Long userId);
+
+}

+ 18 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/business/service/ITMingProductService.java

@@ -0,0 +1,18 @@
+package com.qnfhq.modules.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qnfhq.modules.business.entity.MingProduct;
+
+import java.util.List;
+
+/**
+ * mingProductService接口
+ * 
+ * @author table
+ * @date 2023-08-18
+ */
+public interface ITMingProductService extends IService<MingProduct>
+{
+
+    MingProduct selectTMingProductById(Long planId);
+}

+ 200 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/business/service/impl/TMingOrderServiceImpl.java

@@ -0,0 +1,200 @@
+package com.qnfhq.modules.business.service.impl;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.json.JSONUtil;
+import cn.hutool.setting.Setting;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qnfhq.common.utils.DateUtil;
+import com.qnfhq.common.utils.MessageUtils;
+import com.qnfhq.modules.business.dao.TMingProductUserMapper;
+import com.qnfhq.modules.business.entity.AddMosaicSetting;
+import com.qnfhq.modules.business.entity.MingProduct;
+import com.qnfhq.modules.business.entity.MingProductUser;
+import com.qnfhq.modules.business.entity.TMingOrder;
+import com.qnfhq.modules.business.dao.TMingOrderMapper;
+import com.qnfhq.modules.business.service.ITMingOrderService;
+import com.qnfhq.modules.business.service.ITMingProductService;
+import com.qnfhq.modules.user.dao.AppAssetDao;
+import com.qnfhq.modules.user.entity.AppAssetEntity;
+import com.qnfhq.modules.user.entity.AppUserDetailEntity;
+import com.qnfhq.modules.user.entity.AppUserEntity;
+import com.qnfhq.modules.user.entity.SettingEntity;
+import com.qnfhq.modules.user.enums.AssetEnum;
+import com.qnfhq.modules.user.enums.RecordEnum;
+import com.qnfhq.modules.user.enums.SettingEnum;
+import com.qnfhq.modules.user.service.AppUserDetailService;
+import com.qnfhq.modules.user.service.AppUserService;
+import com.qnfhq.modules.user.service.AppWalletRecordService;
+import com.qnfhq.modules.user.service.SettingService;
+import com.qnfhq.utils.OrderUtils;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * mingService业务层处理
+ *
+ * @author table
+ * @date 2023-08-18
+ */
+@Service
+public class TMingOrderServiceImpl extends ServiceImpl<TMingOrderMapper, TMingOrder> implements ITMingOrderService {
+    @Resource
+    private TMingOrderMapper tMingOrderMapper;
+
+    @Resource
+    private AppWalletRecordService appWalletRecordService;
+
+    @Resource
+    private AppUserService appUserService;
+
+    @Resource
+    private AppUserDetailService appUserDetailService;
+
+
+    @Resource
+    private ITMingProductService mingProductService;
+
+    @Resource
+    private AppAssetDao appAssetDao;
+
+    @Resource
+    private TMingProductUserMapper tMingProductUserMapper;
+
+    @Resource
+    private SettingService settingService;
+
+
+    @Override
+    public String bugMingOrder(Long planId, BigDecimal amount, Long userId) {
+        //获取用户信息
+        AppUserEntity user = appUserService.getUserByUserId(userId);
+        //获取用户详情
+        AppUserDetailEntity tAppUserDetail = appUserDetailService.selectUserDetailByUserId(userId);
+        Integer tradeFlag = tAppUserDetail.getTradeFlag();
+        if (null != tradeFlag) {
+            if (1 == tradeFlag) {
+                if (tAppUserDetail.getTradeMessage() == null || tAppUserDetail.getTradeMessage().equals("")) {
+                    return MessageUtils.message("user.push.message");
+                } else {
+                    return tAppUserDetail.getTradeMessage();
+                }
+            }
+        }
+
+        //获取产品信息
+        MingProduct tMingProduct = mingProductService.selectTMingProductById(planId);
+        if(tMingProduct == null) {
+            return MessageUtils.message("product.not.exist");
+        }
+
+        // 单个用户单笔下注最小金额 和最大金额
+        if (null != tMingProduct.getLimitMin()) {
+            if (amount.compareTo(tMingProduct.getLimitMin()) < 0) {
+                return MessageUtils.message("order.single.min");
+            }
+        }
+        if (null != tMingProduct.getLimitMax()) {
+            if (tMingProduct.getLimitMax().compareTo(amount) < 0) {
+                return MessageUtils.message("order.single.max");
+            }
+        }
+
+        ////判断有没有个人购买限制
+        MingProductUser tMingProductUser = tMingProductUserMapper
+                .selectOne(new LambdaQueryWrapper<MingProductUser>()
+                        .eq(MingProductUser::getProductId, planId)
+                        .eq(MingProductUser::getAppUserId, userId));
+        if (Objects.nonNull(tMingProductUser) && Objects.nonNull(tMingProductUser.getPledgeNum()))
+            tMingProduct.setTimeLimit(tMingProductUser.getPledgeNum());
+        //判断金额是否足够
+        AppAssetEntity tAppAsset = appAssetDao
+                .selectOne(new LambdaQueryWrapper<AppAssetEntity>()
+                        .eq(AppAssetEntity::getType, AssetEnum.PLATFORM_ASSETS.getCode())
+                        .eq(AppAssetEntity::getUserId, userId).eq(AppAssetEntity::getSymbol, tMingProduct.getCoin()));
+
+        // 2. 金额判断
+        if (Objects.isNull(tAppAsset)) {
+            return MessageUtils.message("order_amount_error");
+        }
+
+        if (tAppAsset.getTotal().compareTo(amount) < 0) {
+            return MessageUtils.message("order_amount_error");
+        }
+        // 3. 订单数量判断
+        long count = this.count(new LambdaQueryWrapper<TMingOrder>().eq(TMingOrder::getPlanId, tMingProduct.getId()).eq(TMingOrder::getUserId, userId));
+        if (count >= tMingProduct.getTimeLimit()) {
+            return MessageUtils.message("financial.count.max");
+        }
+        String days = tMingProduct.getDays();
+        TMingOrder mineOrder = new TMingOrder();
+        mineOrder.setUserId(userId);
+        mineOrder.setPlanId(planId);
+        Date now = new DateTime();
+        // 下单
+        String serialId = "E" + OrderUtils.generateOrderNum();
+        //  Date endTime = DateUtil.dateFormatDay(now, Integer.valueOf(days));
+        Date settleTime = DateUtil.dateFormatDay(now, Integer.valueOf(tMingProduct.getSettleDay()));
+
+        //当日利率从接口获取,现在取最小利率
+        mineOrder.setOrderNo(serialId);
+        mineOrder.setPlanId(tMingProduct.getId());
+        mineOrder.setCreateTime(new Date());
+        mineOrder.setDays(Integer.valueOf(days));
+        mineOrder.setSettleTime(settleTime);
+        //币种
+        mineOrder.setCoin(tMingProduct.getCoin());
+        mineOrder.setAmount(amount);
+        mineOrder.setAccumulaEarn(BigDecimal.ZERO);
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        Date endTime = null;
+        try {
+            endTime = sdf.parse("2026-02-17");
+        } catch (Exception e) {
+//            throw new RuntimeException(e);
+        }
+        mineOrder.setEndTime(endTime);
+        mineOrder.setPlanTitle(tMingProduct.getTitle());
+        mineOrder.setMinOdds(tMingProduct.getMinOdds());
+        mineOrder.setMaxOdds(tMingProduct.getMaxOdds());
+        mineOrder.setAdminUserIds(user.getAdminParentIds());
+        mineOrder.setUserId(user.getId());
+        mineOrder.setStatus(0);
+
+        //  先扣钱,再下单
+        Map<String, Object> map = new HashMap<>();
+        map.put("userId", userId);
+        map.put("symbol", tMingProduct.getCoin());
+        map.put("money", amount);
+        map.put("type", AssetEnum.PLATFORM_ASSETS.getCode());
+        appAssetDao.releaseAssetByUserId(map);
+        BigDecimal bigDecimal = tAppAsset.getAvailable();
+
+
+        appWalletRecordService.generateRecord(user.getId(),
+                amount,
+                RecordEnum.PLEDGE_RECHARGE.getCode(),
+                user.getLoginName(),
+                serialId,
+                "质押认购", bigDecimal, bigDecimal.subtract(amount), tMingProduct.getCoin().toLowerCase(), user.getAdminParentIds());
+        tMingOrderMapper.insert(mineOrder);
+        //质押打码
+       /* SettingEntity setting = settingService.getSetting(SettingEnum.ADD_MOSAIC_SETTING.name());
+        if (Objects.nonNull(setting)){
+            AddMosaicSetting addMosaic = JSONUtil.toBean(setting.getSettingValue(), AddMosaicSetting.class);
+            if (Objects.nonNull(addMosaic) && Objects.nonNull(addMosaic.getIsOpen()) && addMosaic.getIsOpen() && Objects.nonNull(addMosaic.getPledgeIsOpen()) && addMosaic.getPledgeIsOpen()){
+                user.setTotleAmont(user.getTotleAmont().add(mineOrder.getAmount()));
+                appUserService.updateTotleAmont(user);
+            }
+        }*/
+        return "success";
+    }
+}
+

+ 27 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/business/service/impl/TMingProductServiceImpl.java

@@ -0,0 +1,27 @@
+package com.qnfhq.modules.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qnfhq.modules.business.entity.MingProduct;
+import com.qnfhq.modules.business.dao.TMingProductMapper;
+import com.qnfhq.modules.business.service.ITMingProductService;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+
+/**
+ * mingProductService业务层处理
+ * 
+ * @author table
+ * @date 2023-08-18
+ */
+@Service
+public class TMingProductServiceImpl extends ServiceImpl<TMingProductMapper, MingProduct> implements ITMingProductService
+{
+    @Resource
+    private TMingProductMapper tMingProductMapper;
+
+
+    @Override
+    public MingProduct selectTMingProductById(Long planId) {
+        return tMingProductMapper.selectById(planId);
+    }
+}

+ 11 - 11
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/C2cAdController.java

@@ -149,7 +149,7 @@ public class C2cAdController extends ApiBaseController {
         }
 
         Long adId = c2cAd.getId();
-        C2cAdEntity ad = c2cAdService.getById(adId);
+        C2cAdEntity ad = c2cAdService.selectById(adId);
         if(ad==null) {
             return error(MessageUtils.message("c2c.ad.id.invalid"));//广告编号无效
         }
@@ -179,17 +179,17 @@ public class C2cAdController extends ApiBaseController {
         if(c2cAdVo.getMerchantId()==null) {
             return error(MessageUtils.message("c2c.ad.merchant.id.blank"));//商家编号不能空
         }
-        Page<C2cAdEntity> page = c2cAdService.page(c2cAdVo.getPage(),c2cAdVo.timeQuery());
+//        Page<C2cAdEntity> page = c2cAdService.page(c2cAdVo.getPage(),c2cAdVo.timeQuery());
 //        //分页
-//        String pageNum = Convert.toStr(c2cAdVo.getPageNum(),"1");
-//        String pageSize = Convert.toStr(c2cAdVo.getPageSize(),"10");
-//        Map<String,Object> params = new HashMap<>();
-//        params.put(Constant.PAGE,pageNum);
-//        params.put(Constant.LIMIT,pageSize);
-//        params.put("merchantId",c2cAdVo.getMerchantId());
-//        params.put("direction",c2cAdVo.getDirection());
-//        params.put("status", AdStatusEnum.PASS.getCode());
-//        PageData<C2cAdEntity> page = c2cAdService.page(params);
+        String pageNum = Convert.toStr(c2cAdVo.getPageNum(),"1");
+        String pageSize = Convert.toStr(c2cAdVo.getPageSize(),"10");
+        Map<String,Object> params = new HashMap<>();
+        params.put(Constant.PAGE,pageNum);
+        params.put(Constant.LIMIT,pageSize);
+        params.put("merchantId",c2cAdVo.getMerchantId());
+        params.put("direction",c2cAdVo.getDirection());
+        params.put("status", AdStatusEnum.PASS.getCode());
+        PageData<C2cAdEntity> page = c2cAdService.page(params);
         return new Result<>().ok(page);
     }
 

+ 137 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/C2cMsgContentController.java

@@ -0,0 +1,137 @@
+package com.qnfhq.modules.c2c.controller;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.map.MapUtil;
+import com.qnfhq.annotation.RepeatSubmit;
+import com.qnfhq.common.ApiBaseController;
+import com.qnfhq.common.constant.Constant;
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.redis.RedisUtils;
+import com.qnfhq.common.utils.MessageUtils;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.common.validator.ValidatorUtils;
+import com.qnfhq.constant.CacheConstants;
+import com.qnfhq.modules.c2c.dto.C2cMsgContactDTO;
+import com.qnfhq.modules.c2c.dto.C2cMsgContentDTO;
+import com.qnfhq.modules.c2c.dto.C2cMsgRelationDTO;
+import com.qnfhq.modules.c2c.entity.C2cMsgContactEntity;
+import com.qnfhq.modules.c2c.entity.C2cMsgRelationEntity;
+import com.qnfhq.modules.c2c.enums.MsgTypeEnum;
+import com.qnfhq.modules.c2c.service.C2cMsgContactService;
+import com.qnfhq.modules.c2c.service.C2cMsgContentService;
+import com.qnfhq.modules.c2c.service.C2cMsgRelationService;
+import com.qnfhq.modules.user.entity.AppUserEntity;
+import com.qnfhq.modules.user.service.AppUserService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import java.util.*;
+
+
+/**
+ * 聊天消息表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@RestController
+@RequestMapping("/c2cmsg")
+@Tag(name="c2c聊天接口")
+@Slf4j
+public class C2cMsgContentController extends ApiBaseController {
+    @Resource
+    private C2cMsgContentService c2cMsgContentService;
+
+    @Resource
+    private C2cMsgRelationService c2cMsgRelationService;
+
+    @Resource
+    private C2cMsgContactService c2cMsgContactService;
+    @Resource
+    private AppUserService appUserService;
+    @Resource
+    private RedisUtils redisUtils;
+
+    @PostMapping("/send")
+    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
+    @Operation(summary = "发消息")
+    public Result send(@RequestBody C2cMsgContentDTO dto){
+        //效验数据
+        ValidatorUtils.validateEntity(dto);
+
+        Long receptId = dto.getRecipientId();
+        AppUserEntity receptUser = appUserService.getById(receptId);
+        if(Objects.isNull(receptUser)) {
+            return new Result().error(MessageUtils.message("c2c.msg.receptId.notexists"));//"接收人不存在"
+        }
+
+        if(!MsgTypeEnum.isValid(dto.getMsgType())) {
+            return new Result().error(MessageUtils.message("c2c.msg.msgType.err"));//"消息类型错误"
+        }
+
+        if(receptId.longValue() == StpUtil.getLoginIdAsLong()) {
+            return new Result().error(MessageUtils.message("c2c.msg.receptId.err"));//不能给自己发消息
+        }
+
+        try {
+            return c2cMsgContentService.saveMsg(dto);
+        } catch (Exception e) {
+            log.error("c2cMsgContentService.saveMsg============"+e.getMessage(),e);
+            return new Result().error(MessageUtils.message("operation.fail.please.refresh"));//操作失败,请刷新后重试
+        }
+    }
+
+
+    @PostMapping("/chatList")
+    @Operation(summary = "查询与某人的聊天记录")
+    public Result<PageData<C2cMsgRelationEntity>> chatList(@RequestBody C2cMsgRelationDTO dto){
+        ValidatorUtils.validateEntity(dto);
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put(Constant.PAGE, dto.getPageNum());
+        params.put(Constant.LIMIT, dto.getPageSize());
+        params.put(Constant.ORDER_FIELD, "mid");
+        params.put(Constant.ORDER, "desc");
+        params.put("ownerUid", StpUtil.getLoginIdAsLong());
+        params.put("otherUid", dto.getOtherUid());
+        params.put("mid", dto.getMid());
+        PageData<C2cMsgRelationEntity> page = c2cMsgRelationService.selectChatPage(params);
+        page.getList().forEach(item -> item.setC2cMsg(c2cMsgContentService.getById(item.getMid())));
+
+        //聊天未读数更新
+        Long unreadC = Convert.toLong(redisUtils.hGet(CacheConstants.getChatUnreadKey(StpUtil.getLoginIdAsLong()), dto.getOtherUid().toString()),0L);
+        if(unreadC!=null && unreadC.longValue()>0) {
+            redisUtils.increment(CacheConstants.getChatUnreadKey(StpUtil.getLoginIdAsLong()), dto.getOtherUid().toString(), -unreadC.longValue(), -1L);
+            //总未读数更新
+            redisUtils.decrement(CacheConstants.getTotalUnreadKey(StpUtil.getLoginIdAsLong()), unreadC.longValue(), -1L);
+        }
+
+        return new Result<PageData<C2cMsgRelationEntity>>().ok(page);
+    }
+
+
+    @PostMapping("/contactList")
+    @Operation(summary = "查询我的最近联系人列表")
+    public Result<PageData<C2cMsgContactEntity>> contactList(@RequestBody C2cMsgContactDTO dto){
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put(Constant.PAGE, dto.getPageNum());
+        params.put(Constant.LIMIT, dto.getPageSize());
+        params.put(Constant.ORDER_FIELD, "mid");
+        params.put(Constant.ORDER, "desc");
+        params.put("ownerUid", StpUtil.getLoginIdAsLong());
+        PageData<C2cMsgContactEntity> page = c2cMsgContactService.selectContactPage(params);
+        page.getList().forEach(item -> {
+            item.setC2cMsg(c2cMsgContentService.getById(item.getMid()));
+            item.setUnreads(Convert.toLong(redisUtils.hGet(CacheConstants.getChatUnreadKey(item.getOwnerUid()), item.getOtherUid().toString()),0L));
+        });
+        //总未读数
+        Map data = MapUtil.of("totalUnread", Convert.toLong(redisUtils.get(CacheConstants.getTotalUnreadKey(StpUtil.getLoginIdAsLong())),0L));
+        data.put("page",page);
+        return new Result().ok(data);
+    }
+
+
+
+}

+ 97 - 51
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/C2cOrderController.java

@@ -5,14 +5,13 @@ import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
-import com.alibaba.fastjson.JSON;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qnfhq.annotation.RepeatSubmit;
 import com.qnfhq.common.ApiBaseController;
 import com.qnfhq.common.constant.Constant;
 import com.qnfhq.common.exception.ErrorCode;
 import com.qnfhq.common.page.PageData;
 import com.qnfhq.common.redis.RedisUtils;
+import com.qnfhq.common.utils.DateUtils;
 import com.qnfhq.common.utils.MessageUtils;
 import com.qnfhq.common.utils.Result;
 import com.qnfhq.common.validator.ValidatorUtils;
@@ -36,7 +35,6 @@ import com.qnfhq.utils.DistributedRedisLock;
 import io.swagger.v3.oas.annotations.Operation;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -86,8 +84,11 @@ public class C2cOrderController extends ApiBaseController {
 
     @Resource
     private C2cOrderComplainVoucherService orderComplainVoucherService;
-    @Autowired
+    @Resource
     private AppUserService appUserService;
+    @Resource
+    private C2cMerchantService c2cMerchantService;
+
 
     private String getC2cAdLockKey(String adId) {
         return new StringBuilder(LOCK_C2C_AD).append(adId).toString();
@@ -104,10 +105,10 @@ public class C2cOrderController extends ApiBaseController {
         Result result = new Result();
         ValidatorUtils.validateEntity(c2cOrder);
 
+        //进行中的订单
         String odUserKey = c2cOrderService.getC2cOrderKeyByUid(StpUtil.getLoginIdAsString());//c2c_order_uid:1
         String orderId = (String)redisUtils.get(odUserKey);
         if(StrUtil.isNotBlank(orderId)) {
-            //判断订单状态
             C2cOrderEntity order = c2cOrderService.selectOrder(Long.valueOf(orderId));
             if(order == null) {//订单编号无效
                 c2cOrderService.deleteOrderCache(orderId, StpUtil.getLoginIdAsString());
@@ -133,6 +134,7 @@ public class C2cOrderController extends ApiBaseController {
             return result.error(ErrorCode.SHIMING_VERIFY,MessageUtils.message("user.authentication.not.certified"));//请先进行实名认证
         }
 
+
         //卖出检查资产
         if(direction.intValue() == DirectionEnum.SELL.getCode().intValue()) {
             AppAssetEntity tAppAsset = new AppAssetEntity();
@@ -141,7 +143,7 @@ public class C2cOrderController extends ApiBaseController {
             tAppAsset.setType(AssetEnum.PLATFORM_ASSETS.getCode());
             List<AppAssetEntity> assetList = appAssetService.selectList(tAppAsset);
             if(assetList==null || assetList.size()==0) {
-                AppUserEntity user = appUserService.getUserByUserId(loginUserId);
+                AppUserEntity user = appUserService.getById(loginUserId);
                 appUserService.initAppUserAsset(user);
                 return error(MessageUtils.message("c2c.order.availableAmount.buzu"));//您的可用资产不足
             }
@@ -151,7 +153,8 @@ public class C2cOrderController extends ApiBaseController {
             }
         }
 
-        C2cAdEntity c2cAd = c2cAdService.getById(c2cOrder.getC2cAdId());
+        C2cAdEntity c2cAd = c2cAdService.selectById(c2cOrder.getC2cAdId());
+
         if(c2cAd==null) {
             //清除缓存
             Integer adDirection = direction.intValue() == DirectionEnum.SELL.getCode().intValue() ? DirectionEnum.BUY.getCode() : DirectionEnum.SELL.getCode();
@@ -173,15 +176,45 @@ public class C2cOrderController extends ApiBaseController {
         BigDecimal maxAmount = c2cAd.getMaxAmount();
         BigDecimal price = c2cAd.getPrice();
 
+        //数币金额
+        String unit = c2cOrder.getUnit().toLowerCase();
+        String symbol = c2cOrder.getSymbol().toLowerCase();
+        BigDecimal symbolAmount = BigDecimal.ZERO;
+        BigDecimal legalCoinAmount = BigDecimal.ZERO;
+        if(unit.equals(symbol)) {
+            symbolAmount = c2cOrder.getTranAmount();
+            legalCoinAmount = symbolAmount.multiply(price).setScale(2, RoundingMode.DOWN);
+        } else {
+            symbolAmount = c2cOrder.getTranAmount().divide(price).setScale(8, RoundingMode.DOWN);
+            legalCoinAmount = c2cOrder.getTranAmount().setScale(2, RoundingMode.DOWN);
+        }
+        //卖出检查资产
+        if(direction.intValue() == DirectionEnum.SELL.getCode().intValue()) {
+            AppAssetEntity tAppAsset = new AppAssetEntity();
+            tAppAsset.setUserId(loginUserId);
+            tAppAsset.setSymbol(c2cOrder.getSymbol());
+            tAppAsset.setType(AssetEnum.PLATFORM_ASSETS.getCode());
+            List<AppAssetEntity> assetList = appAssetService.selectList(tAppAsset);
+            if(assetList==null || assetList.size()==0) {
+                AppUserEntity user = appUserService.getById(loginUserId);
+                appUserService.initAppUserAsset(user);
+                return error(MessageUtils.message("c2c.order.availableAmount.buzu"));//您的可用资产不足
+            }
+            AppAssetEntity sellerAsset = assetList.get(0);
+            if (sellerAsset.getAvailable().compareTo(symbolAmount) == -1) {
+                return error(MessageUtils.message("c2c.order.availableAmount.insufficient"));//您的可用资产必须大于卖出数量
+            }
+        }
+
         BigDecimal adMinBuyNum = minAmount.divide(price,2,BigDecimal.ROUND_DOWN);
         if(availableNum.compareTo(adMinBuyNum)==-1) {
             c2cAdService.updateC2cAdDisabled(c2cAd);
             return error(MessageUtils.message("c2c.order.param.adid.invalid"));//广告已不可用
         }
 
-        if(c2cAdService.selectAdFromRedis(c2cOrder.getC2cAdId())==null) {
-            c2cAdService.setAdCache(c2cAd);
-        }
+//        if(c2cAdService.selectAdFromRedis(c2cOrder.getC2cAdId())==null) {
+//            c2cAdService.setAdCache(c2cAd);
+//        }
         //买入对应广告卖出
         if(direction.intValue() == c2cAd.getDirection().intValue()) {
             return error(MessageUtils.message("c2c.order.direction.invalid"));//参数direction值不正确
@@ -190,34 +223,21 @@ public class C2cOrderController extends ApiBaseController {
             return error(MessageUtils.message("c2c.order.buyer.seller.must.different"));//买家和卖家不能是同一个用户
         }
 
-        //交易币的数量 保留8位
-        String tranBy = c2cOrder.getTranBy();
-        BigDecimal tranAmount = c2cOrder.getTranAmount();
-        BigDecimal symbolNum = BigDecimal.ZERO;
-        if("amt".equals(tranBy)) {//按金额
-            symbolNum = tranAmount.divide(price,8, RoundingMode.DOWN);
-            tranAmount = tranAmount.setScale(2, RoundingMode.DOWN);
-        } else {//按数量
-            //用户卖出
-            symbolNum = tranAmount.setScale(8, RoundingMode.DOWN);
-            tranAmount = symbolNum.multiply(price).setScale(2, RoundingMode.DOWN);
-        }
-
-        if (tranAmount.compareTo(minAmount) == -1) {
-            return error(MessageUtils.message("c2c.order.param.tranAmt.min"));//金额必须大于最小限额
+        if (legalCoinAmount.compareTo(minAmount) == -1) {
+            return error(MessageUtils.message("c2c.order.param.tranAmt.min"));//金额必须大于广告最小限额
         }
-        if (tranAmount.compareTo(maxAmount) == 1) {
-            return error(MessageUtils.message("c2c.order.param.tranAmt.max"));//金额必须小于最大限额
+        if (legalCoinAmount.compareTo(maxAmount) == 1) {
+            return error(MessageUtils.message("c2c.order.param.tranAmt.max"));//金额必须小于广告最大限额
         }
-        if(symbolNum.compareTo(availableNum)==1) {
-            return error(MessageUtils.message("c2c.order.param.tranAmt.max"));//交易金额超过最大限额
+        if(symbolAmount.compareTo(availableNum)==1) {
+            return error(MessageUtils.message("c2c.order.param.tranAmt.over.avail"));//交易金额超过广告可用数量
         }
 
         //获取锁对象
         String lockKey = getC2cAdLockKey(c2cOrder.getC2cAdId().toString());
         if (distributedRedisLock.lock(lockKey)) {
             try {
-                return c2cOrderService.createC2cOrder(c2cOrder, c2cAd, symbolNum, loginUserId, appUserDetail.getRealName());
+                return c2cOrderService.createC2cOrder(c2cOrder, c2cAd, legalCoinAmount,symbolAmount, loginUserId, appUserDetail.getRealName());
             } catch (Exception e) {
                 log.error("createC2cOrder,{},{},{}",loginUserId,c2cOrder.getC2cAdId(),e.getMessage());
                 return error(e.getMessage());
@@ -497,27 +517,25 @@ public class C2cOrderController extends ApiBaseController {
     @PostMapping("/mylist")
     public Result mylist(@RequestBody C2cOrderListDTO orderVo)
     {
-
         ValidatorUtils.validateEntity(orderVo);
         //分页
-        Page<C2cOrderEntity> page = c2cOrderService.page(orderVo.getPage());
-//        String pageNum = Convert.toStr(orderVo.getPageNum(),"1");
-//        String pageSize = Convert.toStr(orderVo.getPageSize(),"10");
-//
-//        Map<String,Object> params = new HashMap<>();
-//        params.put(Constant.PAGE,pageNum);
-//        params.put(Constant.LIMIT,pageSize);
-//        params.put("direction",orderVo.getDirection());
-//        params.put("flow",orderVo.getFlow());
-//        params.put("status",orderVo.getStatus());
-//        params.put("orderNo",orderVo.getOrderNo());
-//        params.put("isMt",orderVo.getIsMt());
-//        PageData<C2cOrderEntity> page = c2cOrderService.page(params);
-
-        List<C2cOrderEntity> orderList = page.getRecords();
+//        Page<C2cOrderEntity> page = c2cOrderService.page(orderVo.getPage());
+        String pageNum = Convert.toStr(orderVo.getPageNum(),"1");
+        String pageSize = Convert.toStr(orderVo.getPageSize(),"10");
+        Map<String,Object> params = new HashMap<>();
+        params.put(Constant.PAGE,pageNum);
+        params.put(Constant.LIMIT,pageSize);
+        params.put("direction",orderVo.getDirection());
+        params.put("flow",orderVo.getFlow());
+        params.put("status",orderVo.getStatus());
+        params.put("orderNo",orderVo.getOrderNo());
+        params.put("isMt",orderVo.getIsMt());
+        PageData<C2cOrderEntity> page = c2cOrderService.page(params);
+
+        List<C2cOrderEntity> orderList = page.getList();
         // 查询付款凭证
         orderList = c2cOrderService.selectPaymentVoucherByOrderList(orderList);
-        page.setRecords(orderList);
+        page.setList(orderList);
 
         return new Result<>().ok(page);
 
@@ -570,7 +588,6 @@ public class C2cOrderController extends ApiBaseController {
 
         //待放币的订单数量
         String releaseCountsKey = CacheConstants.getC2cMertUnReleaseKey(StpUtil.getLoginIdAsString());
-log.info("商户待处理Key:"+unpayCountsKey+":"+releaseCountsKey);
 
         Integer unpayCounts = 0;
         Integer releaseCounts = 0;
@@ -584,7 +601,6 @@ log.info("商户待处理Key:"+unpayCountsKey+":"+releaseCountsKey);
         } else {
             releaseCounts = Convert.toInt(redisUtils.get(releaseCountsKey),0);
         }
-log.info("商户待处理数Count:"+unpayCounts+":"+releaseCounts);
 
         if(unpayCounts<0 || releaseCounts<0) {
             unpayCounts = c2cOrderService.setMtUnPayCount(unpayCountsKey);
@@ -602,8 +618,7 @@ log.info("商户待处理数Count:"+unpayCounts+":"+releaseCounts);
     {
         ValidatorUtils.validateEntity(c2cOrderComplain);
 
-        C2cOrderEntity order = c2cOrderService.selectOrder(c2cOrderComplain.getOrderId());
-        log.info("订单信息:"+ JSON.toJSONString(order));
+        C2cOrderEntity order = c2cOrderService.selectById(c2cOrderComplain.getOrderId());
         if(order == null) {
             return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
         }
@@ -773,4 +788,35 @@ log.info("商户待处理数Count:"+unpayCounts+":"+releaseCounts);
         return success(data);
     }
 
+
+    /**
+     * c2c我的信息
+     *
+     */
+    @Operation(summary = "c2c我的")
+    @PostMapping("/myInfo")
+    public Result myInfo()
+    {
+        AppUserEntity user = appUserService.getById(StpUtil.getLoginIdAsLong());
+        AppUserDetailEntity detail = appUserDetailService.selectAppUserDetailByUserId(user.getId());
+        AppAssetEntity asset = appAssetService.getAppAssetEntity(user.getId(), "usdt",AssetEnum.PLATFORM_ASSETS.getCode());
+        C2cMerchantEntity merchant = c2cMerchantService.getMerchantEntity(user.getId());
+
+        Map data = MapUtil.of("email", user.getEmail());
+        data.put("loginName",user.getLoginName());
+        data.put("country", user.getCountry());
+        data.put("phone", user.getPhone());
+        data.put("register_time", DateUtils.format(user.getCreateTime(),"yyyy/MM/dd"));
+        data.put("auth_time", DateUtils.format(detail.getOperateTime(),"yyyy/MM/dd"));
+        data.put("avail",asset.getAvailable().setScale(8, RoundingMode.DOWN).stripTrailingZeros().toPlainString());
+        data.put("frozen",asset.getFrozen().setScale(8, RoundingMode.DOWN).stripTrailingZeros().toPlainString());
+        data.put("finishNum",merchant.getFinishNum());
+        data.put("finishRate",merchant.getFinishRate());
+        data.put("averagePayTime",merchant.getAveragePayTime());
+        data.put("averagePassTime",merchant.getAveragePassTime());
+
+        return success(data);
+    }
+
+
 }

+ 16 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/C2cMsgContactDao.java

@@ -0,0 +1,16 @@
+package com.qnfhq.modules.c2c.dao;
+
+import com.qnfhq.common.dao.BaseDao;
+import com.qnfhq.modules.c2c.entity.C2cMsgContactEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 最近联系人
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@Mapper
+public interface C2cMsgContactDao extends BaseDao<C2cMsgContactEntity> {
+	
+}

+ 16 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/C2cMsgContentDao.java

@@ -0,0 +1,16 @@
+package com.qnfhq.modules.c2c.dao;
+
+import com.qnfhq.common.dao.BaseDao;
+import com.qnfhq.modules.c2c.entity.C2cMsgContentEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 聊天消息表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@Mapper
+public interface C2cMsgContentDao extends BaseDao<C2cMsgContentEntity> {
+	
+}

+ 16 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/C2cMsgRelationDao.java

@@ -0,0 +1,16 @@
+package com.qnfhq.modules.c2c.dao;
+
+import com.qnfhq.common.dao.BaseDao;
+import com.qnfhq.modules.c2c.entity.C2cMsgRelationEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 用户消息关联表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@Mapper
+public interface C2cMsgRelationDao extends BaseDao<C2cMsgRelationEntity> {
+	
+}

+ 5 - 2
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cAdViewDTO.java

@@ -43,10 +43,13 @@ public class C2cAdViewDTO implements Serializable {
 	private String payway;
 
 	@SchemaProperty(name = "页码")
-	private Integer pageNum;
+	private String pageNum;
 
 	@SchemaProperty(name = "每页条数")
-	private Integer pageSize;
+	private String pageSize;
 
+    @SchemaProperty(name = "标签")
+    @NotNull(message="{NotNull.tag}")//标签不能为空
+    private Integer tag;
 
 }

+ 27 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cMsgContactDTO.java

@@ -0,0 +1,27 @@
+package com.qnfhq.modules.c2c.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 最近联系人
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@Data
+@Schema(name = "最近联系人")
+public class C2cMsgContactDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @SchemaProperty(name = "页码")
+    private String pageNum;
+
+    @SchemaProperty(name = "每页条数")
+    private String pageSize;
+}

+ 50 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cMsgContentDTO.java

@@ -0,0 +1,50 @@
+package com.qnfhq.modules.c2c.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 聊天消息表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@Data
+@Schema(name = "聊天消息表")
+public class C2cMsgContentDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @SchemaProperty(name = "消息编号")
+    private Long mid;
+
+	@SchemaProperty(name = "发送人编号")
+//    @NotNull(message="{NotBlank.senderId}")//发送人不能空
+	private Long senderId;
+
+	@SchemaProperty(name = "接收人编号")
+    @NotNull(message="{NotBlank.recipientId}")//接收人不能空
+	private Long recipientId;
+
+	@SchemaProperty(name = "消息内容")
+    @Length(min=1, max = 1000,message="{Length.content}")//消息内容长度不能超过1000
+    @NotBlank(message="{NotBlank.content}")//消息内容不能空
+	private String content;
+
+	@SchemaProperty(name = "消息类型: text 文本 image 图片 voice 语音 video 视频 location位置 ")
+    @NotBlank(message="{NotBlank.msgType}")//消息类型不能空
+	private String msgType;
+
+    @SchemaProperty(name = "0已发送 1已送达 2已读 3已撤回")
+    private Integer status;
+
+    @SchemaProperty(name = "发送时间")
+    private Date sendTime;
+}

+ 35 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cMsgRelationDTO.java

@@ -0,0 +1,35 @@
+package com.qnfhq.modules.c2c.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 用户消息关联表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@Data
+@Schema(name = "用户消息关联表")
+public class C2cMsgRelationDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+	@SchemaProperty(name = "返回大于消息编号数据")
+	private Long mid;
+
+	@SchemaProperty(name = "对方编号")
+    @NotNull(message="{NotNull.otherUid}")//对方编号不能为空
+	private Long otherUid;
+
+    @SchemaProperty(name = "页码")
+    private String pageNum;
+
+    @SchemaProperty(name = "每页条数")
+    private String pageSize;
+}

+ 2 - 3
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderComplainVoucherDTO.java

@@ -1,13 +1,12 @@
 package com.qnfhq.modules.c2c.dto;
 
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
 import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 
 import java.io.Serializable;
-import java.util.Date;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.media.SchemaProperty;
 
 /**
  * c2c申诉证明材料

+ 5 - 6
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderCreateDTO.java

@@ -8,7 +8,6 @@ import lombok.Data;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
-import java.util.Date;
 
 /**
  * c2c订单
@@ -29,7 +28,7 @@ public class C2cOrderCreateDTO implements Serializable {
     @NotBlank(message="{NotBlank.legalCoin}")//法币不能为空
 	private String legalCoin;
 
-	@SchemaProperty(name = "交易币种USDT,BTC")
+	@SchemaProperty(name = "交易币种")
     @NotBlank(message="{NotBlank.symbol}")//交易币种不能为空
 	private String symbol;
 
@@ -37,13 +36,13 @@ public class C2cOrderCreateDTO implements Serializable {
     @NotNull(message="{NotNull.c2cAdId}")//广告编号不能为空
 	private Long c2cAdId;
 
-	@SchemaProperty(name = "交易金额/数量")
+	@SchemaProperty(name = "法币/数币金额")
     @NotNull(message="{NotNull.tranAmount}")//交易金额/数量不能为空
 	private BigDecimal tranAmount;
 
-    @SchemaProperty(name = "交易方式amt/qty")
-    @NotBlank(message="{NotNull.tranBy}")//交易方式不能为空
-    private String tranBy;
+    @SchemaProperty(name = "单位cny/usdt")
+    @NotBlank(message="{NotNull.unit}")//交易单位不能为空
+    private String unit;
 
 	@SchemaProperty(name = "支付方式比如1微信 2支付宝 3银行借记卡")
     @NotNull(message="{NotNull.payType}")//支付方式不能为空

+ 24 - 5
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderDTO.java

@@ -1,11 +1,16 @@
 package com.qnfhq.modules.c2c.dto;
 
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.qnfhq.modules.c2c.entity.C2cPaymentVoucherEntity;
+import com.qnfhq.modules.c2c.entity.C2cUserReceiptEntity;
 import lombok.Data;
 
 import java.io.Serializable;
 import java.util.Date;
 
 import java.math.BigDecimal;
+import java.util.List;
+
 import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.media.SchemaProperty;
 /**
@@ -19,7 +24,7 @@ import io.swagger.v3.oas.annotations.media.SchemaProperty;
 public class C2cOrderDTO implements Serializable {
     private static final long serialVersionUID = 1L;
 
-	@SchemaProperty(name = "")
+	@SchemaProperty(name = "自增编号")
 	private Long id;
 
 	@SchemaProperty(name = "订单编号")
@@ -61,6 +66,9 @@ public class C2cOrderDTO implements Serializable {
 	@SchemaProperty(name = "1微信  2支付宝 3银行借记卡")
 	private Integer payType;
 
+    @SchemaProperty(name = "付款时间")
+    private Date payTime;
+
 	@SchemaProperty(name = "0 进行中 1 已结束 ")
 	private Integer flow;
 
@@ -76,11 +84,22 @@ public class C2cOrderDTO implements Serializable {
 	@SchemaProperty(name = "")
 	private Date updateTime;
 
-	@SchemaProperty(name = "")
-	private Date endTime;
+    @SchemaProperty(name = "支付过期时间")
+    private Date payExpireTime;
 
-	@SchemaProperty(name = "")
-	private Integer expireTime;
+    @SchemaProperty(name = "完成时间")
+    private Date finishTime;
+
+    @SchemaProperty(name = "关闭时间")
+    private Date closeTime;
+
+    @SchemaProperty(name = "卖家收款信息")
+    C2cUserReceiptEntity receiptInfo;
+
+    @SchemaProperty(name = "是否有付款凭证")
+    Integer isVoucher=0;
 
+    @SchemaProperty(name = "买家付款凭证")
+    List<C2cPaymentVoucherEntity> payVoucherList;
 
 }

+ 0 - 2
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderIdDTO.java

@@ -6,8 +6,6 @@ import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 
 import java.io.Serializable;
-import java.math.BigDecimal;
-import java.util.Date;
 
 /**
  * c2c订单

+ 0 - 3
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderListDTO.java

@@ -3,13 +3,10 @@ package com.qnfhq.modules.c2c.dto;
 import com.qnfhq.common.entity.BaseQueryDTO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.media.SchemaProperty;
-import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 
 import java.io.Serializable;
-import java.math.BigDecimal;
-import java.util.Date;
 
 /**
  * c2c订单

+ 0 - 2
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cPaymentVoucherIdDTO.java

@@ -2,12 +2,10 @@ package com.qnfhq.modules.c2c.dto;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.media.SchemaProperty;
-import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 
 import java.io.Serializable;
-import java.util.Date;
 
 /**
  * c2c付款证明

+ 14 - 1
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cAdEntity.java

@@ -3,6 +3,9 @@ package com.qnfhq.modules.c2c.entity;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.qnfhq.common.BigDecimalSerialize;
+import com.qnfhq.common.BigDecimalSerialize2;
 import lombok.Data;
 
 import java.io.Serializable;
@@ -54,26 +57,31 @@ public class C2cAdEntity implements Serializable {
     /**
      * 数币的总数量
      */
+    @JsonSerialize(using = BigDecimalSerialize.class)
 	private BigDecimal num;
     /**
      * 剩余可用数币的数量
      */
+    @JsonSerialize(using = BigDecimalSerialize.class)
 	private BigDecimal availableNum;
     /**
      * 价格类型:1固定
      */
 	private Integer priceType;
     /**
-     * 法币单价
+     * 法币单价 保留2位小数
      */
+    @JsonSerialize(using = BigDecimalSerialize2.class)
 	private BigDecimal price;
     /**
      * 限量最小法币金额
      */
+    @JsonSerialize(using = BigDecimalSerialize.class)
 	private BigDecimal minAmount;
     /**
      * 限量最大法币金额
      */
+    @JsonSerialize(using = BigDecimalSerialize.class)
 	private BigDecimal maxAmount;
     /**
      * 支付方式
@@ -103,4 +111,9 @@ public class C2cAdEntity implements Serializable {
      * 
      */
 	private Long version;
+
+    /**
+     *  标签 0 默认 1新手友好
+     */
+    private Integer tag;
 }

+ 33 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cMerchantEntity.java

@@ -110,4 +110,37 @@ public class C2cMerchantEntity implements Serializable {
      * 审核通过时间
      */
 	private Date operateTime;
+
+    /**
+     * 标签 0 默认 1新手友好
+     */
+    private Integer tag;
+
+
+    /**
+     * 30日购买单数
+     */
+    private Integer day30BuyNum;
+
+    /**
+     * 30日出售单数
+     */
+    private Integer day30SellNum;
+
+    /**
+     * 30日交易对手数
+     */
+    private Integer day30TranUserNum;
+
+    /**
+     * 平均付款用时分钟
+     */
+    private Integer averagePayTime;
+
+    /**
+     * 平均放币用时分钟
+     */
+    private Integer averagePassTime;
+
+
 }

+ 53 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cMsgContactEntity.java

@@ -0,0 +1,53 @@
+package com.qnfhq.modules.c2c.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 最近联系人
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@Data
+@TableName("c2c_msg_contact")
+public class C2cMsgContactEntity {
+
+    /**
+     * 
+     */
+	private Long ownerUid;
+    /**
+     * 
+     */
+	private Long otherUid;
+    /**
+     * 昵称
+     */
+	private String otherNickname;
+    /**
+     * 头像
+     */
+	private String otherAvatar;
+    /**
+     * 
+     */
+	private Long mid;
+    /**
+     * 消息类型: text 文本 image 图片 voice 语音 video 视频 location位置 
+     */
+	private String msgType;
+    /**
+     * 
+     */
+	private Date createTime;
+
+    @TableField(exist = false)
+    private C2cMsgContentEntity c2cMsg;
+
+    @TableField(exist = false)
+    private Long unreads;
+}

+ 49 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cMsgContentEntity.java

@@ -0,0 +1,49 @@
+package com.qnfhq.modules.c2c.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 聊天消息表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@Data
+@TableName("c2c_msg_content")
+public class C2cMsgContentEntity implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+
+    @TableId(type = IdType.AUTO)
+	private Long mid;
+    /**
+     * 
+     */
+	private Long senderId;
+    /**
+     * 
+     */
+	private Long recipientId;
+    /**
+     * 消息内容
+     */
+	private String content;
+    /**
+     * 消息类型: text 文本 image 图片 voice 语音 video 视频 location位置 链接link
+     */
+	private String msgType;
+    /**
+     * 0已发送 1已送达 2已读 3已撤回
+     */
+	private Integer status;
+    /**
+     * 
+     */
+	private Date sendTime;
+}

+ 42 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cMsgRelationEntity.java

@@ -0,0 +1,42 @@
+package com.qnfhq.modules.c2c.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 用户消息关联表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@Data
+@TableName("c2c_msg_relation")
+public class C2cMsgRelationEntity {
+
+    /**
+     * 
+     */
+	private Long mid;
+    /**
+     * 
+     */
+	private Long ownerUid;
+    /**
+     * 
+     */
+	private Long otherUid;
+    /**
+     * 类型 0发件箱 1收件箱
+     */
+	private Integer type;
+    /**
+     * 
+     */
+	private Date createTime;
+
+    @TableField(exist = false)
+    private C2cMsgContentEntity c2cMsg;
+}

+ 22 - 11
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cOrderEntity.java

@@ -38,15 +38,15 @@ public class C2cOrderEntity implements Serializable {
      */
 	private String userName;
     /**
-     * 1买入  2 卖出
+     * 方向:1买入  2 卖出
      */
 	private Integer direction;
     /**
-     * 法定货
+     * 法币
      */
 	private String legalCoin;
     /**
-     * 交易币USDT,BTC
+     * 数币
      */
 	private String symbol;
     /**
@@ -66,7 +66,7 @@ public class C2cOrderEntity implements Serializable {
      */
 	private BigDecimal tranPrice;
     /**
-     * 数量USDT
+     * 数币数
      */
 	private BigDecimal symbolNum;
     /**
@@ -74,15 +74,19 @@ public class C2cOrderEntity implements Serializable {
      */
 	private BigDecimal tranAmount;
     /**
-     * 1微信  2支付宝 3银行借记卡
+     * 支付方式:1微信  2支付宝 3银行借记卡
      */
 	private Integer payType;
     /**
-     * 0 进行中 1 已结束 
+     * 付款时间
+     */
+    private Date payTime;
+    /**
+     * 流程:0 进行中 1 已结束
      */
 	private Integer flow;
     /**
-     * 0 未付款 1 已付款(确认付款后)2 申诉 3 已完成 4 已取消 
+     * 订单状态:0 未付款 1 已付款(确认付款后)2 申诉 3 已完成 4 已取消
      */
 	private Integer status;
     /**
@@ -97,14 +101,20 @@ public class C2cOrderEntity implements Serializable {
      * 
      */
 	private Date updateTime;
+
     /**
-     * 
+     * 支付过期时间
      */
-	private Date endTime;
+	private Date payExpireTime;
     /**
-     * 
+     * 完成时间
      */
-	private Integer expireTime;
+    private Date finishTime;
+    /**
+     * 关闭时间 订单取消
+     */
+    private Date closeTime;
+
 
     /**
      * 卖家收款信息
@@ -115,6 +125,7 @@ public class C2cOrderEntity implements Serializable {
     //是否有付款凭证
     @TableField(exist = false)
     Integer isVoucher=0;
+
     //买家付款凭证
     @TableField(exist = false)
     List<C2cPaymentVoucherEntity> payVoucherList;

+ 32 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/enums/MsgRelationEnum.java

@@ -0,0 +1,32 @@
+package com.qnfhq.modules.c2c.enums;
+
+/**
+ * 一句话描述
+ *
+ * @Author: Yelz 30262728@qq.com
+ * @Date: 2025/11/26 06:17
+ * @Description:
+ */
+public enum MsgRelationEnum {
+    SEND_BOX(0,"发件箱"),
+    RECEIVE_BOX(1,"收件箱");
+
+    private Integer code;
+
+    private String desc;
+
+    public Integer getCode()
+    {
+        return code;
+    }
+
+    public String getDesc()
+    {
+        return desc;
+    }
+
+    MsgRelationEnum(Integer code, String desc){
+        this.code = code;
+        this.desc = desc;
+    }
+}

+ 35 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/enums/MsgStatusEnum.java

@@ -0,0 +1,35 @@
+package com.qnfhq.modules.c2c.enums;
+
+/**
+ * 一句话描述
+ *
+ * @Author: Yelz 30262728@qq.com
+ * @Date: 2025/11/26 09:13
+ * @Description:
+ */
+public enum MsgStatusEnum {
+
+    SEND(0,"已发送"),
+    ARRIVED(1,"已送达"),
+    READ(2,"已读"),
+    REVOKE(3,"已撤回");
+
+    private Integer code;
+
+    private String desc;
+
+    public Integer getCode()
+    {
+        return code;
+    }
+
+    public String getDesc()
+    {
+        return desc;
+    }
+
+    MsgStatusEnum(Integer code, String desc){
+        this.code = code;
+        this.desc = desc;
+    }
+}

+ 20 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/enums/MsgTypeEnum.java

@@ -0,0 +1,20 @@
+package com.qnfhq.modules.c2c.enums;
+
+
+public enum MsgTypeEnum {
+
+    TEXT,
+    IMAGE,
+    VOICE,
+    VIDEO,
+    LOCATION;
+
+    public static boolean isValid(String name) {
+        for (MsgTypeEnum em: MsgTypeEnum.values()) {
+            if (em.name().equals(name.toUpperCase())) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

+ 3 - 3
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cAdService.java

@@ -2,7 +2,7 @@ package com.qnfhq.modules.c2c.service;
 
 import com.qnfhq.common.page.PageData;
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.qnfhq.common.service.BaseService;
 import com.qnfhq.common.utils.Result;
 import com.qnfhq.modules.c2c.dto.*;
 import com.qnfhq.modules.c2c.entity.C2cAdEntity;
@@ -16,13 +16,13 @@ import java.util.Map;
  * @author yelz 30262728@qq.com
  * @since 1.0.0 2025-11-17
  */
-public interface C2cAdService extends IService<C2cAdEntity> {
+public interface C2cAdService extends BaseService<C2cAdEntity> {
 
     public Result createAd(C2cAdCreateDTO c2cAdDTO, long loginId) throws Exception;
 
     public Result cancelAd(C2cAdEntity ad) throws Exception;
 
-//    PageData<C2cAdEntity> page(Map<String, Object> params);
+    PageData<C2cAdEntity> page(Map<String, Object> params);
 
     /**
      *  设置广告缓存

+ 38 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cMsgContactService.java

@@ -0,0 +1,38 @@
+package com.qnfhq.modules.c2c.service;
+
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.service.BaseService;
+import com.qnfhq.common.service.CrudService;
+import com.qnfhq.modules.c2c.dto.C2cMsgContactDTO;
+import com.qnfhq.modules.c2c.entity.C2cMsgContactEntity;
+import com.qnfhq.modules.c2c.entity.C2cMsgContentEntity;
+import java.util.Map;
+
+/**
+ * 最近联系人
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+public interface C2cMsgContactService extends BaseService<C2cMsgContactEntity> {
+    /**
+     * 最近联系人分页查询
+     * @param params
+     * @return
+     */
+    PageData<C2cMsgContactEntity> selectContactPage(Map<String, Object> params);
+
+    /**
+     * 查询最近联系人
+     * @param ownerUid
+     * @param otherUid
+     * @return
+     */
+    C2cMsgContactEntity selectByOwnerUidOtherUid(Long ownerUid, Long otherUid);
+
+    /**
+     * 保存最近联系人
+     * @param msgEntity
+     */
+    void saveByMsgContact(C2cMsgContentEntity msgEntity) throws Exception;
+}

+ 23 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cMsgContentService.java

@@ -0,0 +1,23 @@
+package com.qnfhq.modules.c2c.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.modules.c2c.dto.C2cMsgContentDTO;
+import com.qnfhq.modules.c2c.entity.C2cMsgContentEntity;
+
+/**
+ * 聊天消息表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+public interface C2cMsgContentService extends IService<C2cMsgContentEntity> {
+
+    /**
+     * 保存消息
+     * @param dto
+     * @return
+     * @throws Exception
+     */
+    Result saveMsg(C2cMsgContentDTO dto) throws Exception;
+}

+ 31 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cMsgRelationService.java

@@ -0,0 +1,31 @@
+package com.qnfhq.modules.c2c.service;
+
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.service.BaseService;
+import com.qnfhq.common.service.CrudService;
+import com.qnfhq.modules.c2c.dto.C2cMsgRelationDTO;
+import com.qnfhq.modules.c2c.entity.C2cMsgContentEntity;
+import com.qnfhq.modules.c2c.entity.C2cMsgRelationEntity;
+
+import java.util.Map;
+
+/**
+ * 用户消息关联表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+public interface C2cMsgRelationService extends BaseService<C2cMsgRelationEntity> {
+    /**
+     * 查询用户聊天列表
+     * @param params
+     * @return
+     */
+    PageData<C2cMsgRelationEntity> selectChatPage(Map<String, Object> params);
+
+    /**
+     * 保存消息关联
+     * @param msgEntity
+     */
+    void saveMsgRelation(C2cMsgContentEntity msgEntity) throws Exception;
+}

+ 0 - 2
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cOrderComplainVoucherService.java

@@ -1,8 +1,6 @@
 package com.qnfhq.modules.c2c.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.qnfhq.modules.c2c.dto.C2cOrderComplainVoucherDTO;
 import com.qnfhq.modules.c2c.entity.C2cOrderComplainVoucherEntity;
 
 import java.util.List;

+ 4 - 7
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cOrderService.java

@@ -1,15 +1,12 @@
 package com.qnfhq.modules.c2c.service;
 
-
 import com.qnfhq.common.page.PageData;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.qnfhq.common.service.BaseService;
 import com.qnfhq.common.utils.Result;
 import com.qnfhq.modules.c2c.dto.C2cOrderCreateDTO;
-import com.qnfhq.modules.c2c.dto.C2cOrderDTO;
 import com.qnfhq.modules.c2c.entity.C2cAdEntity;
 import com.qnfhq.modules.c2c.entity.C2cOrderComplainEntity;
 import com.qnfhq.modules.c2c.entity.C2cOrderEntity;
-
 import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
@@ -20,9 +17,9 @@ import java.util.Map;
  * @author yelz 30262728@qq.com
  * @since 1.0.0 2025-11-17
  */
-public interface C2cOrderService extends IService<C2cOrderEntity> {
+public interface C2cOrderService extends BaseService<C2cOrderEntity> {
 
-//    PageData<C2cOrderEntity> page(Map<String, Object> params);
+    PageData<C2cOrderEntity> page(Map<String, Object> params);
 
     /**
      * c2c订单编号缓存Key
@@ -60,7 +57,7 @@ public interface C2cOrderService extends IService<C2cOrderEntity> {
      * @return
      * @throws Exception
      */
-    public Result createC2cOrder(C2cOrderCreateDTO c2cOrder, C2cAdEntity c2cAd, BigDecimal symbolNum,
+    public Result createC2cOrder(C2cOrderCreateDTO c2cOrder, C2cAdEntity c2cAd, BigDecimal legalCoinAmount, BigDecimal symbolNum,
                                  Long loginUserId, String realName) throws Exception;
 
 

+ 88 - 139
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cAdServiceImpl.java

@@ -3,19 +3,14 @@ package com.qnfhq.modules.c2c.service.impl;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.map.MapUtil;
-import cn.hutool.json.JSONArray;
-import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.Query;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qnfhq.common.constant.Constant;
 import com.qnfhq.common.exception.ErrorCode;
 import com.qnfhq.common.page.PageData;
 import com.qnfhq.common.redis.RedisUtils;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.qnfhq.common.service.impl.CrudServiceImpl;
+import com.qnfhq.common.service.impl.BaseServiceImpl;
 import com.qnfhq.common.utils.MessageUtils;
 import com.qnfhq.common.utils.Result;
 import com.qnfhq.modules.c2c.dao.C2cAdDao;
@@ -32,15 +27,12 @@ import com.qnfhq.modules.user.service.AppAssetService;
 import com.qnfhq.utils.OrderUtils;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
-
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.*;
-import java.util.concurrent.TimeUnit;
 
 /**
  * c2c商家广告
@@ -50,7 +42,7 @@ import java.util.concurrent.TimeUnit;
  */
 @Slf4j
 @Service
-public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> implements C2cAdService {
+public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> implements C2cAdService {
 
     @Resource
     private C2cMerchantService c2cMerchantService;
@@ -141,7 +133,7 @@ public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> impleme
 //        c2cAd.setFinishNum(merchant.getFinishNum());
         //成单率
 //        c2cAd.setFinishRate(merchant.getFinishRate());
-        if(!save(c2cAd)) {
+        if(!updateById(c2cAd)) {
             throw new Exception(MessageUtils.message("c2c.order.save.fail"));//保存广告失败
         }
         if (direction.intValue() == DirectionEnum.SELL.getCode().intValue()) {
@@ -194,15 +186,15 @@ public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> impleme
         String adHKey = getAdHKey(c2cAdId);
         redisUtils.delete(adHKey);
 
-        //2 按价格排序,用于浏览广告
-        String zsetKey = getViewAdKey(direction, legalCoin, symbol);
-        redisUtils.removeZset(zsetKey, c2cAdId.toString());
-
-        //3 按支付方式、按最小数量排序,用于快捷交易 c2c_ad_payId_buy_cnyusdt
-        String[] paywayAr = payway.split(",");
-        for (String paywayId : paywayAr) {
-            redisUtils.removeZset(getQuickAdKey(zsetKey, paywayId), c2cAdId.toString());
-        }
+//        //2 按价格排序,用于浏览广告
+//        String zsetKey = getViewAdKey(direction, legalCoin, symbol);
+//        redisUtils.removeZset(zsetKey, c2cAdId.toString());
+//
+//        //3 按支付方式、按最小数量排序,用于快捷交易 c2c_ad_payId_buy_cnyusdt
+//        String[] paywayAr = payway.split(",");
+//        for (String paywayId : paywayAr) {
+//            redisUtils.removeZset(getQuickAdKey(zsetKey, paywayId), c2cAdId.toString());
+//        }
     }
 
     @Override
@@ -235,26 +227,26 @@ public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> impleme
         redisUtils.hMSet(adHKey, adMap, randomHour*3600L);
 
         //2 按价格排序,用于浏览广告
-        String zsetKey = getViewAdKey(c2cAd.getDirection(), c2cAd.getLegalCoin(), c2cAd.getSymbol());
-        redisUtils.addZSet(zsetKey, c2cAd.getId().toString(), c2cAd.getPrice().doubleValue(), c2cAd.getDirection());
+//        String zsetKey = getViewAdKey(c2cAd.getDirection(), c2cAd.getLegalCoin(), c2cAd.getSymbol());
+//        redisUtils.addZSet(zsetKey, c2cAd.getId().toString(), c2cAd.getPrice().doubleValue(), c2cAd.getDirection());
 
         //3 按支付方式、按最小数量排序,用于快捷交易
-        String[] paywayAr = payway.split(",");
-        for (String paywayId : paywayAr) {
-            redisUtils.addZSet(getQuickAdKey(zsetKey, paywayId), c2cAd.getId().toString(), c2cAd.getMinAmount().doubleValue(), c2cAd.getDirection());
-        }
+//        String[] paywayAr = payway.split(",");
+//        for (String paywayId : paywayAr) {
+//            redisUtils.addZSet(getQuickAdKey(zsetKey, paywayId), c2cAd.getId().toString(), c2cAd.getMinAmount().doubleValue(), c2cAd.getDirection());
+//        }
     }
 
 
-//    @Override
-//    public PageData<C2cAdEntity> page(Map<String, Object> params) {
-//        IPage<C2cAdEntity> page = baseDao.selectPage(
-//                getPage(params, "id", false),
-//                getWrapper(params)
-//        );
-//
-//        return getPageData(page, C2cAdEntity.class);
-//    }
+    @Override
+    public PageData<C2cAdEntity> page(Map<String, Object> params) {
+        IPage<C2cAdEntity> page = baseDao.selectPage(
+                getPage(params, "id", false),
+                getWrapper(params)
+        );
+
+        return getPageData(page, C2cAdEntity.class);
+    }
 
     private QueryWrapper<C2cAdEntity> getWrapper(Map<String, Object> params){
 
@@ -273,17 +265,17 @@ public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> impleme
 
     /**
      * 快捷交易查询
+     * 优先匹配“新手友好”商家
      * @param tranDTO
      * @return
      */
     @Override
     public Result queryTranAd(C2cAdTranDTO tranDTO) {
         Result result = new Result();
-        long loginId = StpUtil.getLoginIdAsLong();
         String tranSymbol = tranDTO.getSymbol().toLowerCase();
         String tranLegalCoin = tranDTO.getLegalCoin().toUpperCase();
         Integer tranDirection = tranDTO.getDirection();
-        //所有支付方式
+        //支付方式
         List<C2cPayWayEntity> paywayList = c2cPayWayService.selectListByLegalCoin(tranLegalCoin);
         if(CollectionUtils.isEmpty(paywayList)) {
             return result.error(MessageUtils.message("c2c.ad.current.payway.empty"));//当前法币未设置支付方式
@@ -293,37 +285,48 @@ public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> impleme
         if(Objects.isNull(tLegalCoin)) {
             return result.error(MessageUtils.message("c2c.ad.legalCoin.notset"));//当前法币未设置
         }
+        //买入法币金额,卖出是数币
         BigDecimal maxAmount = BigDecimal.ZERO;
         if (tranDTO.getDirection().intValue() == DirectionEnum.BUY.getCode().intValue()) {
-            maxAmount = tranDTO.getAmount();//法币cny的金额
+            maxAmount = tranDTO.getAmount();
         } else {
-            //卖出是usdt币的数量
             maxAmount = tranDTO.getAmount().multiply(tLegalCoin.getExchangeRate());
         }
 
 
-        boolean flag = true;
-        //1从redis取数
+        Integer direction = 0;
+        if (tranDTO.getDirection().intValue() == DirectionEnum.BUY.getCode().intValue()) {
+            direction = DirectionEnum.SELL.getCode();
+        } else {
+            direction = DirectionEnum.BUY.getCode();
+        }
+        //先查新手友好的商行
+        List<C2cAdEntity> queryAdList = selectC2cAdTranList(tranSymbol,direction,tranLegalCoin,maxAmount,1);
+        setPaywayList(paywayList, queryAdList,tranDirection);
+
+        int total = 0;
         for(C2cPayWayEntity payway : paywayList) {
-            String zsetKey = getViewAdKey(tranDirection, tranLegalCoin, tranSymbol);
-            String zQuickKey = getQuickAdKey(zsetKey,payway.getId().toString());
-
-            ArrayList<Object> adidList = null;
-            //配置 最小买入金额
-            adidList = redisUtils.getRangeByScore(zQuickKey, 10.0, maxAmount.doubleValue());
-            if (adidList != null) {
-                List<C2cAdEntity> adList = new ArrayList<>();
-                for (Object adId : adidList) {
-                    Long adIdLong = Long.valueOf((String)adId);
-                    C2cAdEntity ad = selectAdFromRedis(adIdLong);
-                    if(ad == null) {
-                        ad = getById(adIdLong);
-                        if(ad==null) {
-                            redisUtils.removeZset(zQuickKey, adIdLong.toString());
-                        }
-                        delSetAdCache(ad);
-                    }
-                    if (ad!=null && ad.getMaxAmount().compareTo(maxAmount) != -1) {
+            if(payway.getAdList()!=null) {
+                total += payway.getAdList().size();
+            }
+        }
+
+        if(total<3) {
+            //查其他的商行
+            queryAdList = selectC2cAdTranList(tranSymbol,direction,tranLegalCoin,maxAmount,0);
+            setPaywayList(paywayList, queryAdList,tranDirection);
+        }
+
+        return result.ok(paywayList);
+    }
+
+    private List<C2cPayWayEntity> setPaywayList(List<C2cPayWayEntity> paywayList,List<C2cAdEntity> queryAdList,Integer direction) {
+        if (!CollectionUtils.isEmpty(queryAdList)) {
+            for(C2cPayWayEntity payway : paywayList) {
+                List<C2cAdEntity> adList = payway.getAdList()==null ? new ArrayList<>() : payway.getAdList();
+                for(C2cAdEntity ad : queryAdList) {
+                    String[] payIds = ad.getPayway().split(",");
+                    if(Arrays.asList(payIds).contains(payway.getId().toString())) {
                         adList.add(ad);
                         if (adList.size() > 2) {
                             break;
@@ -331,47 +334,17 @@ public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> impleme
                     }
                 }
                 if(adList.size()>0) {
-                    flag = false;
-                    sortAdList(adList,tranDTO.getDirection());
+                    sortAdList(adList,direction);
                     payway.setAdList(adList);
                 }
             }
         }
-
-        if(flag) {
-            //2从数据库查询
-            Integer direction = 0;
-            if (tranDTO.getDirection().intValue() == DirectionEnum.BUY.getCode().intValue()) {
-                direction = DirectionEnum.SELL.getCode();
-            } else {
-                direction = DirectionEnum.BUY.getCode();
-            }
-            List<C2cAdEntity> queryAdList = selectC2cAdTranList(tranSymbol,direction,tranLegalCoin,maxAmount);
-            if (!CollectionUtils.isEmpty(queryAdList)) {
-                for(C2cPayWayEntity payway : paywayList) {
-                    List<C2cAdEntity> adList = new ArrayList<>();
-                    for(C2cAdEntity ad : queryAdList) {
-                        String[] payIds = ad.getPayway().split(",");
-                        if(Arrays.asList(payIds).contains(payway.getId().toString())
-                                && ad.getUserId().longValue()!=loginId) {
-                            adList.add(ad);
-                            if (adList.size() > 2) {
-                                break;
-                            }
-                        }
-                    }
-                    if(adList.size()>0) {
-                        sortAdList(adList,tranDTO.getDirection());
-                        payway.setAdList(adList);
-                    }
-                }
-            }
-        }
-        return result.ok(paywayList);
+        return paywayList;
     }
 
     /**
      * 查询快捷交易广告
+     *
      * @param symbol
      * @param direction
      * @param legalCoin
@@ -379,15 +352,15 @@ public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> impleme
      * @return
      */
     private List<C2cAdEntity> selectC2cAdTranList(String symbol,Integer direction,
-                                                  String legalCoin,BigDecimal tranAmount) {
-        return list(new LambdaQueryWrapper<C2cAdEntity>()
-                    .eq(C2cAdEntity::getDirection,direction)
-                    .eq(C2cAdEntity::getLegalCoin,legalCoin)
-                    .eq(C2cAdEntity::getSymbol,symbol)
+                                                  String legalCoin,BigDecimal tranAmount,Integer tag) {
+        return baseDao.selectList(new LambdaQueryWrapper<C2cAdEntity>()
+                    .ne(C2cAdEntity::getUserId, StpUtil.getLoginIdAsLong())
+                    .eq(Objects.nonNull(direction),C2cAdEntity::getDirection, direction)
+                    .eq(StrUtil.isNotBlank(legalCoin),C2cAdEntity::getLegalCoin, legalCoin)
+                    .eq(StrUtil.isNotBlank(symbol),C2cAdEntity::getSymbol, symbol)
                     .eq(C2cAdEntity::getStatus,AdStatusEnum.PASS.getCode())
-                    .ge(C2cAdEntity::getMaxAmount,tranAmount)
-                    .le(C2cAdEntity::getMinAmount,tranAmount)
-                    .last(" limit 50")
+                    .eq(Objects.nonNull(tag),C2cAdEntity::getTag,tag)
+                    .last(" limit 100")
                 );
     }
 
@@ -405,7 +378,7 @@ public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> impleme
         if(viewDTO.getId()!=null) {
             C2cAdEntity ad = selectAdFromRedis(viewDTO.getId());
             if(ad == null) {
-                ad = getById(viewDTO.getId());
+                ad = selectById(viewDTO.getId());
             }
             if(ad!=null) {
                 resList.add(ad);
@@ -418,6 +391,8 @@ public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> impleme
         BigDecimal amount = viewDTO.getAmount();
         //设置支付方式
         String payway = viewDTO.getPayway();
+        //标签
+        Integer tag = viewDTO.getTag();
 
         Map<String, Object> params = new HashMap<>();
         //买入\卖出广告
@@ -431,37 +406,12 @@ public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> impleme
             direction = DirectionEnum.BUY.getCode();
             params.put("direction", DirectionEnum.BUY.getCode());
         }
-        Integer pageNum = Convert.toInt(viewDTO.getPageNum(), 1);
-        Integer pageSize = Convert.toInt(viewDTO.getPageSize(), 10);
-        params.put(Constant.PAGE,pageNum.toString());
-        params.put(Constant.LIMIT,pageSize.toString());
+        params.put(Constant.PAGE,viewDTO.getPageNum());
+        params.put(Constant.LIMIT,viewDTO.getPageSize());
         String inputSymbol = viewDTO.getSymbol().toLowerCase();
         String inputLegalCoin = viewDTO.getLegalCoin().toUpperCase();
 
-        //1从redis查询
-        if(amount == null && StrUtil.isEmpty(payway)) {
-            long start = (pageNum - 1) * pageSize;
-            long end = pageNum * pageSize-1;
-            String zsetKey = getViewAdKey(direction, inputLegalCoin, inputSymbol);
-            ArrayList<Object> adList = redisUtils.getRange(zsetKey, type, start, end);
-            if (adList != null) {
-                for(Object adId : adList) {
-                    Long adIdLong = Long.valueOf((String)adId);
-                    C2cAdEntity ad = selectAdFromRedis(adIdLong);
-                    if(ad == null) {
-                        ad = getById(adIdLong);
-                        delSetAdCache(ad);
-                    }
-                    if(ad!=null && ad.getUserId().longValue()!=StpUtil.getLoginIdAsLong()) {
-                        resList.add(ad);
-                    }
-                }
-                PageData<C2cAdEntity> data = new PageData<C2cAdEntity>(resList,resList.size());
-                return result.ok(data);
-            }
-        }
-
-        //2 查数据库
+        // 查数据库
         List paywayList = new ArrayList();
         if (StrUtil.isNotEmpty(payway)) {
             paywayList = Arrays.stream(payway.split(",")).toList();
@@ -472,6 +422,7 @@ public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> impleme
                 .eq(StrUtil.isNotBlank(inputLegalCoin),C2cAdEntity::getLegalCoin, inputLegalCoin)
                 .eq(StrUtil.isNotBlank(inputSymbol),C2cAdEntity::getSymbol, inputSymbol)
                 .eq(C2cAdEntity::getStatus,AdStatusEnum.PASS.getCode())
+                .eq(Objects.nonNull(tag) && tag != -1,C2cAdEntity::getTag,tag)
                 .le(Objects.nonNull(amount),C2cAdEntity::getMinAmount,amount)
                 .ge(Objects.nonNull(amount),C2cAdEntity::getMaxAmount,amount);
         if(paywayList.size()>0) {
@@ -479,15 +430,13 @@ public class C2cAdServiceImpl extends ServiceImpl<C2cAdDao, C2cAdEntity> impleme
             wrapper.and(qw -> createQw(qw, finalPaywayList));
         }
 
-        //todo 分页
-        return null;
-//        IPage<C2cAdEntity> page2 =new Page<>();
-//        IPage<C2cAdEntity> page = baseDao.selectPage(
-//                getPage(params, "price", "asc".equals(type) ? true : false),
-//                wrapper
-//        );
-//        PageData<C2cAdEntity> data = getPageData(page, C2cAdEntity.class);
-//        return result.ok(data);
+        IPage<C2cAdEntity> page = baseDao.selectPage(
+                getPage(params, "price", "asc".equals(type) ? true : false),
+                wrapper
+        );
+        PageData<C2cAdEntity> data = getPageData(page, C2cAdEntity.class);
+        return result.ok(data);
+
     }
 
     private void createQw(LambdaQueryWrapper<C2cAdEntity> qw, List<String> paywayList) {

+ 104 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cMsgContactServiceImpl.java

@@ -0,0 +1,104 @@
+package com.qnfhq.modules.c2c.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.qnfhq.common.constant.Constant;
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.service.impl.BaseServiceImpl;
+import com.qnfhq.modules.c2c.dao.C2cMsgContactDao;
+import com.qnfhq.modules.c2c.entity.C2cMsgContactEntity;
+import com.qnfhq.modules.c2c.entity.C2cMsgContentEntity;
+import com.qnfhq.modules.c2c.service.C2cMsgContactService;
+import com.qnfhq.modules.user.entity.AppUserEntity;
+import com.qnfhq.modules.user.service.AppUserService;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+import java.util.Date;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 最近联系人
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@Service
+public class C2cMsgContactServiceImpl extends BaseServiceImpl<C2cMsgContactDao, C2cMsgContactEntity> implements C2cMsgContactService {
+
+    @Resource
+    private AppUserService appUserService;
+
+
+    @Override
+    public PageData<C2cMsgContactEntity> selectContactPage(Map<String, Object> params) {
+        Long ownerUid = (Long)params.get("ownerUid");
+
+        LambdaQueryWrapper<C2cMsgContactEntity> wrapper = new LambdaQueryWrapper<C2cMsgContactEntity>()
+                .eq(Objects.nonNull(ownerUid),C2cMsgContactEntity::getOwnerUid, ownerUid);
+
+        IPage<C2cMsgContactEntity> page = baseDao.selectPage(
+                getPage(params, (String)params.get(Constant.ORDER_FIELD), "asc".equals(params.get(Constant.ORDER)) ? true : false),
+                wrapper
+        );
+        return getPageData(page, C2cMsgContactEntity.class);
+    }
+
+    @Override
+    public C2cMsgContactEntity selectByOwnerUidOtherUid(Long ownerUid, Long otherUid) {
+        LambdaQueryWrapper<C2cMsgContactEntity> wrapper = new LambdaQueryWrapper<C2cMsgContactEntity>()
+                .eq(Objects.nonNull(ownerUid),C2cMsgContactEntity::getOwnerUid, ownerUid)
+                .eq(Objects.nonNull(otherUid),C2cMsgContactEntity::getOtherUid, otherUid);
+        return baseDao.selectOne(wrapper);
+    }
+
+    private void updateByOwnerUidOtherUid(C2cMsgContactEntity contactEntity) throws Exception{
+        baseDao.update(contactEntity, new LambdaQueryWrapper<C2cMsgContactEntity>()
+                .eq(Objects.nonNull(contactEntity.getOwnerUid()),C2cMsgContactEntity::getOwnerUid, contactEntity.getOwnerUid())
+                .eq(Objects.nonNull(contactEntity.getOtherUid()),C2cMsgContactEntity::getOtherUid, contactEntity.getOtherUid()));
+    }
+
+
+    @Override
+    public void saveByMsgContact(C2cMsgContentEntity msgEntity) throws Exception{
+        AppUserEntity receiptUser = appUserService.getById(msgEntity.getRecipientId());
+        AppUserEntity senderUser = appUserService.getById(msgEntity.getSenderId());
+        // 更新发件人的最近联系人
+        C2cMsgContactEntity senderContact = selectByOwnerUidOtherUid(msgEntity.getSenderId(), msgEntity.getRecipientId());
+        if(senderContact!=null) {
+            senderContact.setMid(msgEntity.getMid());
+            senderContact.setMsgType(msgEntity.getMsgType());
+            senderContact.setCreateTime(new Date());
+            updateByOwnerUidOtherUid(senderContact);
+        } else {
+            senderContact = new C2cMsgContactEntity();
+            senderContact.setOwnerUid(msgEntity.getSenderId());
+            senderContact.setOtherUid(msgEntity.getRecipientId());
+            senderContact.setOtherNickname(receiptUser.getNickname());
+            senderContact.setOtherAvatar(receiptUser.getAvatar());
+            senderContact.setMid(msgEntity.getMid());
+            senderContact.setMsgType(msgEntity.getMsgType());
+            senderContact.setCreateTime(new Date());
+            insert(senderContact);
+        }
+
+        // 更新收件人的最近联系人
+        C2cMsgContactEntity receipterContact = selectByOwnerUidOtherUid(msgEntity.getRecipientId(),msgEntity.getSenderId());
+        if(receipterContact!=null) {
+            receipterContact.setMid(msgEntity.getMid());
+            receipterContact.setMsgType(msgEntity.getMsgType());
+            receipterContact.setCreateTime(new Date());
+            updateByOwnerUidOtherUid(receipterContact);
+        } else {
+            receipterContact = new C2cMsgContactEntity();
+            receipterContact.setOwnerUid(msgEntity.getRecipientId());
+            receipterContact.setOtherUid(msgEntity.getSenderId());
+            receipterContact.setOtherNickname(senderUser.getNickname());
+            receipterContact.setOtherAvatar(senderUser.getAvatar());
+            receipterContact.setMid(msgEntity.getMid());
+            receipterContact.setMsgType(msgEntity.getMsgType());
+            receipterContact.setCreateTime(new Date());
+            insert(receipterContact);
+        }
+    }
+}

+ 62 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cMsgContentServiceImpl.java

@@ -0,0 +1,62 @@
+package com.qnfhq.modules.c2c.service.impl;
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qnfhq.common.redis.RedisUtils;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.constant.CacheConstants;
+import com.qnfhq.modules.c2c.dao.C2cMsgContentDao;
+import com.qnfhq.modules.c2c.dto.C2cMsgContentDTO;
+import com.qnfhq.modules.c2c.entity.C2cMsgContentEntity;
+import com.qnfhq.modules.c2c.enums.MsgStatusEnum;
+import com.qnfhq.modules.c2c.service.C2cMsgContactService;
+import com.qnfhq.modules.c2c.service.C2cMsgContentService;
+import com.qnfhq.modules.c2c.service.C2cMsgRelationService;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import java.util.Date;
+
+/**
+ * 聊天消息表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@Service
+public class C2cMsgContentServiceImpl extends ServiceImpl<C2cMsgContentDao, C2cMsgContentEntity> implements C2cMsgContentService {
+
+    @Resource
+    private C2cMsgRelationService c2cMsgRelationService;
+    @Resource
+    private C2cMsgContactService c2cMsgContactService;
+    @Resource
+    private RedisUtils redisUtils;
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result saveMsg(C2cMsgContentDTO dto) throws Exception{
+        C2cMsgContentEntity msgEntity = new C2cMsgContentEntity();
+        msgEntity.setSenderId(StpUtil.getLoginIdAsLong());
+        msgEntity.setRecipientId(dto.getRecipientId());
+        msgEntity.setContent(dto.getContent());
+        msgEntity.setMsgType(dto.getMsgType().toLowerCase());
+        msgEntity.setStatus(MsgStatusEnum.SEND.getCode());
+        msgEntity.setSendTime(new Date());
+        if(save(msgEntity)) {
+            // 保存消息关系
+            c2cMsgRelationService.saveMsgRelation(msgEntity);
+
+            // 保存最近联系人
+            c2cMsgContactService.saveByMsgContact(msgEntity);
+
+            //总未读数更新 2001534_UNREAD_T
+            redisUtils.increment(CacheConstants.getTotalUnreadKey(msgEntity.getRecipientId()), 1L,-1L);
+            //聊天用户未读数更新
+            redisUtils.increment(CacheConstants.getChatUnreadKey(msgEntity.getRecipientId()), msgEntity.getSenderId().toString(), 1L, -1L);
+        }
+        return new Result().ok(msgEntity);
+    }
+
+}

+ 64 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cMsgRelationServiceImpl.java

@@ -0,0 +1,64 @@
+package com.qnfhq.modules.c2c.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.qnfhq.common.constant.Constant;
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.service.impl.BaseServiceImpl;
+import com.qnfhq.modules.c2c.dao.C2cMsgRelationDao;
+import com.qnfhq.modules.c2c.entity.C2cMsgContentEntity;
+import com.qnfhq.modules.c2c.entity.C2cMsgRelationEntity;
+import com.qnfhq.modules.c2c.enums.MsgRelationEnum;
+import com.qnfhq.modules.c2c.service.C2cMsgRelationService;
+import org.springframework.stereotype.Service;
+import java.util.*;
+
+/**
+ * 用户消息关联表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-25
+ */
+@Service
+public class C2cMsgRelationServiceImpl extends BaseServiceImpl<C2cMsgRelationDao, C2cMsgRelationEntity> implements C2cMsgRelationService {
+
+
+    @Override
+    public PageData<C2cMsgRelationEntity> selectChatPage(Map<String, Object> params) {
+        Long ownerUid = (Long)params.get("ownerUid");
+        Long otherUid = (Long)params.get("otherUid");
+        Long mid = (Long)params.get("mid");
+
+        LambdaQueryWrapper<C2cMsgRelationEntity> wrapper = new LambdaQueryWrapper<C2cMsgRelationEntity>()
+                .eq(Objects.nonNull(ownerUid),C2cMsgRelationEntity::getOwnerUid, ownerUid)
+                .eq(Objects.nonNull(otherUid),C2cMsgRelationEntity::getOtherUid, otherUid)
+                .gt(Objects.nonNull(mid),C2cMsgRelationEntity::getMid,mid);
+
+        IPage<C2cMsgRelationEntity> page = baseDao.selectPage(
+                getPage(params, (String)params.get(Constant.ORDER_FIELD), "asc".equals(params.get(Constant.ORDER)) ? true : false),
+                wrapper
+        );
+        return getPageData(page, C2cMsgRelationEntity.class);
+    }
+
+    @Override
+    public void saveMsgRelation(C2cMsgContentEntity msgEntity) throws Exception{
+        /**存发件人的发件箱*/
+        C2cMsgRelationEntity messageRelationSender = new C2cMsgRelationEntity();
+        messageRelationSender.setMid(msgEntity.getMid());
+        messageRelationSender.setOwnerUid(msgEntity.getSenderId());
+        messageRelationSender.setOtherUid(msgEntity.getRecipientId());
+        messageRelationSender.setType(MsgRelationEnum.SEND_BOX.getCode());
+        messageRelationSender.setCreateTime(new Date());
+        insert(messageRelationSender);
+
+        /**存收件人的收件箱*/
+        C2cMsgRelationEntity messageRelationRecipient = new C2cMsgRelationEntity();
+        messageRelationRecipient.setMid(msgEntity.getMid());
+        messageRelationRecipient.setOwnerUid(msgEntity.getRecipientId());
+        messageRelationRecipient.setOtherUid(msgEntity.getSenderId());
+        messageRelationRecipient.setType(MsgRelationEnum.RECEIVE_BOX.getCode());
+        messageRelationRecipient.setCreateTime(new Date());
+        insert(messageRelationRecipient);
+    }
+}

+ 0 - 13
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cOrderComplainVoucherServiceImpl.java

@@ -2,16 +2,12 @@ package com.qnfhq.modules.c2c.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.qnfhq.common.service.impl.CrudServiceImpl;
 import com.qnfhq.modules.c2c.dao.C2cOrderComplainVoucherDao;
-import com.qnfhq.modules.c2c.dto.C2cOrderComplainVoucherDTO;
 import com.qnfhq.modules.c2c.entity.C2cOrderComplainVoucherEntity;
 import com.qnfhq.modules.c2c.service.C2cOrderComplainVoucherService;
-import cn.hutool.core.util.StrUtil;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
-import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -23,15 +19,6 @@ import java.util.Objects;
 @Service
 public class C2cOrderComplainVoucherServiceImpl extends ServiceImpl<C2cOrderComplainVoucherDao, C2cOrderComplainVoucherEntity> implements C2cOrderComplainVoucherService {
 
-//    @Override
-//    public QueryWrapper<C2cOrderComplainVoucherEntity> getWrapper(Map<String, Object> params){
-//        String id = (String)params.get("id");
-//
-//        QueryWrapper<C2cOrderComplainVoucherEntity> wrapper = new QueryWrapper<>();
-//        wrapper.eq(StrUtil.isNotBlank(id), "id", id);
-//
-//        return wrapper;
-//    }
 
     @Override
     public List<C2cOrderComplainVoucherEntity> selectList(Long complainId) {

+ 31 - 59
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cOrderServiceImpl.java

@@ -6,19 +6,15 @@ import cn.hutool.core.map.MapUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.qnfhq.common.constant.Constant;
 import com.qnfhq.common.page.PageData;
 import com.qnfhq.common.redis.RedisUtils;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.qnfhq.common.service.impl.CrudServiceImpl;
+import com.qnfhq.common.service.impl.BaseServiceImpl;
 import com.qnfhq.common.utils.DateUtils;
 import com.qnfhq.common.utils.MessageUtils;
 import com.qnfhq.common.utils.Result;
 import com.qnfhq.constant.CacheConstants;
 import com.qnfhq.modules.c2c.dao.C2cOrderDao;
 import com.qnfhq.modules.c2c.dto.C2cOrderCreateDTO;
-import com.qnfhq.modules.c2c.dto.C2cOrderDTO;
-import com.qnfhq.modules.c2c.dto.C2cOrderLogDTO;
 import com.qnfhq.modules.c2c.entity.*;
 import com.qnfhq.modules.c2c.enums.*;
 import com.qnfhq.modules.c2c.service.*;
@@ -33,14 +29,11 @@ import com.qnfhq.modules.user.service.AppWalletRecordService;
 import com.qnfhq.utils.OrderUtils;
 import com.qnfhq.utils.RandomNumberGenerator;
 import jakarta.annotation.Resource;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.util.*;
-import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 /**
@@ -50,7 +43,7 @@ import java.util.stream.Collectors;
  * @since 1.0.0 2025-11-17
  */
 @Service
-public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity> implements C2cOrderService {
+public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEntity> implements C2cOrderService {
     @Resource
     private RedisUtils redisUtils;
 
@@ -85,15 +78,15 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
     private C2cOrderDao c2cOrderDao;
 
 
-//    @Override
-//    public PageData<C2cOrderEntity> page(Map<String, Object> params) {
-//        IPage<C2cOrderEntity> page = baseDao.selectPage(
-//                getPage(params, "id", false),
-//                getWrapper(params)
-//        );
-//
-//        return getPageData(page, C2cOrderEntity.class);
-//    }
+    @Override
+    public PageData<C2cOrderEntity> page(Map<String, Object> params) {
+        IPage<C2cOrderEntity> page = baseDao.selectPage(
+                getPage(params, "id", false),
+                getWrapper(params)
+        );
+
+        return getPageData(page, C2cOrderEntity.class);
+    }
 
 
     public QueryWrapper<C2cOrderEntity> getWrapper(Map<String, Object> params){
@@ -129,16 +122,6 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
     }
 
 
-//    @Override
-//    public QueryWrapper<C2cOrderEntity> getWrapper(Map<String, Object> params){
-//        String id = (String)params.get("id");
-//
-//        QueryWrapper<C2cOrderEntity> wrapper = new QueryWrapper<>();
-//        wrapper.eq(StrUtil.isNotBlank(id), "id", id);
-//
-//        return wrapper;
-//    }
-
     @Override
     public String getC2cOrderKeyByUid(String uid) {
         return new StringBuilder("c2c_order_uid:").append(uid).toString();
@@ -146,10 +129,9 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
 
     @Override
     public C2cOrderEntity getTradingByAdId(long adId) {
-        return getOne(new LambdaQueryWrapper<C2cOrderEntity>()
+        return baseDao.selectOne(new LambdaQueryWrapper<C2cOrderEntity>()
                 .eq(C2cOrderEntity::getC2cAdId, adId)
                 .eq(C2cOrderEntity::getFlow, 0)
-                .last(" limit 1")
         );
     }
 
@@ -159,7 +141,7 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
     public C2cOrderEntity selectOrder(Long id) {
         C2cOrderEntity order = selectOrderFromRedis(id);
         if(order == null) {
-            order = getById(id);
+            order = selectById(id);
             if(order == null) {
                 return null;
             }
@@ -200,7 +182,7 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
         order.setStatus(Convert.toInt(odMap.get("status")));
         order.setCreateTime(DateUtils.strForDate(Convert.toStr(odMap.get("createTime"))));
         order.setUpdateTime(DateUtils.strForDate(Convert.toStr(odMap.get("updateTime"))));
-        order.setEndTime(DateUtils.strForDate(Convert.toStr(odMap.get("endTime"))));
+        order.setPayExpireTime(DateUtils.strForDate(Convert.toStr(odMap.get("payExpireTime"))));
         return order;
     }
 
@@ -226,10 +208,8 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
         odMap.put("status", c2cOrder.getStatus());
         odMap.put("createTime", DateUtils.format(c2cOrder.getCreateTime(),DateUtils.DATE_TIME_PATTERN));
         odMap.put("updateTime", DateUtils.format(c2cOrder.getUpdateTime(),DateUtils.DATE_TIME_PATTERN));
-        odMap.put("endTime", DateUtils.format(c2cOrder.getEndTime(),DateUtils.DATE_TIME_PATTERN));
-        Random random = new Random();
-        long randomSecond = random.nextLong(3600L)+3600L; // 生成1到2小时的随机数
-        redisUtils.hMSet(odHKey, odMap, randomSecond);
+        odMap.put("payExpireTime", DateUtils.format(c2cOrder.getPayExpireTime(),DateUtils.DATE_TIME_PATTERN));
+        redisUtils.hMSet(odHKey, odMap, RandomNumberGenerator.getRandomNumber(3600,3*3600));
     }
     private void setOrderUserIdCache(C2cOrderEntity c2cOrder) {
         //c2c_order_uid:1
@@ -267,7 +247,7 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public Result createC2cOrder(C2cOrderCreateDTO c2cOrderDTO, C2cAdEntity c2cAd, BigDecimal symbolNum,
+    public Result createC2cOrder(C2cOrderCreateDTO c2cOrderDTO, C2cAdEntity c2cAd, BigDecimal legalCoinAmount, BigDecimal symbolNum,
                                  Long loginUserId, String realName) throws Exception {
         /** 1买入  2 卖出 */
         Integer direction = c2cOrderDTO.getDirection();
@@ -275,14 +255,10 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
         String symbol = c2cOrderDTO.getSymbol().toLowerCase();
         /** 法定货币 */
         String legalCoin = c2cOrderDTO.getLegalCoin().toLowerCase();
-        /** 交易金额 */
-        BigDecimal tranAmount = c2cOrderDTO.getTranAmount();
         /** 广告编号 */
         Long c2cAdId = c2cOrderDTO.getC2cAdId();
         /** 支付方式 */
         Integer payType = c2cOrderDTO.getPayType();
-
-
         String adUserName = c2cAd.getUserName();
         BigDecimal price = c2cAd.getPrice();
         Long tranUserId = c2cAd.getUserId();
@@ -299,13 +275,12 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
         c2cOrder.setTranUserName(adUserName);
         c2cOrder.setTranPrice(price);
         c2cOrder.setSymbolNum(symbolNum);
-        c2cOrder.setTranAmount(tranAmount);
+        c2cOrder.setTranAmount(legalCoinAmount);
         c2cOrder.setPayType(payType);
         c2cOrder.setFlow(C2cOrderFlowEnum.PROGRESS.getCode());
         c2cOrder.setStatus(C2cOrderStatusEnum.CREATE.getCode());
         c2cOrder.setCreateTime(new Date());
         c2cOrder.setUpdateTime(new Date());
-        c2cOrder.setEndTime(DateUtils.getNowDateAddMins(CacheConstants.C2C_ORDER_EXPIRE_MIN));
 
         String adHKey = CacheConstants.getC2cAdHKey(c2cAd.getId().toString());
         if(c2cOrderDao.insertC2cOrder(c2cOrder)<=0) {
@@ -331,12 +306,11 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
         // 更新广告的可用数量
         BigDecimal newMaxAmount = null;
         Integer newStatus = null;
-        BigDecimal avaiAmount = c2cAd.getAvailableNum().subtract(symbolNum).multiply(price);
-        if(c2cAd.getMaxAmount().compareTo(avaiAmount)==1) {
-            newMaxAmount = avaiAmount;
-            redisUtils.hSet(adHKey, "maxAmount", newMaxAmount);
+        BigDecimal maxAvail = c2cAd.getAvailableNum().subtract(symbolNum).multiply(price);
+        if(c2cAd.getMaxAmount().compareTo(maxAvail)==1) {
+            newMaxAmount = maxAvail;
         }
-        if(avaiAmount.compareTo(c2cAd.getMinAmount())==-1) {
+        if(maxAvail.compareTo(c2cAd.getMinAmount())==-1) {
             newStatus = AdStatusEnum.NOPASS.getCode();
             c2cAdService.deleteC2cAdCache(c2cAd);
         }
@@ -353,10 +327,7 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
         setOrderCache(c2cOrder);
         setOrderUserIdCache(c2cOrder);
 
-        if(c2cOrder.getDirection().intValue() == DirectionEnum.BUY.getCode().intValue()) {
-            //用户待支付数+1
-//                unpayCountsKey = StringUtils.format(CacheConstants.C2C_UNPAY_COUNTS, c2cOrder.getUserId());
-        } else {
+        if(c2cOrder.getDirection().intValue() == DirectionEnum.SELL.getCode().intValue()) {
             //如果是卖出,商家待支付数统计
             String unpayCountsKey = CacheConstants.getC2cMertUnPayKey(c2cOrder.getTranUserId().toString());
             redisUtils.increment(unpayCountsKey, 1L, RedisUtils.NOT_EXPIRE);
@@ -393,7 +364,7 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
     @Override
     public int cancelC2cOrderRedis(int oldStatus,C2cOrderEntity order) {
         //redis广告可用数量恢复
-        C2cAdEntity c2cAd = c2cAdService.getById(order.getC2cAdId());
+        C2cAdEntity c2cAd = c2cAdService.selectById(order.getC2cAdId());
         c2cAdService.deleteAdCache(c2cAd.getId(),c2cAd.getPayway().replaceAll("^,|,$", ""),c2cAd.getLegalCoin(),c2cAd.getSymbol(),c2cAd.getDirection());
         c2cAdService.setAdCache(c2cAd);
         deleteOrderCache(order);
@@ -459,7 +430,7 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
         order.setFlow(C2cOrderFlowEnum.END.getCode());
         order.setStatus(C2cOrderStatusEnum.CANCEL.getCode());
         order.setUpdateTime(new Date());
-        order.setEndTime(new Date());
+        order.setCloseTime(new Date());
         if(!updateById(order)) {
             throw new Exception(MessageUtils.message("c2c.order.update.fail"));//更新订单失败
         }
@@ -472,10 +443,10 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
             appAssetLogService.insertAssetLog(order.getId(),order.getUserId(),order.getSymbol(),AssetEnum.PLATFORM_ASSETS.getCode(),
                     info.getTotal(),info.getTotal(),
                     info.getAvailable(),info.getAvailable().add(order.getSymbolNum()),
-                    info.getFrozen(),info.getFrozen().subtract(order.getSymbolNum()),"用户卖出订单取消解冻资产");
+                    info.getFrozen(),info.getFrozen().subtract(order.getSymbolNum()),"c2c订单取消解冻资产");
         }
         //广告可用数量恢复
-        C2cAdEntity c2cAd = c2cAdService.getById(order.getC2cAdId());
+        C2cAdEntity c2cAd = c2cAdService.selectById(order.getC2cAdId());
         BigDecimal maxAmount = null;
         if(order.getTranAmount().compareTo(c2cAd.getMaxAmount())==1) {
             maxAmount = order.getTranAmount();
@@ -485,7 +456,7 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
         }
         c2cAdLogService.insertC2cAdLog(order.getC2cAdId(),order.getId(),order.getSymbolNum(),
                 c2cAd.getAvailableNum(),c2cAd.getAvailableNum().add(order.getSymbolNum()),
-                c2cAd.getMaxAmount(),c2cAd.getMaxAmount(),"用户取消订单恢复广告可用数量");
+                c2cAd.getMaxAmount(),c2cAd.getMaxAmount(),"c2c订单取消,恢复广告可用数量");
         return 1;
     }
 
@@ -532,13 +503,14 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
                 order.getRemark(),loginId,"app");
 
         order.setStatus(C2cOrderStatusEnum.PAY.getCode());
+        order.setPayTime(new Date());
         if(!updateById(order)) {
             throw new Exception(MessageUtils.message("c2c.order.update.fail"));//更新订单失败
         }
         //设置订单状态
         setOrderStatusCache(order);
 
-        //用户买入,用户未支付数减1 商家放币订单数+1
+        //用户买入,用户未支付数减1 商家放币订单数+1
         if(order.getDirection().intValue() == DirectionEnum.BUY.getCode().intValue()) {
             String releaseCountsKey = CacheConstants.getC2cMertUnReleaseKey(sellUserId.toString());
             redisUtils.increment(releaseCountsKey, 1L, RedisUtils.NOT_EXPIRE);
@@ -620,7 +592,7 @@ public class C2cOrderServiceImpl extends ServiceImpl<C2cOrderDao, C2cOrderEntity
         order.setFlow(C2cOrderFlowEnum.END.getCode());
         order.setStatus(C2cOrderStatusEnum.COMPLETE.getCode());
         order.setUpdateTime(new Date());
-        order.setEndTime(new Date());
+        order.setFinishTime(new Date());
         //1 更新订单状态已完成
         if(!updateById(order)) {
             throw new Exception(MessageUtils.message("c2c.order.update.fail"));//更新订单失败

+ 14 - 54
qnfhq-api/src/main/java/com/qnfhq/modules/user/controller/ApiAppUserController.java

@@ -1,11 +1,7 @@
 package com.qnfhq.modules.user.controller;
 
 import cn.dev33.satoken.stp.StpUtil;
-import cn.hutool.core.lang.Validator;
-import cn.hutool.core.map.MapUtil;
-import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.qnfhq.common.exception.ErrorCode;
-import com.qnfhq.common.exception.RenException;
 import com.qnfhq.common.utils.MessageUtils;
 import com.qnfhq.common.utils.Result;
 import com.qnfhq.common.validator.AssertUtils;
@@ -80,7 +76,7 @@ public class ApiAppUserController {
         if(StpUtil.isLogin()) {
             Long userId = StpUtil.getLoginIdAsLong();
             logger.info("userId = {}", userId);
-            AppUserEntity user = appUserService.getUserByUserId(userId);
+            AppUserEntity user = appUserService.getById(userId);
 
             result.setMsg("success");
             result.setData(user);
@@ -98,8 +94,8 @@ public class ApiAppUserController {
         if(StpUtil.isLogin()) {
             Long userId = StpUtil.getLoginIdAsLong();
             StpUtil.logout(userId);
-            AppUserEntity one = appUserService.getUserByUserId(userId);
-            appuserLoginLogService.insertAppActionLog(one, "用户退出", "0", request);
+            AppUserEntity user = appUserService.getById(userId);
+            appuserLoginLogService.insertAppActionLog(user, "用户退出", "0", request);
         }
         return new Result();
     }
@@ -112,7 +108,7 @@ public class ApiAppUserController {
 
         ValidatorUtils.validateEntity(sendCodeDTO);
 
-        return appUserService.sendEmailCode(sendCodeDTO.getCodeType(),sendCodeDTO.getEmail());
+        return appUserService.sendEmailCode(sendCodeDTO.getUuid(),sendCodeDTO.getCodeType(),sendCodeDTO.getEmail());
 
     }
 
@@ -121,52 +117,7 @@ public class ApiAppUserController {
     @PostMapping("/sendMobileCode")
     public Result sendMobileCode (@RequestBody SendPhoneCodeDTO codeDTO){
         ValidatorUtils.validateEntity(codeDTO);
-        return appUserService.sendMobileCode(codeDTO.getCodeType(),codeDTO.getPhone(),codeDTO.getZone());
-    }
-
-
-    @GetMapping("/captcha")
-    @Operation(summary = "获取图形验证码")
-    @Parameter(in = ParameterIn.QUERY, ref = "string", name = "uuid", required = true)
-    public void captcha(HttpServletResponse response, String uuid) throws IOException {
-        //唯一标识不能为空
-        AssertUtils.isBlank(uuid, ErrorCode.IDENTIFIER_NOT_NULL);
-        //生成验证码
-        captchaService.create(response, uuid);
-    }
-
-
-
-
-    /**
-     * 重置登陆密码 old
-     *
-     * @return
-     */
-//    @PostMapping("/resetPwdByEmail")
-//    public Result resetPwdByEmail (@RequestBody ResetPwdByEmailDTO codeDTO){
-//        ValidatorUtils.validateEntity(codeDTO);
-//        return appUserService.resetPwdByEmail(codeDTO);
-//    }
-
-    /**
-     * 重置登陆密码 old
-     *
-     * @return
-     */
-//    @PostMapping("/resetPwdByPhone")
-//    public Result resetPwdByPhone (@RequestBody ResetPwdByPhoneDTO codeDTO){
-//        ValidatorUtils.validateEntity(codeDTO);
-//
-//        return appUserService.resetPwdByPhone(codeDTO);
-//    }
-
-
-    @PostMapping("/checkCaptcha")
-    @Operation(summary = "验证图形验证码")
-    public Result checkCaptcha(@RequestBody CheckCaptchaDTO dto, HttpServletRequest request) {
-        ValidatorUtils.validateEntity(dto);
-        return appUserService.checkCaptcha(dto,request);
+        return appUserService.sendMobileCode(codeDTO.getUuid(),codeDTO.getCodeType(),codeDTO.getPhone(),codeDTO.getZone());
     }
 
 
@@ -200,4 +151,13 @@ public class ApiAppUserController {
         ValidatorUtils.validateEntity(dto);
         return appUserService.resetPwdByPhone(dto.getZone(),dto.getPhone(),dto.getNewPwd());
     }
+
+
+    @Operation(summary = "阿里云智能验证码")
+    @PostMapping("/verifyIntelligentCaptcha")
+    public Result verifyIntelligentCaptcha (@RequestBody VerifyIntelligentCaptchaDTO dto){
+        ValidatorUtils.validateEntity(dto);
+        return appUserService.verifyIntelligentCaptcha(dto.getVerifyParam());
+    }
+
 }

+ 7 - 1
qnfhq-api/src/main/java/com/qnfhq/modules/user/dao/AppAssetDao.java

@@ -4,7 +4,10 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.qnfhq.modules.user.entity.AppAssetEntity;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.web.bind.annotation.RequestParam;
 
+import java.math.BigDecimal;
 import java.util.Map;
 
 /**
@@ -43,4 +46,7 @@ public interface AppAssetDao extends BaseMapper<AppAssetEntity> {
      * @return
      */
     int releaseAssetByUserId(Map<String, Object> params);
-}
+
+
+
+ }

+ 3 - 1
qnfhq-api/src/main/java/com/qnfhq/modules/user/dto/SendEmailCodeDTO.java

@@ -18,5 +18,7 @@ public class SendEmailCodeDTO {
     @NotBlank(message="{NotBlank.email}")//邮箱不能为空
     private String email;
 
-
+    @Schema(title = "唯一标识")
+    @NotBlank(message="{NotBlank.uuid}")//唯一标识不能为空
+    private String uuid;
 }

+ 3 - 1
qnfhq-api/src/main/java/com/qnfhq/modules/user/dto/SendPhoneCodeDTO.java

@@ -20,5 +20,7 @@ public class SendPhoneCodeDTO {
     @NotBlank(message="{NotBlank.zone}")//区号不能为空
     private String zone;
 
-
+    @Schema(title = "唯一标识")
+    @NotBlank(message="{NotBlank.uuid}")//唯一标识不能为空
+    private String uuid;
 }

+ 17 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/user/dto/VerifyIntelligentCaptchaDTO.java

@@ -0,0 +1,17 @@
+package com.qnfhq.modules.user.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+
+@Data
+@Schema(title = "阿里云智能验证码表单")
+public class VerifyIntelligentCaptchaDTO {
+
+    @Schema(title = "验证码参数")
+    @NotBlank(message="{NotBlank.verifyParam}")//验证码参数不能为空
+    private String verifyParam;
+
+
+}

+ 17 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/user/dto/setting/CaptchaSetting.java

@@ -0,0 +1,17 @@
+package com.qnfhq.modules.user.dto.setting;
+
+import lombok.Data;
+
+/**
+ * 验证码配置
+ */
+@Data
+public class CaptchaSetting {
+
+
+    private String accessKeyId;
+    private String accessKeySecret;
+    private String sceneId;
+    private String endpoint;//"captcha.cn-shanghai.aliyuncs.com"
+
+}

+ 1 - 1
qnfhq-api/src/main/java/com/qnfhq/modules/user/entity/AppUserDetailEntity.java

@@ -89,7 +89,7 @@ public class AppUserDetailEntity implements Serializable {
     /**
      * 交易是否被限制 1 为限制
      */
-	private String tradeFlag;
+	private Integer tradeFlag;
     /**
      * 金额是否被限制 1 为限制
      */

+ 10 - 4
qnfhq-api/src/main/java/com/qnfhq/modules/user/enums/RecordEnum.java

@@ -50,6 +50,15 @@ public enum RecordEnum {
     FINANCIAL_REDEMPTION(55, "理财赎回"),
     C2C_TRAN_BUY(56, "C2C交易买入+平台资产"),
     C2C_TRAN_SELL(57, "C2C交易卖出-平台资产"),
+    EARN_COIN_BUY(58, "赚币交易买入+平台资产"),
+    EARN_COIN_SELL(59, "赚币交易赎回+平台资产"),
+    EARN_COIN_SETTLE(63, "赚币交易结算+平台资产"),
+
+    PLEDGE_RECHARGE(60, "质押认购"),
+
+    PLEDGE_Profit(61, "质押收益"),
+
+    PLEDGE_Profit_SETTLE(62, "质押结算"),
     ;
     private final Integer code;
     private final String desc;
@@ -77,8 +86,5 @@ public enum RecordEnum {
 
     }
 
-    public static void main(String[] args) {
-        LinkedHashMap<Integer, String> map = getMap();
-        System.out.println(map);
-    }
+
 }

+ 2 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/user/enums/SettingEnum.java

@@ -99,5 +99,7 @@ public enum SettingEnum {
     REFUSE_SUBMIT,
     //广告配置
     AD_SETTING,
+    //验证码配置
+    CAPTCHA_SETTING,
     ;
 }

+ 3 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/user/service/AppUserDetailService.java

@@ -12,4 +12,7 @@ import com.qnfhq.modules.user.entity.AppUserDetailEntity;
 public interface AppUserDetailService extends IService<AppUserDetailEntity> {
 
     AppUserDetailEntity selectAppUserDetailByUserId(long userId);
+
+    AppUserDetailEntity selectUserDetailByUserId(Long userId);
+
 }

+ 40 - 12
qnfhq-api/src/main/java/com/qnfhq/modules/user/service/AppUserService.java

@@ -18,8 +18,6 @@ public interface AppUserService extends IService<AppUserEntity> {
 
     AppUserEntity getUserByMobile(String mobile,String zone);
 
-    AppUserEntity getUserByUserId(Long userId);
-
     AppUserEntity getUserByActiveCode(String activeCode);
 
 
@@ -57,7 +55,7 @@ public interface AppUserService extends IService<AppUserEntity> {
      * @param email 邮箱
      * @return
      */
-    public Result sendEmailCode(String codeType, String email);
+    public Result sendEmailCode(String uuid,String codeType, String email);
 
     /**
      * 手机发送验证码
@@ -66,19 +64,49 @@ public interface AppUserService extends IService<AppUserEntity> {
      * @param zone 区号
      * @return
      */
-    public Result sendMobileCode(String codeType,String phone,String zone);
-
-
-
-    Result resetPwdByEmail(ResetPwdByEmailDTO codeDTO);
-    Result resetPwdByPhone(ResetPwdByPhoneDTO codeDTO);
-
-
-    Result checkCaptcha(CheckCaptchaDTO dto, HttpServletRequest request);
+    public Result sendMobileCode(String uuid,String codeType,String phone,String zone);
 
+    /**
+     * 验证码校验
+     * @param codeType
+     * @param zone
+     * @param phone
+     * @param code
+     * @return
+     */
     Result checkPhoneCode(String codeType,String zone,String phone,String code);
 
+    /**
+     * 验证码校验
+     * @param codeType
+     * @param email
+     * @param code
+     * @return
+     */
     Result checkEmailCode(String codeType,String email,String code);
+
+    /**
+     * 重置密码
+     * @param email
+     * @param pwd
+     * @return
+     */
     Result resetPwdByEmail(String email,String pwd);
+
+    /**
+     * 重置密码
+     * @param zone
+     * @param phone
+     * @param pwd
+     * @return
+     */
     Result resetPwdByPhone(String zone,String phone,String pwd);
+
+    /**
+     * 阿里智能验证码
+     * @return
+     */
+    Result verifyIntelligentCaptcha(String verifyParam);
+
+    AppUserEntity getUserByUserId(Long userId);
 }

+ 3 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/user/service/SettingService.java

@@ -1,5 +1,6 @@
 package com.qnfhq.modules.user.service;
 
+import cn.hutool.setting.Setting;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qnfhq.modules.user.entity.SettingEntity;
 
@@ -11,4 +12,6 @@ import com.qnfhq.modules.user.entity.SettingEntity;
  */
 public interface SettingService extends IService<SettingEntity> {
     SettingEntity getSetting(String id);
+
+
 }

+ 5 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/user/service/impl/AppUserDetailServiceImpl.java

@@ -39,5 +39,10 @@ public class AppUserDetailServiceImpl extends ServiceImpl<AppUserDetailDao, AppU
         );
     }
 
+    @Override
+    public AppUserDetailEntity selectUserDetailByUserId(Long userId) {
+        return  getOne(new LambdaQueryWrapper<AppUserDetailEntity>().eq(AppUserDetailEntity::getUserId, userId));
+    }
+
 
 }

+ 79 - 94
qnfhq-api/src/main/java/com/qnfhq/modules/user/service/impl/AppUserServiceImpl.java

@@ -5,8 +5,11 @@ import cn.hutool.core.lang.Validator;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
+import com.aliyun.captcha20230305.models.VerifyIntelligentCaptchaResponse;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.qnfhq.aliyun.CaptchaConfig;
+import com.qnfhq.common.exception.ErrorCode;
 import com.qnfhq.common.exception.RenException;
 import com.qnfhq.common.redis.RedisUtils;
 import com.qnfhq.common.utils.DateUtils;
@@ -15,8 +18,10 @@ import com.qnfhq.common.utils.MessageUtils;
 import com.qnfhq.common.utils.Result;
 import com.qnfhq.constant.ApiConstant;
 import com.qnfhq.modules.user.dao.AppUserDao;
+import com.qnfhq.modules.user.dao.AppUserDetailDao;
 import com.qnfhq.modules.user.dto.*;
 import com.qnfhq.modules.user.dto.setting.AssetSymbolSetting;
+import com.qnfhq.modules.user.dto.setting.CaptchaSetting;
 import com.qnfhq.modules.user.entity.AppAssetEntity;
 import com.qnfhq.modules.user.entity.AppUserDetailEntity;
 import com.qnfhq.modules.user.entity.AppUserEntity;
@@ -34,11 +39,9 @@ import jakarta.servlet.http.HttpServletRequest;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
-
 import lombok.AllArgsConstructor;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
@@ -72,15 +75,11 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
     @Resource
     private SmsSendService smsSendService;
 
-    @Resource
-    private CaptchaService captchaService;
-
     @Override
     public AppUserEntity getUserByEmail(String email) {
         return getOne(new LambdaQueryWrapper<AppUserEntity>()
                 .eq(AppUserEntity::getEmail, email)
                 .eq(AppUserEntity::getStatus, UserStatus.OK.getCode())
-                .last(" limit 1")
         );
     }
 
@@ -90,21 +89,15 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
                 .eq(AppUserEntity::getPhone, mobile)
                 .eq(AppUserEntity::getZone, zone)
                 .eq(AppUserEntity::getStatus, UserStatus.OK.getCode())
-                .last(" limit 1")
         );
     }
 
-    @Override
-    public AppUserEntity getUserByUserId(Long userId) {
-        return getById(userId);
-    }
 
     @Override
     public AppUserEntity getUserByActiveCode(String activeCode) {
         return getOne(new LambdaQueryWrapper<AppUserEntity>()
                 .eq(AppUserEntity::getActiveCode, activeCode)
                 .eq(AppUserEntity::getStatus, UserStatus.OK.getCode())
-                .last(" limit 1")
         );
     }
 
@@ -207,7 +200,7 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
         appUserEntity.setUid(uuid);
         appUserEntity.setCreateTime(new Date());
         appUserEntity.setUpdateTime(new Date());
-        if (save(appUserEntity)) {
+        if (!save(appUserEntity)) {
             throw new RenException(MessageUtils.message("user.register.fail"));//注册失败
         }
 
@@ -232,10 +225,6 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
     @Transactional(rollbackFor = Exception.class)
     @Override
     public Result login(AppLoginDTO dto, HttpServletRequest request) {
-        //图形验证码 要改滑动码
-        //if(!captchaService.validate(dto.getUuid(), dto.getCode())) {
-        //    throw new RenException(MessageUtils.message("appUser.login.code.err"));//验证码错误
-        //}
 
         //账号密码失败重试次数
         checkPwdErrTryTimes(dto.getLoginName());
@@ -337,7 +326,9 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
      * @return
      */
     @Override
-    public Result sendEmailCode(String codeType, String email) {
+    public Result sendEmailCode(String uuid, String codeType, String email) {
+        //阿里云滑动验证码
+        checkIntelligentCaptcha(uuid);
 
         if (!EmailUtils.checkEmail(email)) {
             throw new RenException(MessageUtils.message("user.register.email.format"));//邮箱格式不正确
@@ -375,7 +366,9 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
      * @return
      */
     @Override
-    public Result sendMobileCode(String codeType, String phone, String zone) {
+    public Result sendMobileCode(String uuid, String codeType, String phone, String zone) {
+        //阿里云滑动验证码
+        checkIntelligentCaptcha(uuid);
 
         if (StringUtils.isEmpty(phone)) {
             throw new RenException(MessageUtils.message("phone_code_empty"));//手机号不能为空!
@@ -420,30 +413,6 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
     }
 
 
-    /**
-     * 重设密码
-     *
-     * @param codeDTO
-     * @return
-     */
-    @Override
-    public Result resetPwdByEmail(ResetPwdByEmailDTO codeDTO) {
-        Result result = new Result();
-
-        //校验邮箱验证码
-        checkEmailCode("FIND_PASSWORD", codeDTO.getEmail(), codeDTO.getCode());
-
-        //更新密码
-        AppUserEntity appUser = getUserByEmail(codeDTO.getEmail());
-        if (Objects.isNull(appUser)) {
-            throw new RenException(MessageUtils.message("user.not.exist"));//用户不存在
-        }
-        appUser.setLoginPassword(PasswordUtils.encode(codeDTO.getNewPwd()));
-        updateById(appUser);
-        return result;
-
-    }
-
 
     @Override
     public Result resetPwdByEmail(String email, String newPwd) {
@@ -477,21 +446,22 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
     public Result resetPwdByPhone(String zone, String phone, String newPwd) {
         Result result = new Result();
         String codeType = "FIND_PASSWORD";
-        //校验手机验证码
-        final String phoneCodeResultKey = String.format("%s%s%s%s%s", CachePrefix.SMS_CODE.getPrefix(), UserCodeTypeEnum.valueOf(codeType).name(), zone, phone, ":result");
-        verifyResult(phoneCodeResultKey);
+
 
         //密码强度检测
         PasswordStrengthValidator.validatePasswordStrength(newPwd);
-        //更新密码
+
         AppUserEntity appUser = getUserByMobile(phone, zone);
         if (Objects.isNull(appUser)) {
             throw new RenException(MessageUtils.message("user.not.exist"));//用户不存在
         }
-
+        //校验手机验证码
+        final String phoneCodeResultKey = String.format("%s%s%s%s%s", CachePrefix.SMS_CODE.getPrefix(), UserCodeTypeEnum.valueOf(codeType).name(), zone, phone, ":result");
+        verifyResult(phoneCodeResultKey);
+        //校验邮箱验证码
         final String emailCodeResultKey = String.format("%s%s%s%s", CachePrefix.EMAIL_CODE.getPrefix(), UserCodeTypeEnum.valueOf(codeType).name(), appUser.getEmail(), ":result");
         verifyResult(emailCodeResultKey);
-
+        //更新密码
         appUser.setLoginPassword(PasswordUtils.encode(newPwd));
         appUser.setTransferOutTime(DateUtils.addDays(new Date(), 1));
         updateById(appUser);
@@ -499,7 +469,10 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
 
     }
 
-
+    /**
+     * 校验手机或邮箱验证码是否通过
+     * @param codeResultKey
+     */
     private void verifyResult(String codeResultKey) {
         Object codeResult = redisUtils.get(codeResultKey);
         if (Objects.isNull(codeResult) || (int) codeResult != 1) {
@@ -509,28 +482,17 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
     }
 
     /**
-     * 重设密码
-     *
-     * @param codeDTO
-     * @return
+     * 验证码智能验证是否通过
      */
-    @Override
-    public Result resetPwdByPhone(ResetPwdByPhoneDTO codeDTO) {
-        Result result = new Result();
+    private void checkIntelligentCaptcha(String uuid) {
+        Object codeResult = redisUtils.get(uuid);
+        if (Objects.isNull(codeResult) || (int) codeResult != 1) {
+            throw new RenException(ErrorCode.AUTH_ALIYUN_CAPTCHA);//智能验证码校验失败
+        }
+    }
 
-        //校验手机验证码
-        checkPhoneCode("FIND_PASSWORD", codeDTO.getZone(), codeDTO.getPhone(), codeDTO.getCode());
 
-        //更新密码
-        AppUserEntity appUser = getUserByMobile(codeDTO.getPhone(), codeDTO.getZone());
-        if (Objects.isNull(appUser)) {
-            throw new RenException(MessageUtils.message("user.not.exist"));//用户不存在
-        }
-        appUser.setLoginPassword(PasswordUtils.encode(codeDTO.getNewPwd()));
-        updateById(appUser);
-        return result;
 
-    }
 
     /**
      * 限制验证码重试次数
@@ -587,31 +549,23 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
         return pwdFailTimes;
     }
 
-
-    @Override
-    public Result checkCaptcha(CheckCaptchaDTO dto, HttpServletRequest request) {
-        if (!captchaService.validate(dto.getUuid(), dto.getCode())) {
-            throw new RenException(MessageUtils.message("appUser.login.code.err"));//验证码错误
-        }
-        Result result = new Result();
-        return result;
-    }
-
     @Override
     public Result checkPhoneCode(String codeType, String zone, String phone, String code) {
         //校验手机验证码
         final String phoneCodeKey = String.format("%s%s%s%s", CachePrefix.SMS_CODE.getPrefix(), UserCodeTypeEnum.valueOf(codeType).name(), zone, phone);
         checkCode(phoneCodeKey, code);
 
-        AppUserEntity user = getUserByMobile(phone, zone);
-        if (Objects.isNull(user)) {
-            throw new RenException(MessageUtils.message("user.not.exist"));//用户不存在
-        }
-        Map data = MapUtil.of("phone", user.getPhone());
-        data.put("zone", user.getZone());
-        data.put("email", user.getEmail());
         Result result = new Result();
-        result.setData(data);
+        if(!codeType.equals(UserCodeTypeEnum.REGISTER.name())) {
+            AppUserEntity user = getUserByMobile(phone, zone);
+            if (Objects.isNull(user)) {
+                throw new RenException(MessageUtils.message("user.not.exist"));//用户不存在
+            }
+            Map data = MapUtil.of("phone", user.getPhone());
+            data.put("zone", user.getZone());
+            data.put("email", user.getEmail());
+            result.setData(data);
+        }
         return result;
     }
 
@@ -622,15 +576,17 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
         final String emailCodeKey = String.format("%s%s%s", CachePrefix.EMAIL_CODE.getPrefix(), UserCodeTypeEnum.valueOf(codeType).name(), email);
         checkCode(emailCodeKey, code);
 
-        AppUserEntity user = getUserByEmail(email);
-        if (Objects.isNull(user)) {
-            throw new RenException(MessageUtils.message("user.not.exist"));//用户不存在
-        }
-        Map data = MapUtil.of("phone", user.getPhone());
-        data.put("zone", user.getZone());
-        data.put("email", user.getEmail());
         Result result = new Result();
-        result.setData(data);
+        if(!codeType.equals(UserCodeTypeEnum.REGISTER.name())) {
+            AppUserEntity user = getUserByEmail(email);
+            if (Objects.isNull(user)) {
+                throw new RenException(MessageUtils.message("user.not.exist"));//用户不存在
+            }
+            Map data = MapUtil.of("phone", user.getPhone());
+            data.put("zone", user.getZone());
+            data.put("email", user.getEmail());
+            result.setData(data);
+        }
         return result;
     }
 
@@ -659,4 +615,33 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
         final String checkCodeResult = String.format("%s%s", cacheKey, ":result");
         redisUtils.set(checkCodeResult, 1, ApiConstant.CHECK_EXPIRE);
     }
+
+    @Override
+    public Result verifyIntelligentCaptcha(String verifyParam) {
+        SettingEntity setting = settingService.getSetting(SettingEnum.CAPTCHA_SETTING.name());
+        CaptchaSetting captchaSetting = JSONUtil.toBean(setting.getSettingValue(), CaptchaSetting.class);
+        VerifyIntelligentCaptchaResponse response = CaptchaConfig.verifyIntelligentCaptcha(captchaSetting.getAccessKeyId(), captchaSetting.getAccessKeySecret(),
+                captchaSetting.getSceneId(),captchaSetting.getEndpoint(), verifyParam);
+        if(response==null) {
+            throw new RenException(MessageUtils.message("user.verifyIntelligentCaptcha.err"));//验证码校验接口报错
+        }
+        if(response.statusCode == 200 && response.body.success) {
+            //设置验证通过
+            final String uuid = UUID.randomUUID().toString();
+            redisUtils.set(uuid, 1, ApiConstant.CHECK_EXPIRE);
+
+            Map data = MapUtil.of("verifyResult", response.body.result.verifyResult);
+            data.put("uuid", uuid);
+            return new Result().ok(data);
+        } else {
+            return new Result().error(response.body.message);
+        }
+    }
+
+    @Override
+    public AppUserEntity getUserByUserId(Long userId) {
+        return getById(userId);
+    }
+
+
 }

+ 2 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/user/service/impl/SettingServiceImpl.java

@@ -34,4 +34,6 @@ public class SettingServiceImpl extends ServiceImpl<SettingDao, SettingEntity> i
         return getById(id);
     }
 
+
+
 }

+ 2 - 2
qnfhq-api/src/main/resources/application.yml

@@ -64,7 +64,7 @@ renren:
 mybatis-plus:
   mapper-locations: classpath*:/mapper/**/*.xml
   #实体扫描,多个package用逗号或者分号分隔
-  typeAliasesPackage: com.qnfhq.entity
+  typeAliasesPackage: com.qnfhq.modules.**.entity
   global-config:
     #数据库相关配置
     db-config:
@@ -134,4 +134,4 @@ aliyun:
     merchantBizId: qiniufuhuaqi
     idThreshold: 0
     productCode : eKYC
-    callbackUrl :
+    callbackUrl :

+ 8 - 3
qnfhq-api/src/main/resources/i18n/messages.properties

@@ -92,8 +92,6 @@ c2c.order.param.adid=Nombor iklan tidak sah
 c2c.order.param.adid.invalid=Iklan tidak boleh digunakan
 c2c.order.direction.invalid=Nilai parameter direction tidak betul
 c2c.order.buyer.seller.must.different=Pembeli dan penjual tidak boleh menjadi pengguna yang sama
-c2c.order.param.tranAmt.min=Jumlah transaksi mesti lebih besar daripada had minimum
-c2c.order.param.tranAmt.max=Jumlah transaksi mesti kurang daripada had maksimum
 c2c.order.update.asset.fail=Gagal mengemas kini aset penjual
 c2c.order.not.exist=Nombor pesanan tidak sah
 c2c.order.status.end.not.cancel=Pesanan telah selesai dan tidak boleh dibatalkan
@@ -131,4 +129,11 @@ c2c.order.availableAmount.buzu=Aset boleh guna anda tidak mencukupi
 c2c.order.not.seller=Anda bukan penjual
 c2c.userReceipt.id.invalid=Nombor tidak sah
 c2c.order.complainId.orderId.all.empty=Nombor rayuan dan nombor pesanan tidak boleh kosong serentak
-
+c2c.order.param.tranAmt.min=Jumlah mesti lebih besar daripada had minimum iklan  
+c2c.order.param.tranAmt.max=Jumlah mesti kurang daripada had maksimum iklan  
+c2c.order.param.tranAmt.over.avail=Jumlah transaksi melebihi kuantiti iklan yang tersedia  
+c2c.msg.receptId.notexists=Penerima tidak wujud  
+c2c.msg.msgType.err=Jenis mesej salah  
+c2c.msg.receptId.err=Tidak boleh menghantar mesej kepada diri sendiri  
+user.verifyIntelligentCaptcha.err=Ralat pada antara muka pengesahan captcha pintar  
+609=Pengesahan captcha pintar gagal

+ 9 - 4
qnfhq-api/src/main/resources/i18n/messages_de.properties

@@ -91,9 +91,7 @@ c2c.order.availableAmount.insufficient=Ihr verf\u00fcgbares Verm\u00f6gen muss g
 c2c.order.param.adid=Ung\u00fcltige Anzeigen-ID  
 c2c.order.param.adid.invalid=Anzeige ist nicht mehr verf\u00fcgbar  
 c2c.order.direction.invalid=Der Parameterwert f\u00fcr direction ist nicht korrekt  
-c2c.order.buyer.seller.must.different=K\u00e4ufer und Verk\u00e4ufer d\u00fcrfen nicht der gleiche Benutzer sein  
-c2c.order.param.tranAmt.min=Der Transaktionsbetrag muss gr\u00f6\u00dfer als das Mindestlimit sein  
-c2c.order.param.tranAmt.max=Der Transaktionsbetrag muss kleiner als das H\u00f6chstlimit sein  
+c2c.order.buyer.seller.must.different=K\u00e4ufer und Verk\u00e4ufer d\u00fcrfen nicht der gleiche Benutzer sein
 c2c.order.update.asset.fail=Aktualisierung des Verk\u00e4uferverm\u00f6gens fehlgeschlagen  
 c2c.order.not.exist=Ung\u00fcltige Bestellnummer  
 c2c.order.status.end.not.cancel=Die Bestellung ist abgeschlossen und kann nicht storniert werden  
@@ -131,4 +129,11 @@ c2c.order.availableAmount.buzu=Ihr verf\u00fcgbares Guthaben ist unzureichend
 c2c.order.not.seller=Sie sind kein Verk\u00e4ufer
 c2c.userReceipt.id.invalid=Ung\u00fcltige Nummer
 c2c.order.complainId.orderId.all.empty=Beschwerde- und Bestellnummer d\u00fcrfen nicht beide leer sein
-
+c2c.order.param.tranAmt.min=Der Betrag muss gr\u00f6\u00dfer als das minimale Anzeigenlimit sein  
+c2c.order.param.tranAmt.max=Der Betrag muss kleiner als das maximale Anzeigenlimit sein  
+c2c.order.param.tranAmt.over.avail=Der Transaktionsbetrag \u00fcbersteigt die verf\u00fcgbare Menge der Anzeige  
+c2c.msg.receptId.notexists=Empf\u00e4nger existiert nicht  
+c2c.msg.msgType.err=Fehler beim Nachrichtentyp  
+c2c.msg.receptId.err=Sie k\u00f6nnen sich selbst keine Nachricht senden  
+user.verifyIntelligentCaptcha.err=Fehler bei der \u00dcberpr\u00fcfung des Captcha-Interfaces  
+609=Intelligente Captcha-\u00dcberpr\u00fcfung fehlgeschlagen

+ 9 - 3
qnfhq-api/src/main/resources/i18n/messages_en.properties

@@ -91,9 +91,7 @@ c2c.order.availableAmount.insufficient=Your available assets must be greater tha
 c2c.order.param.adid=Invalid advertisement ID  
 c2c.order.param.adid.invalid=Advertisement is no longer available  
 c2c.order.direction.invalid=Invalid value for parameter direction  
-c2c.order.buyer.seller.must.different=Buyer and seller cannot be the same user  
-c2c.order.param.tranAmt.min=Transaction amount must be greater than the minimum limit  
-c2c.order.param.tranAmt.max=Transaction amount must be less than the maximum limit  
+c2c.order.buyer.seller.must.different=Buyer and seller cannot be the same user
 c2c.order.update.asset.fail=Failed to update seller?s assets  
 c2c.order.not.exist=Invalid order number  
 c2c.order.status.end.not.cancel=Order has ended and cannot be canceled  
@@ -131,3 +129,11 @@ c2c.order.availableAmount.buzu=Your available assets are insufficient
 c2c.order.not.seller=You are not the seller
 c2c.userReceipt.id.invalid=Invalid ID
 c2c.order.complainId.orderId.all.empty=Complaint ID and order ID cannot both be empty
+c2c.order.param.tranAmt.min=The amount must be greater than the advertisement minimum limit  
+c2c.order.param.tranAmt.max=The amount must be less than the advertisement maximum limit  
+c2c.order.param.tranAmt.over.avail=The transaction amount exceeds the available quantity of the advertisement
+c2c.msg.receptId.notexists=Recipient does not exist
+c2c.msg.msgType.err=Message type error
+c2c.msg.receptId.err=Cannot send message to yourself
+user.verifyIntelligentCaptcha.err=Verification code validation interface error
+609 = Intelligent CAPTCHA verification failed

+ 9 - 4
qnfhq-api/src/main/resources/i18n/messages_es.properties

@@ -91,9 +91,7 @@ c2c.order.availableAmount.insufficient=Su activo disponible debe ser mayor que l
 c2c.order.param.adid=El n\u00famero de anuncio no es v\u00e1lido  
 c2c.order.param.adid.invalid=El anuncio ya no est\u00e1 disponible  
 c2c.order.direction.invalid=El valor del par\u00e1metro direction no es correcto  
-c2c.order.buyer.seller.must.different=El comprador y el vendedor no pueden ser el mismo usuario  
-c2c.order.param.tranAmt.min=El monto de la transacci\u00f3n debe ser mayor que el l\u00edmite m\u00ednimo  
-c2c.order.param.tranAmt.max=El monto de la transacci\u00f3n debe ser menor que el l\u00edmite m\u00e1ximo  
+c2c.order.buyer.seller.must.different=El comprador y el vendedor no pueden ser el mismo usuario
 c2c.order.update.asset.fail=Error al actualizar los activos del vendedor  
 c2c.order.not.exist=El n\u00famero de orden no es v\u00e1lido  
 c2c.order.status.end.not.cancel=La orden ha finalizado y no puede ser cancelada  
@@ -131,4 +129,11 @@ c2c.order.availableAmount.buzu=Sus activos disponibles son insuficientes
 c2c.order.not.seller=Usted no es el vendedor  
 c2c.userReceipt.id.invalid=Identificaci\u00f3n no v\u00e1lida  
 c2c.order.complainId.orderId.all.empty=El n\u00famero de apelaci\u00f3n y el n\u00famero de pedido no pueden estar ambos vac\u00edos
-
+c2c.order.param.tranAmt.min=El monto debe ser mayor que el l\u00edmite m\u00ednimo del anuncio  
+c2c.order.param.tranAmt.max=El monto debe ser menor que el l\u00edmite m\u00e1ximo del anuncio  
+c2c.order.param.tranAmt.over.avail=El monto de la transacci\u00f3n supera la cantidad disponible del anuncio  
+c2c.msg.receptId.notexists=El destinatario no existe  
+c2c.msg.msgType.err=Error en el tipo de mensaje  
+c2c.msg.receptId.err=No puedes enviarte mensajes a ti mismo  
+user.verifyIntelligentCaptcha.err=Error en la interfaz de verificaci\u00f3n del captcha  
+609=Fallo en la verificaci\u00f3n del captcha inteligente

+ 9 - 4
qnfhq-api/src/main/resources/i18n/messages_fr.properties

@@ -91,9 +91,7 @@ c2c.order.availableAmount.insufficient=Votre actif disponible doit \u00eatre sup
 c2c.order.param.adid=Num\u00e9ro d'annonce invalide  
 c2c.order.param.adid.invalid=L'annonce n'est plus disponible  
 c2c.order.direction.invalid=La valeur du param\u00e8tre direction est incorrecte  
-c2c.order.buyer.seller.must.different=L'acheteur et le vendeur ne peuvent pas \u00eatre le m\u00eame utilisateur  
-c2c.order.param.tranAmt.min=Le montant de la transaction doit \u00eatre sup\u00e9rieur au minimum autoris\u00e9  
-c2c.order.param.tranAmt.max=Le montant de la transaction doit \u00eatre inf\u00e9rieur au maximum autoris\u00e9  
+c2c.order.buyer.seller.must.different=L'acheteur et le vendeur ne peuvent pas \u00eatre le m\u00eame utilisateur
 c2c.order.update.asset.fail=\u00c9chec de la mise \u00e0 jour des actifs du vendeur  
 c2c.order.not.exist=Num\u00e9ro de commande invalide  
 c2c.order.status.end.not.cancel=La commande est termin\u00e9e et ne peut pas \u00eatre annul\u00e9e  
@@ -131,4 +129,11 @@ c2c.order.availableAmount.buzu=Vos actifs disponibles sont insuffisants
 c2c.order.not.seller=Vous n'\u00eates pas le vendeur  
 c2c.userReceipt.id.invalid=Num\u00e9ro invalide  
 c2c.order.complainId.orderId.all.empty=Le num\u00e9ro de r\u00e9clamation et le num\u00e9ro de commande ne peuvent pas \u00eatre tous deux vides
-
+c2c.order.param.tranAmt.min=Le montant doit \u00eatre sup\u00e9rieur au montant minimum de l'annonce
+c2c.order.param.tranAmt.max=Le montant doit \u00eatre inf\u00e9rieur au montant maximum de l'annonce
+c2c.order.param.tranAmt.over.avail=Le montant de la transaction d\u00e9passe la quantit\u00e9 disponible de l'annonce
+c2c.msg.receptId.notexists=Le destinataire n'existe pas
+c2c.msg.msgType.err=Type de message incorrect
+c2c.msg.receptId.err=Vous ne pouvez pas vous envoyer un message \u00e0 vous-m\u00eame
+user.verifyIntelligentCaptcha.err=Erreur lors de la v\u00e9rification du captcha
+609=\u00c9chec de la v\u00e9rification du captcha intelligent

+ 8 - 2
qnfhq-api/src/main/resources/i18n/messages_ja.properties

@@ -92,8 +92,6 @@ c2c.order.param.adid=\u5e83\u544a\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059
 c2c.order.param.adid.invalid=\u5e83\u544a\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093
 c2c.order.direction.invalid=\u30d1\u30e9\u30e1\u30fc\u30bfdirection\u306e\u5024\u304c\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093
 c2c.order.buyer.seller.must.different=\u8cb7\u3044\u624b\u3068\u58f2\u308a\u624b\u306f\u540c\u4e00\u30e6\u30fc\u30b6\u30fc\u3067\u3042\u3063\u3066\u306f\u306a\u308a\u307e\u305b\u3093
-c2c.order.param.tranAmt.min=\u53d6\u5f15\u91d1\u984d\u306f\u6700\u5c0f\u9650\u5ea6\u984d\u3088\u308a\u5927\u304d\u304f\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093
-c2c.order.param.tranAmt.max=\u53d6\u5f15\u91d1\u984d\u306f\u6700\u5927\u9650\u5ea6\u984d\u3088\u308a\u5c0f\u3055\u304f\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093
 c2c.order.update.asset.fail=\u58f2\u308a\u624b\u306e\u8cc7\u7523\u66f4\u65b0\u306b\u5931\u6557\u3057\u307e\u3057\u305f
 c2c.order.not.exist=\u6ce8\u6587\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059
 c2c.order.status.end.not.cancel=\u6ce8\u6587\u306f\u7d42\u4e86\u3057\u3066\u304a\u308a\u3001\u30ad\u30e3\u30f3\u30bb\u30eb\u3067\u304d\u307e\u305b\u3093
@@ -131,4 +129,12 @@ c2c.order.availableAmount.buzu=\u5229\u7528\u53ef\u80fd\u306a\u8cc7\u7523\u304c\
 c2c.order.not.seller=\u3042\u306a\u305f\u306f\u58f2\u308a\u624b\u3067\u306f\u3042\u308a\u307e\u305b\u3093
 c2c.userReceipt.id.invalid=\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059
 c2c.order.complainId.orderId.all.empty=\u7533\u8a34\u756a\u53f7\u3068\u6ce8\u6587\u756a\u53f7\u306e\u4e21\u65b9\u3092\u7a7a\u306b\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093
+c2c.order.param.tranAmt.min=\u91d1\u984d\u306f\u5e83\u544a\u306e\u6700\u5c0f\u9650\u5ea6\u984d\u3088\u308a\u5927\u304d\u304f\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093
+c2c.order.param.tranAmt.max=\u91d1\u984d\u306f\u5e83\u544a\u306e\u6700\u5927\u9650\u5ea6\u984d\u3088\u308a\u5c0f\u3055\u304f\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093
+c2c.order.param.tranAmt.over.avail=\u53d6\u5f15\u91d1\u984d\u304c\u5e83\u544a\u306e\u5229\u7528\u53ef\u80fd\u6570\u91cf\u3092\u8d85\u3048\u3066\u3044\u307e\u3059
+c2c.msg.receptId.notexists=\u53d7\u4fe1\u8005\u304c\u5b58\u5728\u3057\u307e\u305b\u3093
+c2c.msg.msgType.err=\u30e1\u30c3\u30bb\u30fc\u30b8\u30bf\u30a4\u30d7\u304c\u9593\u9055\u3063\u3066\u3044\u307e\u3059
+c2c.msg.receptId.err=\u81ea\u5206\u81ea\u8eab\u306b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093
+user.verifyIntelligentCaptcha.err=\u8a8d\u8a3c\u30b3\u30fc\u30c9\u691c\u8a3c\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3067\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f
+609=\u30a4\u30f3\u30c6\u30ea\u30b8\u30a7\u30f3\u30c8\u8a8d\u8a3c\u30b3\u30fc\u30c9\u306e\u691c\u8a3c\u306b\u5931\u6557\u3057\u307e\u3057\u305f
 

+ 8 - 3
qnfhq-api/src/main/resources/i18n/messages_ko.properties

@@ -92,8 +92,6 @@ c2c.order.param.adid=\uad11\uace0 \ubc88\ud638\uac00 \uc720\ud6a8\ud558\uc9c0 \u
 c2c.order.param.adid.invalid=\uad11\uace0\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
 c2c.order.direction.invalid=\ud30c\ub77c\ubbf8\ud130 direction \uac12\uc774 \uc62c\ubc14\ub974\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4
 c2c.order.buyer.seller.must.different=\uad6c\ub9e4\uc790\uc640 \ud310\ub9e4\uc790\ub294 \ub3d9\uc77c\ud55c \uc0ac\uc6a9\uc790\uac00 \ub420 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
-c2c.order.param.tranAmt.min=\uac70\ub798 \uae08\uc561\uc740 \ucd5c\uc18c \ud55c\ub3c4\ubcf4\ub2e4 \ucee4\uc57c \ud569\ub2c8\ub2e4
-c2c.order.param.tranAmt.max=\uac70\ub798 \uae08\uc561\uc740 \ucd5c\ub300 \ud55c\ub3c4\ubcf4\ub2e4 \uc791\uc544\uc57c \ud569\ub2c8\ub2e4
 c2c.order.update.asset.fail=\ud310\ub9e4\uc790 \uc790\uc0b0 \uc5c5\ub370\uc774\ud2b8 \uc2e4\ud328
 c2c.order.not.exist=\uc8fc\ubb38 \ubc88\ud638\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4
 c2c.order.status.end.not.cancel=\uc8fc\ubb38\uc774 \uc885\ub8cc\ub418\uc5b4 \ucde8\uc18c\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
@@ -131,4 +129,11 @@ c2c.order.availableAmount.buzu=\uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc790\uc0b0\uc77
 c2c.order.not.seller=\ub2f9\uc2e0\uc740 \ud310\ub9e4\uc790\uac00 \uc544\ub2d9\ub2c8\ub2e4
 c2c.userReceipt.id.invalid=\ubc88\ud638\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4
 c2c.order.complainId.orderId.all.empty=\uc2e0\uccad \ubc88\ud638\uc640 \uc8fc\ubb38 \ubc88\ud638\ub294 \ubaa8\ub450 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
-
+c2c.order.param.tranAmt.min=\uae08\uc561\uc740 \uad11\uace0 \ucd5c\uc18c \ud55c\ub3c4\ubcf4\ub2e4 \ucee4\uc57c \ud569\ub2c8\ub2e4
+c2c.order.param.tranAmt.max=\uae08\uc561\uc740 \uad11\uace0 \ucd5c\ub300 \ud55c\ub3c4\ubcf4\ub2e4 \uc791\uc544\uc57c \ud569\ub2c8\ub2e4
+c2c.order.param.tranAmt.over.avail=\uac70\ub798 \uae08\uc561\uc774 \uad11\uace0 \uc0ac\uc6a9 \uac00\ub2a5 \uc218\ub7c9\uc744 \ucd08\uacfc\ud588\uc2b5\ub2c8\ub2e4
+c2c.msg.receptId.notexists=\uc218\uc2e0\uc790\uac00 \uc874\uc7ac\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4
+c2c.msg.msgType.err=\uba54\uc2dc\uc9c0 \uc720\ud615 \uc624\ub958
+c2c.msg.receptId.err=\uc790\uae30 \uc790\uc2e0\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0bc \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+user.verifyIntelligentCaptcha.err=\uc778\uc99d \ucf54\ub4dc \uac80\uc99d \uc778\ud130\ud398\uc774\uc2a4 \uc624\ub958
+609=\uc9c0\ub2a5\ud615 \uc778\uc99d \ucf54\ub4dc \uac80\uc99d \uc2e4\ud328

+ 9 - 4
qnfhq-api/src/main/resources/i18n/messages_th.properties

@@ -91,9 +91,7 @@ c2c.order.availableAmount.insufficient=\u0e2a\u0e34\u0e19\u0e17\u0e23\u0e31\u0e1
 c2c.order.param.adid=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e42\u0e06\u0e29\u0e13\u0e32\u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07  
 c2c.order.param.adid.invalid=\u0e42\u0e06\u0e29\u0e13\u0e32\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e44\u0e14\u0e49  
 c2c.order.direction.invalid=\u0e04\u0e48\u0e32\u0e1e\u0e32\u0e23\u0e32\u0e21\u0e34\u0e40\u0e15\u0e2d\u0e23\u0e4c direction \u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07  
-c2c.order.buyer.seller.must.different=\u0e1c\u0e39\u0e49\u0e0b\u0e37\u0e49\u0e2d\u0e41\u0e25\u0e30\u0e1c\u0e39\u0e49\u0e02\u0e32\u0e22\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e43\u0e0a\u0e48\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\u0e04\u0e19\u0e40\u0e14\u0e35\u0e22\u0e27\u0e01\u0e31\u0e19  
-c2c.order.param.tranAmt.min=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e40\u0e07\u0e34\u0e19\u0e43\u0e19\u0e01\u0e32\u0e23\u0e17\u0e33\u0e18\u0e38\u0e23\u0e01\u0e23\u0e23\u0e21\u0e15\u0e49\u0e2d\u0e07\u0e21\u0e32\u0e01\u0e01\u0e27\u0e48\u0e32\u0e02\u0e31\u0e49\u0e19\u0e15\u0e48\u0e33  
-c2c.order.param.tranAmt.max=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e40\u0e07\u0e34\u0e19\u0e43\u0e19\u0e01\u0e32\u0e23\u0e17\u0e33\u0e18\u0e38\u0e23\u0e01\u0e23\u0e23\u0e21\u0e15\u0e49\u0e2d\u0e07\u0e19\u0e49\u0e2d\u0e22\u0e01\u0e27\u0e48\u0e32\u0e02\u0e31\u0e49\u0e19\u0e2a\u0e39\u0e07\u0e2a\u0e38\u0e14  
+c2c.order.buyer.seller.must.different=\u0e1c\u0e39\u0e49\u0e0b\u0e37\u0e49\u0e2d\u0e41\u0e25\u0e30\u0e1c\u0e39\u0e49\u0e02\u0e32\u0e22\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e43\u0e0a\u0e48\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\u0e04\u0e19\u0e40\u0e14\u0e35\u0e22\u0e27\u0e01\u0e31\u0e19
 c2c.order.update.asset.fail=\u0e2d\u0e31\u0e1b\u0e40\u0e14\u0e15\u0e2a\u0e34\u0e19\u0e17\u0e23\u0e31\u0e1e\u0e22\u0e4c\u0e02\u0e2d\u0e07\u0e1c\u0e39\u0e49\u0e02\u0e32\u0e22\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27  
 c2c.order.not.exist=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07  
 c2c.order.status.end.not.cancel=\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e2a\u0e34\u0e49\u0e19\u0e2a\u0e38\u0e14\u0e41\u0e25\u0e49\u0e27 \u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e22\u0e01\u0e40\u0e25\u0e34\u0e01\u0e44\u0e14\u0e49  
@@ -131,4 +129,11 @@ c2c.order.availableAmount.buzu=\u0e2a\u0e34\u0e19\u0e17\u0e23\u0e31\u0e1e\u0e22\
 c2c.order.not.seller=\u0e04\u0e38\u0e13\u0e44\u0e21\u0e48\u0e43\u0e0a\u0e48\u0e1c\u0e39\u0e49\u0e02\u0e32\u0e22
 c2c.userReceipt.id.invalid=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07
 c2c.order.complainId.orderId.all.empty=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e41\u0e25\u0e30\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e40\u0e27\u0e49\u0e19\u0e27\u0e48\u0e32\u0e07\u0e44\u0e14\u0e49\u0e17\u0e31\u0e49\u0e07\u0e04\u0e39\u0e48
-
+c2c.order.param.tranAmt.min=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e40\u0e07\u0e34\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e21\u0e32\u0e01\u0e01\u0e27\u0e48\u0e32\u0e02\u0e31\u0e49\u0e19\u0e15\u0e48\u0e33\u0e02\u0e2d\u0e07\u0e42\u0e06\u0e29\u0e13\u0e32
+c2c.order.param.tranAmt.max=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e40\u0e07\u0e34\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e19\u0e49\u0e2d\u0e22\u0e01\u0e27\u0e48\u0e32\u0e02\u0e31\u0e49\u0e19\u0e2a\u0e39\u0e07\u0e2a\u0e38\u0e14\u0e02\u0e2d\u0e07\u0e42\u0e06\u0e29\u0e13\u0e32
+c2c.order.param.tranAmt.over.avail=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e40\u0e07\u0e34\u0e19\u0e43\u0e19\u0e01\u0e32\u0e23\u0e17\u0e33\u0e18\u0e38\u0e23\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e34\u0e19\u0e08\u0e33\u0e19\u0e27\u0e19\u0e17\u0e35\u0e48\u0e42\u0e06\u0e29\u0e13\u0e32\u0e21\u0e35\u0e2d\u0e22\u0e39\u0e48
+c2c.msg.receptId.notexists=\u0e1c\u0e39\u0e49\u0e23\u0e31\u0e1a\u0e44\u0e21\u0e48\u0e1e\u0e1a
+c2c.msg.msgType.err=\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14
+c2c.msg.receptId.err=\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e2a\u0e48\u0e07\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e16\u0e36\u0e07\u0e15\u0e31\u0e27\u0e40\u0e2d\u0e07\u0e44\u0e14\u0e49
+user.verifyIntelligentCaptcha.err=\u0e40\u0e01\u0e34\u0e14\u0e02\u0e49\u0e2d\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14\u0e43\u0e19\u0e01\u0e32\u0e23\u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e23\u0e2b\u0e31\u0e2a\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19
+609=\u0e01\u0e32\u0e23\u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e23\u0e2b\u0e31\u0e2a\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e2d\u0e31\u0e08\u0e09\u0e23\u0e34\u0e22\u0e30\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27

+ 8 - 3
qnfhq-api/src/main/resources/i18n/messages_tw.properties

@@ -92,8 +92,6 @@ c2c.order.param.adid=\u5ee3\u544a\u7de8\u865f\u7121\u6548
 c2c.order.param.adid.invalid=\u5ee3\u544a\u5df2\u4e0d\u53ef\u7528
 c2c.order.direction.invalid=\u53c3\u6578direction\u503c\u4e0d\u6b63\u78ba
 c2c.order.buyer.seller.must.different=\u8cb7\u5bb6\u548c\u8ce3\u5bb6\u4e0d\u80fd\u662f\u540c\u4e00\u500b\u7528\u6236
-c2c.order.param.tranAmt.min=\u4ea4\u6613\u91d1\u984d\u5fc5\u9808\u5927\u65bc\u6700\u5c0f\u9650\u984d
-c2c.order.param.tranAmt.max=\u4ea4\u6613\u91d1\u984d\u5fc5\u9808\u5c0f\u65bc\u6700\u5927\u9650\u984d
 c2c.order.update.asset.fail=\u66f4\u65b0\u8ce3\u5bb6\u8cc7\u7522\u5931\u6557
 c2c.order.not.exist=\u8a02\u55ae\u7de8\u865f\u7121\u6548
 c2c.order.status.end.not.cancel=\u8a02\u55ae\u5df2\u7d50\u675f\u4e0d\u80fd\u53d6\u6d88
@@ -131,4 +129,11 @@ c2c.order.availableAmount.buzu=\u60a8\u7684\u53ef\u7528\u8cc7\u7522\u4e0d\u8db3
 c2c.order.not.seller=\u60a8\u4e0d\u662f\u8ce3\u5bb6
 c2c.userReceipt.id.invalid=\u7de8\u865f\u7121\u6548
 c2c.order.complainId.orderId.all.empty=\u7533\u8a34\u7de8\u865f\u3001\u8a02\u55ae\u7de8\u865f\u4e0d\u80fd\u90fd\u70ba\u7a7a
-
+c2c.order.param.tranAmt.min=\u91d1\u984d\u5fc5\u9808\u5927\u65bc\u5ee3\u544a\u6700\u5c0f\u9650\u984d
+c2c.order.param.tranAmt.max=\u91d1\u984d\u5fc5\u9808\u5c0f\u65bc\u5ee3\u544a\u6700\u5927\u9650\u984d
+c2c.order.param.tranAmt.over.avail=\u4ea4\u6613\u91d1\u984d\u8d85\u904e\u5ee3\u544a\u53ef\u7528\u6578\u91cf
+c2c.msg.receptId.notexists=\u63a5\u6536\u4eba\u4e0d\u5b58\u5728
+c2c.msg.msgType.err=\u6d88\u606f\u985e\u578b\u932f\u8aa4
+c2c.msg.receptId.err=\u4e0d\u80fd\u7d66\u81ea\u5df1\u767c\u6d88\u606f
+user.verifyIntelligentCaptcha.err=\u9a57\u8b49\u78bc\u6821\u9a57\u63a5\u53e3\u5831\u932f
+609=\u667a\u80fd\u9a57\u8b49\u78bc\u6821\u9a57\u5931\u6557

+ 9 - 4
qnfhq-api/src/main/resources/i18n/messages_vi.properties

@@ -90,9 +90,7 @@ c2c.order.availableAmount.insufficient=T\u00e0i s\u1ea3n kh\u1ea3 d\u1ee5ng c\u1
 c2c.order.param.adid=M\u00e3 qu\u1ea3ng c\u00e1o kh\u00f4ng h\u1ee3p l\u1ec7  
 c2c.order.param.adid.invalid=Qu\u1ea3ng c\u00e1o kh\u00f4ng c\u00f2n kh\u1ea3 d\u1ee5ng  
 c2c.order.direction.invalid=Gi\u00e1 tr\u1ecb tham s\u1ed1 direction kh\u00f4ng ch\u00ednh x\u00e1c  
-c2c.order.buyer.seller.must.different=Ng\u01b0\u1eddi mua v\u00e0 ng\u01b0\u1eddi b\u00e1n kh\u00f4ng th\u1ec3 l\u00e0 c\u00f9ng m\u1ed9t ng\u01b0\u1eddi d\u00f9ng  
-c2c.order.param.tranAmt.min=S\u1ed1 ti\u1ec1n giao d\u1ecbch ph\u1ea3i l\u1edbn h\u01a1n gi\u1edbi h\u1ea1n t\u1ed1i thi\u1ec3u  
-c2c.order.param.tranAmt.max=S\u1ed1 ti\u1ec1n giao d\u1ecbch ph\u1ea3i nh\u1ecf h\u01a1n gi\u1edbi h\u1ea1n t\u1ed1i \u0111a  
+c2c.order.buyer.seller.must.different=Ng\u01b0\u1eddi mua v\u00e0 ng\u01b0\u1eddi b\u00e1n kh\u00f4ng th\u1ec3 l\u00e0 c\u00f9ng m\u1ed9t ng\u01b0\u1eddi d\u00f9ng
 c2c.order.update.asset.fail=C\u1eadp nh\u1eadt t\u00e0i s\u1ea3n ng\u01b0\u1eddi b\u00e1n th\u1ea5t b\u1ea1i  
 c2c.order.not.exist=M\u00e3 \u0111\u01a1n h\u00e0ng kh\u00f4ng h\u1ee3p l\u1ec7  
 c2c.order.status.end.not.cancel=\u0110\u01a1n h\u00e0ng \u0111\u00e3 k\u1ebft th\u00fac kh\u00f4ng th\u1ec3 h\u1ee7y  
@@ -130,4 +128,11 @@ c2c.order.availableAmount.buzu=T\u00e0i s\u1ea3n kh\u1ea3 d\u1ee5ng c\u1ee7a b\u
 c2c.order.not.seller=B\u1ea1n kh\u00f4ng ph\u1ea3i l\u00e0 ng\u01b0\u1eddi b\u00e1n  
 c2c.userReceipt.id.invalid=M\u00e3 kh\u00f4ng h\u1ee3p l\u1ec7  
 c2c.order.complainId.orderId.all.empty=M\u00e3 khi\u1ebfu n\u1ea1i v\u00e0 m\u00e3 \u0111\u01a1n h\u00e0ng kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng c\u00f9ng l\u00fac
-
+c2c.order.param.tranAmt.min=S\u1ed1 ti\u1ec1n ph\u1ea3i l\u1edbn h\u01a1n h\u1ea1n m\u1ee9c t\u1ed1i thi\u1ec3u c\u1ee7a qu\u1ea3ng c\u00e1o  
+c2c.order.param.tranAmt.max=S\u1ed1 ti\u1ec1n ph\u1ea3i nh\u1ecf h\u01a1n h\u1ea1n m\u1ee9c t\u1ed1i \u0111a c\u1ee7a qu\u1ea3ng c\u00e1o  
+c2c.order.param.tranAmt.over.avail=S\u1ed1 ti\u1ec1n giao d\u1ecbch v\u01b0\u1ee3t qu\u00e1 s\u1ed1 l\u01b0\u1ee3ng c\u00f3 s\u1eb5n c\u1ee7a qu\u1ea3ng c\u00e1o  
+c2c.msg.receptId.notexists=Ng\u01b0\u1eddi nh\u1eadn kh\u00f4ng t\u1ed3n t\u1ea1i  
+c2c.msg.msgType.err=Lo\u1ea1i tin nh\u1eafn sai  
+c2c.msg.receptId.err=Kh\u00f4ng th\u1ec3 g\u1eedi tin nh\u1eafn cho ch\u00ednh m\u00ecnh  
+user.verifyIntelligentCaptcha.err=L\u1ed7i giao di\u1ec7n ki\u1ec3m tra m\u00e3 x\u00e1c nh\u1eadn  
+609=Ki\u1ec3m tra m\u00e3 x\u00e1c nh\u1eadn th\u00f4ng minh th\u1ea5t b\u1ea1i

+ 8 - 3
qnfhq-api/src/main/resources/i18n/messages_zh.properties

@@ -93,8 +93,6 @@ c2c.order.param.adid=\u5e7f\u544a\u7f16\u53f7\u65e0\u6548
 c2c.order.param.adid.invalid=\u5e7f\u544a\u5df2\u4e0d\u53ef\u7528
 c2c.order.direction.invalid=\u53c2\u6570direction\u503c\u4e0d\u6b63\u786e
 c2c.order.buyer.seller.must.different=\u4e70\u5bb6\u548c\u5356\u5bb6\u4e0d\u80fd\u662f\u540c\u4e00\u4e2a\u7528\u6237
-c2c.order.param.tranAmt.min=\u4ea4\u6613\u91d1\u989d\u5fc5\u987b\u5927\u4e8e\u6700\u5c0f\u9650\u989d
-c2c.order.param.tranAmt.max=\u4ea4\u6613\u91d1\u989d\u5fc5\u987b\u5c0f\u4e8e\u6700\u5927\u9650\u989d
 c2c.order.update.asset.fail=\u66f4\u65b0\u5356\u5bb6\u8d44\u4ea7\u5931\u8d25
 c2c.order.not.exist=\u8ba2\u5355\u7f16\u53f7\u65e0\u6548
 c2c.order.status.end.not.cancel=\u8ba2\u5355\u5df2\u7ed3\u675f\u4e0d\u80fd\u53d6\u6d88
@@ -133,4 +131,11 @@ c2c.order.not.seller=\u60a8\u4e0d\u662f\u5356\u5bb6
 c2c.userReceipt.id.invalid=\u7f16\u53f7\u65e0\u6548
 c2c.order.complainId.orderId.all.empty=\u7533\u8bc9\u7f16\u53f7\u3001\u8ba2\u5355\u7f16\u53f7\u4e0d\u80fd\u90fd\u4e3a\u7a7a
 
-
+c2c.order.param.tranAmt.min=\u91d1\u989d\u5fc5\u987b\u5927\u4e8e\u5e7f\u544a\u6700\u5c0f\u9650\u989d
+c2c.order.param.tranAmt.max=\u91d1\u989d\u5fc5\u987b\u5c0f\u4e8e\u5e7f\u544a\u6700\u5927\u9650\u989d
+c2c.order.param.tranAmt.over.avail=\u4ea4\u6613\u91d1\u989d\u8d85\u8fc7\u5e7f\u544a\u53ef\u7528\u6570\u91cf
+c2c.msg.receptId.notexists=\u63a5\u6536\u4eba\u4e0d\u5b58\u5728
+c2c.msg.msgType.err=\u6d88\u606f\u7c7b\u578b\u9519\u8bef
+c2c.msg.receptId.err=\u4e0d\u80fd\u7ed9\u81ea\u5df1\u53d1\u6d88\u606f
+user.verifyIntelligentCaptcha.err=\u9a8c\u8bc1\u7801\u6821\u9a8c\u63a5\u53e3\u62a5\u9519
+609=\u667a\u80fd\u9a8c\u8bc1\u7801\u6821\u9a8c\u5931\u8d25

+ 12 - 3
qnfhq-api/src/main/resources/i18n/validation.properties

@@ -24,8 +24,7 @@ NotNull.status=Status tidak boleh kosong
 NotNull.payType=Cara pembayaran tidak boleh kosong  
 NotBlank.receiptInfo=Maklumat penerimaan tidak boleh kosong  
 NotNull.c2cAdId=Nombor iklan tidak boleh kosong  
-NotNull.tranAmount=Jumlah transaksi tidak boleh kosong  
-NotNull.tranBy=Cara transaksi tidak boleh kosong  
+NotNull.tranAmount=Jumlah transaksi tidak boleh kosong
 NotNull.oId=Nombor pesanan tidak boleh kosong  
 NotBlank.img=Bukti pembayaran tidak boleh kosong  
 NotNull.id=Nombor tidak boleh kosong  
@@ -36,4 +35,14 @@ NotBlank.reason=Alasan aduan tidak boleh kosong
 NotBlank.remark=Penerangan bukti tidak boleh kosong  
 NotBlank.img1=Tangkapan skrin bukti 1 tidak boleh kosong  
 NotNull.complainId=Nombor aduan tidak boleh kosong  
-NotBlank.country=Negara tidak boleh kosong
+NotBlank.country=Negara tidak boleh kosong
+NotNull.tag=Label tidak boleh kosong  
+NotNull.unit=Unit transaksi tidak boleh kosong  
+NotBlank.senderId=Pengirim tidak boleh kosong  
+NotBlank.recipientId=Penerima tidak boleh kosong  
+NotBlank.content=Kandungan mesej tidak boleh kosong  
+NotBlank.msgType=Jenis mesej tidak boleh kosong  
+NotNull.ownerUid=ID pengguna tidak boleh kosong
+NotNull.otherUid=Nombor pihak lain tidak boleh kosong
+Length.content=Kandungan mesej tidak boleh melebihi 1000 aksara
+NotBlank.verifyParam=Parameter kod pengesahan tidak boleh kosong

+ 12 - 3
qnfhq-api/src/main/resources/i18n/validation_de.properties

@@ -24,8 +24,7 @@ NotNull.status=Status darf nicht leer sein
 NotNull.payType=Zahlungsart darf nicht leer sein  
 NotBlank.receiptInfo=Empfangsinformationen d\u00fcrfen nicht leer sein  
 NotNull.c2cAdId=Anzeige-ID darf nicht leer sein  
-NotNull.tranAmount=Transaktionsbetrag darf nicht leer sein  
-NotNull.tranBy=Transaktionsart darf nicht leer sein  
+NotNull.tranAmount=Transaktionsbetrag darf nicht leer sein
 NotNull.oId=Bestellnummer darf nicht leer sein  
 NotBlank.img=Zahlungsnachweis darf nicht leer sein  
 NotNull.id=ID darf nicht leer sein  
@@ -36,4 +35,14 @@ NotBlank.reason=Beschwerdegrund darf nicht leer sein
 NotBlank.remark=Nachweisbeschreibung darf nicht leer sein  
 NotBlank.img1=Screenshot des Nachweises 1 darf nicht leer sein  
 NotNull.complainId=Beschwerde-ID darf nicht leer sein  
-NotBlank.country=Land darf nicht leer sein
+NotBlank.country=Land darf nicht leer sein
+NotNull.tag=Das Etikett darf nicht leer sein  
+NotNull.unit=Die Handelseinheit darf nicht leer sein  
+NotBlank.senderId=Absender darf nicht leer sein  
+NotBlank.recipientId=Empf\u00e4nger darf nicht leer sein  
+NotBlank.content=Nachrichteninhalt darf nicht leer sein  
+NotBlank.msgType=Nachrichtentyp darf nicht leer sein  
+NotNull.ownerUid=Benutzernummer darf nicht leer sein
+NotNull.otherUid=Die Gegenpartei-ID darf nicht leer sein  
+Length.content=Die Nachrichtenl\u00e4nge darf 1000 Zeichen nicht \u00fcberschreiten  
+NotBlank.verifyParam=Der Verifizierungscode darf nicht leer sein

+ 12 - 2
qnfhq-api/src/main/resources/i18n/validation_en.properties

@@ -25,7 +25,6 @@ NotNull.payType=Payment method cannot be empty
 NotBlank.receiptInfo=Receipt information cannot be empty
 NotNull.c2cAdId=Advertisement ID cannot be empty
 NotNull.tranAmount=Transaction amount cannot be empty
-NotNull.tranBy=Transaction method cannot be empty
 NotNull.oId=Order ID cannot be empty
 NotBlank.img=Payment voucher cannot be empty
 NotNull.id=ID cannot be empty
@@ -36,4 +35,15 @@ NotBlank.reason=Appeal reason cannot be empty
 NotBlank.remark=Voucher description cannot be empty
 NotBlank.img1=Voucher screenshot 1 cannot be empty
 NotNull.complainId=Appeal ID cannot be empty
-NotBlank.country=Country cannot be empty
+NotBlank.country=Country cannot be empty
+
+NotNull.tag=Tag cannot be empty
+NotNull.unit=Transaction unit cannot be empty
+NotBlank.senderId=Sender cannot be empty
+NotBlank.recipientId=Recipient cannot be empty
+NotBlank.content=Message content cannot be empty
+NotBlank.msgType=Message type cannot be empty
+NotNull.ownerUid=User ID cannot be empty
+NotNull.otherUid=Counterparty ID cannot be empty
+Length.content=The length of the message content cannot exceed 1000
+NotBlank.verifyParam=Verification code parameter cannot be empty

+ 12 - 3
qnfhq-api/src/main/resources/i18n/validation_es.properties

@@ -24,8 +24,7 @@ NotNull.status=El estado no puede estar vac\u00edo
 NotNull.payType=El tipo de pago no puede estar vac\u00edo  
 NotBlank.receiptInfo=La informaci\u00f3n de recibo no puede estar vac\u00eda  
 NotNull.c2cAdId=El n\u00famero de anuncio no puede estar vac\u00edo  
-NotNull.tranAmount=El monto de la transacci\u00f3n no puede estar vac\u00edo  
-NotNull.tranBy=El m\u00e9todo de transacci\u00f3n no puede estar vac\u00edo  
+NotNull.tranAmount=El monto de la transacci\u00f3n no puede estar vac\u00edo
 NotNull.oId=El n\u00famero de orden no puede estar vac\u00edo  
 NotBlank.img=El comprobante de pago no puede estar vac\u00edo  
 NotNull.id=El n\u00famero no puede estar vac\u00edo  
@@ -36,4 +35,14 @@ NotBlank.reason=La raz\u00f3n de la apelaci\u00f3n no puede estar vac\u00eda
 NotBlank.remark=La descripci\u00f3n del comprobante no puede estar vac\u00eda  
 NotBlank.img1=La captura del comprobante 1 no puede estar vac\u00eda  
 NotNull.complainId=El n\u00famero de apelaci\u00f3n no puede estar vac\u00edo  
-NotBlank.country=El pa\u00eds no puede estar vac\u00edo
+NotBlank.country=El pa\u00eds no puede estar vac\u00edo
+NotNull.tag=La etiqueta no puede estar vac\u00eda  
+NotNull.unit=La unidad de transacci\u00f3n no puede estar vac\u00eda  
+NotBlank.senderId=El remitente no puede estar vac\u00edo  
+NotBlank.recipientId=El destinatario no puede estar vac\u00edo  
+NotBlank.content=El contenido del mensaje no puede estar vac\u00edo  
+NotBlank.msgType=El tipo de mensaje no puede estar vac\u00edo  
+NotNull.ownerUid=El n\u00famero de usuario no puede estar vac\u00edo
+NotNull.otherUid=El n\u00famero de la otra parte no puede estar vac\u00edo
+Length.content=La longitud del contenido del mensaje no puede exceder de 1000
+NotBlank.verifyParam=El par\u00e1metro del c\u00f3digo de verificaci\u00f3n no puede estar vac\u00edo

+ 12 - 3
qnfhq-api/src/main/resources/i18n/validation_fr.properties

@@ -24,8 +24,7 @@ NotNull.status=Le statut ne peut pas \u00eatre vide
 NotNull.payType=Le mode de paiement ne peut pas \u00eatre vide  
 NotBlank.receiptInfo=Les informations de r\u00e9ception ne peuvent pas \u00eatre vides  
 NotNull.c2cAdId=Le num\u00e9ro de l'annonce ne peut pas \u00eatre vide  
-NotNull.tranAmount=Le montant de la transaction ne peut pas \u00eatre vide  
-NotNull.tranBy=Le mode de transaction ne peut pas \u00eatre vide  
+NotNull.tranAmount=Le montant de la transaction ne peut pas \u00eatre vide
 NotNull.oId=Le num\u00e9ro de commande ne peut pas \u00eatre vide  
 NotBlank.img=La preuve de paiement ne peut pas \u00eatre vide  
 NotNull.id=Le num\u00e9ro ne peut pas \u00eatre vide  
@@ -36,4 +35,14 @@ NotBlank.reason=La raison de la plainte ne peut pas \u00eatre vide
 NotBlank.remark=La description de la preuve ne peut pas \u00eatre vide  
 NotBlank.img1=La capture d'\u00e9cran de la preuve 1 ne peut pas \u00eatre vide  
 NotNull.complainId=Le num\u00e9ro de la plainte ne peut pas \u00eatre vide  
-NotBlank.country=Le pays ne peut pas \u00eatre vide
+NotBlank.country=Le pays ne peut pas \u00eatre vide
+NotNull.tag=Le tag ne peut pas \u00eatre vide  
+NotNull.unit=L'unit\u00e9 de transaction ne peut pas \u00eatre vide  
+NotBlank.senderId=L'exp\u00e9diteur ne peut pas \u00eatre vide  
+NotBlank.recipientId=Le destinataire ne peut pas \u00eatre vide  
+NotBlank.content=Le contenu du message ne peut pas \u00eatre vide  
+NotBlank.msgType=Le type de message ne peut pas \u00eatre vide  
+NotNull.ownerUid=Le num\u00e9ro d'utilisateur ne peut pas \u00eatre vide
+NotNull.otherUid=Le num\u00e9ro de l'autre partie ne peut pas \u00eatre nul  
+Length.content=La longueur du contenu du message ne peut pas d\u00e9passer 1000  
+NotBlank.verifyParam=Le param\u00e8tre du code de v\u00e9rification ne peut pas \u00eatre vide

+ 11 - 2
qnfhq-api/src/main/resources/i18n/validation_ja.properties

@@ -25,7 +25,6 @@ NotNull.payType=\u652f\u6255\u3044\u30bf\u30a4\u30d7\u3092\u7a7a\u306b\u3067\u30
 NotBlank.receiptInfo=\u53d7\u53d6\u60c5\u5831\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotNull.c2cAdId=\u5e83\u544a\u756a\u53f7\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotNull.tranAmount=\u53d6\u5f15\u91d1\u984d\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
-NotNull.tranBy=\u53d6\u5f15\u65b9\u6cd5\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotNull.oId=\u6ce8\u6587\u756a\u53f7\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotBlank.img=\u652f\u6255\u3044\u8a3c\u660e\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotNull.id=\u756a\u53f7\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
@@ -36,4 +35,14 @@ NotBlank.reason=\u7533\u7acb\u7406\u7531\u3092\u7a7a\u306b\u3067\u304d\u307e\u30
 NotBlank.remark=\u8a3c\u660e\u306e\u8aac\u660e\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotBlank.img1=\u8a3c\u660e\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c81\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotNull.complainId=\u7533\u7acb\u756a\u53f7\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
-NotBlank.country=\u56fd\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotBlank.country=\u56fd\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotNull.tag=\u30bf\u30b0\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotNull.unit=\u53d6\u5f15\u5358\u4f4d\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotBlank.senderId=\u9001\u4fe1\u8005\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotBlank.recipientId=\u53d7\u4fe1\u8005\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotBlank.content=\u30e1\u30c3\u30bb\u30fc\u30b8\u5185\u5bb9\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotBlank.msgType=\u30e1\u30c3\u30bb\u30fc\u30b8\u30bf\u30a4\u30d7\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotNull.ownerUid=\u30e6\u30fc\u30b6\u30fc\u756a\u53f7\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotNull.otherUid=\u76f8\u624b\u306e\u756a\u53f7\u3092\u7a7a\u306b\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093
+Length.content=\u30e1\u30c3\u30bb\u30fc\u30b8\u5185\u5bb9\u306e\u9577\u3055\u306f1000\u3092\u8d85\u3048\u3066\u306f\u3044\u3051\u307e\u305b\u3093
+NotBlank.verifyParam=\u691c\u8a3c\u30b3\u30fc\u30c9\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u7a7a\u306b\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093

+ 12 - 3
qnfhq-api/src/main/resources/i18n/validation_ko.properties

@@ -24,8 +24,7 @@ NotNull.status=\uc0c1\ud0dc\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\u
 NotNull.payType=\uacb0\uc81c \ubc29\uc2dd\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
 NotBlank.receiptInfo=\uc218\ucde8 \uc815\ubcf4\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
 NotNull.c2cAdId=\uad11\uace0 \ubc88\ud638\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
-NotNull.tranAmount=\uac70\ub798 \uae08\uc561\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
-NotNull.tranBy=\uac70\ub798 \ubc29\uc2dd\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
+NotNull.tranAmount=\uac70\ub798 \uae08\uc561\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
 NotNull.oId=\uc8fc\ubb38 \ubc88\ud638\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
 NotBlank.img=\uacb0\uc81c \uc99d\uba85\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
 NotNull.id=\ubc88\ud638\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
@@ -36,4 +35,14 @@ NotBlank.reason=\uc2e0\uace0 \uc0ac\uc720\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6
 NotBlank.remark=\uc99d\ube59 \uc124\uba85\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
 NotBlank.img1=\uc99d\ube59 \uc2a4\ud06c\ub9b0\uc0f71\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
 NotNull.complainId=\uc2e0\uace0 \ubc88\ud638\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
-NotBlank.country=\uad6d\uac00\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.country=\uad6d\uac00\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotNull.tag=\ud0dc\uadf8\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotNull.unit=\uac70\ub798 \ub2e8\uc704\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.senderId=\ubcf4\ub0b4\ub294 \uc0ac\ub78c\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.recipientId=\ubc1b\ub294 \uc0ac\ub78c\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.content=\uba54\uc2dc\uc9c0 \ub0b4\uc6a9\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.msgType=\uba54\uc2dc\uc9c0 \uc720\ud615\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotNull.ownerUid=\uc0ac\uc6a9\uc790 \ubc88\ud638\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotNull.otherUid=\uc0c1\ub300\ubc29 \ubc88\ud638\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
+Length.content=\uba54\uc2dc\uc9c0 \ub0b4\uc6a9 \uae38\uc774\ub294 1000\uc790\ub97c \ucd08\uacfc\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
+NotBlank.verifyParam=\uc778\uc99d \ucf54\ub4dc \ub9e4\uac1c\ubcc0\uc218\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4

+ 10 - 1
qnfhq-api/src/main/resources/i18n/validation_th.properties

@@ -25,7 +25,6 @@ NotNull.payType=\u0e27\u0e34\u0e18\u0e35\u0e01\u0e32\u0e23\u0e0a\u0e33\u0e23\u0e
 NotBlank.receiptInfo=\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e01\u0e32\u0e23\u0e23\u0e31\u0e1a\u0e0a\u0e33\u0e23\u0e30\u0e40\u0e07\u0e34\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotNull.c2cAdId=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e42\u0e06\u0e29\u0e13\u0e32 C2C \u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotNull.tranAmount=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e40\u0e07\u0e34\u0e19\u0e17\u0e35\u0e48\u0e17\u0e33\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
-NotNull.tranBy=\u0e27\u0e34\u0e18\u0e35\u0e01\u0e32\u0e23\u0e17\u0e33\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotNull.oId=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e40\u0e1b\u0e47\u0e19\u0e04\u0e48\u0e32\u0e27\u0e48\u0e32\u0e07\u0e44\u0e14\u0e49
 NotBlank.img=\u0e2b\u0e25\u0e31\u0e01\u0e10\u0e32\u0e19\u0e01\u0e32\u0e23\u0e0a\u0e33\u0e23\u0e30\u0e40\u0e07\u0e34\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotNull.id=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
@@ -37,3 +36,13 @@ NotBlank.remark=\u0e04\u0e33\u0e2d\u0e18\u0e34\u0e1a\u0e32\u0e22\u0e2b\u0e25\u0e
 NotBlank.img1=\u0e20\u0e32\u0e1e\u0e2b\u0e25\u0e31\u0e01\u0e10\u0e32\u0e19\u0e17\u0e35\u0e48 1 \u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotNull.complainId=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e01\u0e32\u0e23\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotBlank.country=\u0e1b\u0e23\u0e30\u0e40\u0e17\u0e28\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotNull.tag=\u0e41\u0e17\u0e47\u0e01\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotNull.unit=\u0e2b\u0e19\u0e48\u0e27\u0e22\u0e01\u0e32\u0e23\u0e0b\u0e37\u0e49\u0e2d\u0e02\u0e32\u0e22\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotBlank.senderId=\u0e1c\u0e39\u0e49\u0e2a\u0e48\u0e07\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotBlank.recipientId=\u0e1c\u0e39\u0e49\u0e23\u0e31\u0e1a\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotBlank.content=\u0e40\u0e19\u0e37\u0e49\u0e2d\u0e2b\u0e32\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotBlank.msgType=\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotNull.ownerUid=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotNull.otherUid=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e1d\u0e48\u0e32\u0e22\u0e15\u0e23\u0e07\u0e02\u0e49\u0e32\u0e21\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07\u0e40\u0e1b\u0e25\u0e48\u0e32
+Length.content=\u0e04\u0e27\u0e32\u0e21\u0e22\u0e32\u0e27\u0e40\u0e19\u0e37\u0e49\u0e2d\u0e2b\u0e32\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e40\u0e01\u0e34\u0e19 1000
+NotBlank.verifyParam=\u0e1e\u0e32\u0e23\u0e32\u0e21\u0e34\u0e40\u0e15\u0e2d\u0e23\u0e4c\u0e23\u0e2b\u0e31\u0e2a\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07\u0e40\u0e1b\u0e25\u0e48\u0e32

+ 11 - 2
qnfhq-api/src/main/resources/i18n/validation_tw.properties

@@ -25,7 +25,6 @@ NotNull.payType=\u652f\u4ed8\u65b9\u5f0f\u4e0d\u80fd\u70ba\u7a7a
 NotBlank.receiptInfo=\u6536\u6b3e\u4fe1\u606f\u4e0d\u80fd\u7a7a
 NotNull.c2cAdId=\u5ee3\u544a\u7de8\u865f\u4e0d\u80fd\u70ba\u7a7a
 NotNull.tranAmount=\u4ea4\u6613\u91d1\u984d\u4e0d\u80fd\u70ba\u7a7a
-NotNull.tranBy=\u4ea4\u6613\u65b9\u5f0f\u4e0d\u80fd\u70ba\u7a7a
 NotNull.oId=\u8a02\u55ae\u7de8\u865f\u4e0d\u80fd\u70ba\u7a7a
 NotBlank.img=\u652f\u4ed8\u6191\u8b49\u4e0d\u80fd\u70ba\u7a7a
 NotNull.id=\u7de8\u865f\u4e0d\u80fd\u70ba\u7a7a
@@ -36,4 +35,14 @@ NotBlank.reason=\u7533\u8a34\u539f\u56e0\u4e0d\u80fd\u70ba\u7a7a
 NotBlank.remark=\u6191\u8b49\u63cf\u8ff0\u4e0d\u80fd\u70ba\u7a7a
 NotBlank.img1=\u6191\u8b49\u622a\u57161\u4e0d\u80fd\u70ba\u7a7a
 NotNull.complainId=\u7533\u8a34\u7de8\u865f\u4e0d\u80fd\u70ba\u7a7a
-NotBlank.country=\u570b\u5bb6\u4e0d\u80fd\u70ba\u7a7a
+NotBlank.country=\u570b\u5bb6\u4e0d\u80fd\u70ba\u7a7a
+NotNull.tag=\u6a19\u7c64\u4e0d\u80fd\u70ba\u7a7a
+NotNull.unit=\u4ea4\u6613\u55ae\u4f4d\u4e0d\u80fd\u70ba\u7a7a
+NotBlank.senderId=\u767c\u9001\u4eba\u4e0d\u80fd\u7a7a
+NotBlank.recipientId=\u63a5\u6536\u4eba\u4e0d\u80fd\u7a7a
+NotBlank.content=\u6d88\u606f\u5167\u5bb9\u4e0d\u80fd\u7a7a
+NotBlank.msgType=\u6d88\u606f\u985e\u578b\u4e0d\u80fd\u7a7a
+NotNull.ownerUid=\u7528\u6236\u7de8\u865f\u4e0d\u80fd\u70ba\u7a7a
+NotNull.otherUid=????????
+Length.content=??????????1000
+NotBlank.verifyParam=?????????

+ 10 - 1
qnfhq-api/src/main/resources/i18n/validation_vi.properties

@@ -25,7 +25,6 @@ NotNull.payType=Ph\u01b0\u01a1ng th\u1ee9c thanh to\u00e1n kh\u00f4ng \u0111\u01
 NotBlank.receiptInfo=Th\u00f4ng tin nh\u1eadn ti\u1ec1n kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotNull.c2cAdId=M\u00e3 qu\u1ea3ng c\u00e1o kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotNull.tranAmount=S\u1ed1 ti\u1ec1n giao d\u1ecbch kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
-NotNull.tranBy=Ph\u01b0\u01a1ng th\u1ee9c giao d\u1ecbch kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotNull.oId=M\u00e3 \u0111\u01a1n h\u00e0ng kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotBlank.img=B\u1eb1ng ch\u1ee9ng thanh to\u00e1n kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotNull.id=M\u00e3 s\u1ed1 kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
@@ -37,3 +36,13 @@ NotBlank.remark=M\u00f4 t\u1ea3 b\u1eb1ng ch\u1ee9ng kh\u00f4ng \u0111\u01b0\u1e
 NotBlank.img1=\u1ea2nh ch\u1ee5p b\u1eb1ng ch\u1ee9ng 1 kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotNull.complainId=M\u00e3 khi\u1ebfu n\u1ea1i kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotBlank.country=Qu\u1ed1c gia kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotNull.tag=Th\u1ebb kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotNull.unit=\u0110\u01a1n v\u1ecb giao d\u1ecbch kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotBlank.senderId=Ng\u01b0\u1eddi g\u1eedi kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotBlank.recipientId=Ng\u01b0\u1eddi nh\u1eadn kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotBlank.content=N\u1ed9i dung tin nh\u1eafn kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotBlank.msgType=Lo\u1ea1i tin nh\u1eafn kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotNull.ownerUid=M\u00e3 ng\u01b0\u1eddi d\u00f9ng kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotNull.otherUid=M\u00e3 s\u1ed1 \u0111\u1ed1i ph\u01b0\u01a1ng kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+Length.content=\u0110\u1ed9 d\u00e0i n\u1ed9i dung tin nh\u1eafn kh\u00f4ng \u0111\u01b0\u1ee3c v\u01b0\u1ee3t qu\u00e1 1000
+NotBlank.verifyParam=Tham s\u1ed1 m\u00e3 x\u00e1c minh kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng

+ 12 - 2
qnfhq-api/src/main/resources/i18n/validation_zh.properties

@@ -25,7 +25,6 @@ NotNull.payType=\u652f\u4ed8\u65b9\u5f0f\u4e0d\u80fd\u4e3a\u7a7a
 NotBlank.receiptInfo=\u6536\u6b3e\u4fe1\u606f\u4e0d\u80fd\u7a7a
 NotNull.c2cAdId=\u5e7f\u544a\u7f16\u53f7\u4e0d\u80fd\u4e3a\u7a7a
 NotNull.tranAmount=\u4ea4\u6613\u91d1\u989d\u4e0d\u80fd\u4e3a\u7a7a
-NotNull.tranBy=\u4ea4\u6613\u65b9\u5f0f\u4e0d\u80fd\u4e3a\u7a7a
 NotNull.oId=\u8ba2\u5355\u7f16\u53f7\u4e0d\u80fd\u4e3a\u7a7a
 NotBlank.img=\u652f\u4ed8\u51ed\u8bc1\u4e0d\u80fd\u4e3a\u7a7a
 NotNull.id=\u7f16\u53f7\u4e0d\u80fd\u4e3a\u7a7a
@@ -36,4 +35,15 @@ NotBlank.reason=\u7533\u8bc9\u539f\u56e0\u4e0d\u80fd\u4e3a\u7a7a
 NotBlank.remark=\u51ed\u8bc1\u63cf\u8ff0\u4e0d\u80fd\u4e3a\u7a7a
 NotBlank.img1=\u51ed\u8bc1\u622a\u56fe1\u4e0d\u80fd\u4e3a\u7a7a
 NotNull.complainId=\u7533\u8bc9\u7f16\u53f7\u4e0d\u80fd\u4e3a\u7a7a
-NotBlank.country=\u56fd\u5bb6\u4e0d\u80fd\u4e3a\u7a7a
+NotBlank.country=\u56fd\u5bb6\u4e0d\u80fd\u4e3a\u7a7a
+
+NotNull.tag=\u6807\u7b7e\u4e0d\u80fd\u4e3a\u7a7a
+NotNull.unit=\u4ea4\u6613\u5355\u4f4d\u4e0d\u80fd\u4e3a\u7a7a
+NotBlank.senderId=\u53d1\u9001\u4eba\u4e0d\u80fd\u7a7a
+NotBlank.recipientId=\u63a5\u6536\u4eba\u4e0d\u80fd\u7a7a
+NotBlank.content=\u6d88\u606f\u5185\u5bb9\u4e0d\u80fd\u7a7a
+NotBlank.msgType=\u6d88\u606f\u7c7b\u578b\u4e0d\u80fd\u7a7a
+NotNull.ownerUid=\u7528\u6237\u7f16\u53f7\u4e0d\u80fd\u4e3a\u7a7a
+NotNull.otherUid=\u5bf9\u65b9\u7f16\u53f7\u4e0d\u80fd\u4e3a\u7a7a
+Length.content=\u6d88\u606f\u5185\u5bb9\u957f\u5ea6\u4e0d\u80fd\u8d85\u8fc71000
+NotBlank.verifyParam=\u9a8c\u8bc1\u7801\u53c2\u6570\u4e0d\u80fd\u4e3a\u7a7a

+ 2 - 0
qnfhq-api/src/main/resources/mapper/c2c/C2cAdDao.xml

@@ -25,6 +25,8 @@
         <result property="updateTime" column="update_time"/>
         <result property="reason" column="reason"/>
         <result property="version" column="version"/>
+        <result property="tag" column="tag"/>
+
     </resultMap>
 
     <update id="updateC2cAdAvailableNumById" parameterType="java.util.Map">

+ 6 - 0
qnfhq-api/src/main/resources/mapper/c2c/C2cMerchantDao.xml

@@ -27,6 +27,12 @@
         <result property="firstTranNum" column="first_tran_num"/>
         <result property="firstTranTime" column="first_tran_time"/>
         <result property="operateTime" column="operate_time"/>
+        <result property="tag" column="tag"/>
+        <result property="day30BuyNum" column="day30_buy_num"/>
+        <result property="day30SellNum" column="day30_sell_num"/>
+        <result property="day30TranUserNum" column="day30_tran_user_num"/>
+        <result property="averagePayTime" column="average_pay_time"/>
+        <result property="averagePassTime" column="average_pass_time"/>
     </resultMap>
 
 

+ 17 - 0
qnfhq-api/src/main/resources/mapper/c2c/C2cMsgContactDao.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.qnfhq.modules.c2c.dao.C2cMsgContactDao">
+
+    <resultMap type="com.qnfhq.modules.c2c.entity.C2cMsgContactEntity" id="c2cMsgContactMap">
+        <result property="ownerUid" column="owner_uid"/>
+        <result property="otherUid" column="other_uid"/>
+        <result property="otherNickname" column="other_nickname"/>
+        <result property="otherAvatar" column="other_avatar"/>
+        <result property="mid" column="mid"/>
+        <result property="msgType" column="msg_type"/>
+        <result property="createTime" column="create_time"/>
+    </resultMap>
+
+
+</mapper>

+ 17 - 0
qnfhq-api/src/main/resources/mapper/c2c/C2cMsgContentDao.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.qnfhq.modules.c2c.dao.C2cMsgContentDao">
+
+    <resultMap type="com.qnfhq.modules.c2c.entity.C2cMsgContentEntity" id="c2cMsgContentMap">
+        <result property="mid" column="mid"/>
+        <result property="senderId" column="sender_id"/>
+        <result property="recipientId" column="recipient_id"/>
+        <result property="content" column="content"/>
+        <result property="msgType" column="msg_type"/>
+        <result property="status" column="status"/>
+        <result property="sendTime" column="send_time"/>
+    </resultMap>
+
+
+</mapper>

+ 15 - 0
qnfhq-api/src/main/resources/mapper/c2c/C2cMsgRelationDao.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.qnfhq.modules.c2c.dao.C2cMsgRelationDao">
+
+    <resultMap type="com.qnfhq.modules.c2c.entity.C2cMsgRelationEntity" id="c2cMsgRelationMap">
+        <result property="mid" column="mid"/>
+        <result property="ownerUid" column="owner_uid"/>
+        <result property="otherUid" column="other_uid"/>
+        <result property="type" column="type"/>
+        <result property="createTime" column="create_time"/>
+    </resultMap>
+
+
+</mapper>

+ 8 - 8
qnfhq-api/src/main/resources/mapper/c2c/C2cOrderDao.xml

@@ -18,13 +18,15 @@
         <result property="symbolNum" column="symbol_num"/>
         <result property="tranAmount" column="tran_amount"/>
         <result property="payType" column="pay_type"/>
+        <result property="payTime" column="pay_time"/>
         <result property="flow" column="flow"/>
         <result property="status" column="status"/>
         <result property="remark" column="remark"/>
         <result property="createTime" column="create_time"/>
         <result property="updateTime" column="update_time"/>
-        <result property="endTime" column="end_time"/>
-        <result property="expireTime" column="expire_time"/>
+        <result property="payExpireTime" column="pay_expire_time"/>
+        <result property="finishTime" column="finish_time"/>
+        <result property="closeTime" column="close_time"/>
     </resultMap>
 
     <insert id="insertC2cOrder" parameterType="com.qnfhq.modules.c2c.entity.C2cOrderEntity" useGeneratedKeys="true" keyProperty="id">
@@ -48,8 +50,7 @@
             <if test="remark != null">remark,</if>
             <if test="createTime != null">create_time,</if>
             <if test="updateTime != null">update_time,</if>
-            <if test="endTime != null">end_time,</if>
-            expire_time,
+            pay_expire_time,
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="orderNo != null">#{orderNo},</if>
@@ -68,10 +69,9 @@
             <if test="flow != null">#{flow},</if>
             <if test="status != null">#{status},</if>
             <if test="remark != null">#{remark},</if>
-            <if test="createTime != null">#{createTime},</if>
-            <if test="updateTime != null">#{updateTime},</if>
-            <if test="endTime != null">#{endTime},</if>
-            UNIX_TIMESTAMP()+1800
+            <if test="createTime != null">NOW(),</if>
+            <if test="updateTime != null">NOW(),</if>
+             DATE_ADD(NOW(), INTERVAL 30 MINUTE)
         </trim>
     </insert>
 </mapper>

部分文件因文件數量過多而無法顯示