4 Commits 0442331c3e ... 21ceef8fb1

Autor SHA1 Mensagem Data
  30262728@qq.com 21ceef8fb1 Merge branch 'master' of http://git.qiniu1314.com/yelz/blockchain-refactor há 10 horas atrás
  30262728@qq.com 4d0481b0ec 合并 há 10 horas atrás
  30262728@qq.com f8977d11c0 币币交易下单 há 10 horas atrás
  30262728@qq.com 1dc2a37e9d c2c申诉和举报 há 4 dias atrás
100 ficheiros alterados com 3348 adições e 572 exclusões
  1. 7 0
      qnfhq-api/pom.xml
  2. 23 2
      qnfhq-api/src/main/java/com/qnfhq/config/SaTokenConfigure.java
  3. 2 2
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/C2cAdController.java
  4. 184 110
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/C2cOrderController.java
  5. 75 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/OrderReportController.java
  6. 3 3
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/C2cOrderVoucherDao.java
  7. 16 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/OrderReportDao.java
  8. 2 2
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cAdCreateDTO.java
  9. 1 1
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cAdLogDTO.java
  10. 2 2
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cAdTranDTO.java
  11. 2 2
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cAdViewDTO.java
  12. 1 1
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderCancelDTO.java
  13. 11 3
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderComplainDTO.java
  14. 0 51
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderComplainVoucherDTO.java
  15. 30 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderComplainVoucherIDDTO.java
  16. 30 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderConfirmPayDTO.java
  17. 2 2
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderCreateDTO.java
  18. 0 105
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderDTO.java
  19. 39 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderVoucherDTO.java
  20. 47 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/OrderReportDTO.java
  21. 1 1
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/setting/AdSetting.java
  22. 12 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/setting/ComplainReasonSetting.java
  23. 14 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/setting/ReportReasonSetting.java
  24. 1 1
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cAdEntity.java
  25. 1 1
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cAdLogEntity.java
  26. 14 1
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cOrderComplainEntity.java
  27. 7 2
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cOrderEntity.java
  28. 10 21
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cOrderVoucherEntity.java
  29. 1 4
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cPaymentVoucherEntity.java
  30. 70 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/OrderReportEntity.java
  31. 0 16
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cOrderComplainVoucherService.java
  32. 16 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cOrderVoucherService.java
  33. 14 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/OrderReportService.java
  34. 1 1
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cAdLogServiceImpl.java
  35. 20 20
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cAdServiceImpl.java
  36. 0 31
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cOrderComplainVoucherServiceImpl.java
  37. 40 41
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cOrderServiceImpl.java
  38. 31 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cOrderVoucherServiceImpl.java
  39. 1 9
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cPaymentVoucherServiceImpl.java
  40. 31 0
      qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/OrderReportServiceImpl.java
  41. 186 0
      qnfhq-api/src/main/java/com/qnfhq/modules/common/controller/CommonController.java
  42. 31 0
      qnfhq-api/src/main/java/com/qnfhq/modules/common/dto/setting/OssSetting.java
  43. 55 0
      qnfhq-api/src/main/java/com/qnfhq/modules/common/dto/setting/TRechargeChannelSetting.java
  44. 10 0
      qnfhq-api/src/main/java/com/qnfhq/modules/common/service/FileService.java
  45. 66 0
      qnfhq-api/src/main/java/com/qnfhq/modules/common/service/impl/FileServiceImpl.java
  46. 151 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/controller/TCurrencyOrderController.java
  47. 16 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/dao/TCurrencyOrderDao.java
  48. 16 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/dao/TCurrencySymbolDao.java
  49. 27 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/dto/TCurrencyOrderCancelDTO.java
  50. 42 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/dto/TCurrencyOrderQueryDTO.java
  51. 54 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/dto/TCurrencyOrderSubmitDTO.java
  52. 111 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/dto/TCurrencySymbolDTO.java
  53. 111 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/entity/TCurrencyOrderEntity.java
  54. 138 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/entity/TCurrencySymbolEntity.java
  55. 38 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/enums/CurrencyOrderStatusEnum.java
  56. 36 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/enums/DelegateDirectionEnum.java
  57. 36 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/enums/DelegateTypeEnum.java
  58. 35 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/service/TCurrencyOrderService.java
  59. 22 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/service/TCurrencySymbolService.java
  60. 256 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/service/impl/TCurrencyOrderServiceImpl.java
  61. 45 0
      qnfhq-api/src/main/java/com/qnfhq/modules/trade/service/impl/TCurrencySymbolServiceImpl.java
  62. 20 4
      qnfhq-api/src/main/java/com/qnfhq/modules/user/controller/ApiAppUserController.java
  63. 13 2
      qnfhq-api/src/main/java/com/qnfhq/modules/user/dao/AppAssetDao.java
  64. 1 1
      qnfhq-api/src/main/java/com/qnfhq/modules/user/dto/AppAssetDTO.java
  65. 3 14
      qnfhq-api/src/main/java/com/qnfhq/modules/user/dto/AppLoginDTO.java
  66. 2 2
      qnfhq-api/src/main/java/com/qnfhq/modules/user/entity/AppAssetEntity.java
  67. 1 1
      qnfhq-api/src/main/java/com/qnfhq/modules/user/entity/AppUserDetailEntity.java
  68. 5 2
      qnfhq-api/src/main/java/com/qnfhq/modules/user/enums/AssetEnum.java
  69. 314 0
      qnfhq-api/src/main/java/com/qnfhq/modules/user/enums/CountryCodeAndPhoneCodeEnum.java
  70. 6 2
      qnfhq-api/src/main/java/com/qnfhq/modules/user/enums/SettingEnum.java
  71. 15 0
      qnfhq-api/src/main/java/com/qnfhq/modules/user/service/AppAssetService.java
  72. 11 4
      qnfhq-api/src/main/java/com/qnfhq/modules/user/service/AppUserService.java
  73. 42 23
      qnfhq-api/src/main/java/com/qnfhq/modules/user/service/impl/AppAssetServiceImpl.java
  74. 0 1
      qnfhq-api/src/main/java/com/qnfhq/modules/user/service/impl/AppUserDetailServiceImpl.java
  75. 53 12
      qnfhq-api/src/main/java/com/qnfhq/modules/user/service/impl/AppUserServiceImpl.java
  76. 230 0
      qnfhq-api/src/main/java/com/qnfhq/utils/AliOssCloudUtil.java
  77. 24 5
      qnfhq-api/src/main/resources/i18n/messages.properties
  78. 26 5
      qnfhq-api/src/main/resources/i18n/messages_de.properties
  79. 25 6
      qnfhq-api/src/main/resources/i18n/messages_en.properties
  80. 26 5
      qnfhq-api/src/main/resources/i18n/messages_es.properties
  81. 26 5
      qnfhq-api/src/main/resources/i18n/messages_fr.properties
  82. 24 4
      qnfhq-api/src/main/resources/i18n/messages_ja.properties
  83. 24 3
      qnfhq-api/src/main/resources/i18n/messages_ko.properties
  84. 26 5
      qnfhq-api/src/main/resources/i18n/messages_th.properties
  85. 24 3
      qnfhq-api/src/main/resources/i18n/messages_tw.properties
  86. 26 5
      qnfhq-api/src/main/resources/i18n/messages_vi.properties
  87. 25 3
      qnfhq-api/src/main/resources/i18n/messages_zh.properties
  88. 10 3
      qnfhq-api/src/main/resources/i18n/validation.properties
  89. 10 1
      qnfhq-api/src/main/resources/i18n/validation_de.properties
  90. 10 3
      qnfhq-api/src/main/resources/i18n/validation_en.properties
  91. 10 1
      qnfhq-api/src/main/resources/i18n/validation_es.properties
  92. 10 1
      qnfhq-api/src/main/resources/i18n/validation_fr.properties
  93. 10 1
      qnfhq-api/src/main/resources/i18n/validation_ja.properties
  94. 10 1
      qnfhq-api/src/main/resources/i18n/validation_ko.properties
  95. 10 1
      qnfhq-api/src/main/resources/i18n/validation_th.properties
  96. 10 1
      qnfhq-api/src/main/resources/i18n/validation_tw.properties
  97. 11 2
      qnfhq-api/src/main/resources/i18n/validation_vi.properties
  98. 9 3
      qnfhq-api/src/main/resources/i18n/validation_zh.properties
  99. 1 1
      qnfhq-api/src/main/resources/mapper/c2c/C2cAdDao.xml
  100. 1 1
      qnfhq-api/src/main/resources/mapper/c2c/C2cAdLogDao.xml

+ 7 - 0
qnfhq-api/pom.xml

@@ -86,6 +86,13 @@
             <version>${aliyun.captcha.version}</version>
         </dependency>
 
+        <!-- oss存储 -->
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>3.10.2</version>
+        </dependency>
+
         <!--        <dependency>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-starter-websocket</artifactId>

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

@@ -33,6 +33,7 @@ public class SaTokenConfigure {
 //                .addExclude("/**")
                 .addExclude(
                         "/user/register",
+                        "/user/checkPass",
                         "/user/login",
                         "/user/verifyIntelligentCaptcha",
                         "/user/sendEmailCode",
@@ -41,7 +42,8 @@ public class SaTokenConfigure {
                         "/user/resetPwdEmail",
                         "/user/checkPhoneCode",
                         "/user/checkEmailCode",
-                        "/swagger-ui.html","/swagger-ui/**","/v3/api-docs/**"
+                        "/swagger-ui.html","/swagger-ui/**","/v3/api-docs/**",
+                        "/user/getCountryCode"
 
                 )
                 // 认证函数: 每次请求执行
@@ -70,8 +72,27 @@ public class SaTokenConfigure {
                             // 是否启用浏览器默认XSS防护: 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时,停止渲染页面
                             .setHeader("X-XSS-Protection", "1; mode=block")
                             // 禁用浏览器内容嗅探
-                            .setHeader("X-Content-Type-Options", "nosniff");
+                            .setHeader("X-Content-Type-Options", "nosniff")
+
+                            // ---------- 设置跨域响应头 ----------
+                            // 允许指定域访问跨域资源
+//        			        .setHeader("Access-Control-Allow-Origin", "*")
+                            // 允许所有请求方式
+//                            .setHeader("Access-Control-Allow-Methods", "*")
+                            // 允许的header参数
+//                            .setHeader("Access-Control-Allow-Headers", "*")
+                            // 有效时间
+//                            .setHeader("Access-Control-Max-Age", "3600")
+                            ;
+
+                    // 如果是预检请求,则立即返回到前端
+//                    SaRouter.match(SaHttpMethod.OPTIONS)
+//                            .free(a -> System.out.println("--------OPTIONS预检请求,不做处理"))
+//                            .back();
+
                 })
                 ;
     }
+
+
 }

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

@@ -78,7 +78,7 @@ public class C2cAdController extends ApiBaseController {
         if(!DirectionEnum.isValidCode(direction)) {
             return result.error(MessageUtils.message("merchant.param.direction.invalid"));//参数direction值不正确
         }
-        String symbol = request.getSymbol().toLowerCase();
+        String symbol = request.getCoin().toLowerCase();
         String legalCoin = request.getLegalCoin().toUpperCase();
         Integer priceType = request.getPriceType();
         BigDecimal price = request.getPrice();//价格
@@ -107,7 +107,7 @@ public class C2cAdController extends ApiBaseController {
         SettingEntity setting = settingService.getSetting(SettingEnum.AD_SETTING.name());
         List<AdSetting> adSettingsList = JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), AdSetting.class);
         if (!CollectionUtils.isEmpty(adSettingsList)) {
-            Map<String, List<AdSetting>> symbolGroup = adSettingsList.stream().collect(Collectors.groupingBy(AdSetting::getSymbol));
+            Map<String, List<AdSetting>> symbolGroup = adSettingsList.stream().collect(Collectors.groupingBy(AdSetting::getCoin));
             List<AdSetting> symbolSettingList = symbolGroup.get(symbol);
             AdSetting adSet = null;
             for(AdSetting adSetting : symbolSettingList) {

+ 184 - 110
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/C2cOrderController.java

@@ -19,13 +19,14 @@ import com.qnfhq.common.validator.ValidatorUtils;
 import com.qnfhq.constant.CacheConstants;
 import com.qnfhq.modules.c2c.dto.*;
 import com.qnfhq.modules.c2c.dto.setting.CancelReasonSetting;
-import com.qnfhq.modules.c2c.dto.setting.ReviewSetting;
+import com.qnfhq.modules.c2c.dto.setting.ComplainReasonSetting;
 import com.qnfhq.modules.c2c.entity.*;
 import com.qnfhq.modules.c2c.enums.AdStatusEnum;
 import com.qnfhq.modules.c2c.enums.C2cOrderFlowEnum;
 import com.qnfhq.modules.c2c.enums.C2cOrderStatusEnum;
 import com.qnfhq.modules.c2c.enums.DirectionEnum;
 import com.qnfhq.modules.c2c.service.*;
+import com.qnfhq.modules.common.service.FileService;
 import com.qnfhq.modules.user.entity.AppAssetEntity;
 import com.qnfhq.modules.user.entity.AppUserDetailEntity;
 import com.qnfhq.modules.user.entity.AppUserEntity;
@@ -41,12 +42,16 @@ 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.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.*;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * c2c订单
@@ -90,11 +95,13 @@ public class C2cOrderController extends ApiBaseController {
     private C2cOrderComplainService orderComplainService;
 
     @Resource
-    private C2cOrderComplainVoucherService orderComplainVoucherService;
+    private C2cOrderVoucherService orderComplainVoucherService;
     @Resource
     private AppUserService appUserService;
     @Resource
     private C2cUserStatService c2cUserStatService;
+    @Autowired
+    private C2cOrderVoucherService c2cOrderVoucherService;
 
 
     private String getC2cAdLockKey(String adId) {
@@ -146,7 +153,7 @@ public class C2cOrderController extends ApiBaseController {
         if(direction.intValue() == DirectionEnum.SELL.getCode().intValue()) {
             AppAssetEntity tAppAsset = new AppAssetEntity();
             tAppAsset.setUserId(loginUserId);
-            tAppAsset.setSymbol(c2cOrder.getSymbol());
+            tAppAsset.setCoin(c2cOrder.getCoin());
             tAppAsset.setType(AssetEnum.PLATFORM_ASSETS.getCode());
             List<AppAssetEntity> assetList = appAssetService.selectList(tAppAsset);
             if(assetList==null || assetList.size()==0) {
@@ -165,14 +172,14 @@ public class C2cOrderController extends ApiBaseController {
         if(c2cAd==null) {
             //清除缓存
             Integer adDirection = direction.intValue() == DirectionEnum.SELL.getCode().intValue() ? DirectionEnum.BUY.getCode() : DirectionEnum.SELL.getCode();
-            c2cAdService.deleteAdCache(c2cOrder.getC2cAdId(), c2cOrder.getPayType().toString(), c2cOrder.getLegalCoin(), c2cOrder.getSymbol(), adDirection);
+            c2cAdService.deleteAdCache(c2cOrder.getC2cAdId(), c2cOrder.getPayType().toString(), c2cOrder.getLegalCoin(), c2cOrder.getCoin(), adDirection);
             return error(MessageUtils.message("c2c.order.param.adid"));//广告编号无效
         }
         if(c2cAd.getStatus().intValue()== AdStatusEnum.NOPASS.getCode()) {
             //清除缓存
             Integer adDirection = c2cAd.getDirection();
             String adLegalCoin = c2cAd.getLegalCoin();
-            String adSymbol = c2cAd.getSymbol();
+            String adSymbol = c2cAd.getCoin();
             String adPayway = c2cAd.getPayway().replaceAll("^,|,$", "");
             c2cAdService.deleteAdCache(c2cAd.getId(), adPayway, adLegalCoin, adSymbol, adDirection);
             return error(MessageUtils.message("c2c.order.param.adid.invalid"));//广告已不可用
@@ -184,7 +191,7 @@ public class C2cOrderController extends ApiBaseController {
         BigDecimal price = c2cAd.getPrice().setScale(2, RoundingMode.DOWN);
 
         String unit = c2cOrder.getUnit().toLowerCase();
-        String symbol = c2cOrder.getSymbol().toLowerCase();
+        String symbol = c2cOrder.getCoin().toLowerCase();
         //数币金额
         BigDecimal symbolAmount = BigDecimal.ZERO;
         //法币金额
@@ -200,7 +207,7 @@ public class C2cOrderController extends ApiBaseController {
         if(direction.intValue() == DirectionEnum.SELL.getCode().intValue()) {
             AppAssetEntity tAppAsset = new AppAssetEntity();
             tAppAsset.setUserId(loginUserId);
-            tAppAsset.setSymbol(c2cOrder.getSymbol());
+            tAppAsset.setCoin(c2cOrder.getCoin());
             tAppAsset.setType(AssetEnum.PLATFORM_ASSETS.getCode());
             List<AppAssetEntity> assetList = appAssetService.selectList(tAppAsset);
             if(assetList==null || assetList.size()==0) {
@@ -320,7 +327,7 @@ public class C2cOrderController extends ApiBaseController {
                 c2cOrderService.cancelC2cOrder(order, StpUtil.getLoginIdAsLong(), dto.getReasonId(), dto.getReasonType(), dto.getOtherReason());
             } catch (Exception e) {
                 log.error("cancelOrder,{},{}",order.getId(),e.getMessage());
-                return error("取消订单失败");
+                return error(MessageUtils.message("c2c.order.cancel.fail"));//取消订单失败
             } finally {
                 distributedRedisLock.unlock(lockKey);
             }
@@ -334,7 +341,7 @@ public class C2cOrderController extends ApiBaseController {
     @Operation(summary = "我已完成付款按钮")
     @PostMapping("/confirmPay")
     @RepeatSubmit(interval = 3000, message = "请求过于频繁")
-    public Result confirmPay(@RequestBody C2cOrderIdDTO dto)
+    public Result confirmPay(@RequestBody C2cOrderConfirmPayDTO dto)
     {
         ValidatorUtils.validateEntity(dto);
 
@@ -366,6 +373,7 @@ public class C2cOrderController extends ApiBaseController {
         String lockKey = getC2cOrderLockKey(order.getId().toString());
         if (distributedRedisLock.lock(lockKey)) {
             try {
+                order.setVoucherIds(dto.getVoucherIds());
                 order.setRemark("买家已完成付款");
                 return c2cOrderService.confirmPay(order, loginId);
             } catch (Exception e) {
@@ -433,68 +441,88 @@ public class C2cOrderController extends ApiBaseController {
     @Operation(summary = "上传付款凭证")
     @PostMapping("/uploadPayment")
     @RepeatSubmit(interval = 3000, message = "请求过于频繁")
-    public Result uploadPayment(@RequestBody C2cPaymentVoucherDTO c2cPaymentVoucher) {
-        ValidatorUtils.validateEntity(c2cPaymentVoucher);
-
-        Long orderId = c2cPaymentVoucher.getOrderId();
-        String img = c2cPaymentVoucher.getImg();
-
-        C2cOrderEntity order = c2cOrderService.selectOrder(orderId);
+    public Result uploadPayment(MultipartFile file,Long orderId,Long id) {
+        if(Objects.isNull(orderId)) {
+            return error(MessageUtils.message("c2c.orderId.is.empty"));//订单编号不能空
+        }
+        C2cOrderEntity order = c2cOrderService.selectById(orderId);
         if(order == null) {
             return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
         }
         if(order!=null && order.getFlow().intValue()==C2cOrderFlowEnum.END.getCode()) {
             return error(MessageUtils.message("c2c.order.is.end"));//订单已结束
         }
-
-        if(order.getUserId().longValue() != StpUtil.getLoginIdAsLong()
-                && order.getTranUserId().longValue() != StpUtil.getLoginIdAsLong()) {
-            return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败,请刷新后重试
+        if( StpUtil.getLoginIdAsLong() != order.getUserId().longValue()
+                && StpUtil.getLoginIdAsLong() != order.getTranUserId().longValue()) {
+            return error(MessageUtils.message("c2c.complain.voucher.submit.fail"));//提交失败,您不是订单交易方
         }
 
+        List<C2cPaymentVoucherEntity> list = c2cPaymentVoucherService.selectList(orderId);
+        if(list!=null && list.size()>=3) {
+            return error(MessageUtils.message("c2c.order.payment.vouchers.limit"));//付款凭证最多3张
+        }
 
-        if(c2cPaymentVoucher.getId() == null || c2cPaymentVoucher.getId().intValue() == 0) {
-            C2cPaymentVoucherEntity entity = new C2cPaymentVoucherEntity();
-            entity.setOrderId(orderId);
-            entity.setUserId(StpUtil.getLoginIdAsLong());
-            entity.setImg(img);
-            entity.setStatus(1);
-            entity.setCreateTime(new Date());
-            entity.setUpdateTime(new Date());
-            if(c2cPaymentVoucherService.save(entity)) {
-                Map data = MapUtil.of("id", entity.getId());
-                return success(data);
-            } else {
-                return error(MessageUtils.message("c2c.order.uploadPayment.fail"));//上传付款凭证失败
-            }
-
-        } else {
-            C2cPaymentVoucherEntity voucher = c2cPaymentVoucherService.getById(c2cPaymentVoucher.getId());
-            if(voucher==null) {
-                return error(MessageUtils.message("c2c.order.pay.cert.id.invalid"));//凭证编号无效
-            }
-            if(StpUtil.getLoginIdAsString().equals(voucher.getUserId().toString())) {
-
-                C2cPaymentVoucherEntity entity = new C2cPaymentVoucherEntity();
-                entity.setId(c2cPaymentVoucher.getId());
-                entity.setOrderId(orderId);
-                entity.setUserId(StpUtil.getLoginIdAsLong());
-                entity.setImg(img);
-                entity.setStatus(1);
-                entity.setUpdateTime(new Date());
-                if(c2cPaymentVoucherService.updateById(entity)) {
-                    Map data = MapUtil.of("id", entity.getId());
+        try {
+            String filename = file.getResource().getFilename();
+            //这里文件名用了uuid 防止重复,可以根据自己的需要来写
+            String name = UUID.randomUUID() + filename.substring(filename.lastIndexOf("."), filename.length());
+            name = name.replace("-", "");
+            String url = fileService.uploadFileOSS(file,name);
+
+            if(id == null || id.intValue() == 0) {
+                C2cPaymentVoucherEntity voucherEntity = new C2cPaymentVoucherEntity();
+                voucherEntity.setOrderId(orderId);
+                voucherEntity.setImg(url);
+                voucherEntity.setUserId(StpUtil.getLoginIdAsLong());
+                voucherEntity.setStatus(1);
+                voucherEntity.setCreateTime(new Date());
+                voucherEntity.setUpdateTime(new Date());
+                if (c2cPaymentVoucherService.save(voucherEntity)) {
+                    Map data = MapUtil.of("id", voucherEntity.getId());
+                    data.put("file", url);
+                    data.put("name", name);
                     return success(data);
                 } else {
                     return error(MessageUtils.message("c2c.order.uploadPayment.fail"));//上传付款凭证失败
                 }
-
-            } else {
-                return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败,请刷新后重试
+            } else {//修改
+                C2cPaymentVoucherEntity voucher = c2cPaymentVoucherService.getById(id);
+                if(voucher==null) {
+                    return error(MessageUtils.message("c2c.order.pay.cert.id.invalid"));//凭证编号无效
+                }
+                if(StpUtil.getLoginIdAsString().equals(voucher.getUserId().toString())) {
+                    //删除旧的凭证
+                    String fileName = voucher.getImg().substring(voucher.getImg().lastIndexOf("/")+1);
+                    try {
+                        fileService.deleteFileOSS(fileName);
+                    } catch (IOException e) {
+                        log.error("删除付款凭证失败",e);
+                        return error(MessageUtils.message("c2c.deletePayment.voucher.fail"));//删除付款凭证失败
+                    }
+
+                    voucher.setOrderId(orderId);
+                    voucher.setImg(url);
+                    voucher.setUpdateTime(new Date());
+                    if(c2cPaymentVoucherService.updateById(voucher)) {
+                        Map data = MapUtil.of("id", voucher.getId());
+                        data.put("file", url);
+                        data.put("name", name);
+                        return success(data);
+                    } else {
+                        return error(MessageUtils.message("c2c.order.uploadPayment.fail"));//上传付款凭证失败
+                    }
+                } else {
+                    return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败,请刷新后重试
+                }
             }
+        } catch (Exception e) {
+            e.getMessage();
+            return new Result().error(e.getMessage());
         }
     }
 
+    @Resource
+    private FileService fileService;
 
     @Operation(summary = "删除付款凭证")
     @PostMapping("/deletePayment")
@@ -514,6 +542,14 @@ public class C2cOrderController extends ApiBaseController {
 
         if(StpUtil.getLoginIdAsString().equals(voucher.getUserId().toString())) {
 
+            String fileName = voucher.getImg().substring(voucher.getImg().lastIndexOf("/")+1);
+            try {
+                fileService.deleteFileOSS(fileName);
+            } catch (IOException e) {
+                log.error("删除付款凭证失败",e);
+                return error(MessageUtils.message("c2c.deletePayment.voucher.fail"));//删除付款凭证失败
+            }
+
             C2cPaymentVoucherEntity entity = new C2cPaymentVoucherEntity();
             entity.setId(c2cPaymentVoucher.getId());
             entity.setStatus(-1);
@@ -629,6 +665,12 @@ public class C2cOrderController extends ApiBaseController {
     {
         ValidatorUtils.validateEntity(c2cOrderComplain);
 
+        if(c2cOrderComplain.getReasonId().intValue()==4) {//买家取消原因=其他
+            if(StrUtil.isEmpty(c2cOrderComplain.getOtherReason())) {
+                return error(MessageUtils.message("c2c.order.cancel.otherReason.NotEmpty"));//其他原因不能空
+            }
+        }
+
         C2cOrderEntity order = c2cOrderService.selectById(c2cOrderComplain.getOrderId());
         if(order == null) {
             return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
@@ -645,14 +687,17 @@ public class C2cOrderController extends ApiBaseController {
             return error(MessageUtils.message("c2c.complain.submit.fail"));//发起申诉失败,您不是买家或卖家
         }
 
-        if(c2cOrderComplain.getReason().length()>250) {
-            return error(MessageUtils.message("c2c.order.complain.remark.maxval"));//申诉原因最多250个字
+        if(c2cOrderComplain.getRemark().length()>250) {
+            return error(MessageUtils.message("c2c.order.complain.remark.maxval"));//描述最多250个字
         }
 
         try {
             C2cOrderComplainEntity c2cOrderComplainEntity = new C2cOrderComplainEntity();
             c2cOrderComplainEntity.setOrderId(c2cOrderComplain.getOrderId());
-            c2cOrderComplainEntity.setReason(c2cOrderComplain.getReason());
+            c2cOrderComplainEntity.setReasonId(c2cOrderComplain.getReasonId());
+            c2cOrderComplainEntity.setOtherReason(c2cOrderComplain.getOtherReason());
+            c2cOrderComplainEntity.setRemark(c2cOrderComplain.getRemark());
+            c2cOrderComplainEntity.setVoucherIds(c2cOrderComplain.getVoucherIds());
             return c2cOrderService.complain(order,c2cOrderComplainEntity,StpUtil.getLoginIdAsLong());
         } catch (Exception e) {
             return error(e.getMessage());
@@ -661,84 +706,102 @@ public class C2cOrderController extends ApiBaseController {
     }
 
 
-    @Operation(summary = "用户或商家提交申诉凭证")
-    @PostMapping("/complainVoucher")
+    @Operation(summary = "用户或商家上传凭证")
+    @PostMapping("/addVoucher")
     @RepeatSubmit(interval = 3000, message = "请求过于频繁")
-    public Result complainVoucher(@RequestBody C2cOrderComplainVoucherDTO dto)
+    public Result addVoucher(MultipartFile file,Integer type, Long orderId,String remark)
     {
-        ValidatorUtils.validateEntity(dto);
-
-        C2cOrderComplainEntity orderComplain = orderComplainService.getById(dto.getComplainId());
-        if(orderComplain == null) {
-            return error(MessageUtils.message("c2c.order.complain.not.exist"));//申诉编号无效
+        if(Objects.isNull(type)) {
+            return error(MessageUtils.message("c2c.voucher.type.is.empty"));//凭证类别不能空
         }
-
-        if( StpUtil.getLoginIdAsLong() != orderComplain.getFromUserId().longValue()
-                && StpUtil.getLoginIdAsLong() != orderComplain.getToUserId().longValue()) {
-            return error(MessageUtils.message("c2c.complain.voucher.submit.fail"));//提交失败,您不是申诉人或被申诉人
+        if(Objects.isNull(orderId)) {
+            return error(MessageUtils.message("c2c.orderId.is.empty"));//订单编号不能空
+        }
+        C2cOrderEntity order = c2cOrderService.selectById(orderId);
+        if(order == null) {
+            return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
         }
 
-        if(StrUtil.isEmpty(dto.getRemark())) {
-            return error(MessageUtils.message("c2c.order.complain.remark.notEmpty"));//申诉原因不能空
+        if( StpUtil.getLoginIdAsLong() != order.getUserId().longValue()
+                && StpUtil.getLoginIdAsLong() != order.getTranUserId().longValue()) {
+            return error(MessageUtils.message("c2c.complain.voucher.submit.fail"));//提交失败,您不是订单交易方
         }
-        if(dto.getRemark().length()>250) {
+
+        if(remark!=null && remark.length()>250) {
             return error(MessageUtils.message("c2c.order.complain.remark.maxval"));//描述最多250个字
         }
 
-        if(dto.getId()==null || dto.getId().intValue()==0) {
-            C2cOrderComplainVoucherEntity voucherEntity = new C2cOrderComplainVoucherEntity();
-            voucherEntity.setComplainId(dto.getComplainId());
-            voucherEntity.setRemark(dto.getRemark());
-            voucherEntity.setImg1(dto.getImg1());
-            voucherEntity.setImg2(dto.getImg2());
-            voucherEntity.setImg3(dto.getImg3());
-            voucherEntity.setImg4(dto.getImg4());
-            voucherEntity.setImg5(dto.getImg5());
+        List<C2cOrderVoucherEntity> list = c2cOrderVoucherService.selectList(orderId);
+        if(list!=null && list.size()>=5) {
+            return error(MessageUtils.message("c2c.order.complain.files.limit"));//申诉凭证最多5张
+        }
+
+        try {
+            String filename = file.getResource().getFilename();
+            //这里文件名用了uuid 防止重复,可以根据自己的需要来写
+            String name = UUID.randomUUID() + filename.substring(filename.lastIndexOf("."), filename.length());
+            name = name.replace("-", "");
+            String url = fileService.uploadFileOSS(file,name);
+
+            C2cOrderVoucherEntity voucherEntity = new C2cOrderVoucherEntity();
+            voucherEntity.setOrderId(orderId);
+            voucherEntity.setType(type);
+            voucherEntity.setRemark(remark);
+            voucherEntity.setFile(url);
             voucherEntity.setUserId(StpUtil.getLoginIdAsLong());
             voucherEntity.setStatus(1);
             voucherEntity.setCreateTime(new Date());
             voucherEntity.setUpdateTime(new Date());
             if(orderComplainVoucherService.save(voucherEntity)) {
                 Map data = MapUtil.of("id", voucherEntity.getId());
+                data.put("file", url);
+                data.put("name", name);
                 return success(data);
             } else {
                 return error(MessageUtils.message("c2c.order.complain.voucher.save.fail"));//保存申诉凭证失败
             }
+        } catch (Exception e) {
+            e.getMessage();
+            return new Result().error(e.getMessage());
+        }
 
-        } else {
-            C2cOrderComplainVoucherEntity voucherEntity = orderComplainVoucherService.getById(dto.getId());
-            if(voucherEntity==null) {
-                return error(MessageUtils.message("c2c.order.complain.voucher.id.invalid"));//申诉凭证编号无效
-            }
-            if(orderComplain.getFlow().intValue() == C2cOrderFlowEnum.END.getCode()) {
-                return error(MessageUtils.message("c2c.order.complain.voucher.is.end"));//申诉已结束
-            }
-            if(StpUtil.getLoginIdAsLong() == voucherEntity.getUserId().longValue()) {
-                voucherEntity.setComplainId(dto.getComplainId());
-                voucherEntity.setRemark(dto.getRemark());
-                voucherEntity.setImg1(dto.getImg1());
-                voucherEntity.setImg2(dto.getImg2());
-                voucherEntity.setImg3(dto.getImg3());
-                voucherEntity.setImg4(dto.getImg4());
-                voucherEntity.setImg5(dto.getImg5());
-                voucherEntity.setUserId(StpUtil.getLoginIdAsLong());
-                voucherEntity.setStatus(1);
-                voucherEntity.setUpdateTime(new Date());
-                if(orderComplainVoucherService.updateById(voucherEntity)) {
-                    Map data = MapUtil.of("id", voucherEntity.getId());
-                    return success(data);
-                } else {
-                    return error(MessageUtils.message("c2c.order.complain.voucher.update.fail"));//修改申诉凭证失败
-                }
-            } else {
-                return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败,请刷新后重试
-            }
+    }
 
+    @Operation(summary = "删除申诉凭证")
+    @PostMapping("/deleteVoucher")
+    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
+    public Result deleteVoucher(@RequestBody C2cOrderComplainVoucherIDDTO dto) {
+        ValidatorUtils.validateEntity(dto);
+
+        C2cOrderVoucherEntity voucher = c2cOrderVoucherService.getById(dto.getId());
+        if(voucher==null) {
+            return error(MessageUtils.message("c2c.order.pay.cert.id.invalid"));//凭证编号无效
+        }
+
+        //订单已完成不能删除
+        C2cOrderEntity order = c2cOrderService.selectOrder(voucher.getOrderId());
+        if(order!=null && order.getFlow().intValue()==C2cOrderFlowEnum.END.getCode()) {
+            return error(MessageUtils.message("c2c.order.is.end"));//订单已结束
         }
 
+        if(StpUtil.getLoginIdAsString().equals(voucher.getUserId().toString())) {
 
+            String fileName = voucher.getFile().substring(voucher.getFile().lastIndexOf("/")+1);
+            try {
+                fileService.deleteFileOSS(fileName);
+            } catch (IOException e) {
+                log.error("删除凭证失败",e);
+                return error(MessageUtils.message("c2c.deleteVoucher.voucher.fail"));//删除凭证失败
+            }
+            voucher.setStatus(-1);
+            voucher.setUpdateTime(new Date());
+            return toAjax(c2cOrderVoucherService.updateById(voucher));
+        } else {
+            return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败,请刷新后重试
+        }
     }
 
+
     @Operation(summary = "用户或商家查询申诉历史")
     @PostMapping("/complainHis")
     public Result complainHis(@RequestBody C2cOrderComplainOidDTO orderComplain)
@@ -788,7 +851,7 @@ public class C2cOrderController extends ApiBaseController {
             return error(MessageUtils.message("c2c.order.no.permission.view"));//您无权查看
         }
 
-        List<C2cOrderComplainVoucherEntity> complainList = new ArrayList<>();
+        List<C2cOrderVoucherEntity> complainList = new ArrayList<>();
         C2cOrderEntity order = c2cOrderService.selectOrder(orderComplain.getOrderId());
 
         if(c2cOrderService.checkOrderTranUser(order)) {
@@ -866,4 +929,15 @@ public class C2cOrderController extends ApiBaseController {
         return new Result().ok(settingsList);
     }
 
+    @PostMapping("/complainReason")
+    @Operation(summary = "申诉理由查询列表")
+    public Result complainReason(){
+        SettingEntity setting = settingService.getSetting(SettingEnum.COMPLAIN_REASON_SETTING.name());
+        List<ComplainReasonSetting> settingsList = JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), ComplainReasonSetting.class);
+        if (CollectionUtils.isEmpty(settingsList)) {
+            return new Result().error(MessageUtils.message("c2c.order.complain.reason.notset"));//"未配置申诉原因"
+        }
+        return new Result().ok(settingsList);
+    }
+
 }

+ 75 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/controller/OrderReportController.java

@@ -0,0 +1,75 @@
+package com.qnfhq.modules.c2c.controller;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.json.JSONUtil;
+import com.qnfhq.common.utils.MessageUtils;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.common.validator.ValidatorUtils;
+import com.qnfhq.modules.c2c.dto.OrderReportDTO;
+import com.qnfhq.modules.c2c.dto.setting.ReportReasonSetting;
+import com.qnfhq.modules.c2c.entity.OrderReportEntity;
+import com.qnfhq.modules.c2c.service.OrderReportService;
+import com.qnfhq.modules.user.entity.SettingEntity;
+import com.qnfhq.modules.user.enums.SettingEnum;
+import com.qnfhq.modules.user.service.SettingService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * c2c订单举报表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-01
+ */
+@RestController
+@RequestMapping("/c2creport")
+@Tag(name="c2c订单举报表")
+public class OrderReportController {
+    @Resource
+    private OrderReportService orderReportService;
+
+    @Resource
+    private SettingService settingService;
+
+
+    @PostMapping("/save")
+    @Operation(summary = "提交")
+    public Result save(@RequestBody OrderReportDTO dto){
+        //效验数据
+        ValidatorUtils.validateEntity(dto);
+
+        OrderReportEntity reportEntity = new OrderReportEntity();
+        reportEntity.setOrderId(dto.getOrderId());
+        reportEntity.setReasonId(dto.getReasonId());
+        reportEntity.setOtherReason(dto.getOtherReason());
+        reportEntity.setEmail(dto.getEmail());
+        reportEntity.setRemark(dto.getRemark());
+        reportEntity.setVoucherIds(dto.getVoucherIds());
+        reportEntity.setStatus(0);
+        reportEntity.setInputUserId(StpUtil.getLoginIdAsLong());
+        reportEntity.setCreateTime(new Date());
+        orderReportService.save(reportEntity);
+
+        return new Result();
+    }
+
+    @PostMapping("/reason")
+    @Operation(summary = "举报理由列表")
+    public Result reason(){
+        SettingEntity setting = settingService.getSetting(SettingEnum.REPORT_REASON_SETTING.name());
+        List<ReportReasonSetting> settingsList = JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), ReportReasonSetting.class);
+        if (CollectionUtils.isEmpty(settingsList)) {
+            return new Result().error(MessageUtils.message("c2c.order.complain.reason.notset"));//"未配置申诉原因"
+        }
+        return new Result().ok(settingsList);
+    }
+
+}

+ 3 - 3
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/C2cOrderComplainVoucherDao.java → qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dao/C2cOrderVoucherDao.java

@@ -1,16 +1,16 @@
 package com.qnfhq.modules.c2c.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.qnfhq.modules.c2c.entity.C2cOrderComplainVoucherEntity;
+import com.qnfhq.modules.c2c.entity.C2cOrderVoucherEntity;
 import org.apache.ibatis.annotations.Mapper;
 
 /**
- * c2c申诉证明材料
+ * c2c证明材料
  *
  * @author yelz 30262728@qq.com
  * @since 1.0.0 2025-11-17
  */
 @Mapper
-public interface C2cOrderComplainVoucherDao extends BaseMapper<C2cOrderComplainVoucherEntity> {
+public interface C2cOrderVoucherDao extends BaseMapper<C2cOrderVoucherEntity> {
 	
 }

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

@@ -0,0 +1,16 @@
+package com.qnfhq.modules.c2c.dao;
+
+import com.qnfhq.common.dao.BaseDao;
+import com.qnfhq.modules.c2c.entity.OrderReportEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * c2c订单举报表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-01
+ */
+@Mapper
+public interface OrderReportDao extends BaseDao<OrderReportEntity> {
+	
+}

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

@@ -30,8 +30,8 @@ public class C2cAdCreateDTO implements Serializable {
 	private String legalCoin;
 
 	@SchemaProperty(name = "交易币种")
-    @NotBlank(message="{NotBlank.symbol}")//交易币种不能为空
-	private String symbol;
+    @NotBlank(message="{NotBlank.coin}")//交易币种不能为空
+	private String coin;
 
 	@SchemaProperty(name = "数量")
     @NotNull(message="{NotNull.num}")//数量不能为空

+ 1 - 1
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cAdLogDTO.java

@@ -26,7 +26,7 @@ public class C2cAdLogDTO implements Serializable {
 	private Long orderId;
 
 	@SchemaProperty(name = "数币的数量")
-	private BigDecimal symbolNum;
+	private BigDecimal coinNum;
 
 	@SchemaProperty(name = "变更前剩余可用数币的数量")
 	private BigDecimal beforeAvailNum;

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

@@ -30,8 +30,8 @@ public class C2cAdTranDTO implements Serializable {
 	private String legalCoin;
 
 	@SchemaProperty(name = "交易币USDT")
-    @NotBlank(message="{NotBlank.symbol}")//交易币种不能为空
-	private String symbol;
+    @NotBlank(message="{NotBlank.coin}")//交易币种不能为空
+	private String coin;
 
 	@SchemaProperty(name = "买入法币的数量/卖出数币的数量")
     @NotNull(message="{NotNull.num}")//数量不能为空

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

@@ -33,8 +33,8 @@ public class C2cAdViewDTO implements Serializable {
     private String legalCoin;
 
     @SchemaProperty(name = "交易币USDT")
-    @NotBlank(message="{NotBlank.symbol}")//交易币种不能为空
-    private String symbol;
+    @NotBlank(message="{NotBlank.coin}")//交易币种不能为空
+    private String coin;
 
 	@SchemaProperty(name = "数币的总数量")
 	private BigDecimal amount;

+ 1 - 1
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderCancelDTO.java

@@ -24,7 +24,7 @@ public class C2cOrderCancelDTO implements Serializable {
 
 
     @SchemaProperty(name = "取消原因编号")
-    @NotNull(message="{NotNull.reasonId}")//取消原因编号不能为空
+    @NotNull(message="{NotNull.reasonId}")//原因编号不能为空
     private Long reasonId;
 
     @SchemaProperty(name = "取消原因类别")

+ 11 - 3
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderComplainDTO.java

@@ -24,9 +24,17 @@ public class C2cOrderComplainDTO implements Serializable {
     @NotNull(message="{NotNull.orderId}")//订单编号不能为空
 	private Long orderId;
 
-	@SchemaProperty(name = "申诉原因")
-    @NotBlank(message="{NotBlank.reason}")//申诉原因不能为空
-	private String reason;
+    @SchemaProperty(name = "申诉理由编号")
+    @NotNull(message="{NotNull.reasonId}")//申诉理由编号不能为空
+    private Integer reasonId;
 
+	@SchemaProperty(name = "其他理由")
+	private String otherReason;
 
+    @SchemaProperty(name = "申诉描述")
+    private String remark;
+
+    @SchemaProperty(name = "申诉凭证")
+    @NotBlank(message="{NotBlank.voucherIds}")//申诉凭证不能为空
+    private String voucherIds;
 }

+ 0 - 51
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderComplainVoucherDTO.java

@@ -1,51 +0,0 @@
-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;
-
-/**
- * c2c申诉证明材料
- *
- * @author yelz 30262728@qq.com
- * @since 1.0.0 2025-11-17
- */
-@Data
-@Schema(name = "c2c申诉证明材料")
-public class C2cOrderComplainVoucherDTO implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-	@SchemaProperty(name = "自增id")
-	private Long id;
-
-	@SchemaProperty(name = "申诉编号")
-    @NotNull(message="{NotNull.complainId}")//申诉编号不能为空
-	private Long complainId;
-
-	@SchemaProperty(name = "凭证描述")
-    @NotBlank(message="{NotBlank.remark}")//凭证描述不能为空
-	private String remark;
-
-	@SchemaProperty(name = "凭证截图1")
-    @NotBlank(message="{NotBlank.img1}")//凭证截图1不能为空
-	private String img1;
-
-	@SchemaProperty(name = "凭证截图2")
-	private String img2;
-
-	@SchemaProperty(name = "凭证截图3")
-	private String img3;
-
-	@SchemaProperty(name = "凭证截图4")
-	private String img4;
-
-	@SchemaProperty(name = "凭证截图5")
-	private String img5;
-
-
-
-}

+ 30 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderComplainVoucherIDDTO.java

@@ -0,0 +1,30 @@
+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;
+
+/**
+ * c2c申诉证明材料
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-17
+ */
+@Data
+@Schema(name = "c2c申诉证明材料")
+public class C2cOrderComplainVoucherIDDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+	@SchemaProperty(name = "自增id")
+    @NotNull(message="{NotNull.id}")
+	private Long id;
+
+
+
+
+
+}

+ 30 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderConfirmPayDTO.java

@@ -0,0 +1,30 @@
+package com.qnfhq.modules.c2c.dto;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serializable;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.media.SchemaProperty;
+/**
+ * c2c订单
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-17
+ */
+@Data
+@Schema(name = "c2c订单")
+public class C2cOrderConfirmPayDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @SchemaProperty(name = "订单编号")
+    @NotNull(message="{NotNull.oId}")//订单编号不能为空
+    private Long id;
+
+    @SchemaProperty(name = "付款凭证")
+    @NotBlank(message="{NotBlank.Pay.voucherIds}")//付款凭证不能为空
+    private String voucherIds;
+
+}

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

@@ -29,8 +29,8 @@ public class C2cOrderCreateDTO implements Serializable {
 	private String legalCoin;
 
 	@SchemaProperty(name = "交易币种")
-    @NotBlank(message="{NotBlank.symbol}")//交易币种不能为空
-	private String symbol;
+    @NotBlank(message="{NotBlank.coin}")//交易币种不能为空
+	private String coin;
 
 	@SchemaProperty(name = "广告编号")
     @NotNull(message="{NotNull.c2cAdId}")//广告编号不能为空

+ 0 - 105
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderDTO.java

@@ -1,105 +0,0 @@
-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;
-/**
- * c2c订单
- *
- * @author yelz 30262728@qq.com
- * @since 1.0.0 2025-11-17
- */
-@Data
-@Schema(name = "c2c订单")
-public class C2cOrderDTO implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-	@SchemaProperty(name = "自增编号")
-	private Long id;
-
-	@SchemaProperty(name = "订单编号")
-	private String orderNo;
-
-	@SchemaProperty(name = "下单人的编号")
-	private Long userId;
-
-	@SchemaProperty(name = "下单名字")
-	private String userName;
-
-	@SchemaProperty(name = "1买入  2 卖出")
-	private Integer direction;
-
-	@SchemaProperty(name = "法定货币")
-	private String legalCoin;
-
-	@SchemaProperty(name = "交易币USDT,BTC")
-	private String symbol;
-
-	@SchemaProperty(name = "广告编号")
-	private Long c2cAdId;
-
-	@SchemaProperty(name = "交易对手编号")
-	private Long tranUserId;
-
-	@SchemaProperty(name = "交易对手名字")
-	private String tranUserName;
-
-	@SchemaProperty(name = "单价")
-	private BigDecimal tranPrice;
-
-	@SchemaProperty(name = "数量USDT")
-	private BigDecimal symbolNum;
-
-	@SchemaProperty(name = "法币的交易金额")
-	private BigDecimal tranAmount;
-
-	@SchemaProperty(name = "1微信  2支付宝 3银行借记卡")
-	private Integer payType;
-
-    @SchemaProperty(name = "付款时间")
-    private Date payTime;
-
-	@SchemaProperty(name = "0 进行中 1 已结束 ")
-	private Integer flow;
-
-	@SchemaProperty(name = "0 未付款 1 已付款(确认付款后)2 申诉 3 已完成 4 已取消 ")
-	private Integer status;
-
-	@SchemaProperty(name = "广告要求")
-	private String remark;
-
-	@SchemaProperty(name = "")
-	private Date createTime;
-
-	@SchemaProperty(name = "")
-	private Date updateTime;
-
-    @SchemaProperty(name = "支付过期时间")
-    private Date payExpireTime;
-
-    @SchemaProperty(name = "完成时间")
-    private Date finishTime;
-
-    @SchemaProperty(name = "关闭时间")
-    private Date closeTime;
-
-    @SchemaProperty(name = "卖家收款信息")
-    C2cUserReceiptEntity receiptInfo;
-
-    @SchemaProperty(name = "是否有付款凭证")
-    Integer isVoucher=0;
-
-    @SchemaProperty(name = "买家付款凭证")
-    List<C2cPaymentVoucherEntity> payVoucherList;
-
-}

+ 39 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/C2cOrderVoucherDTO.java

@@ -0,0 +1,39 @@
+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;
+
+/**
+ * c2c凭证材料
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-17
+ */
+@Data
+@Schema(name = "c2c凭证材料")
+public class C2cOrderVoucherDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+	@SchemaProperty(name = "自增id")
+	private Long id;
+
+	@SchemaProperty(name = "订单编号")
+    @NotNull(message="{NotNull.orderId}")
+	private Long orderId;
+
+	@SchemaProperty(name = "凭证描述")
+	private String remark;
+
+	@SchemaProperty(name = "凭证")
+    @NotBlank(message="{NotBlank.file}")//凭证不能为空
+	private String file;
+
+
+
+
+}

+ 47 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/OrderReportDTO.java

@@ -0,0 +1,47 @@
+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.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * c2c订单举报表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-01
+ */
+@Data
+@Schema(name = "c2c订单举报表")
+public class OrderReportDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+	@SchemaProperty(name = "订单编号")
+    @NotNull(message="{NotNull.orderId}")//订单编号不能为空
+	private Long orderId;
+
+	@SchemaProperty(name = "举报理由")
+    @NotNull(message="{NotNull.reasonId}")//原因编号不能为空
+	private Long reasonId;
+
+	@SchemaProperty(name = "其他理由")
+	private String otherReason;
+
+	@SchemaProperty(name = "邮箱")
+    @Email(message = "{Email.format.err}")//邮箱格式不正确
+    @NotBlank(message="{NotBlank.email}")//邮箱不能为空
+	private String email;
+
+	@SchemaProperty(name = "描述")
+	private String remark;
+
+    @SchemaProperty(name = "凭证编号")
+    private String voucherIds;
+
+}

+ 1 - 1
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/setting/AdSetting.java

@@ -11,7 +11,7 @@ import java.math.BigDecimal;
 public class AdSetting {
 
     private String legalCoin;//法币
-    private String symbol;//币种
+    private String coin;//币种
     private BigDecimal minPrice;//最小价格
     private BigDecimal maxPrice;//最大价格
     private BigDecimal minAmount;//最小金额

+ 12 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/setting/ComplainReasonSetting.java

@@ -0,0 +1,12 @@
+package com.qnfhq.modules.c2c.dto.setting;
+
+import lombok.Data;
+
+/**
+ * 取消原因配置
+ */
+@Data
+public class ComplainReasonSetting {
+    private Integer reasonId;//编号
+    private String reasonName;//名称
+}

+ 14 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/dto/setting/ReportReasonSetting.java

@@ -0,0 +1,14 @@
+package com.qnfhq.modules.c2c.dto.setting;
+
+import lombok.Data;
+
+/**
+ * 取消原因配置
+ */
+@Data
+public class ReportReasonSetting {
+    private Integer reasonId;//编号
+    private Integer typeId;
+    private String typeName;
+    private String reasonName;//名称
+}

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

@@ -53,7 +53,7 @@ public class C2cAdEntity implements Serializable {
     /**
      * 交易币USDT
      */
-	private String symbol;
+	private String coin;
     /**
      * 数币的总数量
      */

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

@@ -30,7 +30,7 @@ public class C2cAdLogEntity implements Serializable {
     /**
      * 数币的数量
      */
-	private BigDecimal symbolNum;
+	private BigDecimal coinNum;
     /**
      * 变更前剩余可用数币的数量
      */

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

@@ -34,10 +34,23 @@ public class C2cOrderComplainEntity implements Serializable {
      * 申诉人名字
      */
 	private String fromUserName;
+
     /**
      * 申诉原因
      */
-	private String reason;
+    private Integer reasonId;
+    /**
+     * 其他原因
+     */
+	private String otherReason;
+    /**
+     * 申诉凭证编号
+     */
+    private String voucherIds;
+    /**
+     * 申诉描述
+     */
+    private String remark;
     /**
      * 被申诉人的编号
      */

+ 7 - 2
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cOrderEntity.java

@@ -48,7 +48,7 @@ public class C2cOrderEntity implements Serializable {
     /**
      * 数币
      */
-	private String symbol;
+	private String coin;
     /**
      * 广告编号
      */
@@ -68,7 +68,7 @@ public class C2cOrderEntity implements Serializable {
     /**
      * 数币数量
      */
-	private BigDecimal symbolNum;
+	private BigDecimal coinNum;
     /**
      * 法币的交易金额
      */
@@ -81,6 +81,11 @@ public class C2cOrderEntity implements Serializable {
      * 付款时间
      */
     private Date payTime;
+
+    /**
+     * 付款凭证 多个,分割
+     */
+    private String voucherIds;
     /**
      * 流程:0 进行中 1 已结束
      */

+ 10 - 21
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cOrderComplainVoucherEntity.java → qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cOrderVoucherEntity.java

@@ -9,14 +9,14 @@ import java.io.Serializable;
 import java.util.Date;
 
 /**
- * c2c申诉证明材料
+ * c2c凭证证明材料
  *
  * @author yelz 30262728@qq.com
  * @since 1.0.0 2025-11-17
  */
 @Data
-@TableName("c2c_order_complain_voucher")
-public class C2cOrderComplainVoucherEntity implements Serializable {
+@TableName("c2c_order_voucher")
+public class C2cOrderVoucherEntity implements Serializable {
     private static final long serialVersionUID = 1L;
 
 
@@ -25,31 +25,20 @@ public class C2cOrderComplainVoucherEntity implements Serializable {
     /**
      * 
      */
-	private Long complainId;
+	private Long orderId;
     /**
-     * 凭证描述
-     */
-	private String remark;
-    /**
-     * 
-     */
-	private String img1;
-    /**
-     * 
+     * 凭证类型:1申诉 2举报
      */
-	private String img2;
+    private Integer type;
     /**
-     * 
-     */
-	private String img3;
-    /**
-     * 
+     * 凭证描述
      */
-	private String img4;
+	private String remark;
     /**
      * 
      */
-	private String img5;
+	private String file;
+
     /**
      * 上传人的编号
      */

+ 1 - 4
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/C2cPaymentVoucherEntity.java

@@ -26,10 +26,7 @@ public class C2cPaymentVoucherEntity implements Serializable {
      * 
      */
 	private Long orderId;
-    /**
-     * 订单编号
-     */
-	private String orderNo;
+
     /**
      * 
      */

+ 70 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/entity/OrderReportEntity.java

@@ -0,0 +1,70 @@
+package com.qnfhq.modules.c2c.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * c2c订单举报表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-01
+ */
+@Data
+@TableName("c2c_order_report")
+public class OrderReportEntity {
+
+    /**
+     * 
+     */
+	private Long id;
+    /**
+     * 
+     */
+	private Long orderId;
+    /**
+     * 举报理由
+     */
+	private Long reasonId;
+    /**
+     * 其他理由
+     */
+	private String otherReason;
+    /**
+     * 邮箱
+     */
+	private String email;
+    /**
+     * 描述
+     */
+	private String remark;
+    /**
+     * 凭证
+     */
+    private String voucherIds;
+    /**
+     * 0 已提交 1 已受理 2已处理 
+     */
+	private Integer status;
+    /**
+     * 结果
+     */
+	private String result;
+    /**
+     * 操作人
+     */
+	private Long opUserId;
+    /**
+     * 
+     */
+	private Date opTime;
+    /**
+     * 提交人
+     */
+	private Long inputUserId;
+    /**
+     * 
+     */
+	private Date createTime;
+}

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

@@ -1,16 +0,0 @@
-package com.qnfhq.modules.c2c.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.qnfhq.modules.c2c.entity.C2cOrderComplainVoucherEntity;
-
-import java.util.List;
-
-/**
- * c2c申诉证明材料
- *
- * @author yelz 30262728@qq.com
- * @since 1.0.0 2025-11-17
- */
-public interface C2cOrderComplainVoucherService extends IService<C2cOrderComplainVoucherEntity> {
-    List<C2cOrderComplainVoucherEntity> selectList(Long complainId);
-}

+ 16 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/C2cOrderVoucherService.java

@@ -0,0 +1,16 @@
+package com.qnfhq.modules.c2c.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qnfhq.modules.c2c.entity.C2cOrderVoucherEntity;
+
+import java.util.List;
+
+/**
+ * c2c申诉证明材料
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-17
+ */
+public interface C2cOrderVoucherService extends IService<C2cOrderVoucherEntity> {
+    List<C2cOrderVoucherEntity> selectList(Long orderId);
+}

+ 14 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/OrderReportService.java

@@ -0,0 +1,14 @@
+package com.qnfhq.modules.c2c.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qnfhq.modules.c2c.entity.OrderReportEntity;
+
+/**
+ * c2c订单举报表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-01
+ */
+public interface OrderReportService extends IService<OrderReportEntity> {
+
+}

+ 1 - 1
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cAdLogServiceImpl.java

@@ -37,7 +37,7 @@ public class C2cAdLogServiceImpl extends ServiceImpl<C2cAdLogDao, C2cAdLogEntity
         C2cAdLogEntity c2cAdLogEntity = new C2cAdLogEntity();
         c2cAdLogEntity.setAdId(adId);
         c2cAdLogEntity.setOrderId(orderId);
-        c2cAdLogEntity.setSymbolNum(symbolNum);
+        c2cAdLogEntity.setCoinNum(symbolNum);
         c2cAdLogEntity.setBeforeAvailNum(availableNum);
         c2cAdLogEntity.setAfterAvailNum(afterAvailNum);
         c2cAdLogEntity.setBeforeMaxAmount(beforeMaxAmount);

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

@@ -67,7 +67,7 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
     public Result createAd(C2cAdCreateDTO c2cAdDTO, long loginId) throws Exception {
         Result result = new Result();
         Integer direction = c2cAdDTO.getDirection();
-        String symbol = c2cAdDTO.getSymbol().toLowerCase();//usdt小写
+        String symbol = c2cAdDTO.getCoin().toLowerCase();//usdt小写
         String legalCoin = c2cAdDTO.getLegalCoin().toUpperCase();//法币大写
         Integer priceType = c2cAdDTO.getPriceType();
 
@@ -96,7 +96,7 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
         //账户可用资金
         BigDecimal avaAmount = BigDecimal.ZERO;
         AppAssetEntity tAppAsset = new AppAssetEntity();
-        tAppAsset.setSymbol(symbol);
+        tAppAsset.setCoin(symbol);
         tAppAsset.setType(AssetEnum.PLATFORM_ASSETS.getCode());
         tAppAsset.setUserId(merchant.getUserId());
         List<AppAssetEntity> assetList = appAssetService.selectList(tAppAsset);
@@ -119,7 +119,7 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
         c2cAd.setMerchantId(merchant.getId());
         c2cAd.setDirection(direction);
         c2cAd.setLegalCoin(legalCoin);
-        c2cAd.setSymbol(symbol);
+        c2cAd.setCoin(symbol);
         c2cAd.setNum(num);
         c2cAd.setAvailableNum(num);
         c2cAd.setPriceType(priceType);
@@ -135,7 +135,7 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
         }
         if (direction.intValue() == DirectionEnum.SELL.getCode().intValue()) {
             //卖出广告 冻结卖出数量的币
-            if (appAssetService.frozeAssetByUserId(c2cAd.getUserId(), c2cAd.getSymbol(), c2cAd.getNum()) == 0) {
+            if (appAssetService.frozeAssetByUserId(c2cAd.getUserId(), c2cAd.getCoin(), c2cAd.getNum()) == 0) {
                 throw new Exception(MessageUtils.message("seller.asset.freeze.fail"));//冻结卖家资产失败
             }
         }
@@ -154,12 +154,12 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
         }
 
         if (ad.getDirection().intValue() == DirectionEnum.SELL.getCode().intValue()) {
-            if (appAssetService.unblockAssetByUserId(ad.getUserId(), ad.getSymbol(), ad.getAvailableNum()) == 0) {
+            if (appAssetService.unblockAssetByUserId(ad.getUserId(), ad.getCoin(), ad.getAvailableNum()) == 0) {
                 throw new Exception(MessageUtils.message("c2c.user.occupied.asset.fail"));//用户资产解冻失败
             }
         }
 
-        deleteAdCache(ad.getId(),ad.getPayway().replaceAll("^,|,$", ""),ad.getLegalCoin(),ad.getSymbol(),ad.getDirection());
+        deleteAdCache(ad.getId(),ad.getPayway().replaceAll("^,|,$", ""),ad.getLegalCoin(),ad.getCoin(),ad.getDirection());
         return result;
     }
 
@@ -206,7 +206,7 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
         adMap.put("merchantId",c2cAd.getMerchantId());
         adMap.put("direction", c2cAd.getDirection());
         adMap.put("legalCoin", c2cAd.getLegalCoin());
-        adMap.put("symbol", c2cAd.getSymbol());
+        adMap.put("coin", c2cAd.getCoin());
         adMap.put("payway", payway);
         adMap.put("total", c2cAd.getNum());
         //可用数量
@@ -269,7 +269,7 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
     @Override
     public Result queryTranAd(C2cAdTranDTO tranDTO) {
         Result result = new Result();
-        String tranSymbol = tranDTO.getSymbol().toLowerCase();
+        String tranSymbol = tranDTO.getCoin().toLowerCase();
         String tranLegalCoin = tranDTO.getLegalCoin().toUpperCase();
         Integer tranDirection = tranDTO.getDirection();
         //支付方式
@@ -342,19 +342,19 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
     /**
      * 查询快捷交易广告
      *
-     * @param symbol
+     * @param coin
      * @param direction
      * @param legalCoin
      * @param tranAmount
      * @return
      */
-    private List<C2cAdEntity> selectC2cAdTranList(String symbol,Integer direction,
+    private List<C2cAdEntity> selectC2cAdTranList(String coin,Integer direction,
                                                   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(StrUtil.isNotBlank(coin),C2cAdEntity::getCoin, coin)
                     .eq(C2cAdEntity::getStatus,AdStatusEnum.PASS.getCode())
                     .eq(Objects.nonNull(tag),C2cAdEntity::getTag,tag)
                     .last(" limit 100")
@@ -405,7 +405,7 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
         }
         params.put(Constant.PAGE,viewDTO.getPageNum());
         params.put(Constant.LIMIT,viewDTO.getPageSize());
-        String inputSymbol = viewDTO.getSymbol().toLowerCase();
+        String inputCoin = viewDTO.getCoin().toLowerCase();
         String inputLegalCoin = viewDTO.getLegalCoin().toUpperCase();
 
         // 查数据库
@@ -417,7 +417,7 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
                 .ne(C2cAdEntity::getUserId, StpUtil.getLoginIdAsLong())
                 .eq(Objects.nonNull(direction),C2cAdEntity::getDirection, direction)
                 .eq(StrUtil.isNotBlank(inputLegalCoin),C2cAdEntity::getLegalCoin, inputLegalCoin)
-                .eq(StrUtil.isNotBlank(inputSymbol),C2cAdEntity::getSymbol, inputSymbol)
+                .eq(StrUtil.isNotBlank(inputCoin),C2cAdEntity::getCoin, inputCoin)
                 .eq(C2cAdEntity::getStatus,AdStatusEnum.PASS.getCode())
                 .eq(Objects.nonNull(tag) && tag != -1,C2cAdEntity::getTag,tag)
                 .le(Objects.nonNull(amount),C2cAdEntity::getMinAmount,amount)
@@ -464,7 +464,7 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
         c2cAd.setUserName(Convert.toStr(adMap.get("userName")));
         c2cAd.setMerchantId(Convert.toLong(adMap.get("merchantId")));
         c2cAd.setDirection(Convert.toInt(adMap.get("direction")));
-        c2cAd.setSymbol(Convert.toStr(adMap.get("symbol")));
+        c2cAd.setCoin(Convert.toStr(adMap.get("coin")));
         c2cAd.setLegalCoin(Convert.toStr(adMap.get("legalCoin")));
         c2cAd.setNum(Convert.toBigDecimal(adMap.get("total")));
         c2cAd.setAvailableNum(Convert.toBigDecimal(adMap.get("availableNum")));
@@ -482,9 +482,9 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
     private void delSetAdCache(C2cAdEntity ad) {
         if(ad != null) {
             if (ad.getStatus().intValue() == AdStatusEnum.NOPASS.getCode().intValue()) {
-                deleteAdCache(ad.getId(), ad.getPayway().replaceAll("^,|,$", ""), ad.getLegalCoin(), ad.getSymbol(), ad.getDirection());
+                deleteAdCache(ad.getId(), ad.getPayway().replaceAll("^,|,$", ""), ad.getLegalCoin(), ad.getCoin(), ad.getDirection());
             } else {
-                deleteAdCache(ad.getId(), ad.getPayway().replaceAll("^,|,$", ""), ad.getLegalCoin(), ad.getSymbol(), ad.getDirection());
+                deleteAdCache(ad.getId(), ad.getPayway().replaceAll("^,|,$", ""), ad.getLegalCoin(), ad.getCoin(), ad.getDirection());
                 setAdCache(ad);
             }
         }
@@ -514,9 +514,9 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
     public boolean updateC2cAdDisabled(C2cAdEntity c2cAd) {
         Integer adDirection = c2cAd.getDirection();
         String adLegalCoin = c2cAd.getLegalCoin();
-        String adSymbol = c2cAd.getSymbol();
+        String adCoin = c2cAd.getCoin();
         String adPayway = c2cAd.getPayway().replaceAll("^,|,$", "");
-        deleteAdCache(c2cAd.getId(), adPayway, adLegalCoin, adSymbol, adDirection);
+        deleteAdCache(c2cAd.getId(), adPayway, adLegalCoin, adCoin, adDirection);
         c2cAd.setStatus(AdStatusEnum.NOPASS.getCode());
         return updateById(c2cAd);
     }
@@ -531,9 +531,9 @@ public class C2cAdServiceImpl extends BaseServiceImpl<C2cAdDao, C2cAdEntity> imp
     public void deleteC2cAdCache(C2cAdEntity c2cAd) {
         Integer adDirection = c2cAd.getDirection();
         String adLegalCoin = c2cAd.getLegalCoin();
-        String adSymbol = c2cAd.getSymbol();
+        String adCoin = c2cAd.getCoin();
         String adPayway = c2cAd.getPayway().replaceAll("^,|,$", "");
-        deleteAdCache(c2cAd.getId(), adPayway, adLegalCoin, adSymbol, adDirection);
+        deleteAdCache(c2cAd.getId(), adPayway, adLegalCoin, adCoin, adDirection);
     }
 
 

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

@@ -1,31 +0,0 @@
-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.modules.c2c.dao.C2cOrderComplainVoucherDao;
-import com.qnfhq.modules.c2c.entity.C2cOrderComplainVoucherEntity;
-import com.qnfhq.modules.c2c.service.C2cOrderComplainVoucherService;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.Objects;
-
-/**
- * c2c申诉证明材料
- *
- * @author yelz 30262728@qq.com
- * @since 1.0.0 2025-11-17
- */
-@Service
-public class C2cOrderComplainVoucherServiceImpl extends ServiceImpl<C2cOrderComplainVoucherDao, C2cOrderComplainVoucherEntity> implements C2cOrderComplainVoucherService {
-
-
-    @Override
-    public List<C2cOrderComplainVoucherEntity> selectList(Long complainId) {
-        return list(new QueryWrapper<C2cOrderComplainVoucherEntity>()
-                .eq(Objects.nonNull(complainId),"complain_id", complainId)
-                .eq("status", 1)
-                .orderByDesc("id")
-        );
-    }
-}

+ 40 - 41
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cOrderServiceImpl.java

@@ -177,12 +177,12 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
         order.setUserName(Convert.toStr(odMap.get("userName")));
         order.setDirection(Convert.toInt(odMap.get("direction")));
         order.setLegalCoin(Convert.toStr(odMap.get("legalCoin")));
-        order.setSymbol(Convert.toStr(odMap.get("symbol")));
+        order.setCoin(Convert.toStr(odMap.get("coin")));
         order.setC2cAdId(Convert.toLong(odMap.get("c2cAdId")));
         order.setTranUserId(Convert.toLong(odMap.get("tranUserId")));
         order.setTranUserName(Convert.toStr(odMap.get("tranUserName")));
         order.setTranPrice(Convert.toBigDecimal(odMap.get("tranPrice")));
-        order.setSymbolNum(Convert.toBigDecimal(odMap.get("symbolNum")));
+        order.setCoinNum(Convert.toBigDecimal(odMap.get("coinNum")));
         order.setTranAmount(Convert.toBigDecimal(odMap.get("tranAmount")));
         order.setPayType(Convert.toInt(odMap.get("payType")));
         order.setFlow(Convert.toInt(odMap.get("flow")));
@@ -203,12 +203,12 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
         odMap.put("userName", c2cOrder.getUserName());
         odMap.put("direction", c2cOrder.getDirection());
         odMap.put("legalCoin", c2cOrder.getLegalCoin());
-        odMap.put("symbol", c2cOrder.getSymbol());
+        odMap.put("coin", c2cOrder.getCoin());
         odMap.put("c2cAdId", c2cOrder.getC2cAdId());
         odMap.put("tranUserId", c2cOrder.getTranUserId());
         odMap.put("tranUserName", c2cOrder.getTranUserName());
         odMap.put("tranPrice", c2cOrder.getTranPrice());
-        odMap.put("symbolNum", c2cOrder.getSymbolNum());
+        odMap.put("coinNum", c2cOrder.getCoinNum());
         odMap.put("tranAmount", c2cOrder.getTranAmount());
         odMap.put("payType", c2cOrder.getPayType());
         odMap.put("flow", c2cOrder.getFlow());
@@ -254,12 +254,12 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public Result createC2cOrder(C2cOrderCreateDTO c2cOrderDTO, C2cAdEntity c2cAd, BigDecimal legalCoinAmount, BigDecimal symbolNum,
+    public Result createC2cOrder(C2cOrderCreateDTO c2cOrderDTO, C2cAdEntity c2cAd, BigDecimal legalCoinAmount, BigDecimal coinNum,
                                  Long loginUserId, String realName) throws Exception {
         /** 1买入  2 卖出 */
         Integer direction = c2cOrderDTO.getDirection();
         /** 交易币 */
-        String symbol = c2cOrderDTO.getSymbol().toLowerCase();
+        String coin = c2cOrderDTO.getCoin().toLowerCase();
         /** 法定货币 */
         String legalCoin = c2cOrderDTO.getLegalCoin().toLowerCase();
         /** 广告编号 */
@@ -276,12 +276,12 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
         c2cOrder.setUserName(realName);
         c2cOrder.setDirection(direction);
         c2cOrder.setLegalCoin(legalCoin);
-        c2cOrder.setSymbol(symbol);
+        c2cOrder.setCoin(coin);
         c2cOrder.setC2cAdId(c2cAdId);
         c2cOrder.setTranUserId(tranUserId);
         c2cOrder.setTranUserName(adUserName);
         c2cOrder.setTranPrice(price);
-        c2cOrder.setSymbolNum(symbolNum);
+        c2cOrder.setCoinNum(coinNum);
         c2cOrder.setTranAmount(legalCoinAmount);
         c2cOrder.setPayType(payType);
         c2cOrder.setFlow(C2cOrderFlowEnum.PROGRESS.getCode());
@@ -297,23 +297,23 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
         //用户卖出冻结资金
         if(c2cOrder.getDirection().intValue() == DirectionEnum.SELL.getCode().intValue()) {
             AppAssetEntity userPlatformAsset = appAssetService.getAppAssetEntity(c2cOrder.getUserId(),
-                    c2cOrder.getSymbol(),AssetEnum.PLATFORM_ASSETS.getCode());
-            if(userPlatformAsset.getAvailable().compareTo(c2cOrder.getSymbolNum())==-1) {
+                    c2cOrder.getCoin(),AssetEnum.PLATFORM_ASSETS.getCode());
+            if(userPlatformAsset.getAvailable().compareTo(c2cOrder.getCoinNum())==-1) {
                 throw new Exception(MessageUtils.message("c2c.order.availableAmount.insufficient"));//您的可用资产必须大于卖出数量
             }
-            if (appAssetService.frozeAssetByUserId(loginUserId, c2cOrder.getSymbol(), c2cOrder.getSymbolNum()) == 0) {
+            if (appAssetService.frozeAssetByUserId(loginUserId, c2cOrder.getCoin(), c2cOrder.getCoinNum()) == 0) {
                 throw new Exception(MessageUtils.message("c2c.order.update.asset.fail"));//更新卖家资产失败
             }
-            appAssetLogService.insertAssetLog(c2cOrder.getId(),c2cOrder.getUserId(),c2cOrder.getSymbol(),AssetEnum.PLATFORM_ASSETS.getCode(),
+            appAssetLogService.insertAssetLog(c2cOrder.getId(),c2cOrder.getUserId(),c2cOrder.getCoin(),AssetEnum.PLATFORM_ASSETS.getCode(),
                     userPlatformAsset.getTotal(),userPlatformAsset.getTotal(),
-                    userPlatformAsset.getAvailable(),userPlatformAsset.getAvailable().subtract(c2cOrder.getSymbolNum()),
-                    userPlatformAsset.getFrozen(),userPlatformAsset.getFrozen().add(c2cOrder.getSymbolNum()),"c2c卖出冻结资产");
+                    userPlatformAsset.getAvailable(),userPlatformAsset.getAvailable().subtract(c2cOrder.getCoinNum()),
+                    userPlatformAsset.getFrozen(),userPlatformAsset.getFrozen().add(c2cOrder.getCoinNum()),"c2c卖出冻结资产");
         }
 
         // 更新广告的可用数量
         BigDecimal newMaxAmount = null;
         Integer newStatus = null;
-        BigDecimal maxAvail = c2cAd.getAvailableNum().subtract(symbolNum).multiply(price);
+        BigDecimal maxAvail = c2cAd.getAvailableNum().subtract(coinNum).multiply(price);
         if(c2cAd.getMaxAmount().compareTo(maxAvail)==1) {
             newMaxAmount = maxAvail;
         }
@@ -321,11 +321,11 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
             newStatus = AdStatusEnum.NOPASS.getCode();
             c2cAdService.deleteC2cAdCache(c2cAd);
         }
-        if (c2cAdService.updateC2cAdAvailableNumById(c2cAdId, c2cOrder.getSymbolNum(), newMaxAmount, newStatus,c2cAd.getVersion()) == 0) {
+        if (c2cAdService.updateC2cAdAvailableNumById(c2cAdId, c2cOrder.getCoinNum(), newMaxAmount, newStatus,c2cAd.getVersion()) == 0) {
             throw new Exception(MessageUtils.message("operation.fail.please.refresh"));//操作失败,请刷新后重试
         }
-        c2cAdLogService.insertC2cAdLog(c2cAdId,c2cOrder.getId(),c2cOrder.getSymbolNum(),
-                c2cAd.getAvailableNum(),c2cAd.getAvailableNum().subtract(c2cOrder.getSymbolNum()),
+        c2cAdLogService.insertC2cAdLog(c2cAdId,c2cOrder.getId(),c2cOrder.getCoinNum(),
+                c2cAd.getAvailableNum(),c2cAd.getAvailableNum().subtract(c2cOrder.getCoinNum()),
                 c2cAd.getMaxAmount(),
                 newMaxAmount!=null?newMaxAmount:c2cAd.getMaxAmount(),"创建C2C订单");
 
@@ -368,7 +368,7 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
     public int cancelC2cOrderRedis(int oldStatus,C2cOrderEntity order) {
         //redis广告可用数量恢复
         C2cAdEntity c2cAd = c2cAdService.selectById(order.getC2cAdId());
-        c2cAdService.deleteAdCache(c2cAd.getId(),c2cAd.getPayway().replaceAll("^,|,$", ""),c2cAd.getLegalCoin(),c2cAd.getSymbol(),c2cAd.getDirection());
+        c2cAdService.deleteAdCache(c2cAd.getId(),c2cAd.getPayway().replaceAll("^,|,$", ""),c2cAd.getLegalCoin(),c2cAd.getCoin(),c2cAd.getDirection());
         c2cAdService.setAdCache(c2cAd);
         deleteOrderCache(order);
 
@@ -442,14 +442,14 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
         }
 
         if(order.getDirection().intValue() == DirectionEnum.SELL.getCode().intValue()) {
-            AppAssetEntity info = appAssetService.getAppAssetEntity(order.getUserId(),order.getSymbol(),AssetEnum.PLATFORM_ASSETS.getCode());
-            if (appAssetService.unblockAssetByUserId(sellUserId, order.getSymbol(), order.getSymbolNum()) <= 0) {
+            AppAssetEntity info = appAssetService.getAppAssetEntity(order.getUserId(),order.getCoin(),AssetEnum.PLATFORM_ASSETS.getCode());
+            if (appAssetService.unblockAssetByUserId(sellUserId, order.getCoin(), order.getCoinNum()) <= 0) {
                 throw new Exception(MessageUtils.message("c2c.user.occupied.asset.fail"));//用户资产解冻失败
             }
-            appAssetLogService.insertAssetLog(order.getId(),order.getUserId(),order.getSymbol(),AssetEnum.PLATFORM_ASSETS.getCode(),
+            appAssetLogService.insertAssetLog(order.getId(),order.getUserId(),order.getCoin(),AssetEnum.PLATFORM_ASSETS.getCode(),
                     info.getTotal(),info.getTotal(),
-                    info.getAvailable(),info.getAvailable().add(order.getSymbolNum()),
-                    info.getFrozen(),info.getFrozen().subtract(order.getSymbolNum()),"c2c订单取消解冻资产");
+                    info.getAvailable(),info.getAvailable().add(order.getCoinNum()),
+                    info.getFrozen(),info.getFrozen().subtract(order.getCoinNum()),"c2c订单取消解冻资产");
         }
         //广告可用数量恢复
         C2cAdEntity c2cAd = c2cAdService.selectById(order.getC2cAdId());
@@ -457,11 +457,11 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
         if(order.getTranAmount().compareTo(c2cAd.getMaxAmount())==1) {
             maxAmount = order.getTranAmount();
         }
-        if(c2cAdService.addC2cAdAvailableNumById(order.getC2cAdId(),order.getSymbolNum(),maxAmount,c2cAd.getVersion())<=0) {
+        if(c2cAdService.addC2cAdAvailableNumById(order.getC2cAdId(),order.getCoinNum(),maxAmount,c2cAd.getVersion())<=0) {
             throw new Exception(MessageUtils.message("c2c.ad.availAmount.update.fail"));//更新广告可用数量失败
         }
-        c2cAdLogService.insertC2cAdLog(order.getC2cAdId(),order.getId(),order.getSymbolNum(),
-                c2cAd.getAvailableNum(),c2cAd.getAvailableNum().add(order.getSymbolNum()),
+        c2cAdLogService.insertC2cAdLog(order.getC2cAdId(),order.getId(),order.getCoinNum(),
+                c2cAd.getAvailableNum(),c2cAd.getAvailableNum().add(order.getCoinNum()),
                 c2cAd.getMaxAmount(),c2cAd.getMaxAmount(),"c2c订单取消,恢复广告可用数量");
         //消息通知
         c2cMsgContentService.sendOrderCancelMsg(getBuyUserId(order),sellUserId,order.getId(),order.getOrderNo());
@@ -606,12 +606,12 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
             throw new Exception(MessageUtils.message("c2c.order.update.fail"));//更新订单失败
         }
         //2 更新买家账户
-        AppAssetEntity buyerAsset = appAssetService.getAppAssetEntity(buyUserId, order.getSymbol(), AssetEnum.PLATFORM_ASSETS.getCode());
+        AppAssetEntity buyerAsset = appAssetService.getAppAssetEntity(buyUserId, order.getCoin(), AssetEnum.PLATFORM_ASSETS.getCode());
 
         //判断是否需要创建买家资产账户
         if (Objects.isNull(buyerAsset)) {
             AppUserEntity buyUser = appUserService.getById(buyUserId);
-            appAssetService.createAsset(buyUser, order.getSymbol(), AssetEnum.PLATFORM_ASSETS.getCode());
+            appAssetService.createAsset(buyUser, order.getCoin(), AssetEnum.PLATFORM_ASSETS.getCode());
 
             buyerAsset = new AppAssetEntity();
             buyerAsset.setTotal(BigDecimal.ZERO);
@@ -619,27 +619,27 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
             buyerAsset.setAvailable(BigDecimal.ZERO);
         }
         //卖家资产
-        AppAssetEntity sellerAsset = appAssetService.getAppAssetEntity(sellUserId, order.getSymbol(), AssetEnum.PLATFORM_ASSETS.getCode());
+        AppAssetEntity sellerAsset = appAssetService.getAppAssetEntity(sellUserId, order.getCoin(), AssetEnum.PLATFORM_ASSETS.getCode());
 
-        if (appAssetService.addAssetByUserId(buyUserId, order.getSymbol(), order.getSymbolNum()) <= 0) {
+        if (appAssetService.addAssetByUserId(buyUserId, order.getCoin(), order.getCoinNum()) <= 0) {
             throw new Exception(MessageUtils.message("c2c.buyer.asset.update.fail"));//更新买家资产失败
         }
 
-        if(appAssetService.releaseAssetByUserId(sellUserId, order.getSymbol(), order.getSymbolNum()) <= 0) {
+        if(appAssetService.releaseAssetByUserId(sellUserId, order.getCoin(), order.getCoinNum()) <= 0) {
             throw new Exception(MessageUtils.message("c2c.seller.asset.update.fail"));//更新卖家资产失败
         }
 
         //买家资产变更记录
-        appWalletRecordService.generateRecord(buyUserId, order.getSymbolNum(),
+        appWalletRecordService.generateRecord(buyUserId, order.getCoinNum(),
                 RecordEnum.C2C_TRAN_BUY.getCode(), "system", order.getOrderNo(),
-                RecordEnum.C2C_TRAN_BUY.getInfo(), buyerAsset.getTotal(), buyerAsset.getTotal().add(order.getSymbolNum()),
-                order.getSymbol(), "");
+                RecordEnum.C2C_TRAN_BUY.getInfo(), buyerAsset.getTotal(), buyerAsset.getTotal().add(order.getCoinNum()),
+                order.getCoin(), "");
 
         //卖家资产变更记录
-        appWalletRecordService.generateRecord(sellUserId, order.getSymbolNum(),
+        appWalletRecordService.generateRecord(sellUserId, order.getCoinNum(),
                 RecordEnum.C2C_TRAN_SELL.getCode(), "system", order.getOrderNo(),
-                RecordEnum.C2C_TRAN_SELL.getInfo(), buyerAsset.getTotal(), buyerAsset.getTotal().subtract(order.getSymbolNum()),
-                order.getSymbol(), "");
+                RecordEnum.C2C_TRAN_SELL.getInfo(), buyerAsset.getTotal(), buyerAsset.getTotal().subtract(order.getCoinNum()),
+                order.getCoin(), "");
 
         deleteOrderCache(order);
 
@@ -708,7 +708,7 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
             return result;
         }
 
-        insertC2cOrderLog(order.getId(), order.getStatus(), C2cOrderStatusEnum.COMPLAIN.getCode(), c2cOrderComplain.getReason(),StpUtil.getLoginIdAsLong(),"app");
+        insertC2cOrderLog(order.getId(), order.getStatus(), C2cOrderStatusEnum.COMPLAIN.getCode(), c2cOrderComplain.getReasonId().toString(),StpUtil.getLoginIdAsLong(),"app");
 
         order.setStatus(C2cOrderStatusEnum.COMPLAIN.getCode());
         if(!updateById(order)) {
@@ -734,6 +734,7 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
 
         //设置订单状态
         setOrderStatusCache(order);
+        releaseCounts(order, sellUserId);
 
         //邮件通知被申诉人
 //        TAppUser appUser = appUserService.getById(c2cOrderComplain.getToUserId());
@@ -743,8 +744,6 @@ public class C2cOrderServiceImpl extends BaseServiceImpl<C2cOrderDao, C2cOrderEn
 //            EmailUtils.sendComplainMail(appUser.getEmail(), emailText);
 //        }
 
-        releaseCounts(order, sellUserId);
-
         return result.ok(c2cOrderComplain.getId());
     }
 

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

@@ -0,0 +1,31 @@
+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.modules.c2c.dao.C2cOrderVoucherDao;
+import com.qnfhq.modules.c2c.entity.C2cOrderVoucherEntity;
+import com.qnfhq.modules.c2c.service.C2cOrderVoucherService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * c2c申诉证明材料
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-11-17
+ */
+@Service
+public class C2cOrderVoucherServiceImpl extends ServiceImpl<C2cOrderVoucherDao, C2cOrderVoucherEntity> implements C2cOrderVoucherService {
+
+
+    @Override
+    public List<C2cOrderVoucherEntity> selectList(Long orderId) {
+        return list(new QueryWrapper<C2cOrderVoucherEntity>()
+                .eq(Objects.nonNull(orderId),"order_id", orderId)
+                .eq("status", 1)
+                .orderByDesc("id")
+        );
+    }
+}

+ 1 - 9
qnfhq-api/src/main/java/com/qnfhq/modules/c2c/service/impl/C2cPaymentVoucherServiceImpl.java

@@ -28,15 +28,7 @@ public class C2cPaymentVoucherServiceImpl extends ServiceImpl<C2cPaymentVoucherD
         this.c2cPaymentVoucherDao = c2cPaymentVoucherDao;
     }
 
-//    @Override
-//    public QueryWrapper<C2cPaymentVoucherEntity> getWrapper(Map<String, Object> params){
-//        String id = (String)params.get("id");
-//
-//        QueryWrapper<C2cPaymentVoucherEntity> wrapper = new QueryWrapper<>();
-//        wrapper.eq(StrUtil.isNotBlank(id), "id", id);
-//
-//        return wrapper;
-//    }
+
 
     @Override
     public List<C2cPaymentVoucherEntity> selectList(Long orderId) {

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

@@ -0,0 +1,31 @@
+package com.qnfhq.modules.c2c.service.impl;
+
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qnfhq.modules.c2c.dao.OrderReportDao;
+import com.qnfhq.modules.c2c.entity.OrderReportEntity;
+import com.qnfhq.modules.c2c.service.OrderReportService;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * c2c订单举报表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-01
+ */
+@Service
+public class OrderReportServiceImpl extends ServiceImpl<OrderReportDao, OrderReportEntity> implements OrderReportService {
+
+//    @Override
+//    public QueryWrapper<OrderReportEntity> getWrapper(Map<String, Object> params){
+//        String id = (String)params.get("id");
+//
+//        QueryWrapper<OrderReportEntity> wrapper = new QueryWrapper<>();
+//        wrapper.eq(StrUtil.isNotBlank(id), "id", id);
+//
+//        return wrapper;
+//    }
+
+
+}

+ 186 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/common/controller/CommonController.java

@@ -0,0 +1,186 @@
+package com.qnfhq.modules.common.controller;
+
+import cn.hutool.json.JSONUtil;
+import com.qnfhq.common.ApiBaseController;
+import com.qnfhq.common.redis.RedisUtils;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.modules.common.dto.setting.TRechargeChannelSetting;
+import com.qnfhq.modules.common.service.FileService;
+import com.qnfhq.modules.user.entity.SettingEntity;
+import com.qnfhq.modules.user.enums.SettingEnum;
+import com.qnfhq.modules.user.service.SettingService;
+import io.swagger.v3.oas.annotations.Operation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import jakarta.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 通用请求处理
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/home")
+public class CommonController extends ApiBaseController
+{
+    private static final Logger log = LoggerFactory.getLogger(CommonController.class);
+
+    @Resource
+    private RedisUtils redisUtils;
+    @Resource
+    private FileService fileService;
+    @Resource
+    private SettingService settingService;
+
+
+    @Operation(summary = "oss通用上传请求")
+    @PostMapping("/upload/OSS")
+    public Result uploadFileOSS(MultipartFile file, String remark) {
+        try {
+            String filename = file.getResource().getFilename();
+            //这里文件名用了uuid 防止重复,可以根据自己的需要来写
+            String name = UUID.randomUUID() + filename.substring(filename.lastIndexOf("."), filename.length());
+            name = name.replace("-", "");
+            String url = fileService.uploadFileOSS(file,name);
+            Map ajax =new  HashMap();
+            ajax.put("fileName", name);
+            ajax.put("url", url);
+            return new Result().ok(ajax);
+        } catch (Exception e) {
+            e.getMessage();
+            return new Result().error(e.getMessage());
+        }
+    }
+
+
+
+    @Operation(summary = "获取所有配置")
+    @PostMapping("/getAllSetting")
+    public Result getAllSetting() {
+        //提现
+        SettingEntity setting = settingService.getSetting(SettingEnum.WITHDRAWAL_CHANNEL_SETTING.name());
+        HashMap<String, Object> map = new HashMap<>();
+        map.put("WITHDRAWAL_CHANNEL_SETTING",setting == null ? new ArrayList<TRechargeChannelSetting>() :
+                JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), TRechargeChannelSetting.class));
+        //首页
+//        SettingEntity setting = settingService.getSetting(SettingEnum.HOME_COIN_SETTING.name());
+//        map.put("HOME_COIN_SETTING", setting == null ? new ArrayList<HomeCoinSetting>() :
+//                JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), HomeCoinSetting.class)
+//                        .stream().sorted(Comparator.comparing(HomeCoinSetting::getSort)).collect(Collectors.toList()));
+//        //获取客服列表
+//        SettingEntity setting = settingService.getSetting(SettingEnum.SUPPORT_STAFF_SETTING.name());
+//        map.put("SUPPORT_STAFF_SETTING",setting == null ? new ArrayList<HomeCoinSetting>() :
+//                JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), SupportStaffSetting.class));
+        //获取登录注册开关
+//        SettingEntity setting = settingService.getSetting(SettingEnum.LOGIN_REGIS_SETTING.name());
+//        map.put("LOGIN_REGIS_SETTING",setting == null ? new LoginRegisSetting() :
+//                JSONUtil.toBean(setting.getSettingValue(), LoginRegisSetting.class));
+        //获取App侧边栏配置
+//        SettingEntity setting = settingService.getSetting(SettingEnum.APP_SIDEBAR_SETTING.name());
+//        map.put("APP_SIDEBAR_SETTING",setting == null ? new ArrayList<AppSidebarSetting>() :
+//                JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), AppSidebarSetting.class)
+//                        .stream().sorted(Comparator.comparing(AppSidebarSetting::getSort)).collect(Collectors.toList()));
+        //充值通道列表
+//        SettingEntity setting = settingService.getSetting((SettingEnum.ASSET_COIN.name());
+//        map.put("ASSET_COIN",setting == null ? new ArrayList<AssetCoinSetting>() :
+//                JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), AssetCoinSetting.class));
+        //白皮书
+/*        SettingEntity setting = settingService.getSetting(SettingEnum.WHITE_PAPER_SETTING.name());
+        map.put("WHITE_PAPER_SETTING",setting == null ? new WhitePaperSetting() :
+                JSONUtil.toBean(setting.getSettingValue(), WhitePaperSetting.class));*/
+        //defi挖矿配置
+//        SettingEntity setting = settingService.getSetting(SettingEnum.DEFI_INCOME_SETTING.name());
+//        map.put("DEFI_INCOME_SETTING",setting == null ? new DefiIncomeSetting() :
+//                JSONUtil.toBean(setting.getSettingValue(), DefiIncomeSetting.class));
+        //玩法配置
+//        SettingEntity setting = settingService.getSetting(SettingEnum.PLAYING_SETTING.name());
+//        map.put("PLAYING_SETTING",setting == null ? new ArrayList<PlayingSetting>() :
+//                JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), PlayingSetting.class)
+//                        .stream().sorted(Comparator.comparing(PlayingSetting::getSort)).collect(Collectors.toList()));
+
+        //投部TAB_SETTING
+//        SettingEntity setting = settingService.getSetting(SettingEnum.TAB_SETTING.name());
+//        map.put("TAB_SETTING",setting == null ? new ArrayList<PlayingSetting>() :
+//                JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), TabSetting.class)
+//                        .stream().sorted(Comparator.comparing(TabSetting::getSort)).collect(Collectors.toList()));
+        //底部菜单
+//        SettingEntity setting = settingService.getSetting(SettingEnum.BOTTOM_MENU_SETTING.name());
+//        map.put("BOTTOM_MENU_SETTING",setting == null ?new ArrayList<BottomMenuSetting>() :
+//                JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), BottomMenuSetting.class)
+//                        .stream().sorted(Comparator.comparing(BottomMenuSetting::getSort)).collect(Collectors.toList()));
+        //金刚区
+//        SettingEntity setting = settingService.getSetting(SettingEnum.MIDDLE_MENU_SETTING.name());
+//        map.put("MIDDLE_MENU_SETTING",setting == null ? new ArrayList<MiddleMenuSetting>() :
+//                JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), MiddleMenuSetting.class)
+//                        .stream().sorted(Comparator.comparing(MiddleMenuSetting::getSort)).collect(Collectors.toList()));
+        //Logo配置
+//        SettingEntity setting = settingService.getSetting(SettingEnum.LOGO_SETTING.name());
+//        map.put("LOGO_SETTING",setting == null ? new LogoSetting() :
+//                JSONUtil.toBean(setting.getSettingValue(), LogoSetting.class));
+        //下载地址
+//        SettingEntity setting = settingService.getSetting(SettingEnum.DOWNLOAD_SETTING.name());
+//        map.put("DOWNLOAD_SETTING",setting == null ? new ArrayList<DownloadSetting>() :
+//                JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), DownloadSetting.class)
+//                        .stream().sorted(Comparator.comparing(DownloadSetting::getSort)).collect(Collectors.toList()));
+
+        //图形验证码
+//        SettingEntity setting = settingService.getSetting(SettingEnum.MARKET_URL.name());
+//        map.put("MARKET_URL",setting == null ? new MarketUrlSetting() :
+//                JSONUtil.toBean(setting.getSettingValue(), MarketUrlSetting.class));
+
+        //多语言
+//        List<SysDictData> data = dictTypeService.selectDictDataByType("t_app_language");
+//        if (StringUtils.isNull(data))
+//        {
+//            data = new ArrayList<SysDictData>();
+//        }
+//        map.put("t_app_language",data);
+
+        //vip 等级配置
+//        SettingEntity setting = settingService.getSetting(SettingEnum.VIP_LEVEL_SETTING.name());
+//        map.put("VIP_LEVEL_SETTING",setting == null ? new VipLevelSetting() :
+//                JSONUtil.toBean(setting.getSettingValue(), VipLevelSetting.class));
+
+        //vip 说明
+//        SettingEntity setting = settingService.getSetting(SettingEnum.VIP_DIRECTIONS_SETTING.name());
+//        map.put("VIP_DIRECTIONS_SETTING",setting == null ? new ArrayList<VipDirectionsSetting>() :
+//                JSONUtil.toList(JSONUtil.parseArray(setting.getSettingValue()), VipDirectionsSetting.class));
+        //时区
+//        SettingEntity setting = settingService.getSetting(SettingEnum.PLATFORM_SETTING.name());
+//        if(null == setting){
+//            com.table.common.core.domain.entity.TimeZone timeZone = DateUtils.getTimeZone();
+//            map.put("timeZone",timeZone);
+
+//        }else {
+//            PlatformSetting platformSetting = JSONUtil.toBean(setting.getSettingValue(), PlatformSetting.class);
+//            com.table.common.core.domain.entity.TimeZone timeZone = DateUtils.getTimeZone(platformSetting.getTimezone());
+//            map.put("timeZone",timeZone);
+//        }
+
+        //线下付款打款地址
+//        SettingEntity setting = settingService.getSetting(SettingEnum.BANK_SETTING.name());
+//        map.put("BANK_SETTING",setting == null ? new BankSetting() :
+//                JSONUtil.toBean(setting.getSettingValue(), BankSetting.class));
+
+        //法币兑USDT
+//        SettingEntity setting = settingService.getSetting(SettingEnum.CHARGE_FEE.name());
+//        map.put("CHARGE_FEE",setting == null ? new RateSetting() :
+//                JSONUtil.toBean(setting.getSettingValue(), RateSetting.class));
+
+        //认证数据
+//        SettingEntity setting = settingService.getSetting(SettingEnum.AUTH_LIMIT.name());
+//        map.put("AUTH_LIMIT",setting == null ? new AuthLimitSetting():JSONUtil.toBean(setting.getSettingValue(),AuthLimitSetting.class));
+//
+        //首页幻灯片
+//        map.put("HOME_SLIDE",iTAdvertService.selectTAdvertByPage(2L));
+        //首页弹屏广告
+//        map.put("HOME_SCREEN",iTAdvertService.selectTAdvertByPage(3L));
+
+
+        return new Result().ok(map);
+    }
+}

+ 31 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/common/dto/setting/OssSetting.java

@@ -0,0 +1,31 @@
+package com.qnfhq.modules.common.dto.setting;
+
+import lombok.Data;
+
+/**
+ * 阿里文件服务器
+ */
+@Data
+public class OssSetting {
+
+    /**
+     * 存放路径路径
+     */
+    private String picLocation;
+
+    private String endPoint;
+    /**
+     * 储存空间
+     */
+    private String bucketName;
+    /**
+     * 密钥id
+     */
+    private String accessKeyId;
+    /**
+     * 密钥
+     */
+    private String accessKeySecret;
+
+
+}

+ 55 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/common/dto/setting/TRechargeChannelSetting.java

@@ -0,0 +1,55 @@
+package com.qnfhq.modules.common.dto.setting;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 提现通道配置
+ */
+@Data
+public class TRechargeChannelSetting {
+
+    /**
+     *  0-关闭 1-开启
+     */
+    private String status;
+    /**
+     * 展示名称
+     */
+    private String rechargeName;
+    /**
+     * 提现币种
+     */
+    private String rechargeType;
+    /**
+     * 0 为数据货币 1为银行卡
+     */
+    private String type;
+    /**
+     *固定手续费
+     */
+
+    private BigDecimal fee ;
+
+    /**
+     * 手续费
+     */
+    private BigDecimal ratio;
+    /**
+     * 每日提现次数限制
+     */
+    private Integer dayWithdrawalNum;
+    /**
+     * 系统免费提现次数
+     */
+    private Integer freeNum;
+    /**
+     * 最大限制
+     */
+    private BigDecimal withdrawalMax;
+    /**
+     * 最小限制
+     */
+    private BigDecimal withdrawalMix;
+}

+ 10 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/common/service/FileService.java

@@ -0,0 +1,10 @@
+package com.qnfhq.modules.common.service;
+
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+
+public interface FileService {
+    String uploadFileOSS(MultipartFile file, String name) throws IOException;
+    void deleteFileOSS(String fileName) throws IOException;
+}

+ 66 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/common/service/impl/FileServiceImpl.java

@@ -0,0 +1,66 @@
+package com.qnfhq.modules.common.service.impl;
+
+import cn.hutool.json.JSONUtil;
+import com.qnfhq.modules.common.dto.setting.OssSetting;
+import com.qnfhq.modules.common.service.FileService;
+import com.qnfhq.modules.user.entity.SettingEntity;
+import com.qnfhq.modules.user.enums.SettingEnum;
+import com.qnfhq.modules.user.service.SettingService;
+import com.qnfhq.utils.AliOssCloudUtil;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import jakarta.annotation.Resource;
+import java.io.IOException;
+import java.io.InputStream;
+
+@Service
+public class FileServiceImpl implements FileService {
+
+
+    @Resource
+    private SettingService settingService;
+
+
+    @Override
+    public String uploadFileOSS(MultipartFile file, String name) throws IOException {
+        SettingEntity setting = settingService.getSetting(SettingEnum.OSS_SETTING.name());
+        OssSetting ossSetting = JSONUtil.toBean(setting.getSettingValue(), OssSetting.class);
+        InputStream inputStream = null;
+        inputStream = file.getInputStream();
+        //阿里云的endpoint
+        String endpoint =  ossSetting.getEndPoint();
+        //阿里云的accessKeyId
+        String accessKeyId = ossSetting.getAccessKeyId();
+        //阿里云的accessKeySecret
+        String accessKeySecret = ossSetting.getAccessKeySecret();
+        //空间
+        String bucketName =ossSetting.getBucketName();
+        //文件存储目录
+        String filedir = ossSetting.getPicLocation();
+
+        AliOssCloudUtil util = new AliOssCloudUtil(endpoint,accessKeyId,accessKeySecret,bucketName,filedir);
+        //上传成功返回完整路径的url
+        return util.uploadFile2OSS(inputStream, name);
+    }
+
+    @Override
+    public void deleteFileOSS(String fileName) throws IOException {
+        SettingEntity setting = settingService.getSetting(SettingEnum.OSS_SETTING.name());
+        OssSetting ossSetting = JSONUtil.toBean(setting.getSettingValue(), OssSetting.class);
+
+        //阿里云的endpoint
+        String endpoint =  ossSetting.getEndPoint();
+        //阿里云的accessKeyId
+        String accessKeyId = ossSetting.getAccessKeyId();
+        //阿里云的accessKeySecret
+        String accessKeySecret = ossSetting.getAccessKeySecret();
+        //空间
+        String bucketName =ossSetting.getBucketName();
+        //文件存储目录
+        String filedir = ossSetting.getPicLocation();
+
+        AliOssCloudUtil util = new AliOssCloudUtil(endpoint,accessKeyId,accessKeySecret,bucketName,filedir);
+        util.delete(filedir+fileName);
+    }
+}

+ 151 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/controller/TCurrencyOrderController.java

@@ -0,0 +1,151 @@
+package com.qnfhq.modules.trade.controller;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.convert.Convert;
+import com.qnfhq.annotation.RepeatSubmit;
+import com.qnfhq.common.ApiBaseController;
+import com.qnfhq.common.constant.Constant;
+import com.qnfhq.common.exception.RenException;
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.utils.MessageUtils;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.common.validator.ValidatorUtils;
+import com.qnfhq.modules.trade.dto.TCurrencyOrderCancelDTO;
+import com.qnfhq.modules.trade.dto.TCurrencyOrderQueryDTO;
+import com.qnfhq.modules.trade.dto.TCurrencyOrderSubmitDTO;
+import com.qnfhq.modules.trade.entity.TCurrencyOrderEntity;
+import com.qnfhq.modules.trade.enums.CurrencyOrderStatusEnum;
+import com.qnfhq.modules.trade.enums.DelegateDirectionEnum;
+import com.qnfhq.modules.trade.enums.DelegateTypeEnum;
+import com.qnfhq.modules.trade.service.TCurrencyOrderService;
+import com.qnfhq.modules.user.entity.AppAssetEntity;
+import com.qnfhq.modules.user.entity.AppUserDetailEntity;
+import com.qnfhq.modules.user.enums.AssetEnum;
+import com.qnfhq.modules.user.service.AppAssetService;
+import com.qnfhq.modules.user.service.AppUserDetailService;
+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.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+
+/**
+ * 币币交易订单表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+@RestController
+@RequestMapping("/currency")
+@Tag(name="币币交易订单表")
+@Slf4j
+public class TCurrencyOrderController extends ApiBaseController {
+    @Resource
+    private TCurrencyOrderService tCurrencyOrderService;
+
+    @Resource
+    private AppUserDetailService appUserDetailService;
+
+    @Resource
+    private AppAssetService tAppAssetService;
+
+    @PostMapping("/orderList")
+    @Operation(summary = "查询币币交易列表")
+    public Result list(@RequestBody TCurrencyOrderQueryDTO dto) {
+        ValidatorUtils.validateEntity(dto);
+
+        String pageNum = Convert.toStr(dto.getPageNum(),"1");
+        String pageSize = Convert.toStr(dto.getPageSize(),"10");
+        Map<String,Object> params = new HashMap<>();
+        params.put(Constant.PAGE,pageNum);
+        params.put(Constant.LIMIT,pageSize);
+        params.put("symbol", dto.getSymbol());
+        params.put("userId", StpUtil.getLoginIdAsLong());
+        params.put("status", dto.getStatus());
+        params.put("direction",dto.getDirection());
+        params.put("delegateType", dto.getDelegateType());
+        PageData<TCurrencyOrderEntity> page = tCurrencyOrderService.page(params);
+        return new Result<>().ok(page);
+    }
+
+    @GetMapping("/{id}")
+    @Operation(summary = "获取币币交易订单详细信息")
+    public Result<TCurrencyOrderEntity> getInfo(@PathVariable("id") Long id){
+        TCurrencyOrderEntity data = tCurrencyOrderService.selectById(id);
+        return new Result().ok(data);
+    }
+
+    @PostMapping("/submit")
+    @Operation(summary = "币币交易保存")
+    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
+    public Result submit(@RequestBody TCurrencyOrderSubmitDTO dto) {
+        ValidatorUtils.validateEntity(dto);
+        AppUserDetailEntity userDetail = appUserDetailService.selectAppUserDetailByUserId(StpUtil.getLoginIdAsLong());
+        if(userDetail == null){
+            return error(MessageUtils.message("complete.identity.verification"));//完成身份验证
+        }
+        //交易限制检查
+        if(userDetail.getTradeFlag()!=null && userDetail.getTradeFlag()==1) {
+            return error(userDetail.getTradeMessage());
+        }
+        if(dto.getDelegateType().equals(DelegateTypeEnum.LIMIT_PRICE.getCode())) {//限价
+            if(Objects.isNull(dto.getDelegatePrice())) {
+                return error(MessageUtils.message("currency.order.delegate.price.not.null"));//限价单委托价格不能为空
+            }
+        }
+        TCurrencyOrderEntity tCurrencyOrder = new TCurrencyOrderEntity();
+        tCurrencyOrder.setUserId(StpUtil.getLoginIdAsLong());
+        tCurrencyOrder.setDirection(dto.getDirection());//方向(1 买入 2卖出)
+        tCurrencyOrder.setDelegateType(dto.getDelegateType());//委托类型(1 市价 2 限价)
+        tCurrencyOrder.setSymbol(dto.getCoin().toLowerCase()+dto.getBaseCoin().toLowerCase());
+        tCurrencyOrder.setCoin(dto.getCoin().toLowerCase());//交易币种
+        tCurrencyOrder.setBaseCoin(dto.getBaseCoin().toLowerCase());//结算币种
+        tCurrencyOrder.setDelegateAmount(dto.getDelegateAmount());//市价买入(成交金额)usdt数量,其他都是数币数量
+
+        if(dto.getDelegateType().equals(DelegateTypeEnum.MARKET_PRICE.getCode())){
+            tCurrencyOrder.setDelegatePrice(BigDecimal.ZERO);
+        } else{
+            tCurrencyOrder.setDelegatePrice(dto.getDelegatePrice());
+        }
+
+        return tCurrencyOrderService.submitCurrencyOrder(tCurrencyOrder);
+    }
+
+
+
+    @Operation(summary = "币币交易撤单")
+    @PostMapping("/cancelOrder")
+    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
+    public Result cancelOrder(@RequestBody TCurrencyOrderCancelDTO dto) {
+        ValidatorUtils.validateEntity(dto);
+
+        Long id =  dto.getId();
+
+        TCurrencyOrderEntity currencyOrder = tCurrencyOrderService.selectById(id);
+
+        if(currencyOrder == null) {
+            return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
+        }
+        if(currencyOrder.getUserId().longValue() != StpUtil.getLoginIdAsLong()) {
+            return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
+        }
+
+        if(!currencyOrder.getStatus().equals(CurrencyOrderStatusEnum.TRADING.getCode())){
+            return error(MessageUtils.message("currency.order.not.trading.not.cancel"));//订单不是交易状态,无法撤销
+        }
+
+        try {
+            return tCurrencyOrderService.cancelOrder(currencyOrder);
+        } catch (Exception e) {
+            log.error(e.getMessage(),e);
+            return error(MessageUtils.message("c2c.order.cancel.fail"));//取消订单失败
+        }
+    }
+
+}

+ 16 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/dao/TCurrencyOrderDao.java

@@ -0,0 +1,16 @@
+package com.qnfhq.modules.trade.dao;
+
+import com.qnfhq.common.dao.BaseDao;
+import com.qnfhq.modules.trade.entity.TCurrencyOrderEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 币币交易订单表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+@Mapper
+public interface TCurrencyOrderDao extends BaseDao<TCurrencyOrderEntity> {
+	
+}

+ 16 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/dao/TCurrencySymbolDao.java

@@ -0,0 +1,16 @@
+package com.qnfhq.modules.trade.dao;
+
+import com.qnfhq.common.dao.BaseDao;
+import com.qnfhq.modules.trade.entity.TCurrencySymbolEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 币币交易币种配置表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+@Mapper
+public interface TCurrencySymbolDao extends BaseDao<TCurrencySymbolEntity> {
+	
+}

+ 27 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/dto/TCurrencyOrderCancelDTO.java

@@ -0,0 +1,27 @@
+package com.qnfhq.modules.trade.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;
+
+/**
+ * 币币交易订单表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+@Data
+@Schema(name = "币币交易订单撤单表单")
+public class TCurrencyOrderCancelDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+	@SchemaProperty(name = "主键")
+    @NotNull(message="{NotNull.id}")
+	private Long id;
+
+
+
+}

+ 42 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/dto/TCurrencyOrderQueryDTO.java

@@ -0,0 +1,42 @@
+package com.qnfhq.modules.trade.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.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 币币订单查询表单
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+@Data
+@Schema(name = "币币订单查询表单")
+public class TCurrencyOrderQueryDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+	@SchemaProperty(name = "主键")
+	private Long id;
+
+    @SchemaProperty(name = "交易对")
+    private String symbol;
+
+    @SchemaProperty(name = "方向(1 买入 2卖出)")
+	private Integer direction;
+
+    @SchemaProperty(name = "状态  0 (等待成交  1 完全成交  3已撤销)")
+    private Integer status;
+
+	@SchemaProperty(name = "委托类型(0 限价 1 市价 2 止盈止损  3 计划委托)")
+	private Integer delegateType;
+
+    @SchemaProperty(name = "页码")
+    private String pageNum;
+
+    @SchemaProperty(name = "每页条数")
+    private String pageSize;
+}

+ 54 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/dto/TCurrencyOrderSubmitDTO.java

@@ -0,0 +1,54 @@
+package com.qnfhq.modules.trade.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.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 币币交易订单表
+ * 买入:市价+金额(usdt)
+ *      限价:价格+数量(eth)
+ * 卖出:市价+数量(eth)
+ *      限价:价格+数量(eth)
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+@Data
+@Schema(name = "币币交易提交表单")
+public class TCurrencyOrderSubmitDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+	@SchemaProperty(name = "方向(1 买入 2卖出)")
+    @NotNull(message="{NotNull.direction}")//方向不能空
+	private Integer direction;
+
+	@SchemaProperty(name = "委托类型(1 市价 2 限价)")
+    @NotNull(message="{NotNull.delegateType}")//委托类型不能空
+	private Integer delegateType;
+
+	@SchemaProperty(name = "交易币种btc")
+    @NotBlank(message="{NotBlank.CurrencyOrder.coin}")//交易币种不能空
+	private String coin;
+
+	@SchemaProperty(name = "结算币种usdt")
+    @NotBlank(message="{NotBlank.CurrencyOrder.baseCoin}")//结算币种不能空
+	private String baseCoin;
+
+	@SchemaProperty(name = "市价买入金额(usdt)/币数量")
+    @NotNull(message="{NotNull.delegateAmount}")//委托数量不能空
+	private BigDecimal delegateAmount;
+
+	@SchemaProperty(name = "委托价格")
+	private BigDecimal delegatePrice;
+
+//	@SchemaProperty(name = "委托价值")
+    //@NotNull(message="{NotNull.delegateValue}")//委托价值不能空
+//	private BigDecimal delegateValue;
+
+}

+ 111 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/dto/TCurrencySymbolDTO.java

@@ -0,0 +1,111 @@
+package com.qnfhq.modules.trade.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;
+
+import java.math.BigDecimal;
+
+/**
+ * 币币交易币种配置表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+@Data
+@Schema(name = "币币交易币种配置表")
+public class TCurrencySymbolDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+	@SchemaProperty(name = "主键id")
+	private Long id;
+
+	@SchemaProperty(name = "交易对")
+	private String symbol;
+
+	@SchemaProperty(name = "展示交易对")
+	private String showSymbol;
+
+	@SchemaProperty(name = "交易币种")
+	private String coin;
+
+	@SchemaProperty(name = "结算币种")
+	private String baseCoin;
+
+	@SchemaProperty(name = "手续费率")
+	private BigDecimal feeRate;
+
+	@SchemaProperty(name = "交易币种精度")
+	private Integer coinPrecision;
+
+	@SchemaProperty(name = "结算币种精度")
+	private Integer basePrecision;
+
+	@SchemaProperty(name = "最低卖单价")
+	private BigDecimal sellMin;
+
+	@SchemaProperty(name = "最高买单价")
+	private BigDecimal buyMax;
+
+	@SchemaProperty(name = "最小下单量")
+	private BigDecimal orderMin;
+
+	@SchemaProperty(name = "最大下单量")
+	private BigDecimal orderMax;
+
+	@SchemaProperty(name = "启用禁用  1=启用 2=禁用")
+	private String enable;
+
+	@SchemaProperty(name = "前端是否显示 1=显示  2=隐藏")
+	private String isShow;
+
+	@SchemaProperty(name = "是否可交易 1=是 2=否")
+	private String isDeal;
+
+	@SchemaProperty(name = "市价买 1=可以 2=不可以")
+	private String marketBuy;
+
+	@SchemaProperty(name = "市价卖 1=可以 2=不可以")
+	private String marketSell;
+
+	@SchemaProperty(name = "限价买 1=可以 2=不可以")
+	private String limitedBuy;
+
+	@SchemaProperty(name = "限价卖 1=可以 2=不可以")
+	private String limitedSell;
+
+	@SchemaProperty(name = "图标")
+	private String logo;
+
+	@SchemaProperty(name = "交易所")
+	private String market;
+
+	@SchemaProperty(name = "")
+	private String createBy;
+
+	@SchemaProperty(name = "")
+	private Date createTime;
+
+	@SchemaProperty(name = "")
+	private String updateBy;
+
+	@SchemaProperty(name = "")
+	private Date updateTime;
+
+	@SchemaProperty(name = "")
+	private String searchValue;
+
+	@SchemaProperty(name = "")
+	private String remark;
+
+	@SchemaProperty(name = "最低卖出量")
+	private BigDecimal minSell;
+
+	@SchemaProperty(name = "币种分类  1 热门币 2 虚拟币 3 新币")
+	private Integer coinType;
+
+
+}

+ 111 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/entity/TCurrencyOrderEntity.java

@@ -0,0 +1,111 @@
+package com.qnfhq.modules.trade.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.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 币币交易订单表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+@Data
+@TableName("t_currency_order")
+public class TCurrencyOrderEntity implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+
+    @TableId(type = IdType.AUTO)
+	private Long id;
+    /**
+     * 用户id
+     */
+	private Long userId;
+    /**
+     * 方向(1 买入 2卖出)
+     */
+	private Integer direction;
+    /**
+     * 委托类型(1 市价 2 限价)
+     */
+	private Integer delegateType;
+    /**
+     * 交易类型  1 系统交易   2 凑合式
+     */
+	private Integer transactionType;
+    /**
+     * 状态  0 (等待成交  1 完全成交  3已撤销)
+     */
+	private Integer status;
+    /**
+     * 订单编号
+     */
+	private String orderNo;
+    /**
+     * 交易对
+     */
+	private String symbol;
+    /**
+     * 交易币种
+     */
+	private String coin;
+    /**
+     * 结算币种
+     */
+	private String baseCoin;
+    /**
+     * 委托总量
+     */
+	private BigDecimal delegateAmount;
+    /**
+     * 委托价格
+     */
+	private BigDecimal delegatePrice;
+    /**
+     * 委托价值
+     */
+	private BigDecimal delegateValue;
+    /**
+     * 委托时间
+     */
+	private Date delegateTime;
+    /**
+     * 成交数量
+     */
+	private BigDecimal dealAmount;
+    /**
+     * 成交价格
+     */
+	private BigDecimal dealPrice;
+    /**
+     * 成交金额
+     */
+	private BigDecimal dealValue;
+    /**
+     * 成交时间
+     */
+	private Date dealTime;
+    /**
+     * 手续费
+     */
+	private BigDecimal fee;
+    /**
+     * 取消时间
+     */
+	private Date canceledTime;
+    /**
+     * 交易完成时间
+     */
+	private Date completedTime;
+
+    /**
+     * 机器人成交
+     */
+	private Integer robot;
+}

+ 138 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/entity/TCurrencySymbolEntity.java

@@ -0,0 +1,138 @@
+package com.qnfhq.modules.trade.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.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 币币交易币种配置表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+@Data
+@TableName("t_currency_symbol")
+public class TCurrencySymbolEntity implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+
+    @TableId(type = IdType.AUTO)
+	private Long id;
+    /**
+     * 交易对
+     */
+	private String symbol;
+    /**
+     * 展示交易对
+     */
+	private String showSymbol;
+    /**
+     * 交易币种
+     */
+	private String coin;
+    /**
+     * 结算币种
+     */
+	private String baseCoin;
+    /**
+     * 手续费率
+     */
+	private BigDecimal feeRate;
+    /**
+     * 交易币种精度
+     */
+	private Integer coinPrecision;
+    /**
+     * 结算币种精度
+     */
+	private Integer basePrecision;
+    /**
+     * 最低卖单价
+     */
+	private BigDecimal sellMin;
+    /**
+     * 最高买单价
+     */
+	private BigDecimal buyMax;
+    /**
+     * 最小下单量
+     */
+	private BigDecimal orderMin;
+    /**
+     * 最大下单量
+     */
+	private BigDecimal orderMax;
+    /**
+     * 启用禁用  1=启用 2=禁用
+     */
+	private Integer enable;
+    /**
+     * 前端是否显示 1=显示  2=隐藏
+     */
+	private Integer isShow;
+    /**
+     * 是否可交易 1=是 2=否
+     */
+	private Integer isDeal;
+    /**
+     * 市价买 1=可以 2=不可以
+     */
+	private Integer marketBuy;
+    /**
+     * 市价卖 1=可以 2=不可以
+     */
+	private Integer marketSell;
+    /**
+     * 限价买 1=可以 2=不可以
+     */
+	private Integer limitedBuy;
+    /**
+     * 限价卖 1=可以 2=不可以
+     */
+	private Integer limitedSell;
+    /**
+     * 图标
+     */
+	private String logo;
+    /**
+     * 交易所
+     */
+	private String market;
+    /**
+     * 
+     */
+	private String createBy;
+    /**
+     * 
+     */
+	private Date createTime;
+    /**
+     * 
+     */
+	private String updateBy;
+    /**
+     * 
+     */
+	private Date updateTime;
+    /**
+     * 
+     */
+	private String searchValue;
+    /**
+     * 
+     */
+	private String remark;
+    /**
+     * 最低卖出量
+     */
+	private BigDecimal minSell;
+    /**
+     * 币种分类  1 热门币 2 虚拟币 3 新币
+     */
+	private Integer coinType;
+}

+ 38 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/enums/CurrencyOrderStatusEnum.java

@@ -0,0 +1,38 @@
+package com.qnfhq.modules.trade.enums;
+
+import java.util.Arrays;
+
+
+public enum CurrencyOrderStatusEnum {
+
+    TRADING(0,"交易中"),
+    COMPLETED(1,"完全成交"),
+    CANCELED(3,"已撤销"),
+    OVERTIMED(4,"超时"),
+    UNKNOWN(-1,"未知");
+
+    private Integer code;
+
+    private String desc;
+
+    public Integer getCode()
+    {
+        return code;
+    }
+
+    public String getDesc()
+    {
+        return desc;
+    }
+
+    CurrencyOrderStatusEnum(Integer code, String desc){
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public static CurrencyOrderStatusEnum getByKey(int key) {
+        return Arrays.asList(CurrencyOrderStatusEnum.values()).stream()
+                .filter(a -> a.getCode().intValue() == key)
+                .findFirst().orElse(CurrencyOrderStatusEnum.UNKNOWN);
+    }
+}

+ 36 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/enums/DelegateDirectionEnum.java

@@ -0,0 +1,36 @@
+package com.qnfhq.modules.trade.enums;
+
+
+public enum DelegateDirectionEnum {
+
+    SELL(2,"卖出"),
+    BUY(1,"买入");
+
+    private Integer code;
+
+    private String desc;
+
+    public Integer getCode()
+    {
+        return code;
+    }
+
+    public String getDesc()
+    {
+        return desc;
+    }
+
+    DelegateDirectionEnum(Integer code, String desc){
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public static boolean isValidCode(Integer code) {
+        for (DelegateDirectionEnum directionEnum : DelegateDirectionEnum.values()) {
+            if (directionEnum.getCode().intValue() == code.intValue()) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

+ 36 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/enums/DelegateTypeEnum.java

@@ -0,0 +1,36 @@
+package com.qnfhq.modules.trade.enums;
+
+import java.util.Arrays;
+
+
+public enum DelegateTypeEnum {
+
+    MARKET_PRICE(1,"市价"),
+    LIMIT_PRICE(2,"限价"),
+    UNKNOWN(-1,"未知");
+
+    private Integer code;
+
+    private String desc;
+
+    public Integer getCode()
+    {
+        return code;
+    }
+
+    public String getDesc()
+    {
+        return desc;
+    }
+
+    DelegateTypeEnum(Integer code, String desc){
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public static DelegateTypeEnum getByKey(int key) {
+        return Arrays.asList(DelegateTypeEnum.values()).stream()
+                .filter(a -> a.getCode().intValue() == key)
+                .findFirst().orElse(DelegateTypeEnum.UNKNOWN);
+    }
+}

+ 35 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/service/TCurrencyOrderService.java

@@ -0,0 +1,35 @@
+package com.qnfhq.modules.trade.service;
+
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.service.BaseService;
+import com.qnfhq.common.service.CrudService;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.modules.trade.entity.TCurrencyOrderEntity;
+import com.qnfhq.modules.user.entity.AppUserEntity;
+
+import java.util.Map;
+
+/**
+ * 币币交易订单表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+public interface TCurrencyOrderService extends BaseService<TCurrencyOrderEntity> {
+    PageData<TCurrencyOrderEntity> page(Map<String, Object> params);
+
+    /**
+     * 提交订单
+     * @param tCurrencyOrder
+     * @return
+     */
+    Result submitCurrencyOrder(TCurrencyOrderEntity tCurrencyOrder);
+
+    /**
+     * 取消订单
+     * @param currencyOrder
+     * @return
+     * @throws Exception
+     */
+    Result cancelOrder(TCurrencyOrderEntity currencyOrder) throws Exception;
+}

+ 22 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/service/TCurrencySymbolService.java

@@ -0,0 +1,22 @@
+package com.qnfhq.modules.trade.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qnfhq.modules.trade.entity.TCurrencySymbolEntity;
+
+/**
+ * 币币交易币种配置表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+public interface TCurrencySymbolService extends IService<TCurrencySymbolEntity> {
+    /**
+     * 根据交易对获取币种信息
+     * @param symbol
+     * @return
+     */
+    TCurrencySymbolEntity getBySymbol(String symbol);
+
+    TCurrencySymbolEntity getByCoinAndBaseCoin(String coin,String baseCoin);
+}

+ 256 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/service/impl/TCurrencyOrderServiceImpl.java

@@ -0,0 +1,256 @@
+package com.qnfhq.modules.trade.service.impl;
+
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.util.StrUtil;
+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.exception.RenException;
+import com.qnfhq.common.page.PageData;
+import com.qnfhq.common.redis.RedisUtils;
+import com.qnfhq.common.service.impl.BaseServiceImpl;
+import com.qnfhq.common.utils.MessageUtils;
+import com.qnfhq.common.utils.Result;
+import com.qnfhq.modules.c2c.entity.C2cAdEntity;
+import com.qnfhq.modules.trade.dao.TCurrencyOrderDao;
+import com.qnfhq.modules.trade.dto.TCurrencyOrderSubmitDTO;
+import com.qnfhq.modules.trade.entity.TCurrencyOrderEntity;
+import com.qnfhq.modules.trade.entity.TCurrencySymbolEntity;
+import com.qnfhq.modules.trade.enums.CurrencyOrderStatusEnum;
+import com.qnfhq.modules.trade.enums.DelegateDirectionEnum;
+import com.qnfhq.modules.trade.enums.DelegateTypeEnum;
+import com.qnfhq.modules.trade.service.TCurrencyOrderService;
+import com.qnfhq.modules.trade.service.TCurrencySymbolService;
+import com.qnfhq.modules.user.entity.AppAssetEntity;
+import com.qnfhq.modules.user.entity.AppUserEntity;
+import com.qnfhq.modules.user.enums.AssetEnum;
+import com.qnfhq.modules.user.enums.CachePrefix;
+import com.qnfhq.modules.user.service.AppAssetService;
+import com.qnfhq.utils.OrderUtils;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Date;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 币币交易订单表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+@Slf4j
+@Service
+public class TCurrencyOrderServiceImpl extends BaseServiceImpl<TCurrencyOrderDao, TCurrencyOrderEntity> implements TCurrencyOrderService {
+    @Resource
+    private TCurrencySymbolService tCurrencySymbolService;
+
+    @Resource
+    private AppAssetService tAppAssetService;
+
+    @Resource
+    private RedisUtils redisUtils;
+
+
+//    @Override
+//    public QueryWrapper<TCurrencyOrderEntity> getWrapper(Map<String, Object> params){
+//        String id = (String)params.get("id");
+//
+//        QueryWrapper<TCurrencyOrderEntity> wrapper = new QueryWrapper<>();
+//        wrapper.eq(StrUtil.isNotBlank(id), "id", id);
+//
+//        return wrapper;
+//    }
+
+    @Override
+    public PageData<TCurrencyOrderEntity> page(Map<String, Object> params) {
+        IPage<TCurrencyOrderEntity> page = baseDao.selectPage(
+                getPage(params, "id", false),
+                getWrapper(params)
+        );
+
+        return getPageData(page, TCurrencyOrderEntity.class);
+    }
+
+    private QueryWrapper<TCurrencyOrderEntity> getWrapper(Map<String, Object> params){
+        String symbol = (String) params.get("symbol");
+        Long userId = (Long) params.get("userId");
+        Integer status = (Integer) params.get("status");
+        Integer direction = (Integer) params.get("direction");
+        Integer delegateType = (Integer) params.get("delegateType");
+
+        QueryWrapper<TCurrencyOrderEntity> wrapper = new QueryWrapper<>();
+        wrapper.eq(StrUtil.isNotBlank(symbol), "symbol", symbol);
+        wrapper.eq(Objects.nonNull(userId), "user_id", userId);
+        wrapper.eq(Objects.nonNull(status), "status", status);
+        wrapper.eq(Objects.nonNull(direction), "direction", direction);
+        wrapper.eq(Objects.nonNull(delegateType), "delegate_type", delegateType);
+        return wrapper;
+    }
+
+
+    /**
+     * 委托下单和冻结资产
+     * @param tCurrencyOrder
+     * @return
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public Result submitCurrencyOrder(TCurrencyOrderEntity tCurrencyOrder) {
+        //交易币种
+        String coin = tCurrencyOrder.getCoin().toLowerCase();
+        //结算币种
+        String baseCoin=tCurrencyOrder.getBaseCoin().toLowerCase();
+        //委托类型 1 市价 2 限价
+        Integer delegateType = tCurrencyOrder.getDelegateType();
+        //币种设置
+        TCurrencySymbolEntity currencySymbol = tCurrencySymbolService.getByCoinAndBaseCoin(coin,baseCoin);
+
+        if (Objects.isNull(currencySymbol)) {
+            throw new RenException(MessageUtils.message("currency.symbol.setting.notExist",coin+baseCoin));//币种{0}未设置
+        }
+
+        //校验
+        checkOrder(tCurrencyOrder, currencySymbol);
+
+        Long userId = StpUtil.getLoginIdAsLong();
+
+        //实际成交数量
+        tCurrencyOrder.setDealAmount(BigDecimal.ZERO);
+        tCurrencyOrder.setDealValue(BigDecimal.ZERO);
+
+        //根据type 和 delegateType 整合数据
+        String serialNo = "Y" + OrderUtils.generateOrderNum();
+        tCurrencyOrder.setUserId(userId);
+        tCurrencyOrder.setOrderNo(serialNo);
+        tCurrencyOrder.setDelegateTime(new Date());
+        tCurrencyOrder.setStatus(0);
+        baseDao.insert(tCurrencyOrder);
+
+        //委托买入
+        if (tCurrencyOrder.getDirection().equals(DelegateDirectionEnum.BUY.getCode())) {
+            //查询结算币种资产
+            AppAssetEntity baseCoinAsset = tAppAssetService.getAppAssetEntity(StpUtil.getLoginIdAsLong(), tCurrencyOrder.getBaseCoin(), AssetEnum.SPOT_ASSETS.getCode());
+            if(baseCoinAsset==null) {
+                throw new RenException(MessageUtils.message("currency.balance.deficiency", tCurrencyOrder.getBaseCoin().toUpperCase()));//当前{0}币种余额不足
+            }
+            //成交金额
+            BigDecimal turnover;
+            if (tCurrencyOrder.getDelegateType().equals(DelegateTypeEnum.MARKET_PRICE.getCode())) {
+                turnover = tCurrencyOrder.getDelegateAmount();//成交金额(usdt)
+            } else {
+                turnover = tCurrencyOrder.getDelegateAmount().multiply(tCurrencyOrder.getDelegatePrice());
+            }
+            log.info("成交金额:{}", turnover);
+            log.info("可用金额:{}", baseCoinAsset.getAvailable());
+            if (baseCoinAsset.getAvailable().compareTo(turnover) < 0) {
+                throw new RenException(MessageUtils.message("currency.balance.deficiency", baseCoinAsset.getCoin().toUpperCase()));//当前{0}币种余额不足
+            }
+            tAppAssetService.freezeBalance(baseCoinAsset, turnover);
+        } else if (tCurrencyOrder.getDirection().equals(DelegateDirectionEnum.SELL.getCode())) {
+            //委托卖出
+            //查询交易币种资产
+            AppAssetEntity coinAsset = tAppAssetService.getAppAssetEntity(StpUtil.getLoginIdAsLong(), tCurrencyOrder.getCoin(), AssetEnum.SPOT_ASSETS.getCode());
+            if(coinAsset==null) {
+                throw new RenException(MessageUtils.message("currency.balance.deficiency", tCurrencyOrder.getCoin().toUpperCase()));//当前{0}币种余额不足
+            }
+            if (coinAsset.getAvailable().compareTo(tCurrencyOrder.getDelegateAmount()) < 0) {
+                throw new RenException(MessageUtils.message("currency.balance.deficiency", coinAsset.getCoin().toUpperCase()));//当前{0}币种余额不足
+            }
+            tAppAssetService.freezeBalance(coinAsset, tCurrencyOrder.getDelegateAmount());
+        }
+
+        //事件通知撮合交易
+
+        return new Result();
+    }
+
+
+    /**
+     * 币种校验 【如果市价买入设置委托数量】
+     *
+     * @param tCurrencyOrder 提交数据
+     * @param currencySymbol 币币的配置数据
+     * @return
+     */
+    private void checkOrder(TCurrencyOrderEntity tCurrencyOrder, TCurrencySymbolEntity currencySymbol) {
+        Integer direction = tCurrencyOrder.getDirection();
+        //委托类型(1 市价 2 限价)
+        Integer deleType = tCurrencyOrder.getDelegateType();
+        //最小卖出数量
+        BigDecimal minSell = Objects.isNull(currencySymbol.getMinSell()) ? BigDecimal.ZERO : currencySymbol.getMinSell();
+
+        //卖出的时候   检查是否交易数量是否低于设定最低交易数量
+        if(direction == 2  && tCurrencyOrder.getDelegateAmount().compareTo(minSell) < 0) {
+            throw new RenException(MessageUtils.message("currency.order.setting.minSell.err"));//卖出的数量低于最低限制
+        }
+        //买入 限价
+        if(direction == 1 && deleType==2) {
+            //最小下单量
+            if ( tCurrencyOrder.getDelegateAmount().compareTo(currencySymbol.getOrderMin()) < 0) {
+                throw new RenException(MessageUtils.message("currency.order.setting.orderMin.err"));//买入的数量低于最低限制
+            }
+
+            //最大下单量
+            if (tCurrencyOrder.getDelegateAmount().compareTo(currencySymbol.getOrderMax()) > 0) {
+                throw new RenException(MessageUtils.message("currency.order.setting.orderMax.err"));//买入的数量高于最高限制
+            }
+        }
+
+    }
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result cancelOrder(TCurrencyOrderEntity currencyOrder) throws Exception {
+        BigDecimal dealAmount = currencyOrder.getDealAmount();//成交数量
+        BigDecimal dealValue = currencyOrder.getDealValue();//成交额
+        log.info("成交数量:{}", dealAmount);
+        log.info("成交额:{}", dealValue);
+        //下单时候冻结的币,实际成交应扣的币
+        BigDecimal frozenBalance, dealBalance;
+
+        BigDecimal delegateAmount = currencyOrder.getDelegateAmount();
+        if (DelegateDirectionEnum.BUY.getCode().equals(currencyOrder.getDirection())) {//买入
+            if (currencyOrder.getDelegateType().equals(DelegateTypeEnum.LIMIT_PRICE.getCode())) {
+                frozenBalance = delegateAmount.multiply(currencyOrder.getDelegatePrice());
+            } else {
+                frozenBalance = delegateAmount;
+            }
+            dealBalance = dealValue;
+        } else {
+            //卖出
+            frozenBalance = delegateAmount;
+            dealBalance=dealAmount;
+        }
+        log.info("冻结的币:{}", frozenBalance);
+        log.info("实际成交的币:{}", dealBalance);
+        String coinSymbol = currencyOrder.getDirection().equals(DelegateDirectionEnum.BUY.getCode()) ? currencyOrder.getBaseCoin() : currencyOrder.getCoin();
+        AppAssetEntity coinAsset = tAppAssetService.getAppAssetEntity(StpUtil.getLoginIdAsLong(), coinSymbol, AssetEnum.SPOT_ASSETS.getCode());
+
+        //退币
+        BigDecimal refundAmount = frozenBalance.subtract(dealBalance);
+        if (refundAmount.compareTo(BigDecimal.ZERO) > 0) {
+            tAppAssetService.unfreezeBalance(coinAsset, refundAmount);
+        }
+
+        //成交数量
+//        currencyOrder.setDealAmount(dealAmount);
+        //成交金额
+//        currencyOrder.setDealValue(dealValue);
+        currencyOrder.setStatus(CurrencyOrderStatusEnum.CANCELED.getCode());
+        currencyOrder.setCanceledTime(new Date());
+        if(baseDao.updateById(currencyOrder)>0) {
+            return new Result();
+        } else {
+            throw new Exception(MessageUtils.message("c2c.order.cancel.fail"));//取消订单失败
+        }
+    }
+
+}

+ 45 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/trade/service/impl/TCurrencySymbolServiceImpl.java

@@ -0,0 +1,45 @@
+package com.qnfhq.modules.trade.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qnfhq.modules.trade.dao.TCurrencySymbolDao;
+import com.qnfhq.modules.trade.entity.TCurrencySymbolEntity;
+import com.qnfhq.modules.trade.service.TCurrencySymbolService;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * 币币交易币种配置表
+ *
+ * @author yelz 30262728@qq.com
+ * @since 1.0.0 2025-12-03
+ */
+@Service
+public class TCurrencySymbolServiceImpl extends ServiceImpl<TCurrencySymbolDao, TCurrencySymbolEntity> implements TCurrencySymbolService {
+
+//    @Override
+//    public QueryWrapper<TCurrencySymbolEntity> getWrapper(Map<String, Object> params){
+//        String id = (String)params.get("id");
+//
+//        QueryWrapper<TCurrencySymbolEntity> wrapper = new QueryWrapper<>();
+//        wrapper.eq(StrUtil.isNotBlank(id), "id", id);
+//
+//        return wrapper;
+//    }
+
+    @Override
+    public TCurrencySymbolEntity getBySymbol(String symbol) {
+        return getOne(new LambdaQueryWrapper<TCurrencySymbolEntity>()
+                .eq(TCurrencySymbolEntity::getSymbol, symbol)
+                .eq(TCurrencySymbolEntity::getEnable, 1));
+    }
+
+    @Override
+    public TCurrencySymbolEntity getByCoinAndBaseCoin(String coin,String baseCoin) {
+        return getOne(new LambdaQueryWrapper<TCurrencySymbolEntity>()
+                .eq(TCurrencySymbolEntity::getCoin, coin)
+                .eq(TCurrencySymbolEntity::getBaseCoin, baseCoin)
+                .eq(TCurrencySymbolEntity::getEnable, 1));
+    }
+}

+ 20 - 4
qnfhq-api/src/main/java/com/qnfhq/modules/user/controller/ApiAppUserController.java

@@ -9,6 +9,7 @@ import com.qnfhq.common.validator.AssertUtils;
 import com.qnfhq.common.validator.ValidatorUtils;
 import com.qnfhq.modules.user.entity.AppUserEntity;
 import com.qnfhq.modules.user.dto.*;
+import com.qnfhq.modules.user.enums.CountryCodeAndPhoneCodeEnum;
 import com.qnfhq.modules.user.service.AppUserService;
 import com.qnfhq.modules.user.service.AppuserLoginLogService;
 import com.qnfhq.modules.user.service.CaptchaService;
@@ -29,7 +30,7 @@ import java.util.Objects;
 
 /**
  * 注册接口
- * 登录接口
+ * 登录接口: 先阿里智能验证码,验证账号密码,验证手机验证码,登陆成功
  * 退出接口
  * @author yelz
  */
@@ -64,13 +65,22 @@ public class ApiAppUserController {
 
 
 
+    @PostMapping("/checkPass")
+    @Operation(summary = "账户密码验证")
+    public Result checkPass(@RequestBody AppLoginDTO dto, HttpServletRequest request) {
+        ValidatorUtils.validateEntity(dto);
+        return appUserService.checkPass(dto,request);
+    }
+
+    @Operation(summary = "验证手机验证码并登陆")
     @PostMapping("/login")
-    @Operation(summary = "登录")
-    public Result login(@RequestBody AppLoginDTO dto, HttpServletRequest request) {
+    public Result login (@RequestBody CheckPhoneCodeDTO dto, HttpServletRequest request){
         ValidatorUtils.validateEntity(dto);
-        return appUserService.login(dto,request);
+        return appUserService.checkPhoneCodeLogin(dto.getCodeType(),dto.getZone(),dto.getPhone(),dto.getCode(),request);
     }
 
+
+
     @GetMapping("/info")
     @Operation(summary = "登陆用户信息")
     public Result info() throws IOException {
@@ -189,4 +199,10 @@ public class ApiAppUserController {
         appUserService.logout(userId);
         return new Result().ok("appUser.logout.success");
     }
+
+    @Operation(summary = "查询国家")
+    @PostMapping("/getCountryCode")
+    public Result getCountryCode (){
+        return new Result().ok(CountryCodeAndPhoneCodeEnum.getJsonArray());
+    }
 }

+ 13 - 2
qnfhq-api/src/main/java/com/qnfhq/modules/user/dao/AppAssetDao.java

@@ -47,6 +47,17 @@ public interface AppAssetDao extends BaseMapper<AppAssetEntity> {
      */
     int releaseAssetByUserId(Map<String, Object> params);
 
+    /**
+     * 现货交易 冻结资产
+     * @param params
+     * @return
+     */
+    int freezeBalance(Map<String, Object> params);
 
-
- }
+    /**
+     * 现货交易 解冻资产
+     * @param params
+     * @return
+     */
+    int unfreezeBalance(Map<String, Object> params);
+}

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

@@ -27,7 +27,7 @@ public class AppAssetDTO implements Serializable {
 	private Long userId;
 
 	@SchemaProperty(name = "币种")
-	private String symbol;
+	private String coin;
 
 	@SchemaProperty(name = "资产总额")
 	private BigDecimal amout;

+ 3 - 14
qnfhq-api/src/main/java/com/qnfhq/modules/user/dto/AppLoginDTO.java

@@ -34,19 +34,8 @@ public class AppLoginDTO {
     @Schema(title = "区号")
     private String zone;
 
-//    @Schema(title = "图形验证码")
-    //@NotBlank(message="{NotBlank.code}")//验证码不能为空
-//    private String code;
-
-//    @Schema(title = "唯一标识")
-    //@NotBlank(message="{NotBlank.uuid}")//唯一标识不能为空
-//    private String uuid;
-
-//    @Schema(title = "登录类型")
-//    @NotNull(message="登录类型不能为空")
-//    private int signType;
-//
-
-
+    @Schema(title = "唯一标识")
+    @NotBlank(message="{NotBlank.uuid}")//唯一标识不能为空
+    private String uuid;
 
 }

+ 2 - 2
qnfhq-api/src/main/java/com/qnfhq/modules/user/entity/AppAssetEntity.java

@@ -30,7 +30,7 @@ public class AppAssetEntity implements Serializable {
     /**
      * 币种
      */
-	private String symbol;
+	private String coin;
     /**
      * 资产总额
      */
@@ -44,7 +44,7 @@ public class AppAssetEntity implements Serializable {
      */
 	private BigDecimal available;
     /**
-     * 资产类型 1=平台资产 2=理财资产 3=合约账户
+     * 资产类型 1=平台资产 2=理财资产 3=合约账户 4现货
      */
 	private Integer type;
     /**

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

@@ -93,7 +93,7 @@ public class AppUserDetailEntity implements Serializable {
     /**
      * 金额是否被限制 1 为限制
      */
-	private String amountFlag;
+	private Integer amountFlag;
     /**
      * 金额限制提示语
      */

+ 5 - 2
qnfhq-api/src/main/java/com/qnfhq/modules/user/enums/AssetEnum.java

@@ -7,7 +7,7 @@ public enum AssetEnum {
     /**
      * 平台资产
      */
-    PLATFORM_ASSETS(1,"平台资产"),
+    PLATFORM_ASSETS(1,"资金"),
 
     /**
      * 理财资产
@@ -18,7 +18,10 @@ public enum AssetEnum {
      */
     CONTRACT_ASSETS(3,"合约账户"),
 
-
+    /**
+     * 现货资产
+     */
+    SPOT_ASSETS(4,"现货账户"),
 
 
     ;

+ 314 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/user/enums/CountryCodeAndPhoneCodeEnum.java

@@ -0,0 +1,314 @@
+package com.qnfhq.modules.user.enums;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONUtil;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.*;
+
+/**
+ * 国家区号 和 手机区号 枚举
+ * <p>
+ * todo: 需要放到后台 vchatAll 中统一标准
+ */
+@Getter
+@AllArgsConstructor
+@Deprecated
+public enum CountryCodeAndPhoneCodeEnum {
+        AFGHANISTAN("Afghanistan", "阿富汗", "AF", "93"),
+        ALASKA("Alaska", "阿拉斯加", "US", "1907"),
+        ALBANIA("Albania", "阿尔巴尼亚", "AL", "355"),
+        ALGERIA("Algeria", "阿尔及利亚", "DZ", "213"),
+        AMERICAN_SAMOA("American Samoa", "美属萨摩亚", "AS", "1684"),
+        ANDORRA("Andorra", "安道尔", "AD", "376"),
+        ANGOLA("Angola", "安哥拉", "AO", "244"),
+        ANGUILLA("Anguilla", "安圭拉", "AI", "1264"),
+        ANTIGUA_AND_BARBUDA("Antigua and Barbuda", "安提瓜和巴布达", "AG", "1268"),
+        ARGENTINA("Argentina", "阿根廷", "AR", "54"),
+        ARMENIA("Armenia", "亚美尼亚", "AM", "374"),
+        ARUBA("Aruba", "阿鲁巴", "AW", "297"),
+        ASCENSION("Ascension", "阿森松", "SH", "247"),
+        AUSTRALIA("Australia", "澳大利亚", "AU", "61"),
+        AUSTRIA("Austria", "奥地利", "AT", "43"),
+        AZERBAIJAN("Azerbaijan", "阿塞拜疆", "AZ", "994"),
+        BAHAMAS("Bahamas", "巴哈马", "BS", "1242"),
+        BAHRAIN("Bahrain", "巴林", "BH", "973"),
+        BANGLADESH("Bangladesh", "孟加拉国", "BD", "880"),
+        BARBADOS("Barbados", "巴巴多斯", "BB", "1246"),
+        BELARUS("Belarus", "白俄罗斯", "BY", "375"),
+        BELGIUM("Belgium", "比利时", "BE", "32"),
+        BELIZE("Belize", "伯利兹", "BZ", "501"),
+        BENIN("Benin", "贝宁", "BJ", "229"),
+        BERMUDA("Bermuda", "百慕大群岛", "BM", "1441"),
+        BHUTAN("Bhutan", "不丹", "BT", "975"),
+        BOLIVIA("Bolivia", "玻利维亚", "BO", "591"),
+        BOSNIA_AND_HERZEGOVINA("Bosnia and Herzegovina", "波斯尼亚和黑塞哥维那", "BA", "387"),
+        BOTSWANA("Botswana", "博茨瓦纳", "BW", "267"),
+        BRAZIL("Brazil", "巴西", "BR", "55"),
+        BRUNEI("Brunei", "文莱", "BN", "673"),
+        BULGARIA("Bulgaria", "保加利亚", "BG", "359"),
+        BURKINA_FASO("Burkina Faso", "布基纳法索", "BF", "226"),
+        BURUNDI("Burundi", "布隆迪", "BI", "257"),
+        CAMBODIA("Cambodia", "柬埔寨", "KH", "855"),
+        CAMEROON("Cameroon", "喀麦隆", "CM", "237"),
+        CANADA("Canada", "加拿大", "CA", "1"),
+        ISLAS_CANARIAS("Islas Canarias", "加那利群岛", "ES", "34"),
+        CAPE_VERDE("Cape Verde", "开普", "CV", "238"),
+        CAYMAN_ISLANDS("Cayman Islands", "开曼群岛", "KY", "1345"),
+        CENTRAL_AFRICAN_REPUBLIC("Central African Republic", "中非共和国", "CF", "236"),
+        CHAD("Chad", "乍得", "TD", "235"),
+        CHINA("China", "中国", "CN", "86"),
+        CHILE("Chile", "智利", "CL", "56"),
+        /* CHRISTMAS_ISLAND("Christmas Island", "圣诞岛", "CX", "0061 9164"),
+         COCOS_ISLAND("Cocos Island", "科科斯岛", "CC", "0061 9162"),*/
+        COLOMBIA("Colombia", "哥伦比亚", "CO", "57"),
+        DOMINICAN_REPUBLIC("Dominican Republic", "多米尼加共和国", "DO", "1809"),
+        COMOROS("Comoros", "科摩罗", "KM", "269"),
+        REPUBLIC_OF_THE_CONGO("Republic Of The Congo", "刚果共和国", "CG", "242"),
+        COOK_ISLANDS("Cook Islands", "库克群岛", "CK", "682"),
+        COSTA_RICA("Costa Rica", "哥斯达黎加", "CR", "506"),
+        CROATIA("Croatia", "克罗地亚", "HR", "385"),
+        CUBA("Cuba", "古巴", "CU", "53"),
+        CURACAO("Curacao", "库拉索", "CW", "599"),
+        CYPRUS("Cyprus", "塞浦路斯", "CY", "357"),
+        CZECH("Czech", "捷克", "CZ", "420"),
+        DENMARK("Denmark", "丹麦", "DK", "45"),
+        DJIBOUTI("Djibouti", "吉布提", "DJ", "253"),
+        DOMINICA("Dominica", "多米尼加", "DM", "1767"),
+        ECUADOR("Ecuador", "厄瓜多尔", "EC", "593"),
+        EGYPT("Egypt", "埃及", "EG", "20"),
+        EL_SALVADOR("El Salvador", "萨尔瓦多", "SV", "503"),
+        EQUATORIAL_GUINEA("Equatorial Guinea", "赤道几内亚", "GQ", "240"),
+        ERITREA("Eritrea", "厄立特里亚", "ER", "291"),
+        ESTONIA("Estonia", "爱沙尼亚", "EE", "372"),
+        ETHIOPIA("Ethiopia", "埃塞俄比亚", "ET", "251"),
+        FALKLAND_ISLANDS("Falkland Islands", "福克兰群岛", "FK", "500"),
+        FAROE_ISLANDS("Faroe Islands", "法罗群岛", "FO", "298"),
+        FIJI("Fiji", "斐济", "FJ", "679"),
+        FINLAND("Finland", "芬兰", "FI", "358"),
+        FRANCE("France", "法国", "FR", "33"),
+        FRENCH_GUIANA("French Guiana", "法属圭亚那", "GF", "594"),
+        FRENCH_POLYNESIA("French Polynesia", "法属波利尼西亚", "PF", "689"),
+        GABON("Gabon", "加蓬", "GA", "241"),
+        GAMBIA("Gambia", "冈比亚", "GM", "220"),
+        GEORGIA("Georgia", "格鲁吉亚", "GE", "995"),
+        GERMANY("Germany", "德国", "DE", "49"),
+        GHANA("Ghana", "加纳", "GH", "233"),
+        GIBRALTAR("Gibraltar", "直布罗陀", "GI", "350"),
+        GREECE("Greece", "希腊", "GR", "30"),
+        GREENLAND("Greenland", "格陵兰岛", "GL", "299"),
+        GRENADA("Grenada", "格林纳达", "GD", "1473"),
+        GUADELOUPE("Guadeloupe", "瓜德罗普岛", "GP", "590"),
+        GUAM("Guam", "关岛", "GU", "1671"),
+        GUATEMALA("Guatemala", "瓜地马拉", "GT", "502"),
+        GUINEA("Guinea", "几内亚", "GN", "224"),
+        GUINEA_BISSAU("Guinea-Bissau", "几内亚比绍共和国", "GW", "245"),
+        GUYANA("Guyana", "圭亚那", "GY", "592"),
+        HAITI("Haiti", "海地", "HT", "509"),
+        HAWAII("Hawaii", "夏威夷", "US", "1808"),
+        HONDURAS("Honduras", "洪都拉斯", "HN", "504"),
+        HONG_KONG("Hong Kong", "中国香港", "HK", "852"),
+        HUNGARY("Hungary", "匈牙利", "HU", "36"),
+        ICELAND("Iceland", "冰岛", "IS", "354"),
+        INDIA("India", "印度", "IN", "91"),
+        INDONESIA("Indonesia", "印度尼西亚", "ID", "62"),
+        IRAN("Iran", "伊朗", "IR", "98"),
+        IRAQ("Iraq", "伊拉克", "IQ", "964"),
+        IRELAND("Ireland", "爱尔兰", "IE", "353"),
+        ISRAEL("Israel", "以色列", "IL", "972"),
+        ITALY("Italy", "意大利", "IT", "39"),
+        IVORY_COAST("Ivory Coast", "象牙海岸", "CI", "225"),
+        JAMAICA("Jamaica", "牙买加", "JM", "1876"),
+        JAPAN("Japan", "日本", "JP", "81"),
+        JORDAN("Jordan", "约旦", "JO", "962"),
+        KAZAKHSTAN("Kazakhstan", "哈萨克斯坦", "KZ", "7"),
+        KENYA("Kenya", "肯尼亚", "KE", "254"),
+        KIRIBATI("Kiribati", "基里巴斯", "KI", "686"),
+        KOREA_DEMOCRATIC_REP("Korea Democratic Rep.", "朝鲜", "KP", "85"),
+        SOUTH_KOREA("South Korea", "韩国", "KR", "82"),
+        KUWAIT("Kuwait", "科威特", "KW", "965"),
+        KYRGYZSTAN("Kyrgyzstan", "吉尔吉斯斯坦", "KG", "996"),
+        LAOS("Laos", "老挝", "LA", "856"),
+        LATVIA("Latvia", "拉脱维亚", "LV", "371"),
+        LEBANON("Lebanon", "黎巴嫩", "LB", "961"),
+        LESOTHO("Lesotho", "莱索托", "LS", "266"),
+        LIBERIA("Liberia", "利比里亚", "LR", "231"),
+        LIBYA("Libya", "利比亚", "LY", "218"),
+        LIECHTENSTEIN("Liechtenstein", "列支敦士登", "LI", "423"),
+        LITHUANIA("Lithuania", "立陶宛", "LT", "370"),
+        LUXEMBOURG("Luxembourg", "卢森堡", "LU", "352"),
+        MACAU("Macau", "中国澳门", "MO", "853"),
+        MACEDONIA("Macedonia", "马其顿", "MK", "389"),
+        MADAGASCAR("Madagascar", "马达加斯加", "MG", "261"),
+        MALAWI("Malawi", "马拉维", "MW", "265"),
+        MALAYSIA("Malaysia", "马来西亚", "MY", "60"),
+        MALDIVES("Maldives", "马尔代夫", "MV", "960"),
+        MALI("Mali", "马里", "ML", "223"),
+        MALTA("Malta", "马耳他", "MT", "356"),
+        MARSHALL_ISLANDS("Marshall Islands", "马绍尔群岛", "MH", "692"),
+        MARTINIQUE("Martinique", "马提尼克", "MQ", "596"),
+        MAURITANIA("Mauritania", "毛里塔尼亚", "MR", "222"),
+        MAURITIUS("Mauritius", "毛里求斯", "MU", "230"),
+        MAYOTTE("Mayotte", "马约特", "YT", "269"),
+        MEXICO("Mexico", "墨西哥", "MX", "52"),
+        MICRONESIA("Micronesia", "密克罗尼西亚", "FM", "691"),
+        MOLDOVA("Moldova", "摩尔多瓦", "MD", "373"),
+        MONACO("Monaco", "摩纳哥", "MC", "377"),
+        MONGOLIA("Mongolia", "蒙古", "MN", "976"),
+        MONTENEGRO("Montenegro", "黑山", "ME", "382"),
+        MONTSERRAT("Montserrat", "蒙特塞拉特岛", "MS", "1664"),
+        MOROCCO("Morocco", "摩洛哥", "MA", "212"),
+        MOZAMBIQUE("Mozambique", "莫桑比克", "MZ", "258"),
+        MYANMAR("Myanmar", "缅甸", "MM", "95"),
+        NAMIBIA("Namibia", "纳米比亚", "NA", "264"),
+        NAURU("Nauru", "拿鲁岛", "NR", "674"),
+        NEPAL("Nepal", "尼泊尔", "NP", "977"),
+        NETHERLANDS("Netherlands", "荷兰", "NL", "31"),
+        NEW_CALEDONIA("New Caledonia", "新喀里多尼亚", "NC", "687"),
+        NEW_ZEALAND("New Zealand", "新西兰", "NZ", "64"),
+        NICARAGUA("Nicaragua", "尼加拉瓜", "NI", "505"),
+        NIGER("Niger", "尼日尔", "NE", "227"),
+        NIGERIA("Nigeria", "尼日利亚", "NG", "234"),
+        NIUE_ISLAND("Niue Island", "纽埃岛(新)", "NU", "683"),
+        NORFOLK_ISLAND("Norfolk Island", "诺福克岛(澳)", "NF", "6723"),
+        NORWAY("Norway", "挪威", "NO", "47"),
+        OMAN("Oman", "阿曼", "OM", "968"),
+        PALAU("Palau", "帕劳", "PW", "680"),
+        PANAMA("Panama", "巴拿马", "PA", "507"),
+        PAPUA_NEW_GUINEA("Papua New Guinea", "巴布亚新几内亚", "PG", "675"),
+        PARAGUAY("Paraguay", "巴拉圭", "PY", "595"),
+        PERU("Peru", "秘鲁", "PE", "51"),
+        PHILIPPINES("Philippines", "菲律宾", "PH", "63"),
+        POLAND("Poland", "波兰", "PL", "48"),
+        PORTUGAL("Portugal", "葡萄牙", "PT", "351"),
+        PAKISTAN("Pakistan", "巴基斯坦", "PK", "92"),
+        PUERTO_RICO("Puerto Rico", "波多黎各", "PR", "1787"),
+        QATAR("Qatar", "卡塔尔", "QA", "974"),
+        RÉUNION_ISLAND("Réunion Island", "留尼汪", "RE", "262"),
+        ROMANIA("Romania", "罗马尼亚", "RO", "40"),
+        RUSSIA("Russia", "俄罗斯", "RU", "7"),
+        RWANDA("Rwanda", "卢旺达", "RW", "250"),
+        SAMOA_EASTERN("Samoa,Eastern", "东萨摩亚(美)", "AS", "684"),
+        SAMOA("Samoa", "萨摩亚", "WS", "685"),
+        SAN_MARINO("San Marino", "圣马力诺", "SM", "378"),
+        SAINT_PIERRE_AND_MIQUELON("Saint Pierre and Miquelon", "圣彼埃尔和密克隆岛", "PM", "508"),
+        SAO_TOME_AND_PRINCIPE("Sao Tome and Principe", "圣多美和普林西比", "ST", "239"),
+        SAUDI_ARABIA("Saudi Arabia", "沙特阿拉伯", "SA", "966"),
+        SENEGAL("Senegal", "塞内加尔", "SN", "221"),
+        SERBIA("Serbia", "塞尔维亚", "RS", "381"),
+        SEYCHELLES("Seychelles", "塞舌尔", "SC", "248"),
+        SIERRA_LEONE("Sierra Leone", "塞拉利昂", "SL", "232"),
+        SINGAPORE("Singapore", "新加坡", "SG", "65"),
+        SAINT_MAARTEN_DUTCH_PART("Saint Maarten (Dutch Part)", "圣马丁岛(荷兰部分)", "SX", "1721"),
+        SLOVAKIA("Slovakia", "斯洛伐克", "SK", "421"),
+        SLOVENIA("Slovenia", "斯洛文尼亚", "SI", "386"),
+        SOLOMON_ISLANDS("Solomon Islands", "所罗门群岛", "SB", "677"),
+        SOMALIA("Somalia", "索马里", "SO", "252"),
+        SOUTH_AFRICA("South Africa", "南非", "ZA", "27"),
+        SPAIN("Spain", "西班牙", "ES", "34"),
+        SRI_LANKA("Sri Lanka", "斯里兰卡", "LK", "94"),
+        ST_HELENA("St.Helena", "圣赫勒拿", "SH", "290"),
+        SAINT_LUCIA("Saint Lucia", "圣露西亚", "LC", "1758"),
+        SAINT_VINCENT_AND_THE_GRENADINES("Saint Vincent and The Grenadines", "圣文森特和格林纳丁斯", "VC", "1784"),
+        SUDAN("Sudan", "苏丹", "SD", "249"),
+        SURINAME("Suriname", "苏里南", "SR", "597"),
+        SWAZILAND("Swaziland", "斯威士兰", "SZ", "268"),
+        SWEDEN("Sweden", "瑞典", "SE", "46"),
+        SWITZERLAND("Switzerland", "瑞士", "CH", "41"),
+        SYRIA("Syria", "叙利亚", "SY", "963"),
+        TAIWAN("Taiwan", "中国台湾", "TW", "886"),
+        TAJIKISTAN("Tajikistan", "塔吉克斯坦", "TJ", "992"),
+        TANZANIA("Tanzania", "坦桑尼亚", "TZ", "255"),
+        THAILAND("Thailand", "泰国", "TH", "66"),
+        TIMOR_LESTE("Timor-Leste", "东帝汶", "TL", "670"),
+        UNITED_ARAB_EMIRATES("United Arab Emirates", "阿拉伯联合酋长国", "AE", "971"),
+        TOGO("Togo", "多哥", "TG", "228"),
+        TOKELAU_IS("Tokelau Is.", "托克劳群岛(新)", "TK", "690"),
+        TONGA("Tonga", "汤加", "TO", "676"),
+        TRINIDAD_AND_TOBAGO("Trinidad and Tobago", "特立尼达和多巴哥", "TT", "1868"),
+        TUNISIA("Tunisia", "突尼斯", "TN", "216"),
+        TURKEY("Turkey", "土耳其", "TR", "90"),
+        TURKMENISTAN("Turkmenistan", "土库曼斯坦", "TM", "993"),
+        TURKS_AND_CAICOS_ISLANDS("Turks and Caicos Islands", "特克斯和凯科斯群岛", "TC", "1649"),
+        TUVALU("Tuvalu", "图瓦卢", "TK", "688"),
+        UNITED_STATES("United States", "美国", "US", "1"),
+        UGANDA("Uganda", "乌干达", "UG", "256"),
+        UKRAINE("Ukraine", "乌克兰", "UA", "380"),
+        UNITED_KINGDOM("United Kingdom", "英国", "GB", "44"),
+        URUGUAY("Uruguay", "乌拉圭", "UY", "598"),
+        UZBEKISTAN("Uzbekistan", "乌兹别克斯坦", "UZ", "998"),
+        VANUATU("Vanuatu", "瓦努阿图", "VU", "678"),
+        VENEZUELA("Venezuela", "委内瑞拉", "VE", "58"),
+        VIETNAM("Vietnam", "越南", "VN", "84"),
+        VIRGIN_ISLANDS_BRITISH("Virgin Islands, British", "英属处女群岛", "VG", "1340"),
+        VIRGIN_ISLANDS_US("Virgin Islands, US", "美属维尔京群岛", "VI", "1284"),
+        WAKE_I("Wake I.", "威克岛(美)", "UM", "1808"),
+        YEMEN("Yemen", "也门", "YE", "967"),
+        ZAMBIA("Zambia", "赞比亚", "ZM", "260"),
+        ZANZIBAR("Zanzibar", "桑给巴尔", "TZ", "259"),
+        ZIMBABWE("Zimbabwe", "津巴布韦", "ZW", "263"),
+        ;
+        private String englishName;
+        private String chineseName;
+        private String countryCode;
+        private String phoneCode;
+
+
+        public static List<Map> getJsonArray() {
+            StringBuilder str = new StringBuilder();
+            str.append("[");
+            for (CountryCodeAndPhoneCodeEnum anEnum : CountryCodeAndPhoneCodeEnum.values()) {
+                str.append("{")
+                        .append("\"englishName\":\"" + anEnum.getEnglishName() + "\",")
+                        .append("\"chineseName\":\"" + anEnum.getChineseName() + "\",")
+                        .append("\"countryCode\":\"" + anEnum.getCountryCode() + "\",")
+                        .append("\"phoneCode\":\"" + anEnum.getPhoneCode() + "\"")
+                        .append("},");
+            }
+            str.deleteCharAt(str.length() - 1);
+            str.append("]");
+            JSONArray jsonArr = JSONUtil.parseArray(str.toString());
+            List<Map> maps = jsonArr.toList(Map.class);
+
+            ArrayList result = countrySort(maps);
+            return result;
+        }
+
+
+
+
+        private static ArrayList countrySort(List<Map> maps) {
+            ArrayList result = new ArrayList();
+            for (char c = 'A'; c <= 'Z'; ++c) {
+                List data = new ArrayList<>();
+                for (Map map : maps) {
+                    Set<Map.Entry<String, String>> set = map.entrySet();
+
+                    for (Map.Entry<String, String> entry : set) {
+                        String key = entry.getKey();
+                        if ("englishName".equals(key)) {
+                            String value = entry.getValue();
+                            if ((c + "").equalsIgnoreCase(value.charAt(0) + "")) {
+                                data.add(map);
+                            }
+                        }
+                    }
+                }
+
+                if (data.size() > 0) {
+                    Map item = new HashMap<>();
+                    item.put("letter", c + "");
+                    item.put("data", data);
+
+                    result.add(item);
+                }
+            }
+            return result;
+        }
+
+
+
+
+
+    }

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

@@ -99,11 +99,15 @@ public enum SettingEnum {
     REFUSE_SUBMIT,
     //广告配置
     AD_SETTING,
-    //验证码配置
+    //阿里智能验证码配置
     CAPTCHA_SETTING,
     //评论标签设置
     REVIEW_SETTING,
     //c2c取消原因设置
-    CANCEL_REASON_SETTING
+    CANCEL_REASON_SETTING,
+    //c2c申诉原因设置
+    COMPLAIN_REASON_SETTING,
+    //c2c举报原因设置
+    REPORT_REASON_SETTING
     ;
 }

+ 15 - 0
qnfhq-api/src/main/java/com/qnfhq/modules/user/service/AppAssetService.java

@@ -85,4 +85,19 @@ public interface AppAssetService extends IService<AppAssetEntity> {
     int releaseAssetByUserId(Long userId, String symbol, BigDecimal amout);
 
 
+    /**
+     *  现货交易冻结资产
+     * @param baseCoinAsset
+     * @param amount 币的数量
+     * @return
+     */
+    int freezeBalance(AppAssetEntity baseCoinAsset,BigDecimal amount);
+
+    /**
+     *  现货交易解冻资产
+     * @param baseCoinAsset
+     * @param amount 币的数量
+     * @return
+     */
+    int unfreezeBalance(AppAssetEntity baseCoinAsset,BigDecimal amount);
 }

+ 11 - 4
qnfhq-api/src/main/java/com/qnfhq/modules/user/service/AppUserService.java

@@ -42,12 +42,12 @@ public interface AppUserService extends IService<AppUserEntity> {
 
 
     /**
-     * 登陆
+     * 登陆验证
      * @param dto
      * @param request
      * @return
      */
-    Result login(AppLoginDTO dto, HttpServletRequest request);
+    Result checkPass(AppLoginDTO dto, HttpServletRequest request);
 
     /**
      * 邮箱发送验证码
@@ -108,7 +108,14 @@ public interface AppUserService extends IService<AppUserEntity> {
      */
     Result verifyIntelligentCaptcha(String verifyParam);
 
-    AppUserEntity getUserByUserId(Long userId);
 
-    void logout(Long userId);
+    /**
+     * 验证码校验并登陆
+     * @param codeType
+     * @param zone
+     * @param phone
+     * @param code
+     * @return
+     */
+    Result checkPhoneCodeLogin(String codeType, String zone, String phone, String code, HttpServletRequest request);
 }

+ 42 - 23
qnfhq-api/src/main/java/com/qnfhq/modules/user/service/impl/AppAssetServiceImpl.java

@@ -12,6 +12,7 @@ import com.qnfhq.modules.user.enums.AssetEnum;
 import com.qnfhq.modules.user.service.AppAssetService;
 import cn.hutool.core.util.StrUtil;
 import jakarta.annotation.Resource;
+import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -29,23 +30,13 @@ public class AppAssetServiceImpl extends ServiceImpl<AppAssetDao, AppAssetEntity
     @Resource
     private AppAssetDao appAssetDao;
 
-//    public QueryWrapper<AppAssetEntity> getWrapper(Map<String, Object> params){
-//        String id = (String)params.get("id");
-//
-//        QueryWrapper<AppAssetEntity> wrapper = new QueryWrapper<>();
-//        wrapper.eq(StrUtil.isNotBlank(id), "id", id);
-//
-//        return wrapper;
-//    }
-
-
     /**
      * 登陆用户资产
      * @return
      */
     @Override
     public List<AppAssetEntity> getUserAssets() {
-        List<AppAssetEntity> list = appAssetDao.selectList(new LambdaQueryWrapper<AppAssetEntity>().eq(AppAssetEntity::getUserId, StpUtil.getLoginIdAsLong()).eq(AppAssetEntity::getSymbol, "usdt"));
+        List<AppAssetEntity> list = appAssetDao.selectList(new LambdaQueryWrapper<AppAssetEntity>().eq(AppAssetEntity::getUserId, StpUtil.getLoginIdAsLong()).eq(AppAssetEntity::getCoin, "usdt"));
         return list;
     }
 
@@ -54,7 +45,7 @@ public class AppAssetServiceImpl extends ServiceImpl<AppAssetDao, AppAssetEntity
     public List<AppAssetEntity> selectList(AppAssetEntity appAssetEntity) {
         Wrapper<AppAssetEntity> queryWrapper = new LambdaQueryWrapper<AppAssetEntity>()
                 .eq(Objects.nonNull(appAssetEntity.getUserId()),AppAssetEntity::getUserId, appAssetEntity.getUserId())
-                .eq(StrUtil.isNotBlank(appAssetEntity.getSymbol()),AppAssetEntity::getSymbol, appAssetEntity.getSymbol())
+                .eq(StrUtil.isNotBlank(appAssetEntity.getCoin()),AppAssetEntity::getCoin, appAssetEntity.getCoin())
                 .eq(Objects.nonNull(appAssetEntity.getType()),AppAssetEntity::getType, appAssetEntity.getType());
         List<AppAssetEntity> list = appAssetDao.selectList(queryWrapper);
         return list;
@@ -64,27 +55,26 @@ public class AppAssetServiceImpl extends ServiceImpl<AppAssetDao, AppAssetEntity
     public AppAssetEntity getAppAssetEntity(Long userId, String symbol,Integer type) {
         return getOne(new LambdaQueryWrapper<AppAssetEntity>()
                 .eq(Objects.nonNull(userId),AppAssetEntity::getUserId, userId)
-                .eq(StrUtil.isNotBlank(symbol),AppAssetEntity::getSymbol, symbol)
+                .eq(StrUtil.isNotBlank(symbol),AppAssetEntity::getCoin, symbol)
                 .eq(Objects.nonNull(type),AppAssetEntity::getType, type)
-                .last(" limit 1")
         );
     }
 
     @Override
-    public int frozeAssetByUserId(Long userId, String symbol, BigDecimal amout) {
+    public int frozeAssetByUserId(Long userId, String coin, BigDecimal amout) {
         Map<String, Object> map = new HashMap<>();
         map.put("userId", userId);
-        map.put("symbol", symbol);
+        map.put("coin", coin);
         map.put("money", amout);
         map.put("type", AssetEnum.PLATFORM_ASSETS.getCode());
         return appAssetDao.frozeAssetByUserId(map);
     }
 
     @Override
-    public int unblockAssetByUserId(Long userId, String symbol, BigDecimal amout) {
+    public int unblockAssetByUserId(Long userId, String coin, BigDecimal amout) {
         Map<String, Object> map = new HashMap<>();
         map.put("userId", userId);
-        map.put("symbol", symbol);
+        map.put("coin", coin);
         map.put("money", amout);
         map.put("type", AssetEnum.PLATFORM_ASSETS.getCode());
         return appAssetDao.unblockAssetByUserId(map);
@@ -94,7 +84,7 @@ public class AppAssetServiceImpl extends ServiceImpl<AppAssetDao, AppAssetEntity
     public boolean createAsset(AppUserEntity user, String coin, Integer type) {
         AppAssetEntity tAppAsset = new AppAssetEntity();
         tAppAsset.setUserId(user.getId());
-        tAppAsset.setSymbol(coin);
+        tAppAsset.setCoin(coin);
         tAppAsset.setTotal(BigDecimal.ZERO);
         tAppAsset.setFrozen(BigDecimal.ZERO);
         tAppAsset.setAvailable(BigDecimal.ZERO);
@@ -114,10 +104,10 @@ public class AppAssetServiceImpl extends ServiceImpl<AppAssetDao, AppAssetEntity
      * @return
      */
     @Override
-    public int addAssetByUserId(Long userId, String symbol, BigDecimal amout) {
+    public int addAssetByUserId(Long userId, String coin, BigDecimal amout) {
         Map<String, Object> map = new HashMap<>();
         map.put("userId", userId);
-        map.put("symbol", symbol);
+        map.put("coin", coin);
         map.put("money", amout);
         map.put("type", AssetEnum.PLATFORM_ASSETS.getCode());
         return appAssetDao.addAssetByUserId(map);
@@ -131,12 +121,41 @@ public class AppAssetServiceImpl extends ServiceImpl<AppAssetDao, AppAssetEntity
      * @return
      */
     @Override
-    public int releaseAssetByUserId(Long userId, String symbol, BigDecimal amout) {
+    public int releaseAssetByUserId(Long userId, String coin, BigDecimal amout) {
         Map<String, Object> map = new HashMap<>();
         map.put("userId", userId);
-        map.put("symbol", symbol);
+        map.put("coin", coin);
         map.put("money", amout);
         map.put("type", AssetEnum.PLATFORM_ASSETS.getCode());
         return appAssetDao.releaseAssetByUserId(map);
     }
+
+    /**
+     *  现货交易冻结资产
+     * @param baseCoinAsset
+     * @param amount 币的数量
+     * @return
+     */
+    @Override
+    public int freezeBalance(AppAssetEntity baseCoinAsset,BigDecimal amount) {
+        Map<String, Object> map = new HashMap<>();
+        map.put("id", baseCoinAsset.getId());
+        map.put("amount", amount);
+        return appAssetDao.freezeBalance(map);
+    }
+
+    /**
+     *  现货交易解冻资产
+     * @param baseCoinAsset
+     * @param amount 币的数量
+     * @return
+     */
+    @Override
+    public int unfreezeBalance(AppAssetEntity baseCoinAsset,BigDecimal amount) {
+        Map<String, Object> map = new HashMap<>();
+        map.put("id", baseCoinAsset.getId());
+        map.put("amount", amount);
+        return appAssetDao.unfreezeBalance(map);
+    }
+
 }

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

@@ -35,7 +35,6 @@ public class AppUserDetailServiceImpl extends ServiceImpl<AppUserDetailDao, AppU
     public AppUserDetailEntity selectAppUserDetailByUserId(long userId) {
         return getOne(new LambdaQueryWrapper<AppUserDetailEntity>()
                 .eq(AppUserDetailEntity::getUserId, userId)
-                .last(" limit 1")
         );
     }
 

+ 53 - 12
qnfhq-api/src/main/java/com/qnfhq/modules/user/service/impl/AppUserServiceImpl.java

@@ -224,7 +224,9 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
      */
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public Result login(AppLoginDTO dto, HttpServletRequest request) {
+    public Result checkPass(AppLoginDTO dto, HttpServletRequest request) {
+        //阿里云滑动验证码
+        checkIntelligentCaptcha(dto.getUuid());
 
         //账号密码失败重试次数
         checkPwdErrTryTimes(dto.getLoginName());
@@ -238,10 +240,6 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
             checkPwdErrTryTimes(dto.getLoginName());
             throw new RenException(MessageUtils.message("appUser.loginName.or.password.err.limit.chance", ApiConstant.PASSWORD_FAIL_HOUR_TIMES - pwdFailTimes));//账号或密码错误,您还有4次机会
         }
-        //手机验证校验
-        String codeType = UserCodeTypeEnum.LOGIN.name();
-        final String phoneCodeResultKey = String.format("%s%s%s%s%s", CachePrefix.SMS_CODE.getPrefix(), UserCodeTypeEnum.valueOf(codeType).name(), appUser.getZone(), appUser.getPhone(), ":result");
-        verifyResult(phoneCodeResultKey);
 
         //是否黑名单
         if (Objects.nonNull(appUser.getIsBlack()) && appUser.getIsBlack() == UserBlackEnum.BLOCK.getCode()) {
@@ -252,13 +250,24 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
         if (Objects.nonNull(appUser.getStatus()) && appUser.getStatus() == UserBlackEnum.LOGOUT.getCode()) {
             throw new RenException(MessageUtils.message("user_is_logout"));//您的账号已被列入黑名单,无法登录。
         }
+        //设置验证结果
+        redisUtils.set(getCheckLoginNamePassCacheKey(appUser.getLoginName()), 1, ApiConstant.CHECK_EXPIRE);
 
-        StpUtil.login(appUser.getId());
-        appuserLoginLogService.insertAppActionLog(appUser, "用户登录", "0", request);
+        //        //手机验证校验
+//        String codeType = UserCodeTypeEnum.LOGIN.name();
+//        final String phoneCodeResultKey = String.format("%s%s%s%s%s", CachePrefix.SMS_CODE.getPrefix(), UserCodeTypeEnum.valueOf(codeType).name(), appUser.getZone(), appUser.getPhone(), ":result");
+//        verifyResult(phoneCodeResultKey);
+
+//        StpUtil.login(appUser.getId());
+//        appuserLoginLogService.insertAppActionLog(appUser, "用户登录", "0", request);
 
         Result result = new Result();
-        result.setMsg(MessageUtils.message("appUser.login.success"));//登陆成功
-        result.setData(MapUtil.of(StpUtil.getTokenName(), StpUtil.getTokenValue()));
+//        result.setMsg(MessageUtils.message("appUser.login.success"));//登陆成功
+//        result.setData(MapUtil.of(StpUtil.getTokenName(), StpUtil.getTokenValue()));
+        Map data = MapUtil.of("phone", appUser.getPhone());
+        data.put("zone", appUser.getZone());
+        data.put("email", appUser.getEmail());
+        result.setData(data);
         return result;
     }
 
@@ -291,7 +300,7 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
             symbolGroup.forEach((symbol, assetList) -> {
                 AppAssetEntity tAppAsset = new AppAssetEntity();
                 tAppAsset.setUserId(user.getId());
-                tAppAsset.setSymbol(symbol);
+                tAppAsset.setCoin(symbol);
                 tAppAsset.setTotal(BigDecimal.ZERO);
                 tAppAsset.setFrozen(BigDecimal.ZERO);
                 tAppAsset.setAvailable(BigDecimal.ZERO);
@@ -305,7 +314,7 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
         //初始化玩家用户钱包-理财资产
         AppAssetEntity tAppAsset = new AppAssetEntity();
         tAppAsset.setUserId(user.getId());
-        tAppAsset.setSymbol("usdt");
+        tAppAsset.setCoin("usdt");
         tAppAsset.setTotal(BigDecimal.ZERO);
         tAppAsset.setFrozen(BigDecimal.ZERO);
         tAppAsset.setAvailable(BigDecimal.ZERO);
@@ -495,6 +504,19 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
         }
     }
 
+    /**
+     * 验证码账号密码验证是否通过
+     */
+    private void checkLoginNamePass(String loginName) {
+        Object checkResult = redisUtils.get(getCheckLoginNamePassCacheKey(loginName));
+        if (Objects.isNull(checkResult) || (int) checkResult != 1) {
+            throw new RenException(ErrorCode.AUTH_PASSWORD);//账号密码校验失败
+        }
+    }
+
+    private String getCheckLoginNamePassCacheKey(String loginName) {
+        return new StringBuilder("loginName").append(":pass:result").toString();
+    }
 
 
 
@@ -573,7 +595,6 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
         return result;
     }
 
-
     @Override
     public Result checkEmailCode(String codeType, String email, String code) {
         //校验邮箱验证码
@@ -654,6 +675,26 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserDao, AppUserEntity> i
         user.setStatus(3);
         baseMapper.updateById(user);
     }
+    
+    public Result checkPhoneCodeLogin(String codeType, String zone, String phone, String code, HttpServletRequest request) {
+        //校验手机验证码
+        final String phoneCodeKey = String.format("%s%s%s%s", CachePrefix.SMS_CODE.getPrefix(), UserCodeTypeEnum.valueOf(codeType).name(), zone, phone);
+        checkCode(phoneCodeKey, code);
+
+        AppUserEntity appUser = getUserByMobile(phone, zone);
+        if (appUser == null) {
+            throw new RenException(MessageUtils.message("user.not.exist"));//用户不存在
+        }
 
+        //验证账号密码
+        checkLoginNamePass(appUser.getLoginName());
+
+        Result result = new Result();
+        StpUtil.login(appUser.getId());
+        appuserLoginLogService.insertAppActionLog(appUser, "用户登录", "0", request);
+        result.setMsg(MessageUtils.message("appUser.login.success"));//登陆成功
+        result.setData(MapUtil.of(StpUtil.getTokenName(), StpUtil.getTokenValue()));
+        return result;
+    }
 
 }

+ 230 - 0
qnfhq-api/src/main/java/com/qnfhq/utils/AliOssCloudUtil.java

@@ -0,0 +1,230 @@
+package com.qnfhq.utils;
+
+import com.aliyun.oss.OSSClient;
+import com.aliyun.oss.model.*;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+@Slf4j
+public class AliOssCloudUtil {
+    private String endpoint =  "";
+
+    //阿里云的accessKeyId
+    private String accessKeyId = "";
+
+    //阿里云的accessKeySecret
+    private String accessKeySecret = "";
+
+    //空间
+    private String bucketName = "";
+
+    //文件存储目录
+    private String filedir = "";
+
+    private OSSClient ossClient;
+
+    public AliOssCloudUtil(String endpoint, String accessKeyId, String accessKeySecret, String bucketName, String filedir) {
+        this.endpoint = endpoint;
+        this.accessKeyId = accessKeyId;
+        this.accessKeySecret = accessKeySecret;
+        this.bucketName = bucketName;
+        this.filedir = filedir;
+        this.ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
+    }
+
+    public AliOssCloudUtil() {
+        ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
+    }
+
+    public String getFiledir() {
+        return this.filedir;
+    }
+
+    //自定义上传文件夹
+    public AliOssCloudUtil(String filedir) {
+        this.filedir = filedir;
+        ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
+    }
+
+
+    /**
+     * 初始化
+     */
+    public void init() {
+        ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
+    }
+
+    /**
+     * 销毁
+     */
+    public void destory() {
+        ossClient.shutdown();
+    }
+
+
+    /**
+     * 上传到OSS服务器
+     *
+     * @param instream 文件流
+     * @param fileName 文件名称 包括后缀名
+     * @return 出错返回"" ,唯一MD5数字签名
+     */
+    public String uploadFile2OSS(InputStream instream, String fileName) {
+        String ret = "";
+        // 判断bucket是否已经存在,不存在进行创建
+        if (!doesBucketExist()) {
+            createBucket();
+        }
+        try {
+            //创建上传Object的Metadata
+            ObjectMetadata objectMetadata = new ObjectMetadata();
+            objectMetadata.setContentLength(instream.available());
+            objectMetadata.setCacheControl("no-cache");
+            objectMetadata.setHeader("Pragma", "no-cache");
+            objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf(".")+1)));
+            objectMetadata.setContentDisposition("inline;filename=" + fileName);
+
+            // 指定上传文件操作时是否覆盖同名Object。
+            // 不指定x-oss-forbid-overwrite时,默认覆盖同名Object。
+            // 指定x-oss-forbid-overwrite为false时,表示允许覆盖同名Object。
+            // 指定x-oss-forbid-overwrite为true时,表示禁止覆盖同名Object,如果同名Object已存在,程序将报错。
+            objectMetadata.setHeader("x-oss-forbid-overwrite", "false");
+
+            String objectName = filedir + fileName;
+
+            //上传文件
+            ossClient.putObject(bucketName, objectName, instream, objectMetadata);
+            // 封装  url 路径
+            String url = "https://" + bucketName + "." + endpoint + "/" + objectName;
+            System.out.println(objectName);
+            ret = url;
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            ossClient.shutdown();
+            try {
+                if (instream != null) {
+                    instream.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return ret;
+    }
+
+
+    /**
+     * 判断文件是否存在。doesObjectExist还有一个参数isOnlyInOSS,
+     * 如果为true则忽略302重定向或镜像;如果为false,则考虑302重定向或镜像。
+     * yourObjectName 表示上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
+     *
+     * @return 存在返回true
+     */
+    public boolean doesObjectExist(String objectName) {
+        boolean exists = ossClient.doesObjectExist(bucketName, filedir + objectName);
+        return exists;
+    }
+
+    /**
+     * 判断Bucket是否存在
+     *
+     * @return 存在返回true
+     */
+    public boolean doesBucketExist() {
+        boolean exists = ossClient.doesBucketExist(bucketName);
+        return exists;
+    }
+
+    /**
+     * 创建Bucket
+     */
+    public void createBucket() {
+        CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
+        // 设置bucket权限为公共读,默认是私有读写
+        createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
+        // 设置bucket存储类型为低频访问类型,默认是标准类型
+        createBucketRequest.setStorageClass(StorageClass.IA);
+        boolean exists = ossClient.doesBucketExist(bucketName);
+        if (!exists) {
+            try {
+                ossClient.createBucket(createBucketRequest);
+                // 关闭client
+                ossClient.shutdown();
+            } catch (Exception e) {
+                log.error(e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Description: 判断OSS服务文件上传时文件的contentType
+     *
+     * @param FilenameExtension 文件后缀
+     * @return String
+     */
+    public static String getcontentType(String FilenameExtension) {
+        if ("bmp".equalsIgnoreCase(FilenameExtension)) {
+            return "image/bmp";
+        }
+        if ("gif".equalsIgnoreCase(FilenameExtension)) {
+            return "image/gif";
+        }
+        if ("jpeg".equalsIgnoreCase(FilenameExtension) ||
+                "jpg".equalsIgnoreCase(FilenameExtension) ||
+                "png".equalsIgnoreCase(FilenameExtension)) {
+            return "image/jpeg";
+        }
+        if ("html".equalsIgnoreCase(FilenameExtension)) {
+            return "text/html";
+        }
+        if ("txt".equalsIgnoreCase(FilenameExtension)) {
+            return "text/plain";
+        }
+        if ("vsd".equalsIgnoreCase(FilenameExtension)) {
+            return "application/vnd.visio";
+        }
+        if ("pptx".equalsIgnoreCase(FilenameExtension) ||
+                "ppt".equalsIgnoreCase(FilenameExtension)) {
+            return "application/vnd.ms-powerpoint";
+        }
+        if ("docx".equalsIgnoreCase(FilenameExtension) ||
+                "doc".equalsIgnoreCase(FilenameExtension)) {
+            return "application/msword";
+        }
+        if ("xml".equalsIgnoreCase(FilenameExtension)) {
+            return "text/xml";
+        }
+        if ("pdf".equalsIgnoreCase(FilenameExtension)) {
+            return "application/pdf";
+        }
+        return "image/jpeg";
+    }
+
+
+    /**
+     * @param fileName
+     * @return
+     * @Title: getInputStreamByFileUrl
+     * @Description: 根据文件路径获取InputStream流
+     * @return: InputStream
+     */
+    public InputStream getInputStreamByFileUrl(String fileName) {
+        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
+        OSSObject ossObject = ossClient.getObject(bucketName, fileName);
+        return ossObject.getObjectContent();
+    }
+
+
+    /**
+     * @desc 删除文件
+     * @date 2022-10-12
+     */
+    public  void delete(String objectName) {
+        // 根据BucketName,objectName删除文件
+        ossClient.deleteObject(bucketName, objectName);
+        ossClient.shutdown();
+    }
+}

+ 24 - 5
qnfhq-api/src/main/resources/i18n/messages.properties

@@ -112,11 +112,8 @@ c2c.order.not.buyer.seller=Anda bukan pengguna transaksi, tidak boleh memulakan
 c2c.order.pay.update.fail=Gagal mengemas kini pesanan
 c2c.order.complain.submit.fail=Gagal menghantar aduan
 c2c.order.complain.not.exist=Nombor aduan tidak sah
-c2c.complain.voucher.submit.fail=Gagal menghantar, anda bukan pengadu atau yang diadukan
 c2c.order.complain.remark.notEmpty=Sebab aduan tidak boleh kosong
-c2c.order.complain.remark.maxval=Penerangan maksimum 250 aksara
 c2c.order.complain.voucher.id.invalid=Nombor bukti aduan tidak sah
-
 c2c.order.complain.voucher.is.end=Rayuan telah berakhir
 c2c.order.complain.voucher.save.fail=Gagal menyimpan bukti rayuan
 c2c.order.complain.voucher.update.fail=Gagal mengemas kini bukti rayuan
@@ -145,5 +142,27 @@ c2c.order.reviews.not.complete=Status pesanan "Selesai" diperlukan untuk memberi
 c2c.order.reviews.create.fail=Gagal membuat ulasan
 c2c.reviews.save.fail=Gagal menyimpan ulasan
 c2c.order.you.reviewed=Anda telah memberikan ulasan untuk pesanan ini
-c2c.order.cancel.otherReason.NotEmpty=Sebab lain tidak boleh kosong
-c2c.order.cancel.reason.notset=Sebab pembatalan belum ditetapkan
+c2c.order.cancel.otherReason.NotEmpty=Alasan lain tidak boleh kosong
+c2c.order.cancel.reason.notset=Alasan pembatalan belum dikonfigurasi
+c2c.order.complain.reason.notset=Alasan aduan belum dikonfigurasi
+c2c.deletePayment.voucher.fail=Gagal menghapus bukti pembayaran
+c2c.order.complain.remark.maxval=Deskripsi maksimum 250 aksara
+c2c.order.complain.files.limit=Maksimum 5 bukti aduan
+c2c.complain.voucher.submit.fail=Penghantaran gagal, anda bukan pihak transaksi pesanan
+c2c.orderId.is.empty=Nombor pesanan tidak boleh kosong
+c2c.voucher.type.is.empty=Jenis bukti tidak boleh kosong
+c2c.deleteVoucher.voucher.fail=Gagal menghapus bukti
+c2c.order.payment.vouchers.limit = Maksimum 3 voucher pembayaran
+610=Semakan kata laluan akaun gagal
+currency.symbol.setting.notExist=Jenis mata wang {0} belum ditetapkan
+currency.balance.deficiency=Baki mata wang {0} semasa tidak mencukupi
+currency.order.setting.minSell.err=Kuantiti jualan kurang daripada had minimum
+currency.order.setting.orderMin.err=Kuantiti pembelian kurang daripada had minimum
+currency.order.setting.orderMax.err=Kuantiti pembelian melebihi had maksimum
+currency.order.complete.not.cancel=Pesanan telah selesai, tidak boleh dibatalkan
+currency.order.canceled=Pesanan telah dibatalkan
+currency.order.baseCoin.unblock.fail=Gagal membuka kunci aset syiling asas
+currency.order.coin.unblock.fail=Gagal membuka kunci aset syiling perdagangan
+c2c.order.cancel.fail=Gagal membatalkan pesanan
+currency.order.delegate.price.not.null=Harga pesanan had tidak boleh kosong
+currency.order.not.trading.not.cancel=Pesanan bukan dalam status dagangan, tidak boleh dibatalkan

+ 26 - 5
qnfhq-api/src/main/resources/i18n/messages_de.properties

@@ -111,12 +111,9 @@ c2c.complain.submit.fail=Beschwerde konnte nicht eingereicht werden, Sie sind we
 c2c.order.not.buyer.seller=Sie sind kein Handelsteilnehmer und k\u00f6nnen keine Beschwerde einreichen  
 c2c.order.pay.update.fail=Fehler beim Aktualisieren der Bestellung  
 c2c.order.complain.submit.fail=Fehler beim Einreichen der Beschwerde  
-c2c.order.complain.not.exist=Ung\u00fcltige Beschwerde-ID  
-c2c.complain.voucher.submit.fail=Einreichung fehlgeschlagen, Sie sind weder Beschwerdef\u00fchrer noch Beschwerdegegner  
-c2c.order.complain.remark.notEmpty=Beschwerdegrund darf nicht leer sein  
-c2c.order.complain.remark.maxval=Beschreibung darf maximal 250 Zeichen enthalten  
+c2c.order.complain.not.exist=Ung\u00fcltige Beschwerde-ID
+c2c.order.complain.remark.notEmpty=Beschwerdegrund darf nicht leer sein
 c2c.order.complain.voucher.id.invalid=Ung\u00fcltige Beschwerdenachweis-ID
-
 c2c.order.complain.voucher.is.end=Die Beschwerde ist abgeschlossen
 c2c.order.complain.voucher.save.fail=Speichern des Beschwerdebelegs fehlgeschlagen
 c2c.order.complain.voucher.update.fail=Aktualisierung des Beschwerdebelegs fehlgeschlagen
@@ -145,3 +142,27 @@ c2c.order.reviews.not.complete=Nur bei Bestellstatus "Abgeschlossen" kann eine B
 c2c.order.reviews.create.fail=Bewertung abgeben fehlgeschlagen  
 c2c.reviews.save.fail=Bewertung konnte nicht gespeichert werden  
 c2c.order.you.reviewed=Sie haben diese Bestellung bereits bewertet
+c2c.order.cancel.otherReason.NotEmpty=Andere Gr\u00fcnde d\u00fcrfen nicht leer sein  
+c2c.order.cancel.reason.notset=Stornierungsgrund nicht konfiguriert  
+c2c.order.complain.reason.notset=Beschwerdegrund nicht konfiguriert  
+c2c.deletePayment.voucher.fail=Zahlungsbeleg konnte nicht gel\u00f6scht werden  
+c2c.order.complain.remark.maxval=Beschreibung maximal 250 Zeichen  
+c2c.order.complain.files.limit=Maximal 5 Beschwerdebelege  
+c2c.complain.voucher.submit.fail=\u00dcbermittlung fehlgeschlagen, Sie sind keine Vertragspartei der Bestellung  
+c2c.orderId.is.empty=Bestellnummer darf nicht leer sein  
+c2c.voucher.type.is.empty=Belegtyp darf nicht leer sein  
+c2c.deleteVoucher.voucher.fail=L\u00f6schen des Belegs fehlgeschlagen
+c2c.order.payment.vouchers.limit=Maximal 3 Zahlungsscheine
+610=Konto-Passwort-\u00dcberpr\u00fcfung fehlgeschlagen  
+currency.symbol.setting.notExist=Die W\u00e4hrung {0} wurde nicht eingestellt  
+currency.balance.deficiency=Der aktuelle Kontostand der W\u00e4hrung {0} ist unzureichend  
+currency.order.setting.minSell.err=Die Verkaufsmenge liegt unter dem Mindestlimit  
+currency.order.setting.orderMin.err=Die Kaufmenge liegt unter dem Mindestlimit  
+currency.order.setting.orderMax.err=Die Kaufmenge liegt \u00fcber dem H\u00f6chstlimit  
+currency.order.complete.not.cancel=Die Bestellung wurde bereits abgeschlossen und kann nicht storniert werden  
+currency.order.canceled=Die Bestellung wurde storniert  
+currency.order.baseCoin.unblock.fail=Fehler beim Entfrieren des Abrechnungsw\u00e4hrungsverm\u00f6gens  
+currency.order.coin.unblock.fail=Fehler beim Entfrieren des Handelsw\u00e4hrungsverm\u00f6gens  
+c2c.order.cancel.fail=Fehler beim Stornieren der Bestellung
+currency.order.delegate.price.not.null=Der Limit-Auftragspreis darf nicht leer sein  
+currency.order.not.trading.not.cancel=Die Bestellung befindet sich nicht im Handelsstatus und kann nicht storniert werden

+ 25 - 6
qnfhq-api/src/main/resources/i18n/messages_en.properties

@@ -111,12 +111,9 @@ c2c.complain.submit.fail=Failed to initiate complaint, you are not the buyer or
 c2c.order.not.buyer.seller=You are not a transaction user and cannot initiate a complaint  
 c2c.order.pay.update.fail=Failed to update order  
 c2c.order.complain.submit.fail=Failed to submit complaint  
-c2c.order.complain.not.exist=Invalid complaint ID  
-c2c.complain.voucher.submit.fail=Submission failed, you are not the complainant or respondent  
-c2c.order.complain.remark.notEmpty=Complaint reason cannot be empty  
-c2c.order.complain.remark.maxval=Description up to 250 characters  
+c2c.order.complain.not.exist=Invalid complaint ID
+c2c.order.complain.remark.notEmpty=Complaint reason cannot be empty   
 c2c.order.complain.voucher.id.invalid=Invalid complaint proof ID
-
 c2c.order.complain.voucher.is.end=The complaint has ended
 c2c.order.complain.voucher.save.fail=Failed to save complaint voucher
 c2c.order.complain.voucher.update.fail=Failed to update complaint voucher
@@ -146,4 +143,26 @@ c2c.order.reviews.create.fail=Failed to post review
 c2c.reviews.save.fail=Failed to save review
 c2c.order.you.reviewed=You have already reviewed this order
 c2c.order.cancel.otherReason.NotEmpty=Other reasons cannot be empty  
-c2c.order.cancel.reason.notset=Cancellation reason not set
+c2c.order.cancel.reason.notset=Cancel reason not configured  
+c2c.order.complain.reason.notset=Complaint reason not configured  
+c2c.deletePayment.voucher.fail=Failed to delete payment voucher  
+c2c.order.complain.remark.maxval=Description can be up to 250 characters  
+c2c.order.complain.files.limit=Up to 5 complaint vouchers allowed  
+c2c.complain.voucher.submit.fail=Submission failed, you are not a party to the order transaction  
+c2c.orderId.is.empty=Order number cannot be empty  
+c2c.voucher.type.is.empty=Voucher type cannot be empty  
+c2c.deleteVoucher.voucher.fail=Failed to delete voucher
+c2c.order.payment.vouchers.limit=Up to 3 payment vouchers allowed
+610=Account password verification failed
+currency.symbol.setting.notExist=Currency {0} not set
+currency.balance.deficiency=Insufficient balance of current {0} currency
+currency.order.setting.minSell.err=The quantity sold is below the minimum limit
+currency.order.setting.orderMin.err=The quantity bought is below the minimum limit
+currency.order.setting.orderMax.err=The quantity bought exceeds the maximum limit
+currency.order.complete.not.cancel=Order has been completed and cannot be canceled
+currency.order.canceled=Order has been canceled
+currency.order.baseCoin.unblock.fail=Failed to unfreeze base coin assets
+currency.order.coin.unblock.fail=Failed to unfreeze trading coin assets
+c2c.order.cancel.fail=Failed to cancel order
+currency.order.delegate.price.not.null=Limit order delegate price cannot be null
+currency.order.not.trading.not.cancel=Order is not in trading status, cannot be canceled

+ 26 - 5
qnfhq-api/src/main/resources/i18n/messages_es.properties

@@ -111,12 +111,9 @@ c2c.complain.submit.fail=Error al iniciar la disputa, usted no es comprador ni v
 c2c.order.not.buyer.seller=Usted no es parte de la transacci\u00f3n, no puede iniciar una disputa  
 c2c.order.pay.update.fail=Error al actualizar la orden  
 c2c.order.complain.submit.fail=Error al enviar la disputa  
-c2c.order.complain.not.exist=El n\u00famero de disputa no es v\u00e1lido  
-c2c.complain.voucher.submit.fail=Error al enviar, usted no es el reclamante ni el reclamado  
-c2c.order.complain.remark.notEmpty=La raz\u00f3n de la disputa no puede estar vac\u00eda  
-c2c.order.complain.remark.maxval=La descripci\u00f3n puede tener un m\u00e1ximo de 250 caracteres  
+c2c.order.complain.not.exist=El n\u00famero de disputa no es v\u00e1lido
+c2c.order.complain.remark.notEmpty=La raz\u00f3n de la disputa no puede estar vac\u00eda
 c2c.order.complain.voucher.id.invalid=El n\u00famero del comprobante de disputa no es v\u00e1lido
-
 c2c.order.complain.voucher.is.end=La apelaci\u00f3n ha terminado  
 c2c.order.complain.voucher.save.fail=Error al guardar el comprobante de apelaci\u00f3n  
 c2c.order.complain.voucher.update.fail=Error al modificar el comprobante de apelaci\u00f3n  
@@ -145,3 +142,27 @@ c2c.order.reviews.not.complete=El estado del pedido debe ser "Completado" para p
 c2c.order.reviews.create.fail=Error al publicar la evaluaci\u00f3n
 c2c.reviews.save.fail=Error al guardar la evaluaci\u00f3n
 c2c.order.you.reviewed=Ya has publicado una evaluaci\u00f3n para este pedido
+c2c.order.cancel.otherReason.NotEmpty=Otras razones no pueden estar vacías
+c2c.order.cancel.reason.notset=Razón de cancelación no configurada
+c2c.order.complain.reason.notset=Razón de apelación no configurada
+c2c.deletePayment.voucher.fail=Error al eliminar el comprobante de pago
+c2c.order.complain.remark.maxval=La descripción puede tener un máximo de 250 caracteres
+c2c.order.complain.files.limit=Máximo 5 comprobantes de apelación
+c2c.complain.voucher.submit.fail=Error al enviar, usted no es parte de la transacción del pedido
+c2c.orderId.is.empty=El número de pedido no puede estar vacío
+c2c.voucher.type.is.empty=El tipo de comprobante no puede estar vacío
+c2c.deleteVoucher.voucher.fail=Error al eliminar el comprobante
+c2c.order.payment.vouchers.limit=Se permiten hasta 3 comprobantes de pago
+610=Error de verificaci\u00f3n de contrase\u00f1a de la cuenta
+currency.symbol.setting.notExist=La moneda {0} no est\u00e1 configurada
+currency.balance.deficiency=Saldo insuficiente de la moneda {0}
+currency.order.setting.minSell.err=La cantidad vendida es inferior al l\u00edmite m\u00ednimo
+currency.order.setting.orderMin.err=La cantidad comprada es inferior al l\u00edmite m\u00ednimo
+currency.order.setting.orderMax.err=La cantidad comprada es superior al l\u00edmite m\u00e1ximo
+currency.order.complete.not.cancel=El pedido ya ha sido completado, no se puede cancelar
+currency.order.canceled=Pedido cancelado
+currency.order.baseCoin.unblock.fail=Error al desbloquear los activos de la moneda base
+currency.order.coin.unblock.fail=Error al desbloquear los activos de la moneda de transacci\u00f3n
+c2c.order.cancel.fail=Error al cancelar el pedido
+currency.order.delegate.price.not.null=El precio de la orden limitada no puede estar vac\u00edo
+currency.order.not.trading.not.cancel=El pedido no est\u00e1 en estado de negociaci\u00f3n, no se puede cancelar

+ 26 - 5
qnfhq-api/src/main/resources/i18n/messages_fr.properties

@@ -111,12 +111,9 @@ c2c.complain.submit.fail=\u00c9chec de l'initiation de la r\u00e9clamation, vous
 c2c.order.not.buyer.seller=Vous n'\u00eates pas un utilisateur de la transaction, vous ne pouvez pas initier une r\u00e9clamation  
 c2c.order.pay.update.fail=\u00c9chec de la mise \u00e0 jour de la commande  
 c2c.order.complain.submit.fail=\u00c9chec de la soumission de la r\u00e9clamation  
-c2c.order.complain.not.exist=Num\u00e9ro de r\u00e9clamation invalide  
-c2c.complain.voucher.submit.fail=\u00c9chec de la soumission, vous n'\u00eates ni le plaignant ni le d\u00e9fendeur  
-c2c.order.complain.remark.notEmpty=La raison de la r\u00e9clamation ne peut pas \u00eatre vide  
-c2c.order.complain.remark.maxval=La description ne peut pas d\u00e9passer 250 caract\u00e8res  
+c2c.order.complain.not.exist=Num\u00e9ro de r\u00e9clamation invalide
+c2c.order.complain.remark.notEmpty=La raison de la r\u00e9clamation ne peut pas \u00eatre vide
 c2c.order.complain.voucher.id.invalid=Num\u00e9ro de justificatif de r\u00e9clamation invalide
-
 c2c.order.complain.voucher.is.end=La r\u00e9clamation est termin\u00e9e  
 c2c.order.complain.voucher.save.fail=\u00c9chec de la sauvegarde du justificatif de r\u00e9clamation  
 c2c.order.complain.voucher.update.fail=\u00c9chec de la modification du justificatif de r\u00e9clamation  
@@ -145,3 +142,27 @@ c2c.order.reviews.not.complete=Le statut de la commande doit \u00eatre "Termin\u
 c2c.order.reviews.create.fail=\u00c9chec de la publication de l'\u00e9valuation
 c2c.reviews.save.fail=\u00c9chec de l'enregistrement de l'\u00e9valuation
 c2c.order.you.reviewed=Vous avez d\u00e9j\u00e0 laiss\u00e9 un commentaire pour cette commande
+c2c.order.cancel.otherReason.NotEmpty=Autre raison ne peut pas \u00eatre vide  
+c2c.order.cancel.reason.notset=Raison d'annulation non configur\u00e9e  
+c2c.order.complain.reason.notset=Raison de r\u00e9clamation non configur\u00e9e  
+c2c.deletePayment.voucher.fail=\u00c9chec de la suppression du justificatif de paiement  
+c2c.order.complain.remark.maxval=Description jusqu'\u00e0 250 caract\u00e8res maximum  
+c2c.order.complain.files.limit=Maximum 5 justificatifs pour la r\u00e9clamation  
+c2c.complain.voucher.submit.fail=\u00c9chec de la soumission, vous n'\u00eates pas une partie de la transaction  
+c2c.orderId.is.empty=Le num\u00e9ro de commande ne peut pas \u00eatre vide  
+c2c.voucher.type.is.empty=Le type de justificatif ne peut pas \u00eatre vide  
+c2c.deleteVoucher.voucher.fail=\u00c9chec de la suppression du justificatif
+c2c.order.payment.vouchers.limit=Maximum 3 bons de paiement
+610=\u00c9chec de la v\u00e9rification du mot de passe du compte  
+currency.symbol.setting.notExist=La devise {0} n'est pas configur\u00e9e  
+currency.balance.deficiency=Solde insuffisant pour la devise {0}  
+currency.order.setting.minSell.err=La quantit\u00e9 vendue est inf\u00e9rieure \u00e0 la limite minimale  
+currency.order.setting.orderMin.err=La quantit\u00e9 achet\u00e9e est inf\u00e9rieure \u00e0 la limite minimale  
+currency.order.setting.orderMax.err=La quantit\u00e9 achet\u00e9e est sup\u00e9rieure \u00e0 la limite maximale  
+currency.order.complete.not.cancel=La commande est d\u00e9j\u00e0 ex\u00e9cut\u00e9e, impossible d'annuler  
+currency.order.canceled=Commande annul\u00e9e  
+currency.order.baseCoin.unblock.fail=\u00c9chec du d\u00e9blocage des actifs en monnaie de base  
+currency.order.coin.unblock.fail=\u00c9chec du d\u00e9blocage des actifs en monnaie de transaction  
+c2c.order.cancel.fail=\u00c9chec de l'annulation de la commande
+currency.order.delegate.price.not.null=Le prix de l'ordre \u00e0 cours limit\u00e9 ne peut pas \u00eatre nul
+currency.order.not.trading.not.cancel=L'ordre n'est pas en \u00e9tat de n\u00e9gociation, il ne peut pas \u00eatre annul\u00e9

+ 24 - 4
qnfhq-api/src/main/resources/i18n/messages_ja.properties

@@ -112,11 +112,8 @@ c2c.order.not.buyer.seller=\u3042\u306a\u305f\u306f\u53d6\u5f15\u30e6\u30fc\u30b
 c2c.order.pay.update.fail=\u6ce8\u6587\u306e\u66f4\u65b0\u306b\u5931\u6557\u3057\u307e\u3057\u305f
 c2c.order.complain.submit.fail=\u7533\u7acb\u3066\u306e\u63d0\u51fa\u306b\u5931\u6557\u3057\u307e\u3057\u305f
 c2c.order.complain.not.exist=\u7533\u7acb\u3066\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059
-c2c.complain.voucher.submit.fail=\u63d0\u51fa\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u3042\u306a\u305f\u306f\u7533\u7acb\u3066\u4eba\u307e\u305f\u306f\u88ab\u7533\u7acb\u3066\u4eba\u3067\u306f\u3042\u308a\u307e\u305b\u3093
 c2c.order.complain.remark.notEmpty=\u7533\u7acb\u3066\u7406\u7531\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
-c2c.order.complain.remark.maxval=\u8aac\u660e\u306f\u6700\u5927250\u6587\u5b57\u307e\u3067\u3067\u3059
 c2c.order.complain.voucher.id.invalid=\u7533\u7acb\u3066\u8a3c\u660e\u66f8\u756a\u53f7\u304c\u7121\u52b9\u3067\u3059
-
 c2c.order.complain.voucher.is.end=\u7533\u8a34\u306f\u7d42\u4e86\u3057\u307e\u3057\u305f
 c2c.order.complain.voucher.save.fail=\u7533\u8a34\u8a3c\u660e\u306e\u4fdd\u5b58\u306b\u5931\u6557\u3057\u307e\u3057\u305f
 c2c.order.complain.voucher.update.fail=\u7533\u8a34\u8a3c\u660e\u306e\u5909\u66f4\u306b\u5931\u6557\u3057\u307e\u3057\u305f
@@ -145,4 +142,27 @@ c2c.order.reviews.not.complete=\u6ce8\u6587\u306e\u72b6\u614b\u304c\u300c\u5b8c\
 c2c.order.reviews.create.fail=\u8a55\u4fa1\u306e\u6295\u7a3f\u306b\u5931\u6557\u3057\u307e\u3057\u305f
 c2c.reviews.save.fail=\u8a55\u4fa1\u306e\u4fdd\u5b58\u306b\u5931\u6557\u3057\u307e\u3057\u305f
 c2c.order.you.reviewed=\u3053\u306e\u6ce8\u6587\u306b\u306f\u3059\u3067\u306b\u8a55\u4fa1\u3092\u6295\u7a3f\u3057\u3066\u3044\u307e\u3059
-
+c2c.order.cancel.otherReason.NotEmpty=\u305d\u306e\u4ed6\u306e\u7406\u7531\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+c2c.order.cancel.reason.notset=\u30ad\u30e3\u30f3\u30bb\u30eb\u7406\u7531\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+c2c.order.complain.reason.notset=\u7533\u7acb\u3066\u7406\u7531\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+c2c.deletePayment.voucher.fail=\u652f\u6255\u3044\u8a3c\u660e\u66f8\u306e\u524a\u9664\u306b\u5931\u6557\u3057\u307e\u3057\u305f
+c2c.order.complain.remark.maxval=\u8aac\u660e\u306f\u6700\u5927250\u6587\u5b57\u3067\u3059
+c2c.order.complain.files.limit=\u7533\u7acb\u3066\u8a3c\u62e0\u306f\u6700\u59275\u679a\u307e\u3067\u3067\u3059
+c2c.complain.voucher.submit.fail=\u63d0\u51fa\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u3042\u306a\u305f\u306f\u6ce8\u6587\u306e\u53d6\u5f15\u76f8\u624b\u3067\u306f\u3042\u308a\u307e\u305b\u3093
+c2c.orderId.is.empty=\u6ce8\u6587\u756a\u53f7\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+c2c.voucher.type.is.empty=\u8a3c\u660e\u66f8\u306e\u7a2e\u985e\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+c2c.deleteVoucher.voucher.fail=\u8a3c\u660e\u66f8\u306e\u524a\u9664\u306b\u5931\u6557\u3057\u307e\u3057\u305f
+c2c.order.payment.vouchers.limit=\u652f\u6255\u3044\u8a3c\u660e\u66f8\u306f\u6700\u59273\u679a\u307e\u3067
+610=\u30a2\u30ab\u30a6\u30f3\u30c8\u30d1\u30b9\u30ef\u30fc\u30c9\u306e\u691c\u8a3c\u306b\u5931\u6557\u3057\u307e\u3057\u305f
+currency.symbol.setting.notExist=\u901a\u8ca8{0}\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+currency.balance.deficiency=\u73fe\u5728\u306e{0}\u901a\u8ca8\u306e\u6b8b\u9ad8\u304c\u4e0d\u8db3\u3057\u3066\u3044\u307e\u3059
+currency.order.setting.minSell.err=\u58f2\u5374\u6570\u91cf\u304c\u6700\u4f4e\u5236\u9650\u3092\u4e0b\u56de\u3063\u3066\u3044\u307e\u3059
+currency.order.setting.orderMin.err=\u8cfc\u5165\u6570\u91cf\u304c\u6700\u4f4e\u5236\u9650\u3092\u4e0b\u56de\u3063\u3066\u3044\u307e\u3059
+currency.order.setting.orderMax.err=\u8cfc\u5165\u6570\u91cf\u304c\u6700\u9ad8\u5236\u9650\u3092\u8d85\u3048\u3066\u3044\u307e\u3059
+currency.order.complete.not.cancel=\u6ce8\u6587\u306f\u3059\u3067\u306b\u6210\u7acb\u3057\u3066\u304a\u308a\u3001\u30ad\u30e3\u30f3\u30bb\u30eb\u3067\u304d\u307e\u305b\u3093
+currency.order.canceled=\u6ce8\u6587\u306f\u30ad\u30e3\u30f3\u30bb\u30eb\u3055\u308c\u307e\u3057\u305f
+currency.order.baseCoin.unblock.fail=\u30d9\u30fc\u30b9\u30b3\u30a4\u30f3\u8cc7\u7523\u306e\u51cd\u7d50\u89e3\u9664\u306b\u5931\u6557\u3057\u307e\u3057\u305f
+currency.order.coin.unblock.fail=\u53d6\u5f15\u901a\u8ca8\u8cc7\u7523\u306e\u51cd\u7d50\u89e3\u9664\u306b\u5931\u6557\u3057\u307e\u3057\u305f
+c2c.order.cancel.fail=\u6ce8\u6587\u306e\u30ad\u30e3\u30f3\u30bb\u30eb\u306b\u5931\u6557\u3057\u307e\u3057\u305f
+currency.order.delegate.price.not.null=\u6307\u5024\u6ce8\u6587\u306e\u59d4\u8a17\u4fa1\u683c\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+currency.order.not.trading.not.cancel=\u6ce8\u6587\u306f\u53d6\u5f15\u72b6\u614b\u3067\u306f\u306a\u3044\u305f\u3081\u3001\u30ad\u30e3\u30f3\u30bb\u30eb\u3067\u304d\u307e\u305b\u3093

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

@@ -112,11 +112,8 @@ c2c.order.not.buyer.seller=\uac70\ub798 \uc0ac\uc6a9\uc790\uac00 \uc544\ub2c8\ub
 c2c.order.pay.update.fail=\uc8fc\ubb38 \uc5c5\ub370\uc774\ud2b8 \uc2e4\ud328
 c2c.order.complain.submit.fail=\ubd84\uc7c1 \uc81c\ucd9c \uc2e4\ud328
 c2c.order.complain.not.exist=\ubd84\uc7c1 \ubc88\ud638\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4
-c2c.complain.voucher.submit.fail=\uc81c\ucd9c \uc2e4\ud328, \ub2f9\uc2e0\uc740 \ubd84\uc7c1 \ub2f9\uc0ac\uc790\uac00 \uc544\ub2d9\ub2c8\ub2e4
 c2c.order.complain.remark.notEmpty=\ubd84\uc7c1 \uc0ac\uc720\ub97c \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
-c2c.order.complain.remark.maxval=\uc124\uba85\uc740 \ucd5c\ub300 250\uc790\uae4c\uc9c0 \uac00\ub2a5\ud569\ub2c8\ub2e4
 c2c.order.complain.voucher.id.invalid=\ubd84\uc7c1 \uc99d\ube59 \ubc88\ud638\uac00 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4
-
 c2c.order.complain.voucher.is.end=\uc2e0\uccad\uc774 \uc885\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4
 c2c.order.complain.voucher.save.fail=\uc2e0\uccad \uc99d\ube59 \uc800\uc7a5 \uc2e4\ud328
 c2c.order.complain.voucher.update.fail=\uc2e0\uccad \uc99d\ube59 \uc218\uc815 \uc2e4\ud328
@@ -145,3 +142,27 @@ c2c.order.reviews.not.complete=\uc8fc\ubb38 \uc0c1\ud0dc\uac00 "\uc644\ub8cc"\uc
 c2c.order.reviews.create.fail=\ud3c9\uac00 \uc791\uc131 \uc2e4\ud328
 c2c.reviews.save.fail=\ud3c9\uac00 \uc800\uc7a5 \uc2e4\ud328
 c2c.order.you.reviewed=\ud574\ub2f9 \uc8fc\ubb38\uc5d0 \uc774\ubbf8 \ud3c9\uac00\ub97c \uc791\uc131\ud558\uc168\uc2b5\ub2c8\ub2e4
+c2c.order.cancel.otherReason.NotEmpty=\uae30\ud0c0 \uc0ac\uc720\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
+c2c.order.cancel.reason.notset=\ucde8\uc18c \uc0ac\uc720\uac00 \uc124\uc815\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4  
+c2c.order.complain.reason.notset=\uc2e0\uace0 \uc0ac\uc720\uac00 \uc124\uc815\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4  
+c2c.deletePayment.voucher.fail=\uacb0\uc81c \uc99d\ube59\uc11c \uc0ad\uc81c \uc2e4\ud328  
+c2c.order.complain.remark.maxval=\uc124\uba85\uc740 \ucd5c\ub300 250\uc790\uae4c\uc9c0 \uc785\ub825\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4  
+c2c.order.complain.files.limit=\uc2e0\uace0 \uc99d\ube59\uc11c\ub294 \ucd5c\ub300 5\uc7a5\uae4c\uc9c0 \uac00\ub2a5\ud569\ub2c8\ub2e4  
+c2c.complain.voucher.submit.fail=\uc81c\ucd9c \uc2e4\ud328, \uadc0\ud558\ub294 \uc8fc\ubb38 \uac70\ub798 \ub2f9\uc0ac\uc790\uac00 \uc544\ub2d9\ub2c8\ub2e4  
+c2c.orderId.is.empty=\uc8fc\ubb38 \ubc88\ud638\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
+c2c.voucher.type.is.empty=\uc99d\ube59\uc11c \uc885\ub958\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
+c2c.deleteVoucher.voucher.fail=\uc99d\ube59\uc11c \uc0ad\uc81c \uc2e4\ud328
+c2c.order.payment.vouchers.limit=\uacb0\uc81c \uc99d\ube59\uc740 \ucd5c\ub300 3\uc7a5\uae4c\uc9c0 \uac00\ub2a5\ud569\ub2c8\ub2e4
+610=\uacc4\uc815 \ube44\ubc00\ubc88\ud638 \uac80\uc99d \uc2e4\ud328
+currency.symbol.setting.notExist=\ud1b5\ud654 {0} \uc124\uc815\ub418\uc9c0 \uc54a\uc74c
+currency.balance.deficiency=\ud604\uc7ac {0} \ud1b5\ud654 \uc794\uc561 \ubd80\uc871
+currency.order.setting.minSell.err=\ud310\ub9e4 \uc218\ub7c9\uc774 \ucd5c\uc18c \uc81c\ud55c\ubcf4\ub2e4 \uc801\uc74c
+currency.order.setting.orderMin.err=\uad6c\ub9e4 \uc218\ub7c9\uc774 \ucd5c\uc18c \uc81c\ud55c\ubcf4\ub2e4 \uc801\uc74c
+currency.order.setting.orderMax.err=\uad6c\ub9e4 \uc218\ub7c9\uc774 \ucd5c\ub300 \uc81c\ud55c\ubcf4\ub2e4 \ub9ce\uc74c
+currency.order.complete.not.cancel=\uc8fc\ubb38\uc774 \uc774\ubbf8 \uccb4\uacb0\ub418\uc5b4 \ucde8\uc18c\ud560 \uc218 \uc5c6\uc74c
+currency.order.canceled=\uc8fc\ubb38\uc774 \ucde8\uc18c\ub428
+currency.order.baseCoin.unblock.fail=\uae30\ubcf8 \ucf54\uc778 \uc790\uc0b0 \ud574\uc81c \uc2e4\ud328
+currency.order.coin.unblock.fail=\uac70\ub798 \ucf54\uc778 \uc790\uc0b0 \ud574\uc81c \uc2e4\ud328
+c2c.order.cancel.fail=\uc8fc\ubb38 \ucde8\uc18c \uc2e4\ud328
+currency.order.delegate.price.not.null=\uc9c0\uc815\uac00 \uc8fc\ubb38 \uc704\ud0c1 \uac00\uaca9\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+currency.order.not.trading.not.cancel=\uc8fc\ubb38\uc774 \uac70\ub798 \uc0c1\ud0dc\uac00 \uc544\ub2c8\ubbc0\ub85c \ucde8\uc18c\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4

+ 26 - 5
qnfhq-api/src/main/resources/i18n/messages_th.properties

@@ -111,12 +111,9 @@ c2c.complain.submit.fail=\u0e40\u0e23\u0e34\u0e48\u0e21\u0e23\u0e49\u0e2d\u0e07\
 c2c.order.not.buyer.seller=\u0e04\u0e38\u0e13\u0e44\u0e21\u0e48\u0e43\u0e0a\u0e48\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\u0e43\u0e19\u0e01\u0e32\u0e23\u0e17\u0e33\u0e18\u0e38\u0e23\u0e01\u0e23\u0e23\u0e21 \u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e40\u0e23\u0e34\u0e48\u0e21\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e44\u0e14\u0e49  
 c2c.order.pay.update.fail=\u0e2d\u0e31\u0e1b\u0e40\u0e14\u0e15\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27  
 c2c.order.complain.submit.fail=\u0e2a\u0e48\u0e07\u0e04\u0e33\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27  
-c2c.order.complain.not.exist=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07  
-c2c.complain.voucher.submit.fail=\u0e2a\u0e48\u0e07\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27 \u0e04\u0e38\u0e13\u0e44\u0e21\u0e48\u0e43\u0e0a\u0e48\u0e1c\u0e39\u0e49\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e2b\u0e23\u0e37\u0e2d\u0e1c\u0e39\u0e49\u0e16\u0e39\u0e01\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19  
-c2c.order.complain.remark.notEmpty=\u0e40\u0e2b\u0e15\u0e38\u0e1c\u0e25\u0e43\u0e19\u0e01\u0e32\u0e23\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07  
-c2c.order.complain.remark.maxval=\u0e04\u0e33\u0e2d\u0e18\u0e34\u0e1a\u0e32\u0e22\u0e2a\u0e39\u0e07\u0e2a\u0e38\u0e14 250 \u0e15\u0e31\u0e27\u0e2d\u0e31\u0e01\u0e29\u0e23  
+c2c.order.complain.not.exist=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07
+c2c.order.complain.remark.notEmpty=\u0e40\u0e2b\u0e15\u0e38\u0e1c\u0e25\u0e43\u0e19\u0e01\u0e32\u0e23\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 c2c.order.complain.voucher.id.invalid=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e2b\u0e25\u0e31\u0e01\u0e10\u0e32\u0e19\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e44\u0e21\u0e48\u0e16\u0e39\u0e01\u0e15\u0e49\u0e2d\u0e07
-
 c2c.order.complain.voucher.is.end=\u0e01\u0e32\u0e23\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e2a\u0e34\u0e49\u0e19\u0e2a\u0e38\u0e14\u0e41\u0e25\u0e49\u0e27
 c2c.order.complain.voucher.save.fail=\u0e01\u0e32\u0e23\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e2b\u0e25\u0e31\u0e01\u0e10\u0e32\u0e19\u0e01\u0e32\u0e23\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27
 c2c.order.complain.voucher.update.fail=\u0e01\u0e32\u0e23\u0e41\u0e01\u0e49\u0e44\u0e02\u0e2b\u0e25\u0e31\u0e01\u0e10\u0e32\u0e19\u0e01\u0e32\u0e23\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27
@@ -145,3 +142,27 @@ c2c.order.reviews.not.complete=\u0e2a\u0e16\u0e32\u0e19\u0e30\u0e04\u0e33\u0e2a\
 c2c.order.reviews.create.fail=\u0e01\u0e32\u0e23\u0e42\u0e1e\u0e2a\u0e15\u0e4c\u0e23\u0e35\u0e27\u0e34\u0e27\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27
 c2c.reviews.save.fail=\u0e01\u0e32\u0e23\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e23\u0e35\u0e27\u0e34\u0e27\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27
 c2c.order.you.reviewed=\u0e04\u0e38\u0e13\u0e44\u0e14\u0e49\u0e41\u0e2a\u0e14\u0e07\u0e04\u0e27\u0e32\u0e21\u0e04\u0e34\u0e14\u0e40\u0e2b\u0e47\u0e19\u0e43\u0e19\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e19\u0e35\u0e49\u0e41\u0e25\u0e49\u0e27
+c2c.order.cancel.otherReason.NotEmpty=\u0e40\u0e2b\u0e15\u0e38\u0e1c\u0e25\u0e2d\u0e37\u0e48\u0e19 \u0e46 \u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07  
+c2c.order.cancel.reason.notset=\u0e22\u0e31\u0e07\u0e44\u0e21\u0e48\u0e44\u0e14\u0e49\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32\u0e40\u0e2b\u0e15\u0e38\u0e1c\u0e25\u0e01\u0e32\u0e23\u0e22\u0e01\u0e40\u0e25\u0e34\u0e01  
+c2c.order.complain.reason.notset=\u0e22\u0e31\u0e07\u0e44\u0e21\u0e48\u0e44\u0e14\u0e49\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32\u0e40\u0e2b\u0e15\u0e38\u0e1c\u0e25\u0e01\u0e32\u0e23\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19  
+c2c.deletePayment.voucher.fail=\u0e25\u0e1a\u0e2b\u0e25\u0e31\u0e01\u0e10\u0e32\u0e19\u0e01\u0e32\u0e23\u0e0a\u0e33\u0e23\u0e30\u0e40\u0e07\u0e34\u0e19\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27  
+c2c.order.complain.remark.maxval=\u0e04\u0e33\u0e2d\u0e18\u0e34\u0e1a\u0e32\u0e22\u0e2a\u0e39\u0e07\u0e2a\u0e38\u0e14 250 \u0e15\u0e31\u0e27\u0e2d\u0e31\u0e01\u0e29\u0e23  
+c2c.order.complain.files.limit=\u0e2b\u0e25\u0e31\u0e01\u0e10\u0e32\u0e19\u0e01\u0e32\u0e23\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e2a\u0e39\u0e07\u0e2a\u0e38\u0e14 5 \u0e23\u0e39\u0e1b  
+c2c.complain.voucher.submit.fail=\u0e2a\u0e48\u0e07\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27 \u0e04\u0e38\u0e13\u0e44\u0e21\u0e48\u0e43\u0e0a\u0e48\u0e04\u0e39\u0e48\u0e2a\u0e31\u0e0d\u0e0d\u0e32\u0e01\u0e32\u0e23\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d  
+c2c.orderId.is.empty=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e2b\u0e49\u0e32\u0e21\u0e27\u0e48\u0e32\u0e07  
+c2c.voucher.type.is.empty=\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e2b\u0e25\u0e31\u0e01\u0e10\u0e32\u0e19\u0e2b\u0e49\u0e32\u0e21\u0e27\u0e48\u0e32\u0e07  
+c2c.deleteVoucher.voucher.fail=\u0e25\u0e1a\u0e2b\u0e25\u0e31\u0e01\u0e10\u0e32\u0e19\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27
+c2c.order.payment.vouchers.limit=\u0e43\u0e1a\u0e40\u0e2a\u0e23\u0e47\u0e08\u0e23\u0e31\u0e1a\u0e40\u0e07\u0e34\u0e19\u0e2a\u0e39\u0e07\u0e2a\u0e38\u0e14 3 \u0e43\u0e1a
+610=\u0e01\u0e32\u0e23\u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e23\u0e2b\u0e31\u0e2a\u0e1a\u0e31\u0e0d\u0e0a\u0e35\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27
+currency.symbol.setting.notExist=\u0e2a\u0e01\u0e38\u0e25\u0e40\u0e07\u0e34\u0e19 {0} \u0e22\u0e31\u0e07\u0e44\u0e21\u0e48\u0e44\u0e14\u0e49\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32
+currency.balance.deficiency=\u0e22\u0e2d\u0e14\u0e04\u0e07\u0e40\u0e2b\u0e25\u0e37\u0e2d\u0e2a\u0e01\u0e38\u0e25\u0e40\u0e07\u0e34\u0e19 {0} \u0e1b\u0e31\u0e08\u0e08\u0e38\u0e1a\u0e31\u0e19\u0e44\u0e21\u0e48\u0e40\u0e1e\u0e35\u0e22\u0e07\u0e1e\u0e2d
+currency.order.setting.minSell.err=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e17\u0e35\u0e48\u0e02\u0e32\u0e22\u0e15\u0e48\u0e33\u0e01\u0e27\u0e48\u0e32\u0e02\u0e35\u0e14\u0e08\u0e33\u0e01\u0e31\u0e14\u0e02\u0e31\u0e49\u0e19\u0e15\u0e48\u0e33
+currency.order.setting.orderMin.err=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e17\u0e35\u0e48\u0e0b\u0e37\u0e49\u0e2d\u0e15\u0e48\u0e33\u0e01\u0e27\u0e48\u0e32\u0e02\u0e35\u0e14\u0e08\u0e33\u0e01\u0e31\u0e14\u0e02\u0e31\u0e49\u0e19\u0e15\u0e48\u0e33
+currency.order.setting.orderMax.err=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e17\u0e35\u0e48\u0e0b\u0e37\u0e49\u0e2d\u0e2a\u0e39\u0e07\u0e01\u0e27\u0e48\u0e32\u0e02\u0e35\u0e14\u0e08\u0e33\u0e01\u0e31\u0e14\u0e2a\u0e39\u0e07\u0e2a\u0e38\u0e14
+currency.order.complete.not.cancel=\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e44\u0e14\u0e49\u0e16\u0e39\u0e01\u0e14\u0e33\u0e40\u0e19\u0e34\u0e19\u0e01\u0e32\u0e23\u0e41\u0e25\u0e49\u0e27 \u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e22\u0e01\u0e40\u0e25\u0e34\u0e01\u0e44\u0e14\u0e49
+currency.order.canceled=\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e16\u0e39\u0e01\u0e22\u0e01\u0e40\u0e25\u0e34\u0e01\u0e41\u0e25\u0e49\u0e27
+currency.order.baseCoin.unblock.fail=\u0e01\u0e32\u0e23\u0e1b\u0e25\u0e14\u0e25\u0e47\u0e2d\u0e01\u0e2a\u0e34\u0e19\u0e17\u0e23\u0e31\u0e1e\u0e22\u0e4c\u0e2a\u0e01\u0e38\u0e25\u0e40\u0e07\u0e34\u0e19\u0e10\u0e32\u0e19\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27
+currency.order.coin.unblock.fail=\u0e01\u0e32\u0e23\u0e1b\u0e25\u0e14\u0e25\u0e47\u0e2d\u0e01\u0e2a\u0e34\u0e19\u0e17\u0e23\u0e31\u0e1e\u0e22\u0e4c\u0e2a\u0e01\u0e38\u0e25\u0e40\u0e07\u0e34\u0e19\u0e0b\u0e37\u0e49\u0e2d\u0e02\u0e32\u0e22\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27
+c2c.order.cancel.fail=\u0e01\u0e32\u0e23\u0e22\u0e01\u0e40\u0e25\u0e34\u0e01\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e44\u0e21\u0e48\u0e2a\u0e33\u0e40\u0e23\u0e47\u0e08
+currency.order.delegate.price.not.null=\u0e23\u0e32\u0e04\u0e32\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e41\u0e1a\u0e1a\u0e08\u0e33\u0e01\u0e31\u0e14\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e40\u0e1b\u0e47\u0e19\u0e04\u0e48\u0e32\u0e27\u0e48\u0e32\u0e07\u0e44\u0e14\u0e49
+currency.order.not.trading.not.cancel=\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e0b\u0e37\u0e49\u0e2d\u0e44\u0e21\u0e48\u0e44\u0e14\u0e49\u0e2d\u0e22\u0e39\u0e48\u0e43\u0e19\u0e2a\u0e16\u0e32\u0e19\u0e30\u0e01\u0e32\u0e23\u0e0b\u0e37\u0e49\u0e2d\u0e02\u0e32\u0e22 \u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e22\u0e01\u0e40\u0e25\u0e34\u0e01\u0e44\u0e14\u0e49

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

@@ -112,11 +112,8 @@ c2c.order.not.buyer.seller=\u60a8\u4e0d\u662f\u4ea4\u6613\u7528\u6236\uff0c\u4e0
 c2c.order.pay.update.fail=\u8a02\u55ae\u66f4\u65b0\u5931\u6557
 c2c.order.complain.submit.fail=\u63d0\u4ea4\u7533\u8a34\u5931\u6557
 c2c.order.complain.not.exist=\u7533\u8a34\u7de8\u865f\u7121\u6548
-c2c.complain.voucher.submit.fail=\u63d0\u4ea4\u5931\u6557\uff0c\u60a8\u4e0d\u662f\u7533\u8a34\u4eba\u6216\u88ab\u7533\u8a34\u4eba
 c2c.order.complain.remark.notEmpty=\u7533\u8a34\u539f\u56e0\u4e0d\u80fd\u7a7a
-c2c.order.complain.remark.maxval=\u63cf\u8ff0\u6700\u591a250\u500b\u5b57
 c2c.order.complain.voucher.id.invalid=\u7533\u8a34\u6191\u8b49\u7de8\u865f\u7121\u6548
-
 c2c.order.complain.voucher.is.end=\u7533\u8a34\u5df2\u7d50\u675f
 c2c.order.complain.voucher.save.fail=\u4fdd\u5b58\u7533\u8a34\u6191\u8b49\u5931\u6557
 c2c.order.complain.voucher.update.fail=\u4fee\u6539\u7533\u8a34\u6191\u8b49\u5931\u6557
@@ -145,3 +142,27 @@ c2c.order.reviews.not.complete=\u8a02\u55ae\u72c0\u614b"\u5df2\u5b8c\u6210"\u624
 c2c.order.reviews.create.fail=\u767c\u8868\u8a55\u50f9\u5931\u6557
 c2c.reviews.save.fail=\u8a55\u50f9\u4fdd\u5b58\u5931\u6557
 c2c.order.you.reviewed=\u8a72\u8a02\u55ae\u60a8\u5df2\u767c\u8868\u8a55\u50f9
+c2c.order.cancel.otherReason.NotEmpty=\u5176\u4ed6\u539f\u56e0\u4e0d\u80fd\u7a7a  
+c2c.order.cancel.reason.notset=\u672a\u914d\u7f6e\u53d6\u6d88\u539f\u56e0  
+c2c.order.complain.reason.notset=\u672a\u914d\u7f6e\u7533\u8a34\u539f\u56e0  
+c2c.deletePayment.voucher.fail=\u522a\u9664\u4ed8\u6b3e\u6191\u8b49\u5931\u6557  
+c2c.order.complain.remark.maxval=\u63cf\u8ff0\u6700\u591a250\u500b\u5b57  
+c2c.order.complain.files.limit=\u7533\u8a34\u6191\u8b49\u6700\u591a5\u5f35  
+c2c.complain.voucher.submit.fail=\u63d0\u4ea4\u5931\u6557\uff0c\u60a8\u4e0d\u662f\u8a02\u55ae\u4ea4\u6613\u65b9  
+c2c.orderId.is.empty=\u8a02\u55ae\u7de8\u865f\u4e0d\u80fd\u7a7a  
+c2c.voucher.type.is.empty=\u6191\u8b49\u985e\u5225\u4e0d\u80fd\u7a7a  
+c2c.deleteVoucher.voucher.fail=\u522a\u9664\u6191\u8b49\u5931\u6557
+c2c.order.payment.vouchers.limit=\u4ed8\u6b3e\u6191\u8b49\u6700\u591a3\u5f35
+610=\u5e33\u865f\u5bc6\u78bc\u6821\u9a57\u5931\u6557
+currency.symbol.setting.notExist=\u5e63\u7a2e{0}\u672a\u8a2d\u5b9a
+currency.balance.deficiency=\u7576\u524d{0}\u5e63\u7a2e\u9918\u984d\u4e0d\u8db3
+currency.order.setting.minSell.err=\u8ce3\u51fa\u7684\u6578\u91cf\u4f4e\u65bc\u6700\u4f4e\u9650\u5236
+currency.order.setting.orderMin.err=\u8cb7\u5165\u7684\u6578\u91cf\u4f4e\u65bc\u6700\u4f4e\u9650\u5236
+currency.order.setting.orderMax.err=\u8cb7\u5165\u7684\u6578\u91cf\u9ad8\u65bc\u6700\u9ad8\u9650\u5236
+currency.order.complete.not.cancel=\u8a02\u55ae\u5df2\u7d93\u6210\u4ea4\u4e86\uff0c\u7121\u6cd5\u64a4\u92b7
+currency.order.canceled=\u8a02\u55ae\u5df2\u64a4\u92b7
+currency.order.baseCoin.unblock.fail=\u89e3\u51cd\u7d50\u7b97\u5e63\u8cc7\u7522\u5931\u6557
+currency.order.coin.unblock.fail=\u89e3\u51cd\u4ea4\u6613\u5e63\u8cc7\u7522\u5931\u6557
+c2c.order.cancel.fail=\u53d6\u6d88\u8a02\u55ae\u5931\u6557
+currency.order.delegate.price.not.null=\u9650\u50f9\u55ae\u59d4\u8a17\u50f9\u683c\u4e0d\u80fd\u70ba\u7a7a
+currency.order.not.trading.not.cancel=\u8a02\u55ae\u4e0d\u662f\u4ea4\u6613\u72c0\u614b\uff0c\u7121\u6cd5\u64a4\u92b7

+ 26 - 5
qnfhq-api/src/main/resources/i18n/messages_vi.properties

@@ -110,12 +110,9 @@ c2c.complain.submit.fail=Kh\u1edfi ki\u1ec7n th\u1ea5t b\u1ea1i, b\u1ea1n kh\u00
 c2c.order.not.buyer.seller=B\u1ea1n kh\u00f4ng ph\u1ea3i ng\u01b0\u1eddi tham gia giao d\u1ecbch, kh\u00f4ng th\u1ec3 kh\u1edfi ki\u1ec7n  
 c2c.order.pay.update.fail=C\u1eadp nh\u1eadt \u0111\u01a1n h\u00e0ng th\u1ea5t b\u1ea1i  
 c2c.order.complain.submit.fail=G\u1eedi kh\u1edfi ki\u1ec7n th\u1ea5t b\u1ea1i  
-c2c.order.complain.not.exist=M\u00e3 khi\u1ebfu n\u1ea1i kh\u00f4ng h\u1ee3p l\u1ec7  
-c2c.complain.voucher.submit.fail=G\u1eedi th\u1ea5t b\u1ea1i, b\u1ea1n kh\u00f4ng ph\u1ea3i ng\u01b0\u1eddi khi\u1ebfu n\u1ea1i ho\u1eb7c b\u1ecb khi\u1ebfu n\u1ea1i  
-c2c.order.complain.remark.notEmpty=L\u00fd do khi\u1ebfu n\u1ea1i kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng  
-c2c.order.complain.remark.maxval=M\u00f4 t\u1ea3 t\u1ed1i \u0111a 250 k\u00fd t\u1ef1  
+c2c.order.complain.not.exist=M\u00e3 khi\u1ebfu n\u1ea1i kh\u00f4ng h\u1ee3p l\u1ec7
+c2c.order.complain.remark.notEmpty=L\u00fd do khi\u1ebfu n\u1ea1i kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 c2c.order.complain.voucher.id.invalid=M\u00e3 ch\u1ee9ng t\u1eeb khi\u1ebfu n\u1ea1i kh\u00f4ng h\u1ee3p l\u1ec7
-
 c2c.order.complain.voucher.is.end=Khi\u1ebfu n\u1ea1i \u0111\u00e3 k\u1ebft th\u00fac  
 c2c.order.complain.voucher.save.fail=L\u01b0u ch\u1ee9ng t\u1eeb khi\u1ebfu n\u1ea1i th\u1ea5t b\u1ea1i  
 c2c.order.complain.voucher.update.fail=C\u1eadp nh\u1eadt ch\u1ee9ng t\u1eeb khi\u1ebfu n\u1ea1i th\u1ea5t b\u1ea1i  
@@ -144,3 +141,27 @@ c2c.order.reviews.not.complete=Tr\u1ea1ng th\u00e1i \u0111\u01a1n h\u00e0ng ph\u
 c2c.order.reviews.create.fail=\u0110\u0103ng \u0111\u00e1nh gi\u00e1 th\u1ea5t b\u1ea1i
 c2c.reviews.save.fail=L\u01b0u \u0111\u00e1nh gi\u00e1 th\u1ea5t b\u1ea1i
 c2c.order.you.reviewed=B\u1ea1n \u0111\u00e3 \u0111\u00e1nh gi\u00e1 \u0111\u01a1n h\u00e0ng n\u00e0y r\u1ed3i
+c2c.order.cancel.otherReason.NotEmpty=L\u00fd do kh\u00e1c kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+c2c.order.cancel.reason.notset=Ch\u01b0a c\u1ea5u h\u00ecnh l\u00fd do h\u1ee7y
+c2c.order.complain.reason.notset=Ch\u01b0a c\u1ea5u h\u00ecnh l\u00fd do khi\u1ebfu n\u1ea1i
+c2c.deletePayment.voucher.fail=X\u00f3a ch\u1ee9ng t\u1eeb thanh to\u00e1n th\u1ea5t b\u1ea1i
+c2c.order.complain.remark.maxval=M\u00f4 t\u1ea3 t\u1ed1i \u0111a 250 k\u00fd t\u1ef1
+c2c.order.complain.files.limit=T\u1ed1i \u0111a 5 ch\u1ee9ng t\u1eeb khi\u1ebfu n\u1ea1i
+c2c.complain.voucher.submit.fail=G\u1eedi th\u1ea5t b\u1ea1i, b\u1ea1n kh\u00f4ng ph\u1ea3i b\u00ean giao d\u1ecbch \u0111\u01a1n h\u00e0ng
+c2c.orderId.is.empty=M\u00e3 \u0111\u01a1n h\u00e0ng kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+c2c.voucher.type.is.empty=Lo\u1ea1i ch\u1ee9ng t\u1eeb kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+c2c.deleteVoucher.voucher.fail=X\u00f3a ch\u1ee9ng t\u1eeb th\u1ea5t b\u1ea1i
+c2c.order.payment.vouchers.limit=Gi\u1ea5y ch\u1ee9ng nh\u1eadn thanh to\u00e1n t\u1ed1i \u0111a 3 t\u1ea5m
+610=Ki\u1ec3m tra m\u1eadt kh\u1ea9u t\u00e0i kho\u1ea3n kh\u00f4ng th\u00e0nh c\u00f4ng
+currency.symbol.setting.notExist=Lo\u1ea1i ti\u1ec1n {0} ch\u01b0a \u0111\u01b0\u1ee3c thi\u1ebft l\u1eadp
+currency.balance.deficiency=S\u1ed1 d\u01b0 lo\u1ea1i ti\u1ec1n {0} hi\u1ec7n t\u1ea1i kh\u00f4ng \u0111\u1ee7
+currency.order.setting.minSell.err=S\u1ed1 l\u01b0\u1ee3ng b\u00e1n th\u1ea5p h\u01a1n gi\u1edbi h\u1ea1n t\u1ed1i thi\u1ec3u
+currency.order.setting.orderMin.err=S\u1ed1 l\u01b0\u1ee3ng mua th\u1ea5p h\u01a1n gi\u1edbi h\u1ea1n t\u1ed1i thi\u1ec3u
+currency.order.setting.orderMax.err=S\u1ed1 l\u01b0\u1ee3ng mua cao h\u01a1n gi\u1edbi h\u1ea1n t\u1ed1i \u0111a
+currency.order.complete.not.cancel=\u0110\u01a1n h\u00e0ng \u0111\u00e3 \u0111\u01b0\u1ee3c giao d\u1ecbch, kh\u00f4ng th\u1ec3 h\u1ee7y
+currency.order.canceled=\u0110\u01a1n h\u00e0ng \u0111\u00e3 b\u1ecb h\u1ee7y
+currency.order.baseCoin.unblock.fail=M\u1edf kh\u00f3a t\u00e0i s\u1ea3n \u0111\u1ed3ng c\u01a1 s\u1edf th\u1ea5t b\u1ea1i
+currency.order.coin.unblock.fail=M\u1edf kh\u00f3a t\u00e0i s\u1ea3n \u0111\u1ed3ng giao d\u1ecbch th\u1ea5t b\u1ea1i
+c2c.order.cancel.fail=H\u1ee7y \u0111\u01a1n h\u00e0ng th\u1ea5t b\u1ea1i
+currency.order.delegate.price.not.null=Gi\u00e1 \u0111\u1eb7t l\u1ec7nh gi\u1edbi h\u1ea1n kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+currency.order.not.trading.not.cancel=\u0110\u01a1n h\u00e0ng kh\u00f4ng \u1edf tr\u1ea1ng th\u00e1i giao d\u1ecbch, kh\u00f4ng th\u1ec3 h\u1ee7y b\u1ecf

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

@@ -113,9 +113,7 @@ c2c.order.not.buyer.seller=\u60a8\u4e0d\u662f\u4ea4\u6613\u7528\u6237\uff0c\u4e0
 c2c.order.pay.update.fail=\u8ba2\u5355\u66f4\u65b0\u5931\u8d25
 c2c.order.complain.submit.fail=\u63d0\u4ea4\u7533\u8bc9\u5931\u8d25
 c2c.order.complain.not.exist=\u7533\u8bc9\u7f16\u53f7\u65e0\u6548
-c2c.complain.voucher.submit.fail=\u63d0\u4ea4\u5931\u8d25\uff0c\u60a8\u4e0d\u662f\u7533\u8bc9\u4eba\u6216\u88ab\u7533\u8bc9\u4eba
 c2c.order.complain.remark.notEmpty=\u7533\u8bc9\u539f\u56e0\u4e0d\u80fd\u7a7a
-c2c.order.complain.remark.maxval=\u63cf\u8ff0\u6700\u591a250\u4e2a\u5b57
 c2c.order.complain.voucher.id.invalid=\u7533\u8bc9\u51ed\u8bc1\u7f16\u53f7\u65e0\u6548
 
 c2c.order.complain.voucher.is.end=\u7533\u8bc9\u5df2\u7ed3\u675f
@@ -149,4 +147,28 @@ c2c.reviews.save.fail=\u8bc4\u4ef7\u4fdd\u5b58\u5931\u8d25
 c2c.order.you.reviewed=\u8be5\u8ba2\u5355\u60a8\u5df2\u53d1\u8868\u8bc4\u4ef7
 
 c2c.order.cancel.otherReason.NotEmpty=\u5176\u4ed6\u539f\u56e0\u4e0d\u80fd\u7a7a
-c2c.order.cancel.reason.notset=\u672a\u914d\u7f6e\u53d6\u6d88\u539f\u56e0
+c2c.order.cancel.reason.notset=\u672a\u914d\u7f6e\u53d6\u6d88\u539f\u56e0
+c2c.order.complain.reason.notset=\u672a\u914d\u7f6e\u7533\u8bc9\u539f\u56e0
+c2c.deletePayment.voucher.fail=\u5220\u9664\u4ed8\u6b3e\u51ed\u8bc1\u5931\u8d25
+c2c.order.complain.remark.maxval=\u63cf\u8ff0\u6700\u591a250\u4e2a\u5b57
+c2c.order.complain.files.limit=\u7533\u8bc9\u51ed\u8bc1\u6700\u591a5\u5f20
+c2c.complain.voucher.submit.fail=\u63d0\u4ea4\u5931\u8d25\uff0c\u60a8\u4e0d\u662f\u8ba2\u5355\u4ea4\u6613\u65b9
+c2c.orderId.is.empty=\u8ba2\u5355\u7f16\u53f7\u4e0d\u80fd\u7a7a
+c2c.voucher.type.is.empty=\u51ed\u8bc1\u7c7b\u522b\u4e0d\u80fd\u7a7a
+c2c.deleteVoucher.voucher.fail=\u5220\u9664\u51ed\u8bc1\u5931\u8d25
+c2c.order.payment.vouchers.limit=\u4ed8\u6b3e\u51ed\u8bc1\u6700\u591a3\u5f20
+
+610=\u8d26\u53f7\u5bc6\u7801\u6821\u9a8c\u5931\u8d25
+currency.symbol.setting.notExist=\u5e01\u79cd{0}\u672a\u8bbe\u7f6e
+currency.balance.deficiency=\u5F53\u524D{0}\u5E01\u79CD\u4F59\u989D\u4E0D\u8DB3
+currency.order.setting.minSell.err=\u5356\u51fa\u7684\u6570\u91cf\u4f4e\u4e8e\u6700\u4f4e\u9650\u5236
+currency.order.setting.orderMin.err=\u4e70\u5165\u7684\u6570\u91cf\u4f4e\u4e8e\u6700\u4f4e\u9650\u5236
+currency.order.setting.orderMax.err=\u4e70\u5165\u7684\u6570\u91cf\u9ad8\u4e8e\u6700\u9ad8\u9650\u5236
+currency.order.complete.not.cancel=\u8ba2\u5355\u5df2\u7ecf\u6210\u4ea4\u4e86\uff0c\u65e0\u6cd5\u64a4\u9500
+currency.order.canceled=\u8ba2\u5355\u5df2\u64a4\u9500
+currency.order.baseCoin.unblock.fail=\u89e3\u51bb\u7ed3\u7b97\u5e01\u8d44\u4ea7\u5931\u8d25
+currency.order.coin.unblock.fail=\u89e3\u51bb\u4ea4\u6613\u5e01\u8d44\u4ea7\u5931\u8d25
+c2c.order.cancel.fail=\u53d6\u6d88\u8ba2\u5355\u5931\u8d25
+
+currency.order.delegate.price.not.null=\u9650\u4ef7\u5355\u59d4\u6258\u4ef7\u683c\u4e0d\u80fd\u4e3a\u7a7a
+currency.order.not.trading.not.cancel=\u8ba2\u5355\u4e0d\u662f\u4ea4\u6613\u72b6\u6001\uff0c\u65e0\u6cd5\u64a4\u9500

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

@@ -10,7 +10,7 @@ Email.format.err=Format emel tidak betul
 NotBlank.socialAccount=Akaun sosial tidak boleh kosong  
 NotBlank.socialType=Jenis akaun sosial tidak boleh kosong  
 NotNull.direction=Arah tidak boleh kosong  
-NotBlank.symbol=Mata wang perdagangan tidak boleh kosong  
+NotBlank.coin=Mata wang perdagangan tidak boleh kosong  
 NotBlank.legalCoin=Mata wang sah tidak boleh kosong  
 NotNull.priceType=Jenis harga tidak boleh kosong  
 NotNull.price=Harga tidak boleh kosong  
@@ -50,5 +50,12 @@ NotNull.rating=Penilaian tidak boleh kosong
 NotBlank.lables=Label tidak boleh kosong
 NotNull.isAnonymous=Adakah anonim tidak boleh kosong
 NotBlank.content=Kandungan tidak boleh kosong
-NotNull.reasonId=Nombor sebab pembatalan tidak boleh kosong  
-NotNull.reasonType=Jenis sebab pembatalan tidak boleh kosong
+NotNull.reasonType=Kategori sebab pembatalan tidak boleh kosong  
+NotNull.reasonId=Nombor sebab tidak boleh kosong  
+NotBlank.file=Bukti tidak boleh kosong  
+NotBlank.voucherIds=Bukti rayuan tidak boleh kosong
+NotBlank.Pay.voucherIds=ID baucar pembayaran tidak boleh kosong
+NotNull.delegateType=Jenis delegasi tidak boleh kosong
+NotBlank.CurrencyOrder.coin=Mata wang transaksi tidak boleh kosong
+NotBlank.CurrencyOrder.baseCoin=Mata wang penyelesaian tidak boleh kosong
+NotNull.delegateAmount=Jumlah delegasi tidak boleh kosong

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

@@ -10,7 +10,7 @@ Email.format.err=E-Mail-Format ist nicht korrekt
 NotBlank.socialAccount=Sozialkonto darf nicht leer sein  
 NotBlank.socialType=Sozialkonto-Typ darf nicht leer sein  
 NotNull.direction=Richtung darf nicht leer sein  
-NotBlank.symbol=Handelsw\u00e4hrung darf nicht leer sein  
+NotBlank.coin=Handelsw\u00e4hrung darf nicht leer sein  
 NotBlank.legalCoin=Fiat-W\u00e4hrung darf nicht leer sein  
 NotNull.priceType=Preistyp darf nicht leer sein  
 NotNull.price=Preis darf nicht leer sein  
@@ -50,3 +50,12 @@ NotNull.rating=Die Bewertung darf nicht leer sein
 NotBlank.lables=Die Labels d\u00fcrfen nicht leer sein  
 NotNull.isAnonymous=Die Angabe, ob anonym, darf nicht leer sein  
 NotBlank.content=Der Inhalt darf nicht leer sein
+NotNull.reasonType=Der Stornierungsgrundtyp darf nicht leer sein  
+NotNull.reasonId=Die Grundnummer darf nicht leer sein  
+NotBlank.file=Der Nachweis darf nicht leer sein  
+NotBlank.voucherIds=Der Beschwerdenachweis darf nicht leer sein
+NotBlank.Pay.voucherIds=Zahlungsbeleg darf nicht leer sein
+NotNull.delegateType=Der Delegationstyp darf nicht leer sein  
+NotBlank.CurrencyOrder.coin=Die Handelsw\u00e4hrung darf nicht leer sein  
+NotBlank.CurrencyOrder.baseCoin=Die Abrechnungsw\u00e4hrung darf nicht leer sein  
+NotNull.delegateAmount=Die Delegationsmenge darf nicht leer sein

+ 10 - 3
qnfhq-api/src/main/resources/i18n/validation_en.properties

@@ -10,7 +10,7 @@ Email.format.err=Email format is incorrect
 NotBlank.socialAccount=Social account cannot be empty
 NotBlank.socialType=Social account type cannot be empty
 NotNull.direction=Direction cannot be empty
-NotBlank.symbol=Trading currency cannot be empty
+NotBlank.coin=Trading currency cannot be empty
 NotBlank.legalCoin=Legal currency cannot be empty
 NotNull.priceType=Price type cannot be empty
 NotNull.price=Price cannot be empty
@@ -50,5 +50,12 @@ NotNull.rating=Rating cannot be empty
 NotBlank.lables=Labels cannot be empty  
 NotNull.isAnonymous=Anonymous status cannot be empty  
 NotBlank.content=Content cannot be empty
-NotNull.reasonId=Cancellation reason ID cannot be empty  
-NotNull.reasonType=Cancellation reason category cannot be empty
+NotNull.reasonType=Cancellation reason category cannot be empty
+NotNull.reasonId=Reason ID cannot be empty
+NotBlank.file=Voucher cannot be empty
+NotBlank.voucherIds=Appeal voucher cannot be empty
+NotBlank.Pay.voucherIds=Payment voucher cannot be empty
+NotNull.delegateType=Delegate type cannot be empty  
+NotBlank.CurrencyOrder.coin=Transaction currency cannot be empty  
+NotBlank.CurrencyOrder.baseCoin=Settlement currency cannot be empty  
+NotNull.delegateAmount=Delegate amount cannot be empty

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

@@ -10,7 +10,7 @@ Email.format.err=El formato del correo electr\u00f3nico no es correcto
 NotBlank.socialAccount=La cuenta social no puede estar vac\u00eda  
 NotBlank.socialType=El tipo de cuenta social no puede estar vac\u00edo  
 NotNull.direction=La direcci\u00f3n no puede estar vac\u00eda  
-NotBlank.symbol=La moneda de transacci\u00f3n no puede estar vac\u00eda  
+NotBlank.coin=La moneda de transacci\u00f3n no puede estar vac\u00eda  
 NotBlank.legalCoin=La moneda legal no puede estar vac\u00eda  
 NotNull.priceType=El tipo de precio no puede estar vac\u00edo  
 NotNull.price=El precio no puede estar vac\u00edo  
@@ -50,3 +50,12 @@ NotNull.rating=La calificaci\u00f3n no puede estar vac\u00eda
 NotBlank.lables=Las etiquetas no pueden estar vac\u00edas  
 NotNull.isAnonymous=No puede estar vac\u00edo si es an\u00f3nimo  
 NotBlank.content=El contenido no puede estar vac\u00edo
+NotNull.reasonType=La categor\u00eda de motivo de cancelaci\u00f3n no puede estar vac\u00eda  
+NotNull.reasonId=El n\u00famero de motivo no puede estar vac\u00edo  
+NotBlank.file=El comprobante no puede estar vac\u00edo  
+NotBlank.voucherIds=Los comprobantes de apelaci\u00f3n no pueden estar vac\u00edos
+NotBlank.Pay.voucherIds=Los comprobantes de pago no pueden estar vac\u00edos
+NotNull.delegateType=El tipo de delegaci\u00f3n no puede estar vac\u00edo
+NotBlank.CurrencyOrder.coin=La moneda de transacci\u00f3n no puede estar vac\u00eda
+NotBlank.CurrencyOrder.baseCoin=La moneda de liquidaci\u00f3n no puede estar vac\u00eda
+NotNull.delegateAmount=La cantidad delegada no puede estar vac\u00eda

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

@@ -10,7 +10,7 @@ Email.format.err=Le format de l'email est incorrect
 NotBlank.socialAccount=Le compte social ne peut pas \u00eatre vide  
 NotBlank.socialType=Le type de compte social ne peut pas \u00eatre vide  
 NotNull.direction=La direction ne peut pas \u00eatre vide  
-NotBlank.symbol=La devise de transaction ne peut pas \u00eatre vide  
+NotBlank.coin=La devise de transaction ne peut pas \u00eatre vide  
 NotBlank.legalCoin=La monnaie l\u00e9gale ne peut pas \u00eatre vide  
 NotNull.priceType=Le type de prix ne peut pas \u00eatre vide  
 NotNull.price=Le prix ne peut pas \u00eatre vide  
@@ -50,3 +50,12 @@ NotNull.rating=La note ne peut pas \u00eatre vide
 NotBlank.lables=Les \u00e9tiquettes ne peuvent pas \u00eatre vides  
 NotNull.isAnonymous=Le statut anonyme ne peut pas \u00eatre vide  
 NotBlank.content=Le contenu ne peut pas \u00eatre vide
+NotNull.reasonType=La cat\u00e9gorie de raison d'annulation ne peut pas \u00eatre vide  
+NotNull.reasonId=Le num\u00e9ro de raison ne peut pas \u00eatre vide  
+NotBlank.file=Le justificatif ne peut pas \u00eatre vide  
+NotBlank.voucherIds=Les justificatifs de r\u00e9clamation ne peuvent pas \u00eatre vides
+NotBlank.Pay.voucherIds=Les justificatifs de paiement ne peuvent pas \u00eatre vides
+NotNull.delegateType=Le type de d\u00e9l\u00e9gation ne peut pas \u00eatre vide  
+NotBlank.CurrencyOrder.coin=La devise de transaction ne peut pas \u00eatre vide  
+NotBlank.CurrencyOrder.baseCoin=La devise de r\u00e8glement ne peut pas \u00eatre vide  
+NotNull.delegateAmount=La quantit\u00e9 d\u00e9l\u00e9gu\u00e9e ne peut pas \u00eatre vide

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

@@ -10,7 +10,7 @@ Email.format.err=\u30e1\u30fc\u30eb\u5f62\u5f0f\u304c\u6b63\u3057\u304f\u3042\u3
 NotBlank.socialAccount=\u30bd\u30fc\u30b7\u30e3\u30eb\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotBlank.socialType=\u30bd\u30fc\u30b7\u30e3\u30eb\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u7a2e\u985e\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotNull.direction=\u65b9\u5411\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
-NotBlank.symbol=\u53d6\u5f15\u901a\u8ca8\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotBlank.coin=\u53d6\u5f15\u901a\u8ca8\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotBlank.legalCoin=\u6cd5\u5b9a\u901a\u8ca8\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotNull.priceType=\u4fa1\u683c\u30bf\u30a4\u30d7\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotNull.price=\u4fa1\u683c\u3092\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
@@ -50,3 +50,12 @@ NotNull.rating=\u8a55\u4fa1\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotBlank.lables=\u30e9\u30d9\u30eb\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotNull.isAnonymous=\u533f\u540d\u304b\u3069\u3046\u304b\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
 NotBlank.content=\u5185\u5bb9\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotNull.reasonType=\u53d6\u6d88\u539f\u56e0\u306e\u7a2e\u985e\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotNull.reasonId=\u539f\u56e0\u756a\u53f7\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotBlank.file=\u8a3c\u660e\u66f8\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotBlank.voucherIds=\u7533\u7acb\u3066\u8a3c\u660e\u66f8\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotBlank.Pay.voucherIds=\u652f\u6255\u3044\u8a3c\u660e\u66f8\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093
+NotNull.delegateType=\u59d4\u8a17\u30bf\u30a4\u30d7\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093  
+NotBlank.CurrencyOrder.coin=\u53d6\u5f15\u901a\u8ca8\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093  
+NotBlank.CurrencyOrder.baseCoin=\u6c7a\u6e08\u901a\u8ca8\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093  
+NotNull.delegateAmount=\u59d4\u8a17\u6570\u91cf\u306f\u7a7a\u306b\u3067\u304d\u307e\u305b\u3093

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

@@ -10,7 +10,7 @@ Email.format.err=\uc774\uba54\uc77c \ud615\uc2dd\uc774 \uc62c\ubc14\ub974\uc9c0
 NotBlank.socialAccount=\uc18c\uc15c \uacc4\uc815\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
 NotBlank.socialType=\uc18c\uc15c \uacc4\uc815 \uc720\ud615\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
 NotNull.direction=\ubc29\ud5a5\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
-NotBlank.symbol=\uac70\ub798 \ud1b5\ud654\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
+NotBlank.coin=\uac70\ub798 \ud1b5\ud654\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
 NotBlank.legalCoin=\ubc95\uc815 \ud654\ud3d0\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
 NotNull.priceType=\uac00\uaca9 \uc720\ud615\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
 NotNull.price=\uac00\uaca9\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4  
@@ -50,3 +50,12 @@ NotNull.rating=\ud3c9\uc810\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\u
 NotBlank.lables=\ub77c\ubca8\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
 NotNull.isAnonymous=\uc775\uba85 \uc5ec\ubd80\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
 NotBlank.content=\ub0b4\uc6a9\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotNull.reasonType=\ucde8\uc18c \uc0ac\uc720 \uc720\ud615\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotNull.reasonId=\uc0ac\uc720 \ubc88\ud638\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.file=\uc99d\ube59 \uc11c\ub958\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.voucherIds=\uc774\uc758 \uc81c\uae30 \uc99d\ube59\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.Pay.voucherIds=\uacb0\uc81c \uc99d\ube59\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotNull.delegateType=\uc704\uc784 \uc720\ud615\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.CurrencyOrder.coin=\uac70\ub798 \ud654\ud3d0\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotBlank.CurrencyOrder.baseCoin=\uacb0\uc81c \ud654\ud3d0\ub294 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4
+NotNull.delegateAmount=\uc704\uc784 \uc218\ub7c9\uc740 \ube44\uc6cc\ub458 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4

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

@@ -10,7 +10,7 @@ Email.format.err=\u0e23\u0e39\u0e1b\u0e41\u0e1a\u0e1a\u0e2d\u0e35\u0e40\u0e21\u0
 NotBlank.socialAccount=\u0e1a\u0e31\u0e0d\u0e0a\u0e35\u0e42\u0e0b\u0e40\u0e0a\u0e35\u0e22\u0e25\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotBlank.socialType=\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e1a\u0e31\u0e0d\u0e0a\u0e35\u0e42\u0e0b\u0e40\u0e0a\u0e35\u0e22\u0e25\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotNull.direction=\u0e17\u0e34\u0e28\u0e17\u0e32\u0e07\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
-NotBlank.symbol=\u0e2a\u0e01\u0e38\u0e25\u0e40\u0e07\u0e34\u0e19\u0e17\u0e35\u0e48\u0e43\u0e0a\u0e49\u0e43\u0e19\u0e01\u0e32\u0e23\u0e0b\u0e37\u0e49\u0e2d\u0e02\u0e32\u0e22\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotBlank.coin=\u0e2a\u0e01\u0e38\u0e25\u0e40\u0e07\u0e34\u0e19\u0e17\u0e35\u0e48\u0e43\u0e0a\u0e49\u0e43\u0e19\u0e01\u0e32\u0e23\u0e0b\u0e37\u0e49\u0e2d\u0e02\u0e32\u0e22\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotBlank.legalCoin=\u0e2a\u0e01\u0e38\u0e25\u0e40\u0e07\u0e34\u0e19\u0e17\u0e35\u0e48\u0e16\u0e39\u0e01\u0e01\u0e0e\u0e2b\u0e21\u0e32\u0e22\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotNull.priceType=\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e02\u0e2d\u0e07\u0e23\u0e32\u0e04\u0e32\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e40\u0e1b\u0e47\u0e19\u0e04\u0e48\u0e32\u0e27\u0e48\u0e32\u0e07\u0e44\u0e14\u0e49
 NotNull.price=\u0e23\u0e32\u0e04\u0e32\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
@@ -50,3 +50,12 @@ NotNull.rating=\u0e04\u0e30\u0e41\u0e19\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e2
 NotBlank.lables=\u0e1b\u0e49\u0e32\u0e22\u0e01\u0e33\u0e01\u0e31\u0e1a\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
 NotNull.isAnonymous=\u0e15\u0e49\u0e2d\u0e07\u0e23\u0e30\u0e1a\u0e38\u0e27\u0e48\u0e32\u0e0b\u0e48\u0e2d\u0e19\u0e0a\u0e37\u0e48\u0e2d\u0e2b\u0e23\u0e37\u0e2d\u0e44\u0e21\u0e48
 NotBlank.content=\u0e40\u0e19\u0e37\u0e49\u0e2d\u0e2b\u0e32\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07
+NotNull.reasonType=\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e40\u0e2b\u0e15\u0e38\u0e1c\u0e25\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e40\u0e1b\u0e47\u0e19\u0e04\u0e48\u0e32\u0e27\u0e48\u0e32\u0e07\u0e44\u0e14\u0e49  
+NotNull.reasonId=\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e25\u0e02\u0e40\u0e2b\u0e15\u0e38\u0e1c\u0e25\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e40\u0e1b\u0e47\u0e19\u0e04\u0e48\u0e32\u0e27\u0e48\u0e32\u0e07\u0e44\u0e14\u0e49  
+NotBlank.file=\u0e2b\u0e25\u0e31\u0e01\u0e10\u0e32\u0e19\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e40\u0e1b\u0e47\u0e19\u0e04\u0e48\u0e32\u0e27\u0e48\u0e32\u0e07\u0e44\u0e14\u0e49  
+NotBlank.voucherIds=\u0e2b\u0e25\u0e31\u0e01\u0e10\u0e32\u0e19\u0e01\u0e32\u0e23\u0e23\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e35\u0e22\u0e19\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e40\u0e1b\u0e47\u0e19\u0e04\u0e48\u0e32\u0e27\u0e48\u0e32\u0e07\u0e44\u0e14\u0e49
+NotBlank.Pay.voucherIds=\u0e43\u0e1a\u0e40\u0e2a\u0e23\u0e47\u0e08\u0e23\u0e31\u0e1a\u0e40\u0e07\u0e34\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07\u0e40\u0e1b\u0e25\u0e48\u0e32
+NotNull.delegateType=\u0e1b\u0e23\u0e30\u0e40\u0e20\u0e17\u0e15\u0e31\u0e27\u0e41\u0e17\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07  
+NotBlank.CurrencyOrder.coin=\u0e2a\u0e01\u0e38\u0e25\u0e40\u0e07\u0e34\u0e19\u0e17\u0e35\u0e48\u0e43\u0e0a\u0e49\u0e43\u0e19\u0e01\u0e32\u0e23\u0e0b\u0e37\u0e49\u0e2d\u0e02\u0e32\u0e22\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07  
+NotBlank.CurrencyOrder.baseCoin=\u0e2a\u0e01\u0e38\u0e25\u0e40\u0e07\u0e34\u0e19\u0e17\u0e35\u0e48\u0e43\u0e0a\u0e49\u0e43\u0e19\u0e01\u0e32\u0e23\u0e0a\u0e33\u0e23\u0e30\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07  
+NotNull.delegateAmount=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e15\u0e31\u0e27\u0e41\u0e17\u0e19\u0e15\u0e49\u0e2d\u0e07\u0e44\u0e21\u0e48\u0e27\u0e48\u0e32\u0e07

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

@@ -10,7 +10,7 @@ Email.format.err=\u90f5\u7bb1\u683c\u5f0f\u4e0d\u6b63\u78ba
 NotBlank.socialAccount=\u793e\u4ea4\u5e33\u865f\u4e0d\u80fd\u7a7a
 NotBlank.socialType=\u793e\u4ea4\u5e33\u865f\u985e\u578b\u4e0d\u80fd\u7a7a
 NotNull.direction=\u65b9\u5411\u4e0d\u80fd\u70ba\u7a7a
-NotBlank.symbol=\u4ea4\u6613\u5e63\u7a2e\u4e0d\u80fd\u70ba\u7a7a
+NotBlank.coin=\u4ea4\u6613\u5e63\u7a2e\u4e0d\u80fd\u70ba\u7a7a
 NotBlank.legalCoin=\u6cd5\u5e63\u4e0d\u80fd\u70ba\u7a7a
 NotNull.priceType=\u50f9\u683c\u985e\u578b\u4e0d\u80fd\u70ba\u7a7a
 NotNull.price=\u50f9\u683c\u4e0d\u80fd\u70ba\u7a7a
@@ -50,3 +50,12 @@ NotNull.rating=\u8a55\u5206\u4e0d\u80fd\u7a7a
 NotBlank.lables=\u6a19\u7c64\u4e0d\u80fd\u7a7a
 NotNull.isAnonymous=\u662f\u5426\u533f\u540d\u4e0d\u80fd\u7a7a
 NotBlank.content=\u5167\u5bb9\u4e0d\u80fd\u7a7a
+NotNull.reasonType=\u53d6\u6d88\u539f\u56e0\u985e\u5225\u4e0d\u80fd\u70ba\u7a7a
+NotNull.reasonId=\u539f\u56e0\u7de8\u865f\u4e0d\u80fd\u70ba\u7a7a
+NotBlank.file=\u6191\u8b49\u4e0d\u80fd\u70ba\u7a7a
+NotBlank.voucherIds=\u7533\u8a34\u6191\u8b49\u4e0d\u80fd\u70ba\u7a7a
+NotBlank.Pay.voucherIds=\u4ed8\u6b3e\u6191\u8b49\u4e0d\u80fd\u70ba\u7a7a
+NotNull.delegateType=\u59d4\u8a17\u985e\u578b\u4e0d\u80fd\u7a7a  
+NotBlank.CurrencyOrder.coin=\u4ea4\u6613\u5e63\u7a2e\u4e0d\u80fd\u7a7a  
+NotBlank.CurrencyOrder.baseCoin=\u7d50\u7b97\u5e63\u7a2e\u4e0d\u80fd\u7a7a  
+NotNull.delegateAmount=\u59d4\u8a17\u6578\u91cf\u4e0d\u80fd\u7a7a

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

@@ -10,7 +10,7 @@ Email.format.err=\u0110\u1ecbnh d\u1ea1ng email kh\u00f4ng \u0111\u00fang
 NotBlank.socialAccount=T\u00e0i kho\u1ea3n m\u1ea1ng x\u00e3 h\u1ed9i kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotBlank.socialType=Lo\u1ea1i t\u00e0i kho\u1ea3n m\u1ea1ng x\u00e3 h\u1ed9i kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotNull.direction=H\u01b0\u1edbng kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
-NotBlank.symbol=Lo\u1ea1i ti\u1ec1n giao d\u1ecbch kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotBlank.coin=Lo\u1ea1i ti\u1ec1n giao d\u1ecbch kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotBlank.legalCoin=Ti\u1ec1n ph\u00e1p \u0111\u1ecbnh kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotNull.priceType=Lo\u1ea1i gi\u00e1 kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotNull.price=Gi\u00e1 kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
@@ -49,4 +49,13 @@ NotNull.followingId=ID ng\u01b0\u1eddi \u0111\u01b0\u1ee3c theo d\u00f5i kh\u00f
 NotNull.rating=\u0110\u00e1nh gi\u00e1 kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotBlank.lables=Nh\u00e3n kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
 NotNull.isAnonymous=Kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng vi\u1ec7c c\u00f3 \u1ea9n danh hay kh\u00f4ng
-NotBlank.content=N\u1ed9i dung kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotBlank.content=N\u1ed9i dung kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotNull.reasonType=Lo\u1ea1i l\u00fd do h\u1ee7y kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng  
+NotNull.reasonId=M\u00e3 l\u00fd do kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng  
+NotBlank.file=Ch\u1ee9ng t\u1eeb kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng  
+NotBlank.voucherIds=Ch\u1ee9ng t\u1eeb khi\u1ebfu n\u1ea1i kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotBlank.Pay.voucherIds=Ch\u1ee9ng t\u1eeb thanh to\u00e1n kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng
+NotNull.delegateType=Lo\u1ea1i \u1ee7y th\u00e1c kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng  
+NotBlank.CurrencyOrder.coin=Lo\u1ea1i ti\u1ec1n giao d\u1ecbch kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng  
+NotBlank.CurrencyOrder.baseCoin=Lo\u1ea1i ti\u1ec1n thanh to\u00e1n kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng  
+NotNull.delegateAmount=S\u1ed1 l\u01b0\u1ee3ng \u1ee7y th\u00e1c kh\u00f4ng \u0111\u01b0\u1ee3c \u0111\u1ec3 tr\u1ed1ng

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

@@ -10,7 +10,7 @@ Email.format.err=\u90ae\u7bb1\u683c\u5f0f\u4e0d\u6b63\u786e
 NotBlank.socialAccount=\u793e\u4ea4\u8d26\u53f7\u4e0d\u80fd\u7a7a
 NotBlank.socialType=\u793e\u4ea4\u8d26\u53f7\u7c7b\u578b\u4e0d\u80fd\u7a7a
 NotNull.direction=\u65b9\u5411\u4e0d\u80fd\u4e3a\u7a7a
-NotBlank.symbol=\u4ea4\u6613\u5e01\u79cd\u4e0d\u80fd\u4e3a\u7a7a
+NotBlank.coin=\u4ea4\u6613\u5e01\u79cd\u4e0d\u80fd\u4e3a\u7a7a
 NotBlank.legalCoin=\u6cd5\u5e01\u4e0d\u80fd\u4e3a\u7a7a
 NotNull.priceType=\u4ef7\u683c\u7c7b\u578b\u4e0d\u80fd\u4e3a\u7a7a
 NotNull.price=\u4ef7\u683c\u4e0d\u80fd\u4e3a\u7a7a
@@ -50,6 +50,12 @@ NotNull.rating=\u8bc4\u5206\u4e0d\u80fd\u4e3a\u7a7a
 NotBlank.lables=\u6807\u7b7e\u4e0d\u80fd\u4e3a\u7a7a
 NotNull.isAnonymous=\u662f\u5426\u533f\u540d\u4e0d\u80fd\u4e3a\u7a7a
 NotBlank.content=\u5185\u5bb9\u4e0d\u80fd\u7a7a
-
-NotNull.reasonId=\u53d6\u6d88\u539f\u56e0\u7f16\u53f7\u4e0d\u80fd\u4e3a\u7a7a
 NotNull.reasonType=\u53d6\u6d88\u539f\u56e0\u7c7b\u522b\u4e0d\u80fd\u4e3a\u7a7a
+NotNull.reasonId=\u539f\u56e0\u7f16\u53f7\u4e0d\u80fd\u4e3a\u7a7a
+NotBlank.file=\u51ed\u8bc1\u4e0d\u80fd\u4e3a\u7a7a
+NotBlank.voucherIds=\u7533\u8bc9\u51ed\u8bc1\u4e0d\u80fd\u4e3a\u7a7a
+NotBlank.Pay.voucherIds=\u4ed8\u6b3e\u51ed\u8bc1\u4e0d\u80fd\u4e3a\u7a7a
+NotNull.delegateType=\u59d4\u6258\u7c7b\u578b\u4e0d\u80fd\u7a7a
+NotBlank.CurrencyOrder.coin=\u4ea4\u6613\u5e01\u79cd\u4e0d\u80fd\u7a7a
+NotBlank.CurrencyOrder.baseCoin=\u7ed3\u7b97\u5e01\u79cd\u4e0d\u80fd\u7a7a
+NotNull.delegateAmount=\u59d4\u6258\u6570\u91cf\u4e0d\u80fd\u7a7a

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

@@ -11,7 +11,7 @@
         <result property="merchantId" column="merchant_id"/>
         <result property="direction" column="direction"/>
         <result property="legalCoin" column="legal_coin"/>
-        <result property="symbol" column="symbol"/>
+        <result property="coin" column="coin"/>
         <result property="num" column="num"/>
         <result property="availableNum" column="available_num"/>
         <result property="priceType" column="price_type"/>

+ 1 - 1
qnfhq-api/src/main/resources/mapper/c2c/C2cAdLogDao.xml

@@ -6,7 +6,7 @@
     <resultMap type="com.qnfhq.modules.c2c.entity.C2cAdLogEntity" id="c2cAdLogMap">
         <result property="adId" column="ad_id"/>
         <result property="orderId" column="order_id"/>
-        <result property="symbolNum" column="symbol_num"/>
+        <result property="coinNum" column="coin_num"/>
         <result property="beforeAvailNum" column="before_avail_num"/>
         <result property="afterAvailNum" column="after_avail_num"/>
         <result property="beforeMaxAmount" column="before_max_amount"/>

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff