Răsfoiți Sursa

停止追踪 node_modules 和 target 文件夹

13147038669 5 luni în urmă
părinte
comite
118248102c
89 a modificat fișierele cu 2987 adăugiri și 878 ștergeri
  1. 10 0
      crmeb_src/mer_java/.idea/.gitignore
  2. 27 0
      crmeb_src/mer_java/.idea/compiler.xml
  3. 15 0
      crmeb_src/mer_java/.idea/encodings.xml
  4. 20 0
      crmeb_src/mer_java/.idea/jarRepositories.xml
  5. 12 0
      crmeb_src/mer_java/.idea/misc.xml
  6. 6 0
      crmeb_src/mer_java/.idea/vcs.xml
  7. 8 0
      crmeb_src/mer_java/crmeb-admin/pom.xml
  8. 2 0
      crmeb_src/mer_java/crmeb-admin/src/main/java/com/zbkj/admin/service/impl/FinanceServiceImpl.java
  9. 20 4
      crmeb_src/mer_java/crmeb-admin/src/main/java/com/zbkj/admin/task/daibi/DaibiRateTask.java
  10. 77 0
      crmeb_src/mer_java/crmeb-admin/src/main/java/com/zbkj/admin/util/SimpleProxyUtil.java
  11. 1 1
      crmeb_src/mer_java/crmeb-admin/src/main/resources/application-dev.yml
  12. 82 0
      crmeb_src/mer_java/crmeb-admin/src/test/java/com/zbkj/admin/SquidProxyHttpClient.java
  13. 24 0
      crmeb_src/mer_java/crmeb-admin/src/test/java/com/zbkj/admin/StatementTaskTest.java
  14. 12 8
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/constants/BalanceRecordConstants.java
  15. 3 2
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/interceptor/SwaggerInterceptor.java
  16. 3 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/model/bill/PlatformDailyStatement.java
  17. 3 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/model/bill/PlatformMonthStatement.java
  18. 12 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/model/order/Order.java
  19. 6 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/model/user/UserBalanceRecord.java
  20. 85 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/model/user/WithdrawalHistory.java
  21. 4 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/request/CreateOrderRequest.java
  22. 44 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/request/DaibiTransferSettings.java
  23. 4 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/request/OrderPayRequest.java
  24. 41 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/request/PaymentMoneyToUser.java
  25. 44 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/request/RechargeNotice.java
  26. 41 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/request/TransferNotice.java
  27. 6 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/CartPriceResponse.java
  28. 6 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/HomeRateResponse.java
  29. 12 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/OrderFrontDataResponse.java
  30. 12 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/OrderFrontDetailResponse.java
  31. 5 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/OrderPayResultResponse.java
  32. 3 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/PayConfigResponse.java
  33. 32 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/PaymentMoneyToUserResponse.java
  34. 6 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/PlatformHomeRateResponse.java
  35. 15 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/PlatformOrderAdminDetailResponse.java
  36. 12 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/PlatformOrderPageResponse.java
  37. 3 0
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/PlatformStatementResponse.java
  38. 1 1
      crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/result/UserResultCode.java
  39. 1 0
      crmeb_src/mer_java/crmeb-common/src/main/resources/lib/.cfr
  40. 3 2
      crmeb_src/mer_java/crmeb-front/src/main/java/com/zbkj/front/config/WebConfig.java
  41. 77 0
      crmeb_src/mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/DaiBiController.java
  42. 26 0
      crmeb_src/mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/PayController.java
  43. 27 17
      crmeb_src/mer_java/crmeb-front/src/main/java/com/zbkj/front/service/impl/FrontOrderServiceImpl.java
  44. 30 8
      crmeb_src/mer_java/crmeb-front/src/main/java/com/zbkj/front/service/impl/UserCenterServiceImpl.java
  45. 7 2
      crmeb_src/mer_java/crmeb-front/src/main/resources/application-dev.yml
  46. 20 0
      crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/WithdrawalHistoryDao.java
  47. 2 1
      crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/OrderService.java
  48. 20 3
      crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/PayService.java
  49. 11 2
      crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/CartServiceImpl.java
  50. 14 4
      crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/HomeServiceImpl.java
  51. 21 8
      crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/OrderServiceImpl.java
  52. 197 17
      crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/PayServiceImpl.java
  53. 10 1
      crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/StatisticsTaskServiceImpl.java
  54. 3 3
      crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/UploadServiceImpl.java
  55. 58 28
      crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/util/DaibiUtils.java
  56. 2 1
      crmeb_src/mer_java/crmeb-service/src/main/resources/mapper/order/OrderMapper.xml
  57. 2 1
      crmeb_src/mer_pc/.env.development
  58. 1 1
      crmeb_src/mer_pc/package.json
  59. 332 290
      crmeb_src/mer_pc/pnpm-lock.yaml
  60. 6 2
      crmeb_src/mer_plat_admin/src/components/OrderDetail/index.vue
  61. 2 1
      crmeb_src/mer_plat_admin/src/views/dashboard/components/baseInfo.vue
  62. 3 1
      crmeb_src/mer_plat_admin/src/views/finance/statement/index.vue
  63. 6 4
      crmeb_src/mer_plat_admin/src/views/order/index.vue
  64. 6 0
      crmeb_src/mer_uniapp/App.vue
  65. 75 66
      crmeb_src/mer_uniapp/api/user.js
  66. 1 1
      crmeb_src/mer_uniapp/components/BaseMoney.vue
  67. 1 1
      crmeb_src/mer_uniapp/components/orderGoods/index.vue
  68. 2 2
      crmeb_src/mer_uniapp/config/app.js
  69. 11 10
      crmeb_src/mer_uniapp/config/cache.js
  70. 3 2
      crmeb_src/mer_uniapp/mixins/OrderPay.js
  71. 81 63
      crmeb_src/mer_uniapp/pages.json
  72. 133 79
      crmeb_src/mer_uniapp/pages/goods/order_confirm/index.vue
  73. 33 13
      crmeb_src/mer_uniapp/pages/goods/order_details/index.vue
  74. 5 2
      crmeb_src/mer_uniapp/pages/goods/order_list/index.vue
  75. 1 1
      crmeb_src/mer_uniapp/pages/goods/order_pay_status/index.vue
  76. 9 7
      crmeb_src/mer_uniapp/pages/goods/order_payment/index.vue
  77. 15 3
      crmeb_src/mer_uniapp/pages/order_addcart/order_addcart.vue
  78. 44 3
      crmeb_src/mer_uniapp/pages/users/user_bill/index.vue
  79. 315 87
      crmeb_src/mer_uniapp/pages/users/user_money/index.vue
  80. 1 1
      crmeb_src/mer_uniapp/pages/users/user_payment/index.vue
  81. 492 0
      crmeb_src/mer_uniapp/pages/users/user_withd_slgns/index.vue
  82. BIN
      crmeb_src/mer_uniapp/static/tabBar/2026-01-29_145708_158.png
  83. BIN
      crmeb_src/mer_uniapp/static/tabBar/2026-01-29_161511_590.png
  84. BIN
      crmeb_src/mer_uniapp/static/tabBar/2026-01-29_162016_793.png
  85. BIN
      crmeb_src/mer_uniapp/static/tabBar/2026-01-29_163022_466.png
  86. BIN
      crmeb_src/mer_uniapp/static/tabBar/2026-01-29_165252_059.png
  87. 53 30
      crmeb_src/mer_uniapp/store/modules/app.js
  88. 92 92
      crmeb_src/mer_uniapp/utils/cache.js
  89. 14 2
      crmeb_src/mer_uniapp/utils/index.js

+ 10 - 0
crmeb_src/mer_java/.idea/.gitignore

@@ -0,0 +1,10 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Environment-dependent path to Maven home directory
+/mavenHomeManager.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 27 - 0
crmeb_src/mer_java/.idea/compiler.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <annotationProcessing>
+      <profile name="Maven default annotation processors profile" enabled="true">
+        <sourceOutputDir name="target/generated-sources/annotations" />
+        <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
+        <outputRelativeToContentRoot value="true" />
+        <module name="crmeb-front" />
+        <module name="crmeb-admin" />
+        <module name="crmeb-common" />
+        <module name="crmeb-generate" />
+        <module name="crmeb-service" />
+      </profile>
+    </annotationProcessing>
+  </component>
+  <component name="JavacSettings">
+    <option name="ADDITIONAL_OPTIONS_OVERRIDE">
+      <module name="crmeb" options="-verbose -parameters" />
+      <module name="crmeb-admin" options="-verbose -parameters" />
+      <module name="crmeb-common" options="-verbose -parameters" />
+      <module name="crmeb-front" options="-verbose -parameters" />
+      <module name="crmeb-generate" options="-verbose -parameters" />
+      <module name="crmeb-service" options="-verbose -parameters" />
+    </option>
+  </component>
+</project>

+ 15 - 0
crmeb_src/mer_java/.idea/encodings.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding">
+    <file url="file://$PROJECT_DIR$/crmeb-admin/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/crmeb-common/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/crmeb-common/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/crmeb-front/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/crmeb-generate/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/crmeb-generate/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/crmeb-service/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/crmeb-service/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
+  </component>
+</project>

+ 20 - 0
crmeb_src/mer_java/.idea/jarRepositories.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RemoteRepositoriesConfiguration">
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Central Repository" />
+      <option name="url" value="https://repo.maven.apache.org/maven2" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Maven Central repository" />
+      <option name="url" value="https://repo1.maven.org/maven2" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="jboss.community" />
+      <option name="name" value="JBoss Community repository" />
+      <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
+    </remote-repository>
+  </component>
+</project>

+ 12 - 0
crmeb_src/mer_java/.idea/misc.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="MavenProjectsManager">
+    <option name="originalFiles">
+      <list>
+        <option value="$PROJECT_DIR$/pom.xml" />
+      </list>
+    </option>
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK" />
+</project>

+ 6 - 0
crmeb_src/mer_java/.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
+  </component>
+</project>

+ 8 - 0
crmeb_src/mer_java/crmeb-admin/pom.xml

@@ -87,6 +87,14 @@
                     </nonFilteredFileExtensions>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>9</source>
+                    <target>9</target>
+                </configuration>
+            </plugin>
         </plugins>
 
         <resources>

+ 2 - 0
crmeb_src/mer_java/crmeb-admin/src/main/java/com/zbkj/admin/service/impl/FinanceServiceImpl.java

@@ -481,6 +481,7 @@ public class FinanceServiceImpl implements FinanceService {
             PlatformStatementResponse response = new PlatformStatementResponse();
             response.setId(statement.getId());
             response.setOrderRealIncome(statement.getOrderPayAmount());
+            response.setOrderRealIncomeSl(statement.getOrderPayAmountSl());
             response.setOrderReceivable(statement.getOrderPayAmount().add(statement.getPlatCouponPrice().add(statement.getIntegralPrice())));
             response.setPlatCouponPrice(statement.getPlatCouponPrice());
             response.setIntegralPrice(statement.getIntegralPrice());
@@ -537,6 +538,7 @@ public class FinanceServiceImpl implements FinanceService {
             PlatformStatementResponse response = new PlatformStatementResponse();
             response.setId(statement.getId());
             response.setOrderRealIncome(statement.getOrderPayAmount());
+            response.setOrderRealIncomeSl(statement.getOrderPayAmountSl());
             response.setOrderReceivable(statement.getOrderPayAmount().add(statement.getPlatCouponPrice().add(statement.getIntegralPrice())));
             response.setPlatCouponPrice(statement.getPlatCouponPrice());
             response.setIntegralPrice(statement.getIntegralPrice());

+ 20 - 4
crmeb_src/mer_java/crmeb-admin/src/main/java/com/zbkj/admin/task/daibi/DaibiRateTask.java

@@ -1,9 +1,9 @@
 package com.zbkj.admin.task.daibi;
 
 import cn.hutool.core.date.DateUtil;
-import cn.hutool.http.HttpUtil;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
+import com.zbkj.admin.util.SimpleProxyUtil;
 import com.zbkj.common.constants.SysConfigConstants;
 import com.zbkj.common.utils.RedisUtil;
 import org.slf4j.Logger;
@@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.io.IOException;
 import java.math.BigDecimal;
 
 @Component("DaibiRateTask")
@@ -25,24 +26,39 @@ public class DaibiRateTask {
      * 获取当前代币汇率
      */
     public void getDaibiRate() {
+        SimpleProxyUtil simpleProxyUtil = new SimpleProxyUtil();
         // cron : 0 0 1 * * ?
         logger.info("---DaibiRateTask getDaibiRate------produce Data with fixed rate task: Execution Time - {}", DateUtil.date());
         String url = "https://api.coingecko.com/api/v3/simple/price?ids=origin-lgns&vs_currencies=usd";
-        String res = HttpUtil.get(url);
+
+        String res = null;
+        try {
+            res = simpleProxyUtil.get(url);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
         JSONObject obj = JSONUtil.parseObj(res);
         BigDecimal rate = obj.getJSONObject("origin-lgns").getBigDecimal("usd");
         redisUtil.set(SysConfigConstants.DAIBI_RATE_LGNS_USD, rate);
         logger.info("{}代币汇率: {}", SysConfigConstants.DAIBI_RATE_LGNS_USD, rate);
 
         url = "https://api.coingecko.com/api/v3/simple/price?ids=origin-lgns&vs_currencies=cny";
-        res = HttpUtil.get(url);
+        try {
+            res = simpleProxyUtil.get(url);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
         obj = JSONUtil.parseObj(res);
         rate = obj.getJSONObject("origin-lgns").getBigDecimal("cny");
         redisUtil.set(SysConfigConstants.DAIBI_RATE_LGNS_CNY, rate);
         logger.info("{}代币汇率: {}", SysConfigConstants.DAIBI_RATE_LGNS_CNY, rate);
 
         url = "https://api.coingecko.com/api/v3/simple/price?ids=usd&vs_currencies=cny";
-        res = HttpUtil.get(url);
+        try {
+            res = simpleProxyUtil.get(url);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
         obj = JSONUtil.parseObj(res);
         rate = obj.getJSONObject("usd").getBigDecimal("cny");
         redisUtil.set(SysConfigConstants.DAIBI_RATE_USD_CNY, rate);

+ 77 - 0
crmeb_src/mer_java/crmeb-admin/src/main/java/com/zbkj/admin/util/SimpleProxyUtil.java

@@ -0,0 +1,77 @@
+/**
+ * @author Greg
+ * @date 2026-01-31 17:47
+ * @version 1.0
+ */
+package com.zbkj.admin.util;
+
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContexts;
+import org.apache.http.util.EntityUtils;
+
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+
+
+public class SimpleProxyUtil {
+
+
+    // 配置项(和curl一致)
+    private static final String PROXY_HOST = "47.242.139.80";
+    private static final int PROXY_PORT = 1098;
+    private static final String PROXY_USER = "adroot";
+    private static final String PROXY_PASS = "qaz745861"; // 请确认和curl完全一致(有无末尾的点)
+
+    public static String get(String url) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException, Exception {
+        // 1. 创建SSL上下文(禁用证书验证)
+        SSLContext sslContext = SSLContexts.custom()
+                .loadTrustMaterial((chain, authType) -> true)
+                .build();
+
+        // 2. 创建SSL连接工厂
+        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
+                sslContext,
+                NoopHostnameVerifier.INSTANCE
+        );
+
+        // 3. 创建代理认证凭证
+        CredentialsProvider credsProvider = new BasicCredentialsProvider();
+        credsProvider.setCredentials(
+                new AuthScope(PROXY_HOST, PROXY_PORT), // 精准匹配代理地址和端口
+                new UsernamePasswordCredentials(PROXY_USER, PROXY_PASS)
+        );
+
+        // 4. 创建HttpClient(核心:配置代理+认证)
+        CloseableHttpClient httpClient = HttpClients.custom()
+                .setSSLSocketFactory(sslSocketFactory)
+                .setDefaultCredentialsProvider(credsProvider)
+                .setProxy(new HttpHost(PROXY_HOST, PROXY_PORT)) // 设置HTTP代理
+                .build();
+
+        // 5. 创建GET请求
+        HttpGet httpGet = new HttpGet(url);
+
+        CloseableHttpResponse response = httpClient.execute(httpGet);
+        int statusCode = response.getStatusLine().getStatusCode();
+        if (statusCode == 200) {
+            // 读取响应内容
+            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
+            return result;
+        } else {
+            throw new Exception("请求失败,响应码:" + statusCode + ",原因:" + response.getStatusLine().getReasonPhrase());
+        }
+    }
+}

+ 1 - 1
crmeb_src/mer_java/crmeb-admin/src/main/resources/application-dev.yml

@@ -28,7 +28,7 @@ spring:
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://127.0.0.1:3306/crmeb_b2b2c_v2?characterEncoding=utf-8&useSSL=false&serverTimeZone=GMT+8&allowPublicKeyRetrieval=true
     username: root
-    password: CTJG_86866666
+    password: root
   redis:
     host: 127.0.0.1 #地址
     port: 6379 #端口

+ 82 - 0
crmeb_src/mer_java/crmeb-admin/src/test/java/com/zbkj/admin/SquidProxyHttpClient.java

@@ -0,0 +1,82 @@
+/**
+ * @author Greg
+ * @date 2026-01-31 22:32
+ * @version 1.0
+ */
+package com.zbkj.admin;
+
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContexts;
+import org.apache.http.util.EntityUtils;
+
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * 终极方案:使用Apache HttpClient(项目已依赖)
+ * 完美适配Squid代理认证,解决407问题
+ */
+public class SquidProxyHttpClient {
+
+    // 配置项(和curl一致)
+    private static final String PROXY_HOST = "47.242.139.80";
+    private static final int PROXY_PORT = 1098;
+    private static final String PROXY_USER = "adroot";
+    private static final String PROXY_PASS = "qaz745861"; // 请确认和curl完全一致(有无末尾的点)
+    private static final String TARGET_URL = "https://api.coingecko.com/api/v3/simple/price?ids=origin-lgns&vs_currencies=usd";
+
+    public static String get(String url) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException , Exception{
+        // 1. 创建SSL上下文(禁用证书验证)
+        SSLContext sslContext = SSLContexts.custom()
+                .loadTrustMaterial((chain, authType) -> true)
+                .build();
+
+        // 2. 创建SSL连接工厂
+        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
+                sslContext,
+                NoopHostnameVerifier.INSTANCE
+        );
+
+        // 3. 创建代理认证凭证
+        CredentialsProvider credsProvider = new BasicCredentialsProvider();
+        credsProvider.setCredentials(
+                new AuthScope(PROXY_HOST, PROXY_PORT), // 精准匹配代理地址和端口
+                new UsernamePasswordCredentials(PROXY_USER, PROXY_PASS)
+        );
+
+        // 4. 创建HttpClient(核心:配置代理+认证)
+        CloseableHttpClient httpClient = HttpClients.custom()
+                .setSSLSocketFactory(sslSocketFactory)
+                .setDefaultCredentialsProvider(credsProvider)
+                .setProxy(new HttpHost(PROXY_HOST, PROXY_PORT)) // 设置HTTP代理
+                .build();
+
+        // 5. 创建GET请求
+        HttpGet httpGet = new HttpGet(TARGET_URL);
+
+        CloseableHttpResponse response = httpClient.execute(httpGet);
+        int statusCode = response.getStatusLine().getStatusCode();
+        if (statusCode == 200) {
+            // 读取响应内容
+            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
+            return result;
+        } else {
+            throw new Exception("请求失败,响应码:" + statusCode + ",原因:" + response.getStatusLine().getReasonPhrase());
+        }
+    }
+
+}

+ 24 - 0
crmeb_src/mer_java/crmeb-admin/src/test/java/com/zbkj/admin/StatementTaskTest.java

@@ -0,0 +1,24 @@
+package com.zbkj.admin;
+
+import com.zbkj.admin.task.daibi.DaibiRateTask;
+import com.zbkj.admin.task.statistics.StatementTask;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class StatementTaskTest {
+
+    @Autowired
+    private DaibiRateTask daibiRateTask;
+
+    @Test
+    public void testDailyStatement() {
+        System.out.println("开始执行每日账单任务...");
+        daibiRateTask.getDaibiRate();
+        System.out.println("每日账单任务执行结束。");
+    }
+}

+ 12 - 8
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/constants/BalanceRecordConstants.java

@@ -19,6 +19,8 @@ public class BalanceRecordConstants {
     /** 余额记录类型—扣减 */
     public static final Integer BALANCE_RECORD_TYPE_SUB = 2;
 
+    /** 余额记录关联类型—提现 */
+    public static final String BALANCE_RECORD_LINK_TYPE_WITHDRAW = "withdraw";
     /** 余额记录关联类型—订单 */
     public static final String BALANCE_RECORD_LINK_TYPE_ORDER = "order";
     /** 余额记录关联类型—充值 */
@@ -30,21 +32,23 @@ public class BalanceRecordConstants {
     /** 余额记录关联类型—佣金转余额 */
     public static final String BALANCE_RECORD_LINK_TYPE_SVIP = "svip";
 
+    /** 余额记录备注—提现 */
+    public static final String BALANCE_RECORD_REMARK_WITHDRAW = "用户提现发起成功,扣余额{}sL";
     /** 余额记录备注—用户订单付款成功 */
-    public static final String BALANCE_RECORD_REMARK_ORDER = "用户订单付款成功,扣余额{}元";
+    public static final String BALANCE_RECORD_REMARK_ORDER = "用户订单付款成功,扣余额{}sL";
     /** 余额记录备注—用户订单退款成功 */
-    public static final String BALANCE_RECORD_REMARK_ORDER_REFUND = "用户订单退款成功,返还余额{}";
+    public static final String BALANCE_RECORD_REMARK_ORDER_REFUND = "用户订单退款成功,返还余额{}sL";
     /** 余额记录备注—后台操作添加 */
-    public static final String BALANCE_RECORD_REMARK_SYSTEM_ADD = "后台操作,添加余额{}";
+    public static final String BALANCE_RECORD_REMARK_SYSTEM_ADD = "后台操作,添加余额{}sL";
     /** 余额记录备注—后台操作减少 */
-    public static final String BALANCE_RECORD_REMARK_SYSTEM_SUB = "后台操作,减少余额{}";
+    public static final String BALANCE_RECORD_REMARK_SYSTEM_SUB = "后台操作,减少余额{}sL";
     /** 余额记录备注—充值 */
-    public static final String BALANCE_RECORD_REMARK_RECHARGE = "充值成功,余额增加{}";
+    public static final String BALANCE_RECORD_REMARK_RECHARGE = "充值成功,余额增加{}sL";
     /** 余额记录备注—佣金转余额 */
-    public static final String BALANCE_RECORD_REMARK_BROKERAGE = "佣金转余额成功,添加余额{}";
+    public static final String BALANCE_RECORD_REMARK_BROKERAGE = "佣金转余额成功,添加余额{}sL";
     /** 余额记录备注—充值 */
-    public static final String BALANCE_RECORD_REMARK_PAY_SVIP = "购买SVIP成功,余额赠送{}";
+    public static final String BALANCE_RECORD_REMARK_PAY_SVIP = "购买SVIP成功,余额赠送{}sL";
     /** 余额记录备注—购买svip订单 */
-    public static final String BALANCE_RECORD_REMARK_SVIP_ORDER = "余额购买SVIP成功,扣除余额{}";
+    public static final String BALANCE_RECORD_REMARK_SVIP_ORDER = "余额购买SVIP成功,扣除余额{}sL";
 
 }

+ 3 - 2
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/interceptor/SwaggerInterceptor.java

@@ -6,7 +6,8 @@ import org.springframework.core.io.support.ResourcePatternResolver;
 import org.springframework.util.AntPathMatcher;
 import org.springframework.util.FileCopyUtils;
 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
-import sun.misc.BASE64Decoder;
+
+import java.util.Base64;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -53,7 +54,7 @@ public class SwaggerInterceptor extends HandlerInterceptorAdapter {
         if(check){
             if (authorization != null && authorization.split(" ").length == 2) {
 
-                String userAndPass = new String(new BASE64Decoder().decodeBuffer(authorization.split(" ")[1]));
+                String userAndPass = new String(Base64.getDecoder().decode(authorization.split(" ")[1]));
                 String username = userAndPass.split(":").length == 2 ? userAndPass.split(":")[0] : null;
                 String password = userAndPass.split(":").length == 2 ? userAndPass.split(":")[1] : null;
                 return this.username.equals(username) && this.password.equals(password);

+ 3 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/model/bill/PlatformDailyStatement.java

@@ -36,6 +36,9 @@ public class PlatformDailyStatement implements Serializable {
     @ApiModelProperty(value = "订单支付总金额")
     private BigDecimal orderPayAmount;
 
+    @ApiModelProperty(value = "订单支付总金额SL")
+    private BigDecimal orderPayAmountSl;
+
     @ApiModelProperty(value = "订单支付笔数")
     private Integer totalOrderNum;
 

+ 3 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/model/bill/PlatformMonthStatement.java

@@ -36,6 +36,9 @@ public class PlatformMonthStatement implements Serializable {
     @ApiModelProperty(value = "订单支付总金额")
     private BigDecimal orderPayAmount;
 
+    @ApiModelProperty(value = "订单支付总金额SL")
+    private BigDecimal orderPayAmountSl;
+
     @ApiModelProperty(value = "订单支付笔数")
     private Integer totalOrderNum;
 

+ 12 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/model/order/Order.java

@@ -162,4 +162,16 @@ public class Order implements Serializable {
 
     @ApiModelProperty(value = "预约订单取消预约小时数")
     private Integer cancelServiceOrderHour;
+
+    @ApiModelProperty(value = "汇率(RmbToSl)")
+    private BigDecimal rate;
+
+    @ApiModelProperty(value = "汇率差(total_price_reat-pay_fee_sl)")
+    private BigDecimal rateDiff;
+
+    @ApiModelProperty(value = "SL订单金额")
+    private BigDecimal totalPriceReat;
+
+    @ApiModelProperty(value = "rmb算出来的订单金额/汇率")
+    private BigDecimal payFeeSl;
 }

+ 6 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/model/user/UserBalanceRecord.java

@@ -1,6 +1,7 @@
 package com.zbkj.common.model.user;
 
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.annotations.ApiModel;
@@ -58,5 +59,10 @@ public class UserBalanceRecord implements Serializable {
     @ApiModelProperty(value = "添加时间")
     private Date createTime;
 
+    @TableField(exist = false)
+    @ApiModelProperty(value = "提现状态(只有在提现的时候会在数据中加载)")
+    private Integer withdrawStatus;
 
+    @ApiModelProperty(value = "操作时汇率")
+    private BigDecimal rate;
 }

+ 85 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/model/user/WithdrawalHistory.java

@@ -0,0 +1,85 @@
+package com.zbkj.common.model.user;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Value;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * <p>
+ * 用户表
+ * </p>
+ *
+ * @author HZW
+ * @since 2022-07-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("eb_withdrawal_history")
+@ApiModel(value = "WithdrawalHistory对象", description = "用户提现记录")
+public class WithdrawalHistory implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "用户id")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "用户ID")
+    private Integer uid;
+
+    @ApiModelProperty(value = "提现汇率")
+    private BigDecimal rate;
+
+    @ApiModelProperty(value = "提现代币数量")
+    private BigDecimal amount;
+
+    @ApiModelProperty(value = "合约币种{lgns/slgns}")
+    private String tokenType;
+
+    @ApiModelProperty(value = "提现地址")
+    private String address;
+
+    @ApiModelProperty(value = "合约地址")
+    private String token;
+
+    @ApiModelProperty(value = "提现交易ID")
+    private String transactionId;
+
+    @ApiModelProperty(value = "扣款rmb")
+    private BigDecimal amountToRmb;
+
+    @ApiModelProperty(value = "1成功,2失败,0处理中")
+    private Integer status;
+
+    @ApiModelProperty(value = "是否删除0否1是")
+    private Integer isDel;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    @ApiModelProperty(value = "修改时间")
+    private Date updateTime;
+
+    @ApiModelProperty(value = "调用转账时的接口msg")
+    private String remark;
+
+    @ApiModelProperty(value = "区块链过来的不知道是什么")
+    private String txHash;
+
+    @ApiModelProperty(value = "手续费SL")
+    private BigDecimal handlingFeeSl;
+
+    @ApiModelProperty(value = "手续费RMB")
+    private BigDecimal handlingFeeRmb;
+}

+ 4 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/request/CreateOrderRequest.java

@@ -11,6 +11,7 @@ import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
 import java.io.Serializable;
+import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -65,4 +66,7 @@ public class CreateOrderRequest implements Serializable {
 
     @ApiModelProperty(value = "预约联系电话")
     private String reservationPhone;
+
+    @ApiModelProperty(value = "其他附加参数")
+    private HashMap<String, Object> orderInfoVo;
 }

+ 44 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/request/DaibiTransferSettings.java

@@ -0,0 +1,44 @@
+package com.zbkj.common.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 提现代币到用户的钱包
+ *
+ * @author Greg
+ * @version 1.0.0
+ * @Date 2026/1/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "DaibiTransferSettings", description = "代币设置")
+public class DaibiTransferSettings implements Serializable {
+
+    @ApiModelProperty(value = "交易ID")
+    @JsonProperty("withdrawal_wallet_address")
+    private String withdrawalWalletAddress;
+
+    @ApiModelProperty(value = "提现地址")
+    @JsonProperty("withdrawal_private_key")
+    private String withdrawalPrivateKey;
+
+    @ApiModelProperty(value = "状态")
+    @JsonProperty("collect_wallet_address")
+    private String collectWalletAddress;
+
+    @ApiModelProperty(value = "错误内容")
+    @JsonProperty("notify_deposit_url")
+    private String notifyDepositUrl;
+
+    @ApiModelProperty(value = "错误内容")
+    @JsonProperty("notify_withdrawal_url")
+    private String notifyWithdrawalUrl;
+}

+ 4 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/request/OrderPayRequest.java

@@ -8,6 +8,7 @@ import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
 import javax.validation.constraints.NotBlank;
+import java.math.BigDecimal;
 
 /**
  * 支付订单参数
@@ -46,4 +47,7 @@ public class OrderPayRequest {
 
     @ApiModelProperty(value = "下单时小程序的场景值")
     private Integer scene;
+
+    @ApiModelProperty(value = "支付总金额Sl")
+    private BigDecimal totalPriceReat;
 }

+ 41 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/request/PaymentMoneyToUser.java

@@ -0,0 +1,41 @@
+package com.zbkj.common.request;
+
+import com.zbkj.common.annotation.StringContains;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 提现代币到用户的钱包
+ *
+ * @author Greg
+ * @version 1.0.0
+ * @Date 2026/1/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "PaymentMoneyToUser", description = "提现代币到用户")
+public class PaymentMoneyToUser implements Serializable {
+
+    private static final long serialVersionUID = 5243709857679894593L;
+
+    @ApiModelProperty(value = "提现数量")
+    @NotNull(message = "代币数量不能为空")
+    private BigDecimal amount;
+
+    @ApiModelProperty(value = "提现地址")
+    @NotBlank(message = "提现地址不能为空")
+    private String address;
+
+    @ApiModelProperty(value = "提现时汇率")
+    @NotNull(message = "汇率不能为空")
+    private BigDecimal rate;
+}

+ 44 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/request/RechargeNotice.java

@@ -0,0 +1,44 @@
+package com.zbkj.common.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 提现代币到用户的钱包
+ *
+ * @author Greg
+ * @version 1.0.0
+ * @Date 2026/1/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "RechargeNotice", description = "充值通知")
+public class RechargeNotice implements Serializable {
+
+    @ApiModelProperty(value = "可当作充值唯一标识")
+    @JsonProperty("event_id")
+    private String eventId;
+
+    @ApiModelProperty(value = "提现地址")
+    @JsonProperty("tx_hash")
+    private String txHash;
+
+    @ApiModelProperty(value = "地址")
+    private String address;
+
+    @ApiModelProperty(value = "充值代币数量")
+    private BigDecimal amount;
+
+    @ApiModelProperty(value = "代币合约地址")
+    private String token;
+}

+ 41 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/request/TransferNotice.java

@@ -0,0 +1,41 @@
+package com.zbkj.common.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 提现代币到用户的钱包
+ *
+ * @author Greg
+ * @version 1.0.0
+ * @Date 2026/1/29
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "TransferNotice", description = "转账通知")
+public class TransferNotice implements Serializable {
+
+    @ApiModelProperty(value = "交易ID")
+    @JsonProperty("request_id")
+    private String requestId;
+
+    @ApiModelProperty(value = "提现地址")
+    @JsonProperty("tx_hash")
+    private String txHash;
+
+    @ApiModelProperty(value = "状态")
+    private Boolean success;
+
+    @ApiModelProperty(value = "错误内容")
+    private String message;
+}

+ 6 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/CartPriceResponse.java

@@ -8,6 +8,9 @@ import lombok.experimental.Accessors;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 
 /**
  * 购物车价格响应对象
@@ -46,4 +49,7 @@ public class CartPriceResponse implements Serializable {
 
     @ApiModelProperty(value = "总计金额")
     private BigDecimal totalPrice;
+
+    @ApiModelProperty(value = "计算详情")
+    private List<HashMap<String, Object>> details;
 }

+ 6 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/HomeRateResponse.java

@@ -32,9 +32,15 @@ public class HomeRateResponse implements Serializable {
     @ApiModelProperty(value = "今日销售额")
     private BigDecimal sales;
 
+    @ApiModelProperty(value = "今日销售额SL")
+    private BigDecimal salesReat;
+
     @ApiModelProperty(value = "昨日销售额")
     private BigDecimal yesterdaySales;
 
+    @ApiModelProperty(value = "昨日销售额SL")
+    private BigDecimal yesterdaySalesReat;
+
     @ApiModelProperty(value = "今日订单量")
     private Integer orderNum;
 

+ 12 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/OrderFrontDataResponse.java

@@ -115,4 +115,16 @@ public class OrderFrontDataResponse implements Serializable {
 
     @ApiModelProperty(value = "预约订单取消预约小时数")
     private Integer cancelServiceOrderHour;
+
+    @ApiModelProperty(value = "汇率(RmbToSl)")
+    private BigDecimal rate;
+
+    @ApiModelProperty(value = "汇率差(total_price_reat-pay_fee_sl)")
+    private BigDecimal rateDiff;
+
+    @ApiModelProperty(value = "SL订单金额")
+    private BigDecimal totalPriceReat;
+
+    @ApiModelProperty(value = "rmb算出来的订单金额/汇率")
+    private BigDecimal payFeeSl;
 }

+ 12 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/OrderFrontDetailResponse.java

@@ -132,4 +132,16 @@ public class OrderFrontDetailResponse implements Serializable {
 
     @ApiModelProperty(value = "预约订单取消预约标识")
     private Boolean isCancelServiceOrder = false;
+
+    @ApiModelProperty(value = "汇率(RmbToSl)")
+    private BigDecimal rate;
+
+    @ApiModelProperty(value = "汇率差(total_price_reat-pay_fee_sl)")
+    private BigDecimal rateDiff;
+
+    @ApiModelProperty(value = "SL订单金额")
+    private BigDecimal totalPriceReat;
+
+    @ApiModelProperty(value = "rmb算出来的订单金额/汇率")
+    private BigDecimal payFeeSl;
 }

+ 5 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/OrderPayResultResponse.java

@@ -8,6 +8,8 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
+import java.math.BigDecimal;
+
 /**
  * 订单支付结果 Response
  *  +----------------------------------------------------------------------
@@ -53,4 +55,7 @@ public class OrderPayResultResponse {
     private String accountAddress;
 
     private String money;
+
+    @ApiModelProperty(value = "支付总金额Sl")
+    private BigDecimal totalPriceReat;
 }

+ 3 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/PayConfigResponse.java

@@ -41,4 +41,7 @@ public class PayConfigResponse implements Serializable {
 
     @ApiModelProperty(value = "用户余额")
     private BigDecimal userBalance;
+
+    @ApiModelProperty(value = "用户余额")
+    private BigDecimal userBalanceRate;
 }

+ 32 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/PaymentMoneyToUserResponse.java

@@ -0,0 +1,32 @@
+package com.zbkj.common.response;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "PaymentMoneyToUserResponse", description = "提现代币到钱包")
+public class PaymentMoneyToUserResponse implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "提现结果")
+    private Boolean status;
+
+    @ApiModelProperty(value = "提现地址")
+    private String address;
+
+    @ApiModelProperty(value = "提现代币个数")
+    private BigDecimal amount;
+
+    @ApiModelProperty(value = "提现失败的时候的描述")
+    private String remark;
+}

+ 6 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/PlatformHomeRateResponse.java

@@ -35,6 +35,12 @@ public class PlatformHomeRateResponse implements Serializable {
     @ApiModelProperty(value = "昨日销售额")
     private BigDecimal yesterdaySales = BigDecimal.ZERO;
 
+    @ApiModelProperty(value = "今日销售额SL")
+    private BigDecimal salesReat = BigDecimal.ZERO;
+
+    @ApiModelProperty(value = "昨日销售额SL")
+    private BigDecimal yesterdaySalesReat = BigDecimal.ZERO;
+
     @ApiModelProperty(value = "今日访问量")
     private Integer pageviews = 0;
 

+ 15 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/PlatformOrderAdminDetailResponse.java

@@ -198,4 +198,19 @@ public class PlatformOrderAdminDetailResponse implements Serializable {
 
     @ApiModelProperty(value = "核销时间")
     private Date verifyTime;
+
+
+
+    @ApiModelProperty(value = "汇率(RmbToSl)")
+    private BigDecimal rate;
+
+    @ApiModelProperty(value = "汇率差(total_price_reat-pay_fee_sl)")
+    private BigDecimal rateDiff;
+
+    @ApiModelProperty(value = "SL订单金额")
+    private BigDecimal totalPriceReat;
+
+    @ApiModelProperty(value = "rmb算出来的订单金额/汇率")
+    private BigDecimal payFeeSl;
+
 }

+ 12 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/PlatformOrderPageResponse.java

@@ -86,4 +86,16 @@ public class PlatformOrderPageResponse implements Serializable {
 
     @ApiModelProperty(value = "订单商品已退款总数")
     private Integer refundNum = 0;
+
+    @ApiModelProperty(value = "汇率(RmbToSl)")
+    private BigDecimal rate;
+
+    @ApiModelProperty(value = "汇率差(total_price_reat-pay_fee_sl)")
+    private BigDecimal rateDiff;
+
+    @ApiModelProperty(value = "SL订单金额")
+    private BigDecimal totalPriceReat;
+
+    @ApiModelProperty(value = "rmb算出来的订单金额/汇率")
+    private BigDecimal payFeeSl;
 }

+ 3 - 0
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/response/PlatformStatementResponse.java

@@ -30,6 +30,9 @@ public class PlatformStatementResponse {
     @ApiModelProperty(value = "订单实收")
     private BigDecimal orderRealIncome;
 
+    @ApiModelProperty(value = "订单实收Sl")
+    private BigDecimal orderRealIncomeSl;
+
     @ApiModelProperty(value = "订单应收")
     private BigDecimal orderReceivable;
 

+ 1 - 1
crmeb_src/mer_java/crmeb-common/src/main/java/com/zbkj/common/result/UserResultCode.java

@@ -22,8 +22,8 @@ public enum UserResultCode implements BusinessExceptionAssert {
     USER_PHONE_EXIST(8107, "用户手机号已存在"),
     USER_LOGOFF_FAILED(8108, "用户注销失败"),
     USER_NOT_COLLECT_MERCHANT(8109, "用户未收藏商户"),
+    AMOUNT_ZERO(8111,"提现代币不能小于0"),
     USER_BALANCE_INSUFFICIENT(8110, "用户余额不足"),
-
     USER_ADDRESS_NOT_EXIST(8201, "用户地址不存在"),
     USER_ADDRESS_CREATE_FAILED(8202, "用户地址创建失败"),
 

+ 1 - 0
crmeb_src/mer_java/crmeb-common/src/main/resources/lib/.cfr

@@ -0,0 +1 @@
+1769830230693

+ 3 - 2
crmeb_src/mer_java/crmeb-front/src/main/java/com/zbkj/front/config/WebConfig.java

@@ -51,8 +51,8 @@ public class WebConfig implements WebMvcConfigurer {
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
         //添加token拦截器
-        //addPathPatterns添加需要拦截的命名空间;
-        //excludePathPatterns添加排除拦截命名空间
+        // addPathPatterns 添加需要拦截的命名空间;
+        // excludePathPatterns 添加排除拦截命名空间
 
         //前端用户登录token
         registry.addInterceptor(frontTokenInterceptor()).
@@ -76,6 +76,7 @@ public class WebConfig implements WebMvcConfigurer {
                 excludePathPatterns("/api/front/login/wechat/pc").
                 excludePathPatterns("/api/front/login/pc/wechat/public/agree/info").
                 excludePathPatterns("/api/front/city/**").
+                excludePathPatterns("/api/front/daibi/v1/**").
                 excludePathPatterns("/api/front/agreement/**").
                 excludePathPatterns("/api/front/merchant/search/list").
                 excludePathPatterns("/api/front/merchant/street").

+ 77 - 0
crmeb_src/mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/DaiBiController.java

@@ -0,0 +1,77 @@
+package com.zbkj.front.controller;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.zbkj.common.request.DaibiTransferSettings;
+import com.zbkj.common.request.RechargeNotice;
+import com.zbkj.common.request.TransferNotice;
+import com.zbkj.common.result.CommonResult;
+import com.zbkj.service.service.PayService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 代币回调接口 Greg 2026/1/30
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+@Slf4j
+@RestController
+@RequestMapping("api/front/daibi/v1")
+@Api(tags = "代币回调接口")
+public class DaiBiController {
+
+    @Autowired
+    private PayService payService;
+
+    @ApiOperation(value = "充值通知")
+    @RequestMapping(value = "/recharge/notice", method = RequestMethod.POST)
+    public void rechargeNotice(@RequestBody RechargeNotice rechargeNotice) {
+        // 目前没有这个需求 ,暂时不写
+        // 已经在这儿写了 https://play.nanodreamtech.com/api/publicly/payment/callback/daibi/pay
+    }
+
+    @ApiOperation(value = "转账通知")
+    @RequestMapping(value = "/transfer/notice", method = RequestMethod.POST)
+    public void transferNotice(@RequestBody TransferNotice transferNotice) {
+        payService.transferNotice(transferNotice);
+    }
+
+
+    @ApiOperation(value = "转账通知")
+    @RequestMapping(value = "/transfer/settings", method = RequestMethod.POST)
+    public JSONObject transferSettings(@RequestBody DaibiTransferSettings daibiTransferSettings) {
+        return payService.transferSettings(daibiTransferSettings);
+        /**
+         * Greg 2026-01-30
+         * 这是请求设置的时候的参数
+         * 请求参数
+         {
+             "withdrawal_wallet_address":"0x3CC51C594bAe6C1837c12e24C3C2805E18eA2682",
+             "withdrawal_private_key":"0xe1075e1333ec60240dbfeaf7bf7e290adcb439fb41a4205898a0bae595c0f21d",
+             "collect_wallet_address":"0xA1538805C0F09600CE03E0807bAd84299c0A9Cc6",
+             "notify_deposit_url":"https://play.nanodreamtech.com/api/publicly/payment/callback/daibi/pay",
+             "notify_withdrawal_url":"https://play.nanodreamtech.com/api/front/daibi/v1/transfer/notice"
+         }
+         * 响应参数
+         * "data": {
+         *     "code": "OK",
+         *     "message": ""
+         * }
+         *
+         */
+    }
+}
+
+
+

+ 26 - 0
crmeb_src/mer_java/crmeb-front/src/main/java/com/zbkj/front/controller/PayController.java

@@ -1,10 +1,16 @@
 package com.zbkj.front.controller;
 
+import com.alibaba.fastjson.JSONObject;
+import com.zbkj.common.model.user.WithdrawalHistory;
+import com.zbkj.common.page.CommonPage;
 import com.zbkj.common.request.OrderPayRequest;
+import com.zbkj.common.request.PageParamRequest;
+import com.zbkj.common.request.PaymentMoneyToUser;
 import com.zbkj.common.request.WechatPaymentQueryRequest;
 import com.zbkj.common.response.CashierInfoResponse;
 import com.zbkj.common.response.OrderPayResultResponse;
 import com.zbkj.common.response.PayConfigResponse;
+import com.zbkj.common.response.PaymentMoneyToUserResponse;
 import com.zbkj.common.result.CommonResult;
 import com.zbkj.service.service.PayService;
 import io.swagger.annotations.Api;
@@ -14,6 +20,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 /**
  * 支付控制器
  * +----------------------------------------------------------------------
@@ -70,4 +78,22 @@ public class PayController {
     public CommonResult<Boolean> queryWechatPaymentResult(@Validated WechatPaymentQueryRequest request) {
         return CommonResult.success(payService.queryWechatPaymentResult(request));
     }
+
+    @ApiOperation(value = "提现Sl到个人钱包")
+    @RequestMapping(value = "/payment/money/to/user", method = RequestMethod.POST)
+    public CommonResult<PaymentMoneyToUserResponse> paymentMoneyToUser(@RequestBody @Validated PaymentMoneyToUser request) {
+        return CommonResult.success(payService.paymentMoneyToUserResult(request));
+    }
+
+    @ApiOperation(value = "提现记录查询")
+    @RequestMapping(value = "/payment/money/to/user/list", method = RequestMethod.POST)
+    public CommonResult<CommonPage<WithdrawalHistory>> paymentMoneyToUserList(PageParamRequest pageParamRequest) {
+        return CommonResult.success(CommonPage.restPage(payService.paymentMoneyToUserList(pageParamRequest)));
+    }
+
+    @ApiOperation(value = "提现次数查询")
+    @RequestMapping(value = "/payment/money/to/user/number",method = RequestMethod.POST)
+    public CommonResult<JSONObject> paymentMoneyToUserNumber(){
+        return CommonResult.success(payService.paymentMoneyToUserNumber());
+    }
 }

+ 27 - 17
crmeb_src/mer_java/crmeb-front/src/main/java/com/zbkj/front/service/impl/FrontOrderServiceImpl.java

@@ -169,6 +169,7 @@ public class FrontOrderServiceImpl implements FrontOrderService {
 
     /**
      * 预下单V1.7
+     *
      * @param request 预下单请求参数
      * @return PreOrderResponse
      */
@@ -275,16 +276,17 @@ public class FrontOrderServiceImpl implements FrontOrderService {
 
     private OrderNoResponse createPreOrderResponse(Integer userId, PreOrderInfoVo preOrderInfoVo) {
         // 拼团下单参数验证
-        if(preOrderInfoVo.getType().equals(OrderConstants.ORDER_TYPE_PITUAN)){
+        if (preOrderInfoVo.getType().equals(OrderConstants.ORDER_TYPE_PITUAN)) {
             List<PreMerchantOrderVo> merchantOrderVoList = preOrderInfoVo.getMerchantOrderVoList();
             for (PreMerchantOrderVo preMerchantOrderVo : merchantOrderVoList) {
                 List<PreOrderInfoDetailVo> orderInfoList = preMerchantOrderVo.getOrderInfoList();
                 for (PreOrderInfoDetailVo ov : orderInfoList) {
-                    if(ObjectUtil.isEmpty(ov.getGroupBuyActivityId())) throw new CrmebException("拼团活动ID 不能为空");
+                    if (ObjectUtil.isEmpty(ov.getGroupBuyActivityId())) throw new CrmebException("拼团活动ID 不能为空");
                     // 判断该当前用户时候购买过!会在初次打开后,在分享界面没法后买状态,但流程已经到购买状态,所以需要判断
                     List<GroupBuyUser> groupBuyUsers = groupBuyUserService.getCurrentGroupBuyActivityRecordListByUserId(
                             userId, ov.getGroupBuyActivityId(), ov.getGroupBuyRecordId(), GroupBuyRecordEnum.GROUP_BUY_RECORD_ENUM_STATUS_INIT.getCode());
-                    if(ov.getGroupBuyRecordId()>0 && !groupBuyUsers.isEmpty()) throw new CrmebException("当前拼团已经参与过");
+                    if (ov.getGroupBuyRecordId() > 0 && !groupBuyUsers.isEmpty())
+                        throw new CrmebException("当前拼团已经参与过");
                 }
             }
         }
@@ -1238,9 +1240,14 @@ public class FrontOrderServiceImpl implements FrontOrderService {
         }
         List<PreMerchantOrderVo> merchantOrderVoList = orderInfoVo.getMerchantOrderVoList();
 
+        HashMap<String, Object> OrderInfoData = orderRequest.getOrderInfoVo();
         // 平台订单
         Order order = new Order();
         String orderNo = CrmebUtil.getOrderNo(OrderConstants.ORDER_PREFIX_PLATFORM);
+        order.setRate(new BigDecimal(OrderInfoData.get("rate").toString()));
+        order.setRateDiff(new BigDecimal(OrderInfoData.get("reatDiff").toString()));
+        order.setTotalPriceReat(new BigDecimal(OrderInfoData.get("totalPriceReat").toString()));
+        order.setPayFeeSl(new BigDecimal(OrderInfoData.get("payFeeSl").toString()));
         order.setOrderNo(orderNo);
         order.setMerId(0);
         order.setUid(user.getId());
@@ -1558,7 +1565,7 @@ public class FrontOrderServiceImpl implements FrontOrderService {
         // 设置自动过期时间 2025-02-11
         Integer orderCancelTimeMinute = crmebConfig.getOrderCancelTime();
         DateTime expirationTime = DateUtil.offset(order.getCreateTime(), DateField.MINUTE, crmebConfig.getOrderCancelTime());
-        Long expireTime =  (long) orderCancelTimeMinute * 60;
+        Long expireTime = (long) orderCancelTimeMinute * 60;
         redisUtil.set(StrUtil.format(RedisConstants.ORDER_EXPIRE_TIME, order.getOrderNo()), expirationTime.toString(), expireTime);
 
         OrderNoResponse response = new OrderNoResponse();
@@ -1786,6 +1793,7 @@ public class FrontOrderServiceImpl implements FrontOrderService {
 
     /**
      * 撤销退款单
+     *
      * @param refundOrderNo 退款单号
      */
     @Override
@@ -1795,6 +1803,7 @@ public class FrontOrderServiceImpl implements FrontOrderService {
 
     /**
      * 订单列表(v1.4.0)
+     *
      * @param request 搜索参数
      * @return PageInfo
      */
@@ -1839,20 +1848,20 @@ public class FrontOrderServiceImpl implements FrontOrderService {
                 }
             }
             // 在次添加拼团订单信息
-            if(order.getType().equals(OrderConstants.ORDER_TYPE_PITUAN)){
+            if (order.getType().equals(OrderConstants.ORDER_TYPE_PITUAN)) {
                 GroupBuyUser currentGroupBuyUser = groupBuyUserService.getByOrderNo(order.getOrderNo());
-                if(ObjectUtil.isNotNull(currentGroupBuyUser) && currentGroupBuyUser.getId() > 0){
+                if (ObjectUtil.isNotNull(currentGroupBuyUser) && currentGroupBuyUser.getId() > 0) {
                     GroupBuyRecord currentGroupBuyRecord = groupBuyRecordService.getById(currentGroupBuyUser.getGroupRecordId());
                     GroupBuyActivitySku currentSku = null;
                     GroupBuyActivityRecordForFrontShareUse groupBuyActivityRecord = new GroupBuyActivityRecordForFrontShareUse();
-                    if(ObjectUtil.isNotNull(currentGroupBuyRecord)){
+                    if (ObjectUtil.isNotNull(currentGroupBuyRecord)) {
                         currentSku = groupBuyActivitySkuService.getByAttrId(currentGroupBuyUser.getGroupActivityId(), currentGroupBuyRecord.getSkuid());
                         groupBuyActivityRecord.setBuyingCountNum(currentGroupBuyRecord.getBuyingCountNum());
                         groupBuyActivityRecord.setYetBuyingNum(currentGroupBuyRecord.getYetBuyingNum());
                     }
-                    if(ObjectUtil.isNull(currentSku)){ //这里有可能在购买后,管理端删除基础商品的sku后,关联操作拼团sku后导致这里查询不到,拼团价为null的情况下 前端不予生成拼团码
+                    if (ObjectUtil.isNull(currentSku)) { //这里有可能在购买后,管理端删除基础商品的sku后,关联操作拼团sku后导致这里查询不到,拼团价为null的情况下 前端不予生成拼团码
                         groupBuyActivityRecord.setActivePrice(null);
-                    }else{
+                    } else {
                         groupBuyActivityRecord.setActivePrice(currentSku.getActivePrice());
                     }
                     groupBuyActivityRecord.setGroupActivityId(currentGroupBuyUser.getGroupActivityId());
@@ -1872,6 +1881,7 @@ public class FrontOrderServiceImpl implements FrontOrderService {
 
     /**
      * 取消预约服务订单
+     *
      * @param orderNo 订单号
      */
     @Override
@@ -1971,10 +1981,10 @@ public class FrontOrderServiceImpl implements FrontOrderService {
                         dataResponse.setExpand("");
                         dataResponse.setCardSecretIds("");
                     } else if (order.getSecondType().equals(OrderConstants.ORDER_SECOND_TYPE_CDKEY)) {
-                            String cardSecretIds = d.getCardSecretIds();
-                            List<Integer> cardSecretIdList = CrmebUtil.stringToArray(cardSecretIds);
-                            List<CardSecret> cardSecretList = cardSecretService.findByIds(cardSecretIdList);
-                            dataResponse.setCardSecretList(cardSecretList);
+                        String cardSecretIds = d.getCardSecretIds();
+                        List<Integer> cardSecretIdList = CrmebUtil.stringToArray(cardSecretIds);
+                        List<CardSecret> cardSecretList = cardSecretService.findByIds(cardSecretIdList);
+                        dataResponse.setCardSecretList(cardSecretList);
                     }
                 }
                 return dataResponse;
@@ -2122,11 +2132,11 @@ public class FrontOrderServiceImpl implements FrontOrderService {
             redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AFTER_CANCEL_BY_USER, order.getOrderNo());
         }
         // 处理拼团的取消订单逻辑
-        if(order.getType().equals(OrderConstants.ORDER_TYPE_PITUAN)){
+        if (order.getType().equals(OrderConstants.ORDER_TYPE_PITUAN)) {
             List<OrderDetail> ods = orderDetailService.getByOrderNo(order.getOrderNo());
             for (OrderDetail od : ods) {
-                GroupBuyActivitySku groupBuyActivitySku = groupBuyActivitySkuService.getByAttrId(od.getGroupBuyActivityId(),od.getAttrValueId());
-                groupBuyActivitySkuService.rollBackSKUStock(order,groupBuyActivitySku.getGroupActivityId(), od.getAttrValueId(), od.getPayNum());
+                GroupBuyActivitySku groupBuyActivitySku = groupBuyActivitySkuService.getByAttrId(od.getGroupBuyActivityId(), od.getAttrValueId());
+                groupBuyActivitySkuService.rollBackSKUStock(order, groupBuyActivitySku.getGroupActivityId(), od.getAttrValueId(), od.getPayNum());
             }
 
         }
@@ -3048,7 +3058,7 @@ public class FrontOrderServiceImpl implements FrontOrderService {
             DateTime dateTime = DateUtil.parse(reservationDate);
             DateTime startDate = DateUtil.beginOfDay(DateUtil.parse(reservationDateStartDateStr));
             DateTime endDate = DateUtil.endOfDay(DateUtil.parse(reservationDateEndDateStr));
-            int week = dateTime.dayOfWeek()== 1  ?  7 : dateTime.dayOfWeek() - 1;
+            int week = dateTime.dayOfWeek() == 1 ? 7 : dateTime.dayOfWeek() - 1;
             boolean in = DateUtil.isIn(dateTime, startDate, endDate);
             if (!in) {
                 throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "预约日期有误,请重新选择");

+ 30 - 8
crmeb_src/mer_java/crmeb-front/src/main/java/com/zbkj/front/service/impl/UserCenterServiceImpl.java

@@ -4,7 +4,10 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import com.zbkj.common.constants.*;
 import com.zbkj.common.exception.CrmebException;
@@ -14,10 +17,7 @@ import com.zbkj.common.model.record.BrowseRecord;
 import com.zbkj.common.model.reservation.MerchantServiceStaff;
 import com.zbkj.common.model.sgin.UserSignRecord;
 import com.zbkj.common.model.system.SystemUserLevel;
-import com.zbkj.common.model.user.User;
-import com.zbkj.common.model.user.UserBalanceRecord;
-import com.zbkj.common.model.user.UserExperienceRecord;
-import com.zbkj.common.model.user.UserIntegralRecord;
+import com.zbkj.common.model.user.*;
 import com.zbkj.common.page.CommonPage;
 import com.zbkj.common.request.PageParamRequest;
 import com.zbkj.common.response.*;
@@ -27,6 +27,7 @@ import com.zbkj.common.utils.CrmebDateUtil;
 import com.zbkj.common.utils.CrmebUtil;
 import com.zbkj.front.service.FrontOrderService;
 import com.zbkj.front.service.UserCenterService;
+import com.zbkj.service.dao.WithdrawalHistoryDao;
 import com.zbkj.service.service.MerchantEmployeeService;
 import com.zbkj.service.dao.UserDao;
 import com.zbkj.service.service.*;
@@ -35,10 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -90,6 +88,8 @@ public class UserCenterServiceImpl extends ServiceImpl<UserDao, User> implements
     private MerchantEmployeeService merchantEmployeeService;
     @Autowired
     private MerchantServiceStaffService merchantServiceStaffService;
+    @Autowired
+    private WithdrawalHistoryDao withdrawalHistoryDao;
 
 
     /**
@@ -246,9 +246,31 @@ public class UserCenterServiceImpl extends ServiceImpl<UserDao, User> implements
         if (CollUtil.isEmpty(recordList)) {
             return CommonPage.copyPageInfo(pageInfo, CollUtil.newArrayList());
         }
+        List<String> withdraw = new ArrayList<>();
+        recordList.forEach(record -> {
+            if(record.getLinkType().equals(BalanceRecordConstants.BALANCE_RECORD_LINK_TYPE_WITHDRAW)){
+                withdraw.add(record.getLinkId());
+            }
+        });
+        HashMap<String,WithdrawalHistory> withdrawalHistoryMap ;
+        if (CollUtil.isNotEmpty(withdraw)){
+            LambdaUpdateWrapper<WithdrawalHistory> wrapper = new LambdaUpdateWrapper<>();
+            wrapper.in(WithdrawalHistory::getTransactionId, withdraw);
+            withdrawalHistoryMap = withdrawalHistoryDao.selectList(wrapper).stream().collect(Collectors.toMap(
+                    WithdrawalHistory::getTransactionId,
+                    item -> item,
+                    (existing, replacement) -> existing,
+                    HashMap::new
+            ));
+        } else {
+            withdrawalHistoryMap = null;
+        }
         // 获取年-月
         Map<String, List<UserBalanceRecord>> map = CollUtil.newHashMap();
         recordList.forEach(i -> {
+            if(i.getLinkType().equals(BalanceRecordConstants.BALANCE_RECORD_LINK_TYPE_WITHDRAW)){
+                i.setWithdrawStatus(withdrawalHistoryMap.get(i.getLinkId()).getStatus());
+            }
             String month = StrUtil.subPre(CrmebDateUtil.dateToStr(i.getCreateTime(), DateConstants.DATE_FORMAT), 7);
             if (map.containsKey(month)) {
                 map.get(month).add(i);

+ 7 - 2
crmeb_src/mer_java/crmeb-front/src/main/resources/application-dev.yml

@@ -10,6 +10,7 @@ crmeb:
   activityStyleCachedTime: 10 #活动边框缓存周期 秒为单位,生产环境适当5-10分钟即可
   selectProductLimit: 100 # 商品选择 指定商品上线
   productTagCacheMinutes: 10 # 商品标签缓存分钟数
+  orderCancelTime: 30 # 订单支付取消时间,单位分钟
 
 server:
   port: 20810
@@ -24,7 +25,7 @@ spring:
     driver-class-name: com.mysql.cj.jdbc.Driver
     url: jdbc:mysql://127.0.0.1:3306/crmeb_b2b2c_v2?characterEncoding=utf-8&useSSL=false&serverTimeZone=GMT+8&allowPublicKeyRetrieval=true
     username: root
-    password: CTJG_86866666
+    password: root
   redis:
     host: 127.0.0.1 #地址
     port: 6379 #端口
@@ -37,4 +38,8 @@ spring:
         max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
         max-idle: 10 # 连接池中的最大空闲连接
         min-idle: 0 # 连接池中的最小空闲连接
-        time-between-eviction-runs: -1 #逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
+        time-between-eviction-runs: -1 #逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
+
+daibi:
+  url: http://110.41.171.203:9000/wallet-api
+  apiKey: 2ee48a7898a0bc9d4eac60b71b606fe32710d5d32a3e1522685e6031e0bbde84

+ 20 - 0
crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/dao/WithdrawalHistoryDao.java

@@ -0,0 +1,20 @@
+package com.zbkj.service.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zbkj.common.model.user.WithdrawalHistory;
+
+/**
+ * 用户表 Mapper 接口
+ * +----------------------------------------------------------------------
+ * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+ * +----------------------------------------------------------------------
+ * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
+ * +----------------------------------------------------------------------
+ * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+ * +----------------------------------------------------------------------
+ * | Author: CRMEB Team <admin@crmeb.com>
+ * +----------------------------------------------------------------------
+ */
+public interface WithdrawalHistoryDao extends BaseMapper<WithdrawalHistory> {
+
+}

+ 2 - 1
crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/OrderService.java

@@ -10,6 +10,7 @@ import com.zbkj.common.response.*;
 import com.zbkj.common.vo.LogisticsResultVo;
 
 import java.math.BigDecimal;
+import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -194,7 +195,7 @@ public interface OrderService extends IService<Order> {
      * @param date 日期,yyyy-MM-dd格式
      * @return BigDecimal
      */
-    BigDecimal getPayOrderAmountByDate(Integer merId, String date);
+    HashMap<String, BigDecimal> getPayOrderAmountByDate(Integer merId, String date);
 
     /**
      * 订单细节详情列表

+ 20 - 3
crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/PayService.java

@@ -1,11 +1,13 @@
 package com.zbkj.service.service;
 
-import com.zbkj.common.request.OrderPayRequest;
-import com.zbkj.common.request.WechatPaymentQueryRequest;
+import com.alibaba.fastjson.JSONObject;
+import com.github.pagehelper.PageInfo;
+import com.zbkj.common.model.user.WithdrawalHistory;
+import com.zbkj.common.request.*;
 import com.zbkj.common.response.CashierInfoResponse;
 import com.zbkj.common.response.OrderPayResultResponse;
 import com.zbkj.common.response.PayConfigResponse;
-import com.zbkj.common.vo.MyRecord;
+import com.zbkj.common.response.PaymentMoneyToUserResponse;
 
 /**
  * PayService 接口
@@ -62,4 +64,19 @@ public interface PayService {
      * 查询微信支付结果
      */
     Boolean queryWechatPaymentResult(WechatPaymentQueryRequest request);
+
+    /**
+     * 提现代币到用户
+     * @param request
+     * @return
+     */
+    PaymentMoneyToUserResponse paymentMoneyToUserResult(PaymentMoneyToUser request);
+
+    void transferNotice(TransferNotice transferNotice);
+
+    PageInfo<WithdrawalHistory> paymentMoneyToUserList(PageParamRequest pageParamRequest);
+
+    JSONObject transferSettings(DaibiTransferSettings daibiTransferSettings);
+
+    JSONObject paymentMoneyToUserNumber();
 }

+ 11 - 2
crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/CartServiceImpl.java

@@ -224,6 +224,7 @@ public class CartServiceImpl extends ServiceImpl<CartDao, Cart> implements CartS
 
     /**
      * 获取待添加商品
+     *
      * @param productId 商品ID
      */
     private Product getAwaitAddProduct(Integer productId) {
@@ -441,7 +442,8 @@ public class CartServiceImpl extends ServiceImpl<CartDao, Cart> implements CartS
         if (number <= 0 || number > 999)
             throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "加购数不能小于1且大于999");
         Cart storeCart = getById(id);
-        if (ObjectUtil.isNull(storeCart)) throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "当前购物车不存在");
+        if (ObjectUtil.isNull(storeCart))
+            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "当前购物车不存在");
         if (storeCart.getCartNum().equals(number)) {
             return Boolean.TRUE;
         }
@@ -503,6 +505,7 @@ public class CartServiceImpl extends ServiceImpl<CartDao, Cart> implements CartS
      */
     @Override
     public CartPriceResponse calculatePrice(List<Integer> ids) {
+        List<HashMap<String, Object>> details = new ArrayList<>();
         Integer userId = userService.getUserIdException();
         List<Cart> cartList = findListByIds(ids);
         User user = userService.getById(userId);
@@ -549,7 +552,12 @@ public class CartServiceImpl extends ServiceImpl<CartDao, Cart> implements CartS
             } else {
                 proTotalPrice = proTotalPrice.add(attrValue.getPrice().multiply(new BigDecimal(cart.getCartNum().toString())));
             }
-
+            HashMap<String, Object> detail = new HashMap<>();
+            detail.put("num", cart.getCartNum());
+            detail.put("price", attrValue.getPrice());
+            detail.put("vip_price", attrValue.getVipPrice());
+            detail.put("is_vip", product.getIsPaidMember());
+            details.add(detail);
             ProductPriceCalculateDto dto = new ProductPriceCalculateDto();
             dto.setProductId(product.getId());
             dto.setAttrValueId(attrValue.getId());
@@ -1041,6 +1049,7 @@ public class CartServiceImpl extends ServiceImpl<CartDao, Cart> implements CartS
         }
 
         CartPriceResponse cartPriceResponse = new CartPriceResponse();
+        cartPriceResponse.setDetails(details);
         cartPriceResponse.setMerCouponPrice(merCouponPrice);
         cartPriceResponse.setPlatCouponPrice(platCouponPrice);
         cartPriceResponse.setProTotalPrice(totalPrice);

+ 14 - 4
crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/HomeServiceImpl.java

@@ -15,7 +15,9 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -67,8 +69,12 @@ public class HomeServiceImpl implements HomeService {
         String today = DateUtil.date().toString(DateConstants.DATE_FORMAT_DATE);
         String yesterday = DateUtil.yesterday().toString(DateConstants.DATE_FORMAT_DATE);
         HomeRateResponse response = new HomeRateResponse();
-        response.setSales(orderService.getPayOrderAmountByDate(systemAdmin.getMerId(), today));
-        response.setYesterdaySales(orderService.getPayOrderAmountByDate(systemAdmin.getMerId(), yesterday));
+        HashMap<String, BigDecimal> sales = orderService.getPayOrderAmountByDate(systemAdmin.getMerId(), today);
+        response.setSales(sales.get("payPrice"));
+        response.setSalesReat(sales.get("totalPriceReat"));
+        HashMap<String,BigDecimal> yesterdaySales = orderService.getPayOrderAmountByDate(systemAdmin.getMerId(), yesterday);
+        response.setYesterdaySales(yesterdaySales.get("payPrice"));
+        response.setYesterdaySalesReat(yesterdaySales.get("totalPriceReat"));
         response.setOrderNum(orderService.getOrderNumByDate(systemAdmin.getMerId(), today));
         response.setYesterdayOrderNum(orderService.getOrderNumByDate(systemAdmin.getMerId(), yesterday));
         response.setFollowNum(userMerchantCollectService.getCountByMerId(systemAdmin.getMerId()));
@@ -109,8 +115,12 @@ public class HomeServiceImpl implements HomeService {
         response.setYesterdayNewMerchantNum(merchantService.getNewNumByDate(yesterday));
         response.setOrderNum(orderService.getOrderNumByDate(0, today));
         response.setYesterdayOrderNum(orderService.getOrderNumByDate(0, yesterday));
-        response.setSales(orderService.getPayOrderAmountByDate(0, today));
-        response.setYesterdaySales(orderService.getPayOrderAmountByDate(0, yesterday));
+        HashMap<String,BigDecimal> sales = orderService.getPayOrderAmountByDate(0, today);
+        HashMap<String,BigDecimal> yesterdaySales = orderService.getPayOrderAmountByDate(0, yesterday);
+        response.setSales(sales.get("payPrice"));
+        response.setYesterdaySales(yesterdaySales.get("payPrice"));
+        response.setSalesReat(sales.get("totalPriceReat"));
+        response.setYesterdaySalesReat(yesterdaySales.get("totalPriceReat"));
         response.setUserNum(userService.getTotalNum());
         response.setMerchantNum(merchantService.getAllCount());
         return response;

+ 21 - 8
crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/OrderServiceImpl.java

@@ -124,6 +124,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements Or
     private MerchantInfoService merchantInfoService;
     @Autowired
     private ProductService productService;
+
     /**
      * 根据订单编号获取订单
      *
@@ -924,6 +925,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements Or
         MerchantOrder merchantOrder = merchantOrderService.getOneByOrderNo(orderNo);
         BeanUtils.copyProperties(merchantOrder, response);
         BeanUtils.copyProperties(order, response);
+
         List<OrderDetail> orderDetailList = orderDetailService.getByOrderNo(orderNo);
         List<OrderInfoFrontDataResponse> orderInfoList = orderDetailList.stream().map(e -> {
             OrderInfoFrontDataResponse dataResponse = new OrderInfoFrontDataResponse();
@@ -1228,9 +1230,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements Or
      * @return BigDecimal
      */
     @Override
-    public BigDecimal getPayOrderAmountByDate(Integer merId, String date) {
+    public HashMap<String, BigDecimal> getPayOrderAmountByDate(Integer merId, String date) {
         QueryWrapper<Order> wrapper = new QueryWrapper<>();
-        wrapper.select("pay_price");
+        wrapper.select("pay_price,total_price_reat");
         wrapper.eq("paid", 1);
         if (merId > 0) {
             wrapper.eq("mer_id", merId);
@@ -1238,10 +1240,17 @@ public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements Or
         wrapper.eq("is_del", false);
         wrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", date);
         List<Order> orderList = dao.selectList(wrapper);
+
+        HashMap<String, BigDecimal> map = new HashMap<>();
+        map.put("payPrice", new BigDecimal("0"));
+        map.put("totalPriceReat", new BigDecimal("0"));
+
         if (CollUtil.isEmpty(orderList)) {
-            return BigDecimal.ZERO;
+            return map;
         }
-        return orderList.stream().map(Order::getPayPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
+        map.put("payPrice", orderList.stream().map(Order::getPayPrice).reduce(BigDecimal.ZERO, BigDecimal::add));
+        map.put("totalPriceReat", orderList.stream().map(Order::getTotalPriceReat).reduce(BigDecimal.ZERO, BigDecimal::add));
+        return map;
     }
 
     /**
@@ -1853,7 +1862,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements Or
     /**
      * 获取商户id集合和日期获取销售额
      *
-     * @param date 日期,yyyy-MM-dd格式
+     * @param date   日期,yyyy-MM-dd格式
      * @param merIds 商户id集合
      */
     @Override
@@ -1875,7 +1884,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements Or
      * 根据商户id集合和日期获取订单量
      *
      * @param merIds 商户id集合
-     * @param date 日期,yyyy-MM-dd格式
+     * @param date   日期,yyyy-MM-dd格式
      */
     @Override
     public Integer getOrderNumByMerIdsAndDate(List<Integer> merIds, String date) {
@@ -1911,8 +1920,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements Or
 
     /**
      * 圈层端订单分页列表
+     *
      * @param merIdList 商户id集合
-     * @param request 查询参数
+     * @param request   查询参数
      * @return PageInfo
      */
     @Override
@@ -2480,8 +2490,9 @@ public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements Or
 
     /**
      * 获取订单总数(圈层端)
+     *
      * @param merIdList 商户id集合
-     * @param status String 状态
+     * @param status    String 状态
      * @return Integer
      */
     private Integer getCircleCount(List<Integer> merIdList, OrderTabsHeaderRequest request, String status) {
@@ -2764,10 +2775,12 @@ public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements Or
     public Integer getAPC() {
         return Math.toIntExact(productService.count());
     }
+
     @Override
     public Integer getAMC() {
         return Math.toIntExact(merchantService.count());
     }
+
     @Override
     public Integer getAOC() {
         return Math.toIntExact(count());

+ 197 - 17
crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/PayServiceImpl.java

@@ -1,4 +1,9 @@
 package com.zbkj.service.service.impl;
+
+import java.math.RoundingMode;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.Date;
 
 import cn.hutool.core.collection.CollUtil;
@@ -16,10 +21,14 @@ import com.alipay.api.DefaultAlipayClient;
 import com.alipay.api.domain.AlipayTradeQueryModel;
 import com.alipay.api.request.AlipayTradeQueryRequest;
 import com.alipay.api.response.AlipayTradeQueryResponse;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
 import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
 import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryV3Result;
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
 import com.zbkj.common.config.CrmebConfig;
 import com.zbkj.common.constants.*;
 import com.zbkj.common.dto.Location;
@@ -33,17 +42,16 @@ import com.zbkj.common.model.member.PaidMemberOrder;
 import com.zbkj.common.model.merchant.Merchant;
 import com.zbkj.common.model.merchant.MerchantBalanceRecord;
 import com.zbkj.common.model.order.*;
+import com.zbkj.common.model.product.Product;
 import com.zbkj.common.model.product.ProductCoupon;
 import com.zbkj.common.model.reservation.ReservationWorkOrder;
 import com.zbkj.common.model.system.SystemNotification;
 import com.zbkj.common.model.user.*;
 import com.zbkj.common.model.wechat.WechatPayInfo;
 import com.zbkj.common.model.wechat.video.PayComponentProduct;
-import com.zbkj.common.request.OrderPayRequest;
-import com.zbkj.common.request.WechatPaymentQueryRequest;
-import com.zbkj.common.response.CashierInfoResponse;
-import com.zbkj.common.response.OrderPayResultResponse;
-import com.zbkj.common.response.PayConfigResponse;
+import com.zbkj.common.page.CommonPage;
+import com.zbkj.common.request.*;
+import com.zbkj.common.response.*;
 import com.zbkj.common.result.CommonResultCode;
 import com.zbkj.common.result.MemberResultCode;
 import com.zbkj.common.result.OrderResultCode;
@@ -52,12 +60,16 @@ import com.zbkj.common.utils.*;
 import com.zbkj.common.vo.*;
 import com.zbkj.common.vo.wxvedioshop.ShopOrderAddResultVo;
 import com.zbkj.common.vo.wxvedioshop.order.*;
+import com.zbkj.service.dao.WithdrawalHistoryDao;
 import com.zbkj.service.service.*;
+import com.zbkj.service.util.DaibiUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.support.TransactionTemplate;
+import org.springframework.web.bind.annotation.RequestBody;
 
 import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
@@ -156,6 +168,8 @@ public class PayServiceImpl implements PayService {
     private WechatPayService wechatPayService;
     @Autowired
     private ReservationWorkOrderService reservationWorkOrderService;
+    @Autowired
+    private WithdrawalHistoryDao withdrawalHistoryDao;
 
     /**
      * 获取支付配置
@@ -213,7 +227,7 @@ public class PayServiceImpl implements PayService {
 
         // 余额支付
         if (orderPayRequest.getPayType().equals(PayConstants.PAY_TYPE_YUE)) {
-            if (user.getNowMoney().compareTo(order.getPayPrice()) < 0) {
+            if (user.getNowMoney().compareTo(order.getTotalPriceReat()) < 0) {
                 throw new CrmebException(UserResultCode.USER_BALANCE_INSUFFICIENT);
             }
         }
@@ -222,14 +236,17 @@ public class PayServiceImpl implements PayService {
         response.setOrderNo(order.getOrderNo());
         response.setPayType(order.getPayType());
         response.setPayChannel(order.getPayChannel());
+        response.setTotalPriceReat(order.getTotalPriceReat());
         if (!order.getSecondType().equals(OrderConstants.ORDER_SECOND_TYPE_INTEGRAL)) {
-            if (order.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
-                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "支付金额不能低于等于0");
+            if (order.getTotalPriceReat().compareTo(BigDecimal.ZERO) <= 0) {
+                throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "支付金额不能低于等于0");
             }
         }
+
+
         // 余额支付
-        if (order.getPayType().equals(PayConstants.PAY_TYPE_YUE) || order.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
-            Boolean yueBoolean = yuePay(order, user);
+        if (order.getPayType().equals(PayConstants.PAY_TYPE_YUE) || order.getTotalPriceReat().compareTo(BigDecimal.ZERO) <= 0) {
+            Boolean yueBoolean = yuePay(order, user, orderPayRequest);
             response.setStatus(yueBoolean);
             return response;
         }
@@ -815,6 +832,168 @@ public class PayServiceImpl implements PayService {
         return response;
     }
 
+    @Override
+    public JSONObject transferSettings(DaibiTransferSettings daibiTransferSettings) {
+        JSONObject res = DaibiUtils.setSettings(daibiTransferSettings);
+        return res;
+    }
+
+    @Override
+    public JSONObject paymentMoneyToUserNumber() {
+        User user = userService.getInfo();
+        LambdaUpdateWrapper<WithdrawalHistory> wrapper = new LambdaUpdateWrapper<>();
+        LocalDate today = LocalDate.now();
+        String startTime = today.toString() + " 00:00:00";
+        String endTime = today.toString() + " 23:59:59";
+        wrapper.ge(WithdrawalHistory::getCreateTime, startTime)
+                .le(WithdrawalHistory::getCreateTime, endTime)
+                .eq(WithdrawalHistory::getUid, user.getId())
+                .notIn(WithdrawalHistory::getStatus, Arrays.asList(2));
+        Integer dailyCount = withdrawalHistoryDao.selectCount(wrapper);
+
+        LambdaUpdateWrapper<WithdrawalHistory> wrapper2 = new LambdaUpdateWrapper<>();
+        LocalDate sevenDaysAgo = today.minusDays(7);
+        String sevenDaysAgoStr = sevenDaysAgo.toString() + " 00:00:00";
+        wrapper2.ge(WithdrawalHistory::getCreateTime, sevenDaysAgoStr)
+                .le(WithdrawalHistory::getCreateTime, endTime)
+                .eq(WithdrawalHistory::getUid, user.getId())
+                .notIn(WithdrawalHistory::getStatus, Arrays.asList(2));
+        Integer dailyCountAgoCount = withdrawalHistoryDao.selectCount(wrapper2);
+
+
+        JSONObject res = new JSONObject();
+        res.put("dailyCount", dailyCount);
+        res.put("dailyCountAgo", dailyCountAgoCount);
+        if (dailyCountAgoCount >= 3 || dailyCount >= 2) {
+            res.put("status", false);
+        } else {
+            res.put("status", true);
+        }
+
+        return res;
+    }
+
+    @Override
+    public void transferNotice(TransferNotice transferNotice) {
+        if (!transferNotice.getRequestId().isEmpty()) {
+            LambdaUpdateWrapper<WithdrawalHistory> wrapper = new LambdaUpdateWrapper<>();
+            wrapper.eq(WithdrawalHistory::getTransactionId, transferNotice.getRequestId());
+            WithdrawalHistory withdrawalHistory = new WithdrawalHistory();
+            withdrawalHistory.setTxHash(transferNotice.getTxHash());
+            withdrawalHistory.setUpdateTime(new Date());
+            withdrawalHistory.setRemark(transferNotice.getMessage());
+            if (transferNotice.getSuccess()) {
+                withdrawalHistory.setStatus(1);
+            } else {
+                withdrawalHistory.setStatus(2);
+            }
+            withdrawalHistoryDao.update(withdrawalHistory, wrapper);
+        }
+    }
+
+    /**
+     * 提醒记录 Greg
+     *
+     * @param pageParamRequest
+     * @return
+     */
+    @Override
+    public PageInfo<WithdrawalHistory> paymentMoneyToUserList(PageParamRequest pageParamRequest) {
+        User user = userService.getInfo();
+        LambdaUpdateWrapper<WithdrawalHistory> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.eq(WithdrawalHistory::getUid, user.getId());
+        wrapper.orderByDesc(WithdrawalHistory::getCreateTime);
+        Page<WithdrawalHistory> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
+        List<WithdrawalHistory> list = withdrawalHistoryDao.selectList(wrapper);
+        return CommonPage.copyPageInfo(page, list);
+    }
+
+    /**
+     * 提现代币到用户输入的地址 Greg
+     *
+     * @param request
+     * @return
+     */
+    @Override
+    public PaymentMoneyToUserResponse paymentMoneyToUserResult(PaymentMoneyToUser request) {
+        WithdrawalHistory withdrawalHistory = new WithdrawalHistory();
+        User user = userService.getInfo();
+        // rmb 余额不足
+        if (user.getNowMoney().compareTo(request.getAmount()) < 0) {
+            throw new CrmebException(UserResultCode.USER_BALANCE_INSUFFICIENT);
+        }
+        // 代币数量不能小于等于0
+        if (request.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
+            throw new CrmebException(UserResultCode.AMOUNT_ZERO);
+        }
+
+        PaymentMoneyToUserResponse paymentMoneyToUserResponse = new PaymentMoneyToUserResponse();
+        // 提现手续费,实际到账是扣掉手续费的
+        BigDecimal handlingFeeSl = request.getAmount().multiply(new BigDecimal("0.05")).setScale(2, RoundingMode.UP);
+        BigDecimal amount = request.getAmount().subtract(handlingFeeSl);
+        Map<String, Object> res = DaibiUtils.withdrawalSLgns(request.getAddress(), amount.toString());
+
+        withdrawalHistory.setUid(user.getId());
+        withdrawalHistory.setAddress(request.getAddress());
+        withdrawalHistory.setRate(request.getRate());
+        withdrawalHistory.setAmount(amount);
+        withdrawalHistory.setAmountToRmb(request.getRate().multiply(amount));
+        withdrawalHistory.setTransactionId(res.get("request_id").toString());
+        withdrawalHistory.setToken(res.get("token").toString());
+        withdrawalHistory.setTokenType("slgns");
+        withdrawalHistory.setRemark(res.get("message").toString());
+        withdrawalHistory.setHandlingFeeRmb(request.getRate().multiply(handlingFeeSl));
+        withdrawalHistory.setHandlingFeeSl(handlingFeeSl);
+        if ((Boolean) res.get("status")) {
+            // 提现发起成功
+            withdrawalHistory.setStatus(0);
+            withdrawalHistoryDao.insert(withdrawalHistory);
+            // 余额支付
+            Boolean yueBoolean = PaymentMoneyToUserYuePay(user, request, res.get("request_id").toString());
+        }
+        BeanUtils.copyProperties(withdrawalHistory, paymentMoneyToUserResponse);
+        paymentMoneyToUserResponse.setRemark(res.get("message").toString());
+        paymentMoneyToUserResponse.setStatus((Boolean) res.get("status"));
+        return paymentMoneyToUserResponse;
+    }
+
+    /**
+     * 提现代币时扣用户余额 Greg
+     *
+     * @param user
+     * @param request
+     * @param requestId
+     * @return
+     */
+    private Boolean PaymentMoneyToUserYuePay(User user, PaymentMoneyToUser request, String requestId) {
+        // 用户余额扣除
+        Boolean execute = transactionTemplate.execute(e -> {
+            Boolean update = Boolean.TRUE;
+
+            update = userService.updateNowMoney(user.getId(), request.getAmount(), Constants.OPERATION_TYPE_SUBTRACT);
+            if (!update) {
+                logger.error("余额支付,扣除用户余额失败");
+                e.setRollbackOnly();
+                return update;
+            }
+            // 用户余额记录
+            UserBalanceRecord userBalanceRecord = new UserBalanceRecord();
+            userBalanceRecord.setUid(user.getId());
+            userBalanceRecord.setLinkId(requestId);
+            userBalanceRecord.setRate(request.getRate());
+            userBalanceRecord.setLinkType(BalanceRecordConstants.BALANCE_RECORD_LINK_TYPE_WITHDRAW);
+            userBalanceRecord.setType(BalanceRecordConstants.BALANCE_RECORD_TYPE_SUB);
+            userBalanceRecord.setAmount(request.getAmount());
+            userBalanceRecord.setBalance(user.getNowMoney().subtract(request.getAmount()));
+            userBalanceRecord.setRemark(StrUtil.format(BalanceRecordConstants.BALANCE_RECORD_REMARK_WITHDRAW, request.getAmount()));
+            userBalanceRecordService.save(userBalanceRecord);
+
+            return update;
+        });
+        if (!execute) throw new CrmebException("余额支付订单失败");
+        return true;
+    }
+
     /**
      * 查询微信支付结果
      */
@@ -997,7 +1176,7 @@ public class PayServiceImpl implements PayService {
             return CollUtil.newArrayList();
         }
         // 积分订单不参与分佣
-        if (merchantOrder.getType().equals(OrderConstants.ORDER_TYPE_PITUAN)){
+        if (merchantOrder.getType().equals(OrderConstants.ORDER_TYPE_PITUAN)) {
             return CollUtil.newArrayList();
         }
         // 检测商城是否开启分销功能
@@ -1368,7 +1547,7 @@ public class PayServiceImpl implements PayService {
      * @param order 订单
      * @return Boolean Boolean
      */
-    private Boolean yuePay(Order order, User user) {
+    private Boolean yuePay(Order order, User user, OrderPayRequest orderPayRequest) {
         // 用户余额扣除
         Boolean execute = transactionTemplate.execute(e -> {
             Boolean update = Boolean.TRUE;
@@ -1381,8 +1560,8 @@ public class PayServiceImpl implements PayService {
             order.setUpdateTime(DateUtil.date());
             orderService.updateById(order);
             // 这里只扣除金额,账单记录在task中处理
-            if (order.getPayPrice().compareTo(BigDecimal.ZERO) > 0) {
-                update = userService.updateNowMoney(order.getUid(), order.getPayPrice(), Constants.OPERATION_TYPE_SUBTRACT);
+            if (order.getTotalPriceReat().compareTo(BigDecimal.ZERO) > 0) {
+                update = userService.updateNowMoney(order.getUid(), order.getTotalPriceReat(), Constants.OPERATION_TYPE_SUBTRACT);
                 if (!update) {
                     logger.error("余额支付,扣除用户余额失败,orderNo = {}", order.getOrderNo());
                     e.setRollbackOnly();
@@ -1392,11 +1571,12 @@ public class PayServiceImpl implements PayService {
                 UserBalanceRecord userBalanceRecord = new UserBalanceRecord();
                 userBalanceRecord.setUid(user.getId());
                 userBalanceRecord.setLinkId(order.getOrderNo());
+                userBalanceRecord.setRate(order.getRate());
                 userBalanceRecord.setLinkType(BalanceRecordConstants.BALANCE_RECORD_LINK_TYPE_ORDER);
                 userBalanceRecord.setType(BalanceRecordConstants.BALANCE_RECORD_TYPE_SUB);
-                userBalanceRecord.setAmount(order.getPayPrice());
-                userBalanceRecord.setBalance(user.getNowMoney().subtract(order.getPayPrice()));
-                userBalanceRecord.setRemark(StrUtil.format(BalanceRecordConstants.BALANCE_RECORD_REMARK_ORDER, order.getPayPrice()));
+                userBalanceRecord.setAmount(order.getTotalPriceReat());
+                userBalanceRecord.setBalance(user.getNowMoney().subtract(order.getTotalPriceReat()));
+                userBalanceRecord.setRemark(StrUtil.format(BalanceRecordConstants.BALANCE_RECORD_REMARK_ORDER, order.getTotalPriceReat()));
                 userBalanceRecordService.save(userBalanceRecord);
             }
             return update;

+ 10 - 1
crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/StatisticsTaskServiceImpl.java

@@ -32,6 +32,7 @@ import org.springframework.transaction.support.TransactionTemplate;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -194,8 +195,11 @@ public class StatisticsTaskServiceImpl implements StatisticsTaskService {
         // 订单支付数量
         Integer payOrderNum = orderService.getPayOrderNumByDate(yesterdayStr);
 
+        HashMap<String,BigDecimal> sales = orderService.getPayOrderAmountByDate(0, yesterdayStr);
         // 订单支付金额
-        BigDecimal payOrderAmount = orderService.getPayOrderAmountByDate(0, yesterdayStr);
+        BigDecimal payOrderAmount = sales.get("payPrice");
+        // 订单支付金额SL
+        BigDecimal payOrderAmountSl = sales.get("totalPriceReat");
 
         // 订单退款数量
         Integer refundOrderNum = refundOrderService.getRefundOrderNumByDate(yesterdayStr);
@@ -551,6 +555,8 @@ public class StatisticsTaskServiceImpl implements StatisticsTaskService {
             return;
         }
         BigDecimal orderPayAmount = dailyStatementList.stream().map(PlatformDailyStatement::getOrderPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+        BigDecimal orderPayAmountSl = dailyStatementList.stream().map(PlatformDailyStatement::getOrderPayAmountSl).reduce(BigDecimal.ZERO, BigDecimal::add);
+
         int totalOrderNum = dailyStatementList.stream().mapToInt(PlatformDailyStatement::getTotalOrderNum).sum();
         BigDecimal handlingFee = dailyStatementList.stream().map(PlatformDailyStatement::getHandlingFee).reduce(BigDecimal.ZERO, BigDecimal::add);
         BigDecimal payoutAmount = dailyStatementList.stream().map(PlatformDailyStatement::getPayoutAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
@@ -580,6 +586,7 @@ public class StatisticsTaskServiceImpl implements StatisticsTaskService {
 
 
         platformMonthStatement.setOrderPayAmount(orderPayAmount);
+        platformMonthStatement.setOrderPayAmountSl(orderPayAmountSl);
         platformMonthStatement.setTotalOrderNum(totalOrderNum);
         platformMonthStatement.setHandlingFee(handlingFee);
         platformMonthStatement.setMerchantTransferAmount(merchantTransferAmount);
@@ -625,11 +632,13 @@ public class StatisticsTaskServiceImpl implements StatisticsTaskService {
             myRecord.set("status", 0);
             return myRecord;
         }
+        HashMap<String,BigDecimal> sales = orderService.getPayOrderAmountByDate(0, yesterday);
         List<OrderProfitSharing> sharingList = orderProfitSharingService.findByDate(0, yesterday);
         List<RefundOrder> refundOrderList = refundOrderService.findByDate(0, yesterday);
         List<RechargeOrder> rechargeOrderList = rechargeOrderService.findByDate(yesterday);
         // 平台记录写入
         platformDataWrite(platformDailyStatement, sharingList, refundOrderList, rechargeOrderList);
+        platformDailyStatement.setOrderPayAmountSl(sales.get("totalPriceReat"));
         myRecord.set("status", 1);
         myRecord.set("platformDailyStatement", platformDailyStatement);
         // 商户记录写入

+ 3 - 3
crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/service/impl/UploadServiceImpl.java

@@ -21,7 +21,8 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
-import sun.misc.BASE64Decoder;
+import java.util.Base64;
+
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -219,8 +220,7 @@ public class UploadServiceImpl implements UploadService {
             // 去掉base64前缀 data:image/jpeg;base64,
             base64 = base64.substring(base64.indexOf(",", 1) + 1);
             // 解密,解密的结果是一个byte数组
-            BASE64Decoder d = new BASE64Decoder();
-            byte[] imgbytes = d.decodeBuffer(base64);
+            byte[] imgbytes = Base64.getDecoder().decode(base64);
             for (int i = 0; i < imgbytes.length; ++i) {
                 if (imgbytes[i] < 0) {
                     imgbytes[i] += 256;

+ 58 - 28
crmeb_src/mer_java/crmeb-service/src/main/java/com/zbkj/service/util/DaibiUtils.java

@@ -1,15 +1,12 @@
 package com.zbkj.service.util;
 
 import cn.hutool.core.util.IdUtil;
-import cn.hutool.core.util.StrUtil;
 import cn.hutool.http.HttpUtil;
-import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
-import lombok.Getter;
-import lombok.Setter;
+import com.zbkj.common.request.DaibiTransferSettings;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
-
+import com.alibaba.fastjson.JSONObject;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -30,6 +27,10 @@ public class DaibiUtils {
         DaibiUtils.baseUrl = baseUrl;
     }
 
+    public static String lgnsToken = "0xeB51D9A39AD5EEF215dC0Bf39a8821ff804A0F01";
+
+    public static String slgnsToken = "0x99a57E6C8558BC6689f894e068733ADf83C19725";
+
     /**
      * 创建账户
      */
@@ -38,8 +39,8 @@ public class DaibiUtils {
         Map<String, Object> params = new HashMap<>();
         params.put("request_id", IdUtil.fastSimpleUUID());
         String body = post(url, params);
-        JSONObject obj = JSONUtil.parseObj(body);
-        return obj.getStr("address");
+        JSONObject obj = JSONObject.parseObject(body);
+        return obj.getString("address");
     }
 
     /**
@@ -48,13 +49,51 @@ public class DaibiUtils {
      * @param address 收款地址
      * @param amount  代币数量
      */
-    public static void withdrawal(String address, String amount) {
+    public static Map<String, Object> withdrawalLgns(String address, String amount) {
+        return withdrawal(address, amount, lgnsToken);
+    }
+
+    /**
+     * 从转账钱包转出代币
+     *
+     * @param address 收款地址
+     * @param amount  代币数量
+     */
+    public static Map<String, Object> withdrawalSLgns(String address, String amount) {
+        return withdrawal(address, amount, slgnsToken);
+    }
+
+    public static Map<String, Object> withdrawal(String address, String amount, String token) {
         String url = getUrl("/withdrawal");
         Map<String, Object> params = new HashMap<>();
         params.put("request_id", IdUtil.fastSimpleUUID());
         params.put("address", address);
         params.put("amount", amount);
-        post(url, params);
+        params.put("token", token);
+        String body = post(url, params);
+        JSONObject obj = JSONObject.parseObject(body);
+        if (obj.getString("code").equals("OK")) {
+            params.put("status", true);
+            params.put("message", "");
+        } else {
+            params.put("status", false);
+            params.put("message", obj.getString("message"));
+        }
+        return params;
+    }
+
+    /**
+     * 设置转账钱包 Greg
+     * @param daibiTransferSettings
+     */
+    public static JSONObject setSettings(DaibiTransferSettings daibiTransferSettings){
+        return setSettings(
+                daibiTransferSettings.getWithdrawalWalletAddress(),
+                daibiTransferSettings.getWithdrawalPrivateKey(),
+                daibiTransferSettings.getCollectWalletAddress(),
+                daibiTransferSettings.getNotifyDepositUrl(),
+                daibiTransferSettings.getNotifyWithdrawalUrl()
+        );
     }
 
     /**
@@ -66,26 +105,17 @@ public class DaibiUtils {
      * @param depositUrl              充值通知地址
      * @param withdrawalUrl           转账成功后通知地址
      */
-    public static void setSettings(String withdrawalWalletAddress, String withdrawalPrivateKey, String collectWalletAddress, String depositUrl, String withdrawalUrl) {
+    public static JSONObject setSettings(String withdrawalWalletAddress, String withdrawalPrivateKey, String collectWalletAddress, String depositUrl, String withdrawalUrl) {
         String url = getUrl("/settings");
         Map<String, Object> params = new HashMap<>();
-        params.put("request_id", IdUtil.fastSimpleUUID());
-        if (StrUtil.isNotBlank(withdrawalWalletAddress)) {
-            params.put("withdrawal.wallet_address", withdrawalWalletAddress);
-        }
-        if (StrUtil.isNotBlank(withdrawalPrivateKey)) {
-            params.put("withdrawal.private_key", withdrawalPrivateKey);
-        }
-        if (StrUtil.isNotBlank(collectWalletAddress)) {
-            params.put("collect.wallet_address", collectWalletAddress);
-        }
-        if (StrUtil.isNotBlank(depositUrl)) {
-            params.put("notify.deposit_url", depositUrl);
-        }
-        if (StrUtil.isNotBlank(withdrawalUrl)) {
-            params.put("notify.withdrawal_url", withdrawalUrl);
-        }
-        post(url, params);
+        params.put("withdrawal.wallet_address", withdrawalWalletAddress);
+        params.put("withdrawal.private_key", withdrawalPrivateKey);
+        params.put("collect.wallet_address", collectWalletAddress);
+        params.put("notify.deposit_url", depositUrl);
+        params.put("notify.withdrawal_url", withdrawalUrl);
+        String body = post(url, params);
+        JSONObject obj = JSONObject.parseObject(body);
+        return obj;
     }
 
 
@@ -96,7 +126,7 @@ public class DaibiUtils {
     public static String post(String url, Map<String, Object> params) {
         return HttpUtil.createPost(url)
                 .header("x-api-key", apiKey)
-                .body(JSONUtil.toJsonStr(params))
+                .body(JSONObject.toJSONString(params))
                 .execute()
                 .body();
     }

+ 2 - 1
crmeb_src/mer_java/crmeb-service/src/main/resources/mapper/order/OrderMapper.xml

@@ -55,7 +55,8 @@
                o.status, o.refund_status as refundStatus, o.is_user_del as isUserDel, o.is_merchant_del as isMerchantDel,
                o.cancel_status as cancelStatus, o.level, o.type, o.create_time as createTime,o.second_type as secondType, o.group_buy_record_status as groupBuyRecordStatus,
                o.total_num as totalNum,
-               u.nickname,u.is_logoff
+               u.nickname,u.is_logoff,
+               o.rate,o.rate_diff,o.total_price_reat,o.pay_fee_sl
         from eb_order o
         left join eb_user as u on o.uid = u.id
         where o.is_del = 0 and o.second_type in (0,2,5,6,7)

+ 2 - 1
crmeb_src/mer_pc/.env.development

@@ -1,5 +1,6 @@
 VITE_API_ENV = 'dev'
 # 请求域名
-NUXT_API_URL=http://127.0.0.1:8081
+# NUXT_API_URL=http://127.0.0.1:8081
+NUXT_API_URL=http://127.0.0.1:20810
 # 接口默认前缀
 NUXT_API_PREFIX=/api/

+ 1 - 1
crmeb_src/mer_pc/package.json

@@ -68,4 +68,4 @@
   },
   "type": "module",
   "__npminstall_done": false
-}
+}

Fișier diff suprimat deoarece este prea mare
+ 332 - 290
crmeb_src/mer_pc/pnpm-lock.yaml


+ 6 - 2
crmeb_src/mer_plat_admin/src/components/OrderDetail/index.vue

@@ -29,8 +29,12 @@
               </div>
             </li>
             <li class="item">
-              <div class="title">实际支付</div>
-              <div>¥ {{ orderDatalist.payPrice || '0.0' }}</div>
+              <div class="title">实际支付RMB</div>
+              <div>¥ {{ orderDatalist.payPrice || '0.0' }} |  sL{{ orderDatalist.totalPriceReat || '0.0' }}</div>
+            </li>
+            <li class="item">
+              <div class="title">支付汇率</div>
+              <div>{{ orderDatalist.rate}}</div>
             </li>
             <li class="item">
               <div class="title">支付方式</div>

+ 2 - 1
crmeb_src/mer_plat_admin/src/views/dashboard/components/baseInfo.vue

@@ -102,11 +102,12 @@
             <el-tag type="primary">今日</el-tag>
           </div>
           <div class="content">
-            <span class="content-number spBlock my15">{{ viewData.sales || 0 }}</span>
+            <span class="content-number spBlock my15"><span style="margin-right: 50px;">{{ viewData.sales || 0 }} 元</span><span>{{ viewData.salesReat || 0 }} sL</span></span>
             <el-divider></el-divider>
             <div class="acea-row row-between-wrapper">
               <span class="content-time">昨日数据</span>
               <span class="content-time">{{ viewData.yesterdaySales || 0 }} 元</span>
+              <span class="content-time">{{ viewData.yesterdaySalesReat || 0 }} sL</span>
             </div>
           </div>
         </el-card>

+ 3 - 1
crmeb_src/mer_plat_admin/src/views/finance/statement/index.vue

@@ -70,6 +70,8 @@
         />
         <el-table-column prop="brokerage" label="佣金" min-width="100" />
         <el-table-column prop="orderReceivable" label="订单应收金额" min-width="100" />
+        <el-table-column prop="orderRealIncome" label="订单实收金额(RMB)" min-width="120" />
+        <el-table-column prop="orderRealIncomeSl" label="订单实收金额(SL)" min-width="120" />
         <el-table-column prop="payNum" label="订单应收笔数" min-width="100" />
         <el-table-column prop="orderRefundable" label="订单应退金额" min-width="120" />
         <el-table-column prop="refundNum" label="订单应退笔数" min-width="120" />
@@ -132,7 +134,7 @@
                 >
                   <div slot="header" class="acea-row row-between-wrapper">
                     <span class="header_title">订单实收</span>
-                    <div class="card_title">¥{{ accountDetails.orderRealIncome }}</div>
+                    <div class="card_title"><span style="margin-right: 20px;">¥{{ accountDetails.orderRealIncome }}</span> <span>sL{{ accountDetails.orderRealIncomeSl }}</span></div>
                   </div>
                   <div class="text item">
                     <el-row class="item mb20">

+ 6 - 4
crmeb_src/mer_plat_admin/src/views/order/index.vue

@@ -90,7 +90,7 @@
         "
         class="mt20"
       >
-        <el-table-column label="订单编号" min-width="220" v-if="checkedCities.includes('订单编号')">
+        <el-table-column label="订单编号" min-width="180" v-if="checkedCities.includes('订单编号')">
           <template slot-scope="scope">
             <div class="acea-row">
               <font v-show="scope.row.type === 1" class="mr5">[秒杀]</font>
@@ -108,19 +108,21 @@
             <span v-show="scope.row.isUserDel" class="colorPrompt" style="display: block">用户已删除</span>
           </template>
         </el-table-column>
-        <el-table-column prop="merName" label="商户名称" min-width="150" v-if="checkedCities.includes('商户名称')">
+        <el-table-column prop="merName" label="商户名称" min-width="130" v-if="checkedCities.includes('商户名称')">
           <template slot-scope="scope">
             <span> {{ scope.row.merName | filterEmpty }}</span>
           </template>
         </el-table-column>
-        <el-table-column prop="nickName" label="用户昵称" min-width="150" v-if="checkedCities.includes('用户昵称')">
+        <el-table-column prop="nickName" label="用户昵称" min-width="100" v-if="checkedCities.includes('用户昵称')">
           <template slot-scope="scope">
             <span :class="scope.row.isLogoff == true ? 'colorPrompt' : ''">{{ scope.row.nickName }}</span>
             <span :class="scope.row.isLogoff == true ? 'colorPrompt' : ''" v-if="scope.row.isLogoff == true">|</span>
             <span v-if="scope.row.isLogoff == true" class="colorPrompt">(已注销)</span>
           </template>
         </el-table-column>
-        <el-table-column prop="payPrice" label="实际支付" min-width="80" v-if="checkedCities.includes('实际支付')" />
+        <el-table-column prop="payPrice" label="实际支付RMB" min-width="80" v-if="checkedCities.includes('实际支付')" />
+        <el-table-column prop="totalPriceReat" label="实际支付SL" min-width="80"  />
+        <el-table-column prop="rate" label="支付汇率" min-width="80"  />
         <el-table-column label="支付方式" min-width="80" v-if="checkedCities.includes('支付方式')">
           <template slot-scope="scope">
             <span>{{ scope.row.payType | payTypeFilter }}</span>

+ 6 - 0
crmeb_src/mer_uniapp/App.vue

@@ -242,6 +242,12 @@
 
 			//配置项存储
 			store.commit('SET_GLOBAL_DATA', JSON.parse(JSON.stringify(that.globalData)));
+			
+			// 全局定时器:每60秒检查一次汇率是否过期
+			setInterval(() => {
+				store.dispatch('CheckExchangeRate');
+			}, 60000);
+
 		},
 		async mounted() {
 			//if (this.$store.getters.isLogin && !this.$Cache.get('USER_INFO')) await this.$store.dispatch('USERINFO');

+ 75 - 66
crmeb_src/mer_uniapp/api/user.js

@@ -14,7 +14,7 @@ import request from "@/utils/request.js";
  * 8bfb4 获取用户信息
  * 
 */
-export function getUserInfoApi(){
+export function getUserInfoApi() {
   return request.get('user/info');
 }
 
@@ -22,7 +22,7 @@ export function getUserInfoApi(){
  * 设置用户分享
  * 
 */
-export function userShare(){
+export function userShare() {
   return request.post('user/share');
 }
 
@@ -31,7 +31,7 @@ export function userShare(){
  * @param data object 用户账号密码
  */
 export function loginH5(data) {
-  return request.post("login/mobile/password", data, { noAuth : true });
+  return request.post("login/mobile/password", data, { noAuth: true });
 }
 
 /**
@@ -39,7 +39,7 @@ export function loginH5(data) {
  * @param data object
  */
 export function loginMobile(data) {
-  return request.post("login/mobile/captcha", data, { noAuth : true });
+  return request.post("login/mobile/captcha", data, { noAuth: true });
 }
 
 /**
@@ -53,8 +53,8 @@ export function getCodeApi() {
  * h5用户发送验证码
  * @param data object 用户手机号
  */
-export function registerVerify(phone){
-  return request.post('login/send/code', { phone: phone },{noAuth:true})
+export function registerVerify(phone) {
+  return request.post('login/send/code', { phone: phone }, { noAuth: true })
 }
 
 /**
@@ -62,7 +62,7 @@ export function registerVerify(phone){
  * @param data object 用户手机号 验证码 密码
  */
 export function register(data) {
-  return request.post("register", data, { noAuth : true });
+  return request.post("register", data, { noAuth: true });
 }
 
 /**
@@ -86,13 +86,13 @@ export function userCenterInfo() {
  *
  */
 export function userCenterInfoMenu() {
-  return request.get("user/center/info/menu",{},{ noAuth : true});
+  return request.get("user/center/info/menu", {}, { noAuth: true });
 }
 
 /**
  * 签到页信息
 */
-export function signInfo(data){
+export function signInfo(data) {
   return request.get('sign/page/info', data)
 }
 
@@ -101,15 +101,15 @@ export function signInfo(data){
  * @param object data
  * 
 */
-export function getSignMonthList(data){
-  return request.get('sign/record/list',data)
+export function getSignMonthList(data) {
+  return request.get('sign/record/list', data)
 }
 
 /**
  * 活动状态
  * 
 */
-export function userActivity(){
+export function userActivity() {
   return request.get('user/activity');
 }
 
@@ -145,8 +145,8 @@ export function getIntegralList(q) {
  * 获取分销海报图片
  * 
 */
-export function spreadBanner(){
-	return request.get('retail/store/user/poster/banner');
+export function spreadBanner() {
+  return request.get('retail/store/user/poster/banner');
 }
 
 /**
@@ -154,8 +154,8 @@ export function spreadBanner(){
  * 获取推广用户一级和二级
  * @param object data
 */
-export function spreadPeople(data){
-  return request.get('retail/store/spread/people/list',data);
+export function spreadPeople(data) {
+  return request.get('retail/store/spread/people/list', data);
 }
 
 /**
@@ -163,8 +163,8 @@ export function spreadPeople(data){
  * 推广佣金/提现总和
  * @param int type
 */
-export function spreadCount(type){
-  return request.get('spread/count/'+type);
+export function spreadCount(type) {
+  return request.get('spread/count/' + type);
 }
 
 /*
@@ -180,8 +180,8 @@ export function myPromotion() {
  * 推广订单
  * @param object data
 */
-export function spreadOrder(data){
-  return request.get('retail/store/spread/order/list',data);
+export function spreadOrder(data) {
+  return request.get('retail/store/spread/order/list', data);
 }
 
 /*
@@ -202,15 +202,15 @@ export function getBrokerageRank(type) {
  * 用户结算申请
  * @param object data
 */
-export function extractCash(data){
-  return request.post('retail/store/user/closing/apply',data)
+export function extractCash(data) {
+  return request.post('retail/store/user/closing/apply', data)
 }
 
 /**
  * 会员等级列表
  * 
 */
-export function userLevelGrade(){
+export function userLevelGrade() {
   return request.get('user/level/grade');
 }
 
@@ -218,15 +218,15 @@ export function userLevelGrade(){
  * 获取某个等级任务
  * @param int id 任务id
 */
-export function userLevelTask(id){
-  return request.get('user/level/task/'+id);
+export function userLevelTask(id) {
+  return request.get('user/level/task/' + id);
 }
 
 /**
  * 检查用户是否可以成为会员
  * 
 */
-export function userLevelDetection(){
+export function userLevelDetection() {
   return request.get('user/level/detection');
 }
 
@@ -234,7 +234,7 @@ export function userLevelDetection(){
  * 
  * 地址列表
 */
-export function getAddressList(){
+export function getAddressList() {
   return request.get('address/list');
 }
 
@@ -242,7 +242,7 @@ export function getAddressList(){
  * 设置默认地址
  * @param int id
 */
-export function setAddressDefault(id){
+export function setAddressDefault(id) {
   return request.post(`address/set/default/${id}`)
 }
 
@@ -250,16 +250,16 @@ export function setAddressDefault(id){
  * 修改 地址
  * @param object data
 */
-export function editAddress(data){
-  return request.post('address/edit',data);
+export function editAddress(data) {
+  return request.post('address/edit', data);
 }
 
 /**
  * 添加 地址
  * @param object data
 */
-export function addAddress(data){
-  return request.post('address/add',data);
+export function addAddress(data) {
+  return request.post('address/add', data);
 }
 
 /**
@@ -267,7 +267,7 @@ export function addAddress(data){
  * @param int id
  * 
 */
-export function delAddress(id){
+export function delAddress(id) {
   return request.post(`address/delete/${id}`)
 }
 
@@ -275,7 +275,7 @@ export function delAddress(id){
  * 地址详情
  * @param int id 
 */
-export function getAddressDetail(id){
+export function getAddressDetail(id) {
   return request.get(`address/detail/${id}`);
 }
 
@@ -283,7 +283,7 @@ export function getAddressDetail(id){
  * 获取微信地址信息
  * @param object data 
 */
-export function getWxAddressInfo(data){
+export function getWxAddressInfo(data) {
   return request.post(`address/wechat/info`, data);
 }
 
@@ -291,8 +291,8 @@ export function getWxAddressInfo(data){
  * 修改用户信息
  * @param object
 */
-export function userEdit(data){
-  return request.post('user/user/edit',data);
+export function userEdit(data) {
+  return request.post('user/user/edit', data);
 }
 
 /*
@@ -308,15 +308,15 @@ export function getLogout() {
  * 
  */
 export function userOut(data) {
-	return request.post(`user/logoff`, data)
+  return request.post(`user/logoff`, data)
 }
 
 /**
  * 小程序充值
  * 
 */
-export function rechargeRoutine(data){
-  return request.post('recharge/routine',data)
+export function rechargeRoutine(data) {
+  return request.post('recharge/routine', data)
 }
 /*
  * 公众号充值
@@ -336,27 +336,27 @@ export function appWechat(data) {
  * 佣金转入
  * */
 export function transferIn(data) {
-  return request.post("retail/store/brokerage/to/yue", data,1);
+  return request.post("retail/store/brokerage/to/yue", data, 1);
 }
 
 /*
  * 生成用户充值订单
  * */
 export function rechargeCreateApi(data) {
-    return request.post("recharge/user/create", data);
+  return request.post("recharge/user/create", data);
 }
 
 /*
  * 支付宝充值
  * */
 export function alipayFull(data) {
-  return request.post("recharge/alipay", data,{});
+  return request.post("recharge/alipay", data, {});
 }
 
 /**
  * 获取默认地址
 */
-export function getAddressDefaultApi(){
+export function getAddressDefaultApi() {
   return request.get('address/get/default');
 }
 
@@ -364,7 +364,7 @@ export function getAddressDefaultApi(){
 /**
  * 获取用户地址经纬度
  */
-export function getAddressLocationApi(id){
+export function getAddressLocationApi(id) {
   return request.get(`address/get/lon/lat/${id}`);
 }
 
@@ -378,9 +378,8 @@ export function getRechargeApi() {
 /**
  * 登录记录
  */
-export function setVisit(data)
-{
-  return request.post('user/set_visit', {...data}, { noAuth:true});
+export function setVisit(data) {
+  return request.post('user/set_visit', { ...data }, { noAuth: true });
 }
 
 /**
@@ -400,45 +399,40 @@ export function getChatRecord(to_uid, data) {
  * 绑定推广关系
  * @param {number} spreadPid
  */
-export function spreadApi(spreadPid)
-{
-	return request.post(`retail/store/binding/user/${spreadPid}`);
+export function spreadApi(spreadPid) {
+  return request.post(`retail/store/binding/user/${spreadPid}`);
 }
 
 /**
  * 会员等级经验值;
  * 
  */
-export function getlevelInfo()
-{
-	return request.get("user/center/user/level/grade");
+export function getlevelInfo() {
+  return request.get("user/center/user/level/grade");
 }
 
 /**
  * 经验值明细;
  * 
  */
-export function getlevelExpList(data)
-{
-	return request.get("user/expList",data);
+export function getlevelExpList(data) {
+  return request.get("user/expList", data);
 }
 
 /**
  * 我的账户金额明细;
  * 
  */
-export function getMyAccountApi()
-{
-	return request.get("user/center/my/account");
+export function getMyAccountApi() {
+  return request.get("user/center/my/account");
 }
 
 /**
  * 账单记录;
  * 
  */
-export function getBillList(data)
-{
-	return request.get("user/center/balance/record",data);
+export function getBillList(data) {
+  return request.get("user/center/balance/record", data);
 }
 
 /*
@@ -486,13 +480,28 @@ export function myExpRecordApi(data) {
 /**
  * 版权图片
 */
-export function copyrightImageApi(){
-  return request.get(`index/copyright/company/image`,{},{noAuth:true});
+export function copyrightImageApi() {
+  return request.get(`index/copyright/company/image`, {}, { noAuth: true });
 }
 
 /**
  * 版权图片
 */
-export function userLevelRuleApi(){
+export function userLevelRuleApi() {
   return request.get(`agreement/user/level/rule`);
+}
+
+/**
+ * 提现 sLGNS
+ * @param object data
+ */
+export function sLgnsWithdrawApi(data) {
+  return request.post("pay/payment/money/to/user", data);
+}
+
+/**
+ * 获取支付用户数量/信息 (测试接口)
+ */
+export function getPaymentUserNumber() {
+  return request.post("pay/payment/money/to/user/number");
 }

+ 1 - 1
crmeb_src/mer_uniapp/components/BaseMoney.vue

@@ -2,7 +2,7 @@
 	<view :class="{ line: line, weight: weight, 'font-color': !incolor}"
 		:style="{color: '#' + incolor,fontWeight: fontWeight, display:(discount || inline) ? 'inline-block' : 'block' }"
 		class="base-money semiBold line-heightOne">
-		<text v-if="!discount" class="symbol" :style="{'font-size': symbolSize +'rpx'}"></text><text class="integer line-heightOne"
+		<text v-if="!discount" class="symbol" :style="{'font-size': symbolSize +'rpx'}">sL </text><text class="integer line-heightOne"
 			:style="{'font-size': integerSize +'rpx'}">{{ integer }}</text>
 		<text v-if="digits && decimal != '00' && decimal != '0'" class="decimal"
 			:style="{'font-size': decimalSize +'rpx'}">.{{ decimal }}</text>

+ 1 - 1
crmeb_src/mer_uniapp/components/orderGoods/index.vue

@@ -37,7 +37,7 @@
 						<!-- 其他价格 -->
 						<view v-else class='acea-row justify-between' style="align-items: baseline;">
 							<view v-show="item.price || item.productPrice" class="acea-row">
-								<view class='money line-heightOne regular'>¥{{item.price || item.productPrice}}</view>
+								<view class='money line-heightOne regular'>sL{{item.priceSl || item.productPriceSl}}</view>
 							</view>
 							<view
 								v-if="(item.deliveryMethod == 1 || !orderInfo.takeTheirSwitch) && !jump && Number(item.productType)==0"

+ 2 - 2
crmeb_src/mer_uniapp/config/app.js

@@ -8,8 +8,8 @@
 // | Author: CRMEB Team <admin@crmeb.com>
 // +----------------------------------------------------------------------
 //移动端商城API 网络接口修改此配置,小程序域名要求https 例如:https://xxx
- // let domain = 'http://127.0.0.1:20810'
-let domain = 'https://play.nanodreamtech.com'
+let domain = 'http://127.0.0.1:20810'
+//let domain = 'https://play.nanodreamtech.com'
 
 module.exports = {
 	// 请求域名 格式: https://您的域名

+ 11 - 10
crmeb_src/mer_uniapp/config/cache.js

@@ -12,7 +12,7 @@ module.exports = {
         //token
         LOGIN_STATUS: 'LOGIN_STATUS_TOKEN',
         // uid
-        UID:'UID',
+        UID: 'UID',
         //用户信息
         USER_INFO: 'USER_INFO',
         //wx授权
@@ -37,13 +37,14 @@ module.exports = {
         CACHE_LONGITUDE: 'LONGITUDE',
         //缓存纬度
         CACHE_LATITUDE: 'LATITUDE',
-		 //app手机信息
-		PLATFORM: 'systemPlatform',
-		GLOBAL_DATA: 'globalData',
-		//商户权限
-		SELECT_MERID:'selectMerId',
-		MERCHANT_EMPLOYEE_LIST:'merchantEmployeeList',
-		SELECT_MERCHANT:'selectMerchantRole',
-		MANAGER_STATUS:'MANAGER_STATUS_TOKEN',
-		IS_EMPLOYEE:'isEmployee',
+        //app手机信息
+        PLATFORM: 'systemPlatform',
+        GLOBAL_DATA: 'globalData',
+        //商户权限
+        SELECT_MERID: 'selectMerId',
+        MERCHANT_EMPLOYEE_LIST: 'merchantEmployeeList',
+        SELECT_MERCHANT: 'selectMerchantRole',
+        MANAGER_STATUS: 'MANAGER_STATUS_TOKEN',
+        IS_EMPLOYEE: 'isEmployee',
+        EXCHANGE_RATE_CACHE: 'EXCHANGE_RATE_CACHE'
 }

+ 3 - 2
crmeb_src/mer_uniapp/mixins/OrderPay.js

@@ -307,7 +307,7 @@ export default {
 		 * @param {data} res 订单对象
 		 */
 		getToPayment(secondType,data) {
-			let url = `/pages/goods/order_payment/index?orderNo=${data.orderNo}&payPrice=${data.payPrice}`
+			let url = `/pages/goods/order_payment/index?orderNo=${data.orderNo}&payPrice=${data.payPrice}&totalPriceReat=${data.totalPriceReat}`
 			uni.redirectTo({
 				url: url
 			});
@@ -322,8 +322,9 @@ export default {
 		 * @param {Object} fromType  页面来源
 		 * @param {Object} payPrice  支付金额
 		 */
-		changeOrderPay(orderNo, payChannel, payType ,productType, fromType, payPrice) {
+		changeOrderPay(orderNo, payChannel, payType ,productType, fromType, payPrice,totalPriceReat) {
 			orderPayApi({
+				totalPriceReat: totalPriceReat,
 				orderNo: orderNo,
 				payChannel: payChannel,
 				payType: payType,

+ 81 - 63
crmeb_src/mer_uniapp/pages.json

@@ -17,8 +17,8 @@
 				"navigationBarTitleText": "首页",
 				"navigationStyle": "custom",
 				"navigationBarTextStyle": "black"
-					// #ifdef APP-PLUS
-					,
+				// #ifdef APP-PLUS
+				,
 				"enablePullDownRefresh": true
 				// #endif
 			}
@@ -71,10 +71,12 @@
 			}
 		}
 	],
-	"subPackages": [{
+	"subPackages": [
+		{
 			"root": "pages/users",
 			"name": "users",
-			"pages": [{
+			"pages": [
+				{
 					"path": "web_page/index",
 					"style": {
 						//"navigationBarTitleText": "客服",
@@ -127,6 +129,13 @@
 						}
 					}
 				},
+				{
+					"path": "user_withd_slgns/index",
+					"style": {
+						"navigationBarTitleText": "我的账户",
+						"navigationStyle": "custom"
+					}
+				},
 				{
 					"path": "user_bill/index",
 					"style": {
@@ -215,11 +224,11 @@
 					"style": {
 						"navigationBarTitleText": "修改手机号",
 						"navigationBarBackgroundColor": "#e93323"
-							// #ifdef MP || APP-PLUS
-							,
+						// #ifdef MP || APP-PLUS
+						,
 						"navigationBarTextStyle": "black"
-							// #endif
-							,
+						// #endif
+						,
 						"app-plus": {
 							// #ifdef APP-PLUS
 							"titleNView": {
@@ -259,11 +268,11 @@
 					"path": "user_pwd_edit/index",
 					"style": {
 						"navigationBarTitleText": "修改密码"
-							// #ifdef MP || APP-PLUS
-							,
+						// #ifdef MP || APP-PLUS
+						,
 						"navigationBarTextStyle": "black"
-							// #endif
-							,
+						// #endif
+						,
 						"app-plus": {
 							// #ifdef APP-PLUS
 							"titleNView": {
@@ -413,14 +422,14 @@
 		{
 			"root": "pages/merchant",
 			"name": "merchant",
-			"pages": [{
+			"pages": [
+				{
 					"path": "home/index",
 					"style": {
 						"navigationBarTitleText": "商户首页",
 						"navigationStyle": "custom",
 						"enablePullDownRefresh": false
 					}
-
 				},
 				{
 					"path": "classify_coupon/index",
@@ -436,7 +445,6 @@
 							// #endif
 						}
 					}
-
 				},
 				{
 					"path": "application_record/index",
@@ -451,7 +459,6 @@
 							// #endif
 						}
 					}
-
 				},
 				{
 					"path": "detail/index",
@@ -523,7 +530,6 @@
 							// #endif
 						}
 					}
-
 				}
 			]
 		},
@@ -989,7 +995,8 @@
 		{
 			"root": "pages/address",
 			"name": "address",
-			"pages": [{
+			"pages": [
+				{
 					"path": "user_address_list/index",
 					"style": {
 						"navigationBarTitleText": "地址管理",
@@ -1026,13 +1033,14 @@
 		{
 			"root": "pages/activity",
 			"name": "activity",
-			"pages": [{
+			"pages": [
+				{
 					"path": "goods_seckill/index",
 					"style": {
 						"navigationBarTitleText": "秒杀列表",
 						"navigationStyle": "custom"
-							// #ifdef MP || APP-PLUS
-							,
+						// #ifdef MP || APP-PLUS
+						,
 						"navigationBarTextStyle": "black"
 						// #endif
 					}
@@ -1042,8 +1050,8 @@
 					"style": {
 						"navigationBarTitleText": "秒杀列表",
 						"navigationStyle": "custom"
-							// #ifdef MP || APP-PLUS
-							,
+						// #ifdef MP || APP-PLUS
+						,
 						"navigationBarTextStyle": "black"
 						// #endif
 					}
@@ -1053,8 +1061,8 @@
 					"style": {
 						"navigationBarTitleText": "拼团活动",
 						"navigationStyle": "custom"
-							// #ifdef MP || APP-PLUS
-							,
+						// #ifdef MP || APP-PLUS
+						,
 						"navigationBarTextStyle": "black"
 						// #endif
 					}
@@ -1163,8 +1171,8 @@
 					"style": {
 						"navigationBarTitleText": "热门推荐",
 						"navigationStyle": "custom"
-							// #ifdef MP || APP-PLUS
-							,
+						// #ifdef MP || APP-PLUS
+						,
 						"navigationBarTextStyle": "black"
 						// #endif
 					}
@@ -1188,7 +1196,8 @@
 		{
 			"root": "pages/discover",
 			"name": "discover",
-			"pages": [{
+			"pages": [
+				{
 					"path": "discover_search_list/index",
 					"style": {
 						"navigationBarTitleText": "搜索页面",
@@ -1292,7 +1301,8 @@
 		{
 			"root": "pages/admin/",
 			"name": "admin",
-			"pages": [{
+			"pages": [
+				{
 					"path": "work/index",
 					"style": {
 						"navigationBarTitleText": "工作台",
@@ -1551,46 +1561,51 @@
 		{
 			"root": "pages/circle",
 			"name": "circle",
-			"pages": [{
-				"path": "index",
-				"style": {
-					"navigationBarTitleText": "圈层定位",
-					"navigationStyle": "custom"
-				}
-			}, {
-				"path": "select",
-				"style": {
-					"navigationBarTitleText": "选择位置",
-					"navigationStyle": "custom"
-				}
-			}, {
-				"path": "specify",
-				"style": {
-					"navigationBarTitleText": "选择圈层",
-					"app-plus": {
-						// #ifdef APP-PLUS
-						"titleNView": {
-							"type": "default"
+			"pages": [
+				{
+					"path": "index",
+					"style": {
+						"navigationBarTitleText": "圈层定位",
+						"navigationStyle": "custom"
+					}
+				},
+				{
+					"path": "select",
+					"style": {
+						"navigationBarTitleText": "选择位置",
+						"navigationStyle": "custom"
+					}
+				},
+				{
+					"path": "specify",
+					"style": {
+						"navigationBarTitleText": "选择圈层",
+						"app-plus": {
+							// #ifdef APP-PLUS
+							"titleNView": {
+								"type": "default"
+							}
+							// #endif
 						}
-						// #endif
 					}
 				}
-			}]
+			]
 		}
 		//#ifdef H5
 		,
 		{
 			"root": "pages/auth",
 			"name": "pages/auth/index",
-			"pages": [{
-				"path": "index",
-				"style": {
-					"navigationBarTitleText": "CRMEB"
+			"pages": [
+				{
+					"path": "index",
+					"style": {
+						"navigationBarTitleText": "CRMEB"
+					}
 				}
-			}]
+			]
 		}
 		//#endif
-
 	],
 	"globalStyle": {
 		"navigationBarTextStyle": "black",
@@ -1611,7 +1626,8 @@
 		"selectedColor": "#fc4141",
 		"borderStyle": "white",
 		"backgroundColor": "#ffffff",
-		"list": [{
+		"list": [
+			{
 				"pagePath": "pages/index/index",
 				"iconPath": "static/tabBar/shouwei.png",
 				"selectedIconPath": "static/tabBar/shouxuan.png",
@@ -1645,10 +1661,12 @@
 	},
 	"condition": { //模式配置,仅开发期间生效
 		"current": 0, //当前激活的模式(list 的索引项)
-		"list": [{
-			"name": "", //模式名称
-			"path": "", //启动页面,必选
-			"query": "" //启动参数,在页面的onLoad函数里面得到
-		}]
+		"list": [
+			{
+				"name": "", //模式名称
+				"path": "", //启动页面,必选
+				"query": "" //启动参数,在页面的onLoad函数里面得到
+			}
+		]
 	}
 }

+ 133 - 79
crmeb_src/mer_uniapp/pages/goods/order_confirm/index.vue

@@ -124,13 +124,13 @@
 					<view v-show="item.shippingType === 1 && Number(orderInfoVo.secondType)===0"
 						class='item acea-row row-between-wrapper'>
 						<view>快递费用</view>
-						<view v-if='!item.freightFee || item.freightFee == 0' class="noCoupon">免运费</view>
-						<view v-else class='money'>¥{{item.freightFee || 0}}</view>
+						<view v-if='!item.freightFeeSl || item.freightFeeSl == 0' class="noCoupon">免运费</view>
+						<view v-else class='money'>sL{{item.freightFeeSl || 0}}</view>
 					</view>
-					<view v-show="item.svipDiscountPrice != 0&&orderInfoVo.type!=2"
+					<view v-show="item.svipDiscountPriceSl != 0&&orderInfoVo.type!=2"
 						class='item acea-row row-between-wrapper'>
 						<view>会员优惠</view>
-						<view class='money'>-¥{{item.svipDiscountPrice || 0}}</view>
+						<view class='money'>-sL{{item.svipDiscountPriceSl || 0}}</view>
 					</view>
 					<view v-if="isProductType" class='item acea-row row-between-wrapper'>
 						<view>店铺优惠</view>
@@ -138,7 +138,7 @@
 							@tap='couponTap(item.merCouponUserList,item.merId, index)'>
 							<view class='discount acea-row row-between-wrapper'>
 								<text
-									class="couponTitle line1">{{item.couponFee==0?`有${item.merCouponUserList.length}张优惠券可选`:`-¥${item.couponFee}`}}</text>
+									class="couponTitle line1">{{item.couponFeeSl==0?`有${item.merCouponUserList.length}张优惠券可选`:`-sL${item.couponFeeSl}`}}</text>
 								<text class='iconfont text-bbb icon-ic_rightarrow ml-4'></text>
 							</view>
 						</view>
@@ -159,20 +159,20 @@
         <view v-show="secondType !== ProductTypeEnum.Integral" class='moneyList borRadius14'>
           <view class='item acea-row row-between-wrapper'>
             <view>商品总价</view>
-            <view class='money'>¥{{orderInfoVo.proTotalFee || 0}}</view>
+            <view class='money'>sL{{orderInfoVo.proTotalFeeSl || 0}}</view>
           </view>
-          <view class='item acea-row row-between-wrapper' v-if="parseInt(orderInfoVo.freightFee) > 0">
+          <view class='item acea-row row-between-wrapper' v-if="parseInt(orderInfoVo.freightFeeSl) > 0">
             <view>运费:</view>
-            <view class='money'>+¥{{orderInfoVo.freightFee || 0}}</view>
+            <view class='money'>+sL{{orderInfoVo.freightFeeSl || 0}}</view>
           </view>
-          <view v-show="orderInfoVo.svipDiscountPrice != 0 &&orderInfoVo.type!=2"
+          <view v-show="orderInfoVo.svipDiscountPriceSl != 0 &&orderInfoVo.type!=2"
                 class='item acea-row row-between-wrapper'>
             <view>会员优惠</view>
-            <view class='money'>-¥{{orderInfoVo.svipDiscountPrice || 0}}</view>
+            <view class='money'>-sL{{orderInfoVo.svipDiscountPriceSl || 0}}</view>
           </view>
-          <view class='item acea-row row-between-wrapper' v-if="parseInt(merCouponFee) > 0 && isProductType">
+          <view class='item acea-row row-between-wrapper' v-if="parseInt(merCouponFeeSl) > 0 && isProductType">
             <view>店铺优惠</view>
-            <view class='money'>-¥{{merCouponFee}}</view>
+            <view class='money'>-sL{{merCouponFeeSl}}</view>
           </view>
           <view v-if="isProductType" class='item acea-row row-between-wrapper'>
             <view>平台优惠</view>
@@ -180,7 +180,7 @@
                   class='discount acea-row row-between-wrapper'
                   @tap='couponTap(orderInfoVo.platCouponUserList,0)'>
               <text
-                  class="couponTitle line1">{{platCouponFee==0?`有${orderInfoVo.platCouponUserList.length}张优惠券可选`:`-¥${platCouponFee}`}}</text>
+                  class="couponTitle line1">{{platCouponFeeSl==0?`有${orderInfoVo.platCouponUserList.length}张优惠券可选`:`-sL${platCouponFeeSl}`}}</text>
               <text class='text-bbb iconfont icon-ic_rightarrow ml-4'></text>
             </view>
             <view v-else class="noCoupon">暂无优惠券</view>
@@ -200,9 +200,9 @@
             </view>
           </view>
 
-          <view class='item acea-row row-between-wrapper' v-if="Number(orderInfoVo.deductionPrice) > 0">
+          <view class='item acea-row row-between-wrapper' v-if="Number(orderInfoVo.deductionPriceSl) > 0">
             <view>抵扣金额</view>
-            <view class='money'>-¥{{orderInfoVo.deductionPrice || 0}}</view>
+            <view class='money'>-sL {{orderInfoVo.deductionPriceSl || 0}}</view>
           </view>
 
         </view>
@@ -214,7 +214,7 @@
 					<PointsPrice v-if="orderInfoVo.secondType === ProductTypeEnum.Integral" :pointsPrice="orderInfoVo"
 						:pointsGoodsStyle="hotPointsStyle"></PointsPrice>
 					<!-- 其他价格 -->
-					<text v-else class='price_color f-s-38 regular line-heightOne'>¥{{orderInfoVo.payFee || 0}}</text>
+					<text v-else class='price_color f-s-38 regular line-heightOne'>sL{{orderInfoVo.totalPriceReat || 0}}</text>
 				</view>
 				<view class='settlement' style='z-index:100' @tap="SubOrder">
 					{{secondType === ProductTypeEnum.Integral?"确认兑换":"立即下单"}}
@@ -284,6 +284,7 @@
 		ProductMarketingTypeEnum
 	} from "../../../enums/productEnums";
 	import orderPay from "@/mixins/OrderPay.js";
+	import {rmbToLgns,getRmbToLgnsRate} from "@/utils";
 	let app = getApp();
 	/**
 	 * 积分商品推荐样式
@@ -385,6 +386,8 @@
 				platUserCouponId: 0, //平台优惠券id
 				platCouponFee: '', //平台优惠券金额
 				merCouponFee: '', //店铺优惠券总金额
+				platCouponFeeSl: '', //平台优惠券金额
+				merCouponFeeSl: '', //店铺优惠券总金额
 				surplusFee: 0, //商品总金额-商户优惠券金额=平台端可使用优惠券的门槛
 				merUserCouponId: 0, //店铺使用优惠券的id
 				tempCouponObj: {}, //临时优惠券数据
@@ -393,7 +396,7 @@
 				orderExtend: {}, //提交接口表单的数据
 				productId:'',
 				groupActivityId:'',
-        reservationInfo: {} // 预约信息
+				reservationInfo: {} // 预约信息
 			};
 		},
 		watch: {
@@ -423,15 +426,15 @@
 			this.textareaStatus = true;
 		},
 		methods: {
-      //滚动
-      touchStart() {
-        // #ifdef MP || APP
-        this.$refs.navBarRef.currentPage = false;
-        // #endif
-      },
+			//滚动
+			touchStart() {
+				// #ifdef MP || APP
+				this.$refs.navBarRef.currentPage = false;
+				// #endif
+			},
 			popupClose() {
 				this.$refs.sh_popup.close()
-        this.$util.navigateTo('/pages/index/index');
+				this.$util.navigateTo('/pages/index/index');
 			},
 			//去开团
 			toAudit() {
@@ -514,6 +517,7 @@
 			getloadPreOrder: function() {
 				loadPreOrderApi(this.orderNo).then(res => {
 					let orderInfoVo = res.data;
+					orderInfoVo.proTotalFeeSl = 0
 					if(orderInfoVo.merchantInfoList[0].orderInfoList[0].groupBuyActivityId){
 						this.groupActivityId=orderInfoVo.merchantInfoList[0].orderInfoList[0].groupBuyActivityId
 						this.productId=orderInfoVo.merchantInfoList[0].orderInfoList[0].productId
@@ -521,35 +525,73 @@
 					if (orderInfoVo.merchantInfoList[0].deliveryMethodMer.split(',').length == 1) {
 						this.shippingType = orderInfoVo.merchantInfoList[0].deliveryMethodMer
 					}
-          this.reservationInfo =  uni.getStorageSync('reservationInfo') || {} //缓存的预约信息,地址id,配送类型
+          			this.reservationInfo =  uni.getStorageSync('reservationInfo') || {} //缓存的预约信息,地址id,配送类型
+					
 					orderInfoVo.merchantInfoList.map(item => {
-            if (item.shippingType === 2) this.getTakeTheir(item.merId)
+						item.couponFeeSl = rmbToLgns(item.couponFee)
+						item.merCouponFeeSl = rmbToLgns(item.merCouponFee)
+						item.freightFeeSl = rmbToLgns(item.freightFee)
+						item.svipDiscountPriceSl = rmbToLgns(item.svipDiscountPrice)
+						
+						if (item.shippingType === 2) this.getTakeTheir(item.merId)
 						this.orderMerchantRequestList.push({
 							shippingType: orderInfoVo.secondType === this.ProductTypeEnum.Reservation ? this.reservationInfo.shippingType : item.shippingType,
 							merId: item.merId,
 							remark: '',
 							userCouponId: item.userCouponId
 						})
+						item.orderInfoList.map(list => {
+							list.priceSl = rmbToLgns(list.price)
+							list.vipPriceSl = rmbToLgns(list.vipPrice)
+							list.payPriceSl = rmbToLgns(list.payPrice)
+							list.merCouponPriceSl = rmbToLgns(list.merCouponPrice)
+							if(list.vipPriceSl != 0){
+								orderInfoVo.proTotalFeeSl = parseFloat(
+									(parseFloat(orderInfoVo.proTotalFeeSl) + parseFloat((list.vipPriceSl * list.payNum))).toFixed(2)
+								);
+							}else{
+								orderInfoVo.proTotalFeeSl = parseFloat(
+									(parseFloat(orderInfoVo.proTotalFeeSl) + parseFloat((list.payPriceSl * list.payNum))).toFixed(2)
+								);
+							}
+						})
 						item.addressDetail = this.merchangtInfo.addressDetail;
 						item.phone = this.merchangtInfo.phone;
 						item.latitude = this.merchangtInfo.latitude;
 						item.longitude = this.merchangtInfo.longitude;
 					});
-          this.merchantOrderVoList = orderInfoVo.merchantInfoList; //商户端数据
-          this.platCouponFee = orderInfoVo.platCouponFee; //平台优惠券总金额
-          this.platUserCouponId = orderInfoVo.platUserCouponId;
-          this.merCouponFee = orderInfoVo.merCouponFee; //店铺优惠券总金额
-          this.orderInfoVo = {
-            ...orderInfoVo,
-            systemFormValue: orderInfoVo.systemFormValue ? this.$util.objToArr(JSON.parse(
-                orderInfoVo.systemFormValue)) : []
-          };
-          let payNum = orderInfoVo.formDataSubmitType === 1 ? orderInfoVo.merchantInfoList[0].orderInfoList[0].payNum : 1//预约单的商品下单数量
-          this.$nextTick(() => {
-            if(this.orderInfoVo.systemFormValue.length){
-              this.$refs.systemFromRef.getFormList(payNum)
-            }
-          })
+					this.platUserCouponId = orderInfoVo.platUserCouponId;
+					this.merchantOrderVoList = orderInfoVo.merchantInfoList; //商户端数据
+					
+					this.platCouponFee = orderInfoVo.platCouponFee; //平台优惠券总金额
+					this.merCouponFee = orderInfoVo.merCouponFee; //店铺优惠券总金额
+					
+					this.platCouponFeeSl = rmbToLgns(orderInfoVo.platCouponFee); //平台优惠券总金额
+					this.merCouponFeeSl = rmbToLgns(orderInfoVo.merCouponFee); //店铺优惠券总金额
+					orderInfoVo.freightFeeSl = rmbToLgns(orderInfoVo.freightFee);
+					orderInfoVo.svipDiscountPriceSl = rmbToLgns(orderInfoVo.svipDiscountPrice);
+					orderInfoVo.deductionPriceSl = rmbToLgns(orderInfoVo.deductionPrice);
+					orderInfoVo.payFeeSl = rmbToLgns(orderInfoVo.payFee);
+					orderInfoVo.totalPriceReat = parseFloat(
+						(parseFloat(orderInfoVo.proTotalFeeSl) - parseFloat(this.platCouponFeeSl) - parseFloat(this.merCouponFeeSl)).toFixed(2)
+					);
+					// 这是汇率差
+					orderInfoVo.reatDiff = parseFloat(
+					  (parseFloat(orderInfoVo.totalPriceReat) - parseFloat(orderInfoVo.payFeeSl)).toFixed(2)
+					);
+					// 这个是下单时的汇率
+					orderInfoVo.rate = getRmbToLgnsRate()
+					this.orderInfoVo = {
+						...orderInfoVo,
+						systemFormValue: orderInfoVo.systemFormValue ? this.$util.objToArr(JSON.parse(
+							orderInfoVo.systemFormValue)) : []
+					};
+					let payNum = orderInfoVo.formDataSubmitType === 1 ? orderInfoVo.merchantInfoList[0].orderInfoList[0].payNum : 1//预约单的商品下单数量
+					this.$nextTick(() => {
+						if(this.orderInfoVo.systemFormValue.length){
+						this.$refs.systemFromRef.getFormList(payNum)
+						}
+					})
 					this.type = orderInfoVo.type; //订单类型
 					this.secondType = orderInfoVo
 						.secondType; //订单二级类型:0-普通订单,1-积分订单,2-虚拟订单,4-视频号订单,5-云盘订单,6-卡密订单
@@ -710,6 +752,7 @@
 						this.changeOrderPay(res.data.orderNo, 'yue', 'yue', 'integral', 'integral', '0')
 					} else {
 						// 其他商品走正常流程,去支付收银台页面
+						res.data.totalPriceReat = data.orderInfoVo.totalPriceReat
 						this.getToPayment(this.secondType, res.data)
 					}
 
@@ -722,43 +765,55 @@
 				});
 			},
 			//立即下单
-      SubOrder: Debounce(async function (e) {
-        let that = this,
-            data = {};
-        let flag = false;
-        that.orderMerchantRequestList.map(function (v) {
-          if (v.shippingType === 1 && !that.addressId && that.orderInfoVo.secondType !== 2) {
-            flag = true;
-          }
-        });
-        if (flag && this.secondType !== this.ProductTypeEnum.Reservation) {
-          that.$util.Tips({
-            title: '请选择收货地址'
-          });
-          return;
-        }
-        let systemFormData = []
-        if( this.orderInfoVo.systemFormValue.length){
-          systemFormData = await this.$refs.systemFromRef.getSubmitFromData()
-          if(!systemFormData.length) return;
-        }
-
-        data = {
-          addressId: this.secondType === this.ProductTypeEnum.Reservation ? this.reservationInfo.addressId : that.addressId,
-          orderMerchantRequestList: that.orderMerchantRequestList,
-          isUseIntegral: that.isUseIntegral,
-          preOrderNo: that.orderNo,
-          platUserCouponId: this.platUserCouponId,
-          systemFormId: this.orderInfoVo.systemFormId,
-          orderExtend: systemFormData.length ? JSON.stringify(systemFormData) : '',
-          reservationName: this.reservationInfo.reservationName,
-          reservationPhone: this.reservationInfo.reservationPhone
-        };
-        uni.showLoading({
-          title: '订单提交中'
-        });
-        await that.payment(data);
-      })
+			SubOrder: Debounce(async function (e) {
+				let that = this,
+					data = {};
+				let flag = false;
+				that.orderMerchantRequestList.map(function (v) {
+					if (v.shippingType === 1 && !that.addressId && that.orderInfoVo.secondType !== 2) {
+						flag = true;
+					}
+				});
+				if (flag && this.secondType !== this.ProductTypeEnum.Reservation) {
+					that.$util.Tips({
+						title: '请选择收货地址'
+					});
+					return;
+				}
+				let systemFormData = []
+				if( this.orderInfoVo.systemFormValue.length){
+					systemFormData = await this.$refs.systemFromRef.getSubmitFromData()
+					if(!systemFormData.length) return;
+				}
+
+				data = {
+					addressId: this.secondType === this.ProductTypeEnum.Reservation ? this.reservationInfo.addressId : that.addressId,
+					orderMerchantRequestList: that.orderMerchantRequestList,
+					isUseIntegral: that.isUseIntegral,
+					preOrderNo: that.orderNo,
+					platUserCouponId: this.platUserCouponId,
+					systemFormId: this.orderInfoVo.systemFormId,
+					orderExtend: systemFormData.length ? JSON.stringify(systemFormData) : '',
+					reservationName: this.reservationInfo.reservationName,
+					reservationPhone: this.reservationInfo.reservationPhone,
+					reservationPhone: this.reservationInfo.reservationPhone,
+					orderInfoVo: {
+						// 这是 totalPriceReat - payFeeSl 所谓的汇差
+						reatDiff: this.orderInfoVo.reatDiff,
+						// 这是订单下单时候的汇率
+						rate: this.orderInfoVo.rate,
+						// 这是通过产品价格/汇率*数量累计扣掉优惠后的总价(当前使用的是totalPriceReat来结算)
+						totalPriceReat: this.orderInfoVo.totalPriceReat,
+						// 这是rmb直接/汇率后扣掉优惠的总价
+						payFeeSl: this.orderInfoVo.payFeeSl
+					}
+				};
+				console.log(data)
+				uni.showLoading({
+					title: '订单提交中'
+				});
+				await that.payment(data);
+			})
 		}
 	}
 </script>
@@ -769,7 +824,6 @@
 	}
 	.noCoupon {
 		color: #999999;
-
 	}
 
 	.mr14 {

+ 33 - 13
crmeb_src/mer_uniapp/pages/goods/order_details/index.vue

@@ -243,30 +243,30 @@
 						<PointsPrice v-if="secondType === ProductTypeEnum.Integral" :pointsPrice="pointsPrice"
 							:pointsGoodsStyle="hotPointsStyle"></PointsPrice>
 						<!-- 其他价格 -->
-						<view v-else class='conter'>¥{{orderInfo.proTotalPrice || 0}}</view>
+						<view v-else class='conter'>sL{{orderInfo.proTotalPriceSl || 0}}</view>
 					</view>
-					<view class='item acea-row row-between' v-if="orderInfo.payPostage > 0">
+					<view class='item acea-row row-between' v-if="orderInfo.payPostageSl > 0">
 						<view>运费:</view>
-						<view class='conter'>¥{{orderInfo.payPostage || 0}}</view>
+						<view class='conter'>sL{{orderInfo.payPostageSl || 0}}</view>
 					</view>
-					<view class='item acea-row row-between' v-if='orderInfo.svipDiscountPrice > 0'>
+					<view class='item acea-row row-between' v-if='orderInfo.svipDiscountPriceSl > 0'>
 						<view>会员优惠:</view>
-						<view class='conter'>-¥{{orderInfo.svipDiscountPrice || 0}}</view>
+						<view class='conter'>-sL{{orderInfo.svipDiscountPriceSl || 0}}</view>
 					</view>
-					<view class='item acea-row row-between' v-if='orderInfo.merCouponPrice > 0'>
+					<view class='item acea-row row-between' v-if='orderInfo.merCouponPriceSl > 0'>
 						<view>店铺优惠:</view>
-						<view class='conter'>-¥{{orderInfo.merCouponPrice || 0}}</view>
+						<view class='conter'>-sL{{orderInfo.merCouponPriceSl || 0}}</view>
 					</view>
-					<view class='item acea-row row-between' v-if='orderInfo.platCouponPrice > 0'>
+					<view class='item acea-row row-between' v-if='orderInfo.platCouponPriceSl > 0'>
 						<view>平台优惠:</view>
-						<view class='conter'>-¥{{orderInfo.platCouponPrice || 0}}</view>
+						<view class='conter'>-sL{{orderInfo.platCouponPriceSl || 0}}</view>
 					</view>
-					<view class='item acea-row row-between' v-if="orderInfo.integralPrice > 0">
+					<view class='item acea-row row-between' v-if="orderInfo.integralPriceSl > 0">
 						<view>积分抵扣:</view>
-						<view class='conter'>-¥{{orderInfo.integralPrice || 0}}</view>
+						<view class='conter'>-sL{{orderInfo.integralPriceSl || 0}}</view>
 					</view>
 					<view v-show="secondType !== ProductTypeEnum.Integral" class='actualPay acea-row row-right'>
-						实付款<text class='money semiBold'>¥{{orderInfo.payPrice || 0}}</text>
+						实付款<span style="color:#FF448F;">sL <span style="font-weight: bold;">{{orderInfo.totalPriceReat || 0}}</span></span>
 					</view>
 				</view>
 				<view style='height:200rpx;'></view>
@@ -516,7 +516,7 @@
 				});
 
 				uni.navigateTo({
-					url: `/pages/goods/order_payment/index?orderNo=${item.orderNo}&payPrice=${item.payPrice}`
+					url: `/pages/goods/order_payment/index?orderNo=${item.orderNo}&payPrice=${item.payPrice}&totalPriceReat=${item.totalPriceReat}`
 				});
 			}),
 			/**
@@ -584,6 +584,9 @@
 					});
 				});
 			},
+			orderRmbToSl: function(rmb,rate){
+				return (Math.ceil((rmb / rate) * 100) / 100).toFixed(2);
+			},
 			/**
 			 * 获取订单详细信息
 			 *
@@ -596,6 +599,23 @@
 				getOrderDetail(that.orderNo).then(res => {
 					uni.hideLoading();
 					let data = res.data;
+					let rate = data.rate
+		 
+					data.integralPriceSl = that.orderRmbToSl(data.integralPrice,rate)
+					data.platCouponPriceSl = that.orderRmbToSl(data.platCouponPrice,rate)
+					data.merCouponPriceSl = that.orderRmbToSl(data.merCouponPrice,rate)
+					data.svipDiscountPriceSl = that.orderRmbToSl(data.svipDiscountPrice,rate)
+					data.payPostageSl = that.orderRmbToSl(data.payPostage,rate)
+					
+					data.proTotalPriceSl = 0
+					data.merchantOrderList.map(item=>{
+						item.orderInfoList.map(items=>{
+							items.priceSl = that.orderRmbToSl(items.price,rate)
+							items.productPriceSl = that.orderRmbToSl(items.price,rate)
+							data.proTotalPriceSl += items.productPriceSl * items.payNum
+						})
+					})
+				 
 					that.$set(that, 'orderInfo', data);
 					that.merchantOrderList = data.merchantOrderList[0] // 商户信息
 					that.$set(that, 'id', data.id);

+ 5 - 2
crmeb_src/mer_uniapp/pages/goods/order_list/index.vue

@@ -81,7 +81,7 @@
 									</view>
 								</view>
 								<view class='money'>
-									<baseMoney :money="items.price" symbolSize="20" integerSize="32" decimalSize="20"
+									<baseMoney :money="orderRmbToSl(items.price,item.rate)" symbolSize="20" integerSize="32" decimalSize="20"
 										incolor="282828" weight></baseMoney>
 									<view class="fs-24 text--w111-999 lh-34rpx text-right">x {{items.payNum}} 件</view>
 								</view>
@@ -96,7 +96,7 @@
 					<view class='totalPrice flex justify-end items-end' :class="item.status===0?'no-border':''">
 						{{item.totalNum}}
 						件商品,总金额
-						<baseMoney :money="item.payPrice" symbolSize="20" integerSize="40" decimalSize="20" weight>
+						<baseMoney :money="item.totalPriceReat" symbolSize="20" integerSize="40" decimalSize="20" weight>
 						</baseMoney>
 					</view>
 					<view v-if="item.status===0 && item.expirationTime" class="mx-20 flex">
@@ -305,6 +305,9 @@
 			if (options.secondType) this.secondType = options.secondType
 		},
 		methods: {
+			orderRmbToSl: function(rmb,rate){
+				return (Math.ceil((rmb / rate) * 100) / 100).toFixed(2);
+			},
 			/**
 			 * 分享打开
 			 *

+ 1 - 1
crmeb_src/mer_uniapp/pages/goods/order_pay_status/index.vue

@@ -23,7 +23,7 @@
 				</view>
 				<view class='item acea-row row-between-wrapper'>
 					<view>支付金额</view>
-					<view class='itemCom'>{{order_pay_info.payPrice}}</view>
+					<view class='itemCom'><span style="color:#FF448F;">sL <span style="font-weight: bold;">{{order_pay_info.totalPriceReat}}</span></span></view>
 				</view>
 				<view v-show="order_pay_info.secondType === ProductTypeEnum.Integral" class='item acea-row row-between-wrapper'>
 					<view>消耗积分</view>

+ 9 - 7
crmeb_src/mer_uniapp/pages/goods/order_payment/index.vue

@@ -3,7 +3,7 @@
 		<view class='wrapper'>
 			<view class='item borRadius14'>
 				<view class="title text-center">
-          <baseMoney :money="payPrice" symbolSize="48" integerSize="64" decimalSize="48"
+          <baseMoney :money="totalPriceReat" symbolSize="48" integerSize="64" decimalSize="48"
                      incolor="333333" weight></baseMoney>
         </view>
 				<view class='list'>
@@ -20,7 +20,7 @@
 								<view class='tip'>
 									{{item.title}}
 									<block v-if="item.value === 'yue'">
-										{{item.userBalance}}
+										<span style="color:red;">sL<b>{{item.userBalance}}</b></span>
 									</block>
 								</view>
 								<view class="radio">
@@ -38,7 +38,7 @@
 			</view>
 		</view>
 		<view v-if="isShow" class="titleNo">暂无支付方式!</view>
-		<view class="btn-box">
+		<view class="btn-box" style="width: 100%;">
 			<button class='Bnt bg-color' @tap='getOrderPay' :disabled="isBuy">立即支付</button>
 		</view>
 		<view class="alipaysubmit" v-html="formContent"></view>
@@ -58,6 +58,7 @@
 	import {
 		svipOrderCreateApi
 	} from '@/api/activity.js';
+	import {rmbToLgns,getRmbToLgnsRate} from "@/utils";
 	import {
 		Debounce
 	} from '@/utils/validate.js'
@@ -82,6 +83,7 @@
 				payChannel: '',
 				formContent: '',
 				isShow: false,
+				totalPriceReat: '',
 				userBalance: '', //余额
 				fromType: '' ,//页面来源,svip支付,购买商品
 				isBuy: false //是否可以点击购买
@@ -94,6 +96,7 @@
 			this.payPrice = options.payPrice;
 			this.orderNo = options.orderNo;
 			this.fromType = options.fromType || ''
+			this.totalPriceReat = options.totalPriceReat
 		},
 		mounted() {
 			this.payConfig();
@@ -105,7 +108,7 @@
 				// 支付方式
 				store.dispatch('getPayConfig').then((res) => {
 					this.cartArr = res.payConfig;
-          this.userBalance = res.userBalance;
+					this.userBalance = res.userBalance;
 					// if(this.fromType === 'svip') this.cartArr[1].payStatus = 0					
 					if (this.cartArr.length) {
 						this.active = 0;
@@ -168,7 +171,7 @@
 			//立即支付
 			getOrderPay: Debounce(function() {
 				this.getPayCheck();
-				if (Number(this.payPrice)>Number(this.userBalance) && this.payType === 'yue') return this.$util.Tips({
+				if (Number(this.totalPriceReat)>Number(this.userBalance) && this.payType === 'yue') return this.$util.Tips({
 					title: '余额的金额不够,请切换支付方式'
 				});
 				uni.showLoading({
@@ -192,7 +195,7 @@
 					});
 				} else {
 					// 订单支付
-					this.changeOrderPay(this.orderNo, this.payChannel, this.payType ,this.productType, this.fromType, this.payPrice)
+					this.changeOrderPay(this.orderNo, this.payChannel, this.payType ,this.productType, this.fromType, this.payPrice,this.totalPriceReat,this.userBalance)
 				}
 			})
 		},
@@ -216,7 +219,6 @@
 		font-size: 26rpx;
 		font-weight: bold;
 		color: #fff;
-		width: 690rpx;
 		height: 72rpx;
 		border-radius: 200rpx;
 		text-align: center;

+ 15 - 3
crmeb_src/mer_uniapp/pages/order_addcart/order_addcart.vue

@@ -170,7 +170,7 @@
 						<text class='price-color'>
 							<text class="symbol">sL</text>
 							<text
-								class="all_money semiBold">{{rmbToLgnsHandle(calculatePriceData.totalPrice?calculatePriceData.totalPrice:0)}}</text>
+								class="all_money semiBold">{{calculatePriceData.totlePriceRate?calculatePriceData.totlePriceRate:0}}</text>
 						</text>
 					</view>
 					<view class="acea-row row-middle" @click="popupChange()"
@@ -231,7 +231,7 @@
 					<block v-if="calculatePriceData.proTotalPrice>0 && calculatePriceData.totalCouponPrice!=0">
 						<view class="_cell acea-row row-between-wrapper">
 							<text class="_label">商品总价:</text>
-							<text class="_count">sL{{rmbToLgnsHandle(calculatePriceData.proTotalPrice)}}</text>
+							<text class="_count">sL{{calculatePriceData.productTotal}}</text>
 						</view>
 						<view class="_cell acea-row row-between-wrapper">
 							<text class="_label">会员优惠:</text>
@@ -1191,15 +1191,27 @@
 					ids: ids
 				}).then(res => {
 					this.calculatePriceData = res.data;
+					this.calculatePriceData.productTotal = 0
+					this.calculatePriceData.details.map(item => {
+						if(item.is_vip) {
+							this.calculatePriceData.productTotal += rmbToLgns(item.vip_price) * item.num
+						} else {
+							this.calculatePriceData.productTotal += rmbToLgns(item.price) * item.num
+						}
+					})
+					this.calculatePriceData.totlePriceRate = parseFloat(
+						(parseFloat(this.calculatePriceData.productTotal) - rmbToLgns(this.calculatePriceData.totalCouponPrice)).toFixed(2)
+					);
 					this.selectCountPrice = this.calculatePriceData.proTotalPrice;
 				}).catch(err => {
 					this.bayCount = 0;
 					this.selectCountPrice = 0.00;
+					this.calculatePriceData.totlePriceRate = 0.00;
+					this.calculatePriceData.productTotal = 0.00;
 					this.calculatePriceData.proTotalPrice = 0.00;
 					this.calculatePriceData.totalCouponPrice = 0.00;
 					this.calculatePriceData.merCouponPrice = 0.00;
 					this.calculatePriceData.platCouponPrice = 0.00;
-					this.calculatePriceData.totalCouponPrice = 0.00;
 					this.calculatePriceData.totalPrice = 0.00;
 					return this.$util.Tips({
 						title: err

+ 44 - 3
crmeb_src/mer_uniapp/pages/users/user_bill/index.vue

@@ -15,11 +15,25 @@
 							<view class="itemn" v-for="(vo,indexn) in item.list" :key="indexn">
 								<view class='acea-row row-between-wrapper'>
 									<view>
-										<view class='name line1'>{{vo.balance}}</view>
+										<view class='name line1' v-if="vo.linkType === 'withdraw'">提现操作</view>
+										<view class='name line1' v-if="vo.linkType === 'order'">订单消费</view>
+										<view class='name line1' v-if="vo.linkType === 'recharge'">充值入账</view>
+										<view class='name line1' v-if="vo.linkType === 'system'">系统后台</view>
+										<view class='name line1' v-if="vo.linkType === 'brokerage'">佣金转余额</view>
+										<view class='name line1' v-if="vo.linkType === 'svip'">购买VIO</view>
 										<view>{{vo.createTime}}</view>
 									</view>
-									<view class='num font_color' v-if="vo.type == 1">+{{vo.amount}}</view>
-									<view class='num' v-else>-{{vo.amount}}</view>
+									<view class="right-box">
+										<view class='num font_color' v-if="vo.type == 1"><span style="font-size: 15px;color: #999;">+sL</span> {{vo.amount}}</view>
+										<view class='num' v-else><span style="font-size: 15px;color: #999;">-sL</span> {{vo.amount}}</view>
+										<!-- 状态标签示例,请自行添加判断逻辑 -->
+										<!-- <view class="status-txt success">提现成功</view> -->
+										<!-- <view class="status-txt processing">提现中</view> -->
+										<!-- <view class="status-txt failure">提现失败</view> -->
+										<view class="status-txt success" v-if="vo.withdrawStatus === 1">提现成功</view>
+										<view class="status-txt processing" v-if="vo.withdrawStatus === 0">提现中</view>
+										<view class="status-txt failure" v-if="vo.withdrawStatus === 2">提现失败</view>
+									</view>
 								</view>
 								<view class="remark">说明:{{vo.remark}}</view>
 							</view>
@@ -97,6 +111,9 @@
 			this.getUserBillList();
 		},
 		methods: {
+			remarkFormat: function(remark,rate) {
+				return remark.replace(/\d+(\.\d+)?/g, rate).replace("元"," sLGNS").replace("余额","余额 ");
+			},
 			/**
 			 * 获取账户明细
 			 */
@@ -186,4 +203,28 @@
 	.font_color {
 		color: #E93323 !important;
 	}
+	
+	.right-box {
+		display: flex;
+		flex-direction: column;
+		align-items: flex-end;
+		
+		.num {
+			margin-bottom: 5rpx;
+		}
+		
+		.status-txt {
+			font-size: 28rpx;
+			
+			&.success {
+				color: #0987fc; // 绿色
+			}
+			&.processing {
+				color: #4B67AF; // 蓝色
+			}
+			&.failure {
+				color: red; // 红色
+			}
+		}
+	}
 </style>

+ 315 - 87
crmeb_src/mer_uniapp/pages/users/user_money/index.vue

@@ -8,30 +8,62 @@
       </view>
       <!-- #endif -->
 			<view class='wrapper borderPad'>
-				<view class='header borRadius14'>
-					<view class='headerCon'>
-						<view class='account acea-row row-top row-between'>
-							<view class='assets'>
-								<view>账户余额(元)</view>
-								<view class='money semiBold'>{{statistics.nowMoney || 0}}</view>
+				<!-- 新版头部 -->
+				<view class="new-header">
+					<!-- 顶部:实时汇率 -->
+					<view class="rate-card-top">
+						<view style="
+									background: linear-gradient(to top, rgb(255, 107, 159,0.3), rgb(255, 255, 255,0.25));
+									border-radius: 10px;
+									padding: 20rpx 20rpx;
+									">
+							<view class="rate-title-row">
+								<view class="title xuxian">实时汇率</view>
+								<view class="refresh-icon" @click="refreshRate">
+									<text class="iconfont icon-shuaxin1"></text>
+								</view>
 							</view>
-							<view v-if="statistics.rechargeSwitch"
-								@click="openSubscribe('/pages/users/user_payment/index')"
-								class='recharge font_color relative z-10'>充值</view>
+							<view class="rate-content">
+								<view class="rate-info">
+									<view class="rate-row">
+										<text class="label">sLGNS:</text>
+										<text class="value">¥{{globalData.daibiRateLgnsCny || '0.00'}}</text>
+									</view>
+								</view>
+								<view class="coin-img">
+									<image src="/static/tabBar/2026-01-29_145708_158.png" mode="aspectFit"></image>
+								</view>
+							</view>
+					</view>
+					</view>
+					
+					<!-- 底部:余额信息 -->
+					<view class="rate-card-bottom">
+						<view class="balance-main">
+							<view class="balance-item border-right">
+								<view class="label">账户余额(元)</view>
+								<view class="num">{{parseFloat((statistics.nowMoney * rate).toFixed(2)) || '0.00'}}</view>
+								<view class="btn" v-if="statistics.rechargeSwitch" @click="openSubscribe('/pages/users/user_payment/index')">充值</view>
+							</view>
+							<view class="balance-item">
+								<view class="label">sLGNS余额</view>
+								<view class="num">{{statistics.nowMoney || 0}}</view>
+								<view class="btn btn-outline" :class="{disabled: !withdrawNumber.status}" @click="onWithdrawClick">提现</view>
+							</view>
+						</view>
+						<view class="withdraw-tip">
+							7天只能3次提现已用({{withdrawNumber.dailyCountAgo}}),今天只能2次提现已用({{withdrawNumber.dailyCount}})
 						</view>
-						<view class='cumulative acea-row row-middle'>
-							<view class='item mr-80' v-if="statistics.rechargeSwitch">
-								<view>余额充值(元)</view>
-								<view class='money semiBold'>{{statistics.recharge || 0}}</view>
+						<view class="balance-sub">
+							<view class="sub-item">
+								<text class="sub-label">余额充值(元)</text>
+								<text class="sub-value">{{statistics.recharge || '0.00'}}</text>
 							</view>
-							<view class='item'>
-								<view>余额消费(元)</view>
-								<view class='money semiBold'>{{statistics.monetary || 0}}</view>
+							<view class="sub-item">
+								<text class="sub-label">余额消费(元)</text>
+								<text class="sub-value">{{statistics.monetary || '0.00'}}</text>
 							</view>
 						</view>
-            <view class="pictrue">
-              <image :src="urlDomain+'crmebimage/presets/pig.png'"></image>
-            </view>
 					</view>
 				</view>
 				<view class='nav acea-row row-between-wrapper mt20'>
@@ -77,7 +109,8 @@
 	// | Author: CRMEB Team <admin@crmeb.com>
 	// +----------------------------------------------------------------------
 	import {
-		getMyAccountApi
+		getMyAccountApi,
+		getPaymentUserNumber
 	} from '@/api/user.js';
 	import {
 		toLogin
@@ -90,6 +123,7 @@
 	} from '@/api/order.js';
 	import recommend from "@/components/base/recommend.vue";
   import navBar from '@/components/navBar';
+  import {rmbToLgns,getRmbToLgnsRate} from "@/utils";
 	let app = getApp();
 	export default {
 		components: {
@@ -104,13 +138,16 @@
 				hotScroll: false,
 				statistics: {},
 				hotPage: 1,
+				rate: 0,
 				hotLimit: 10,
+				withdrawNumber: {},
 				theme: app.globalData.theme,
 				isNoCommodity: false,
         backgroundColor: '',
+        rechargeSwitch: false, // 充值开关
 			};
 		},
-		computed: mapGetters(['isLogin', 'userInfo']),
+		computed: mapGetters(['isLogin', 'userInfo', 'globalData']),
 		watch: {
 			isLogin: {
 				handler: function(newV, oldV) {
@@ -161,6 +198,9 @@
       // #endif
 		},
 		methods: {
+			rmbToLgns(e) {
+				return rmbToLgns(e,"floor");
+			},
 			getRecommendLength(e) {
 				this.isNoCommodity = e == 0 ? true : false;
 			},
@@ -186,98 +226,286 @@
 			},
 			userDalance() {
 				getMyAccountApi().then(res => {
+					this.rate = getRmbToLgnsRate();
 					this.statistics = res.data;
+					console.log(this.statistics)
 				})
+				// 调用测试接口并打印
+				getPaymentUserNumber().then(res => {
+					this.withdrawNumber = res.data;
+				});
 			},
 			openSubscribe(page) {
 				uni.navigateTo({
 					url: page,
 				});
+			},
+			onWithdrawClick() {
+				if (!this.withdrawNumber.status) return this.$util.Tips({title: '当前暂时无法提现'});
+				this.openSubscribe('/pages/users/user_withd_slgns/index?lgns=' + this.statistics.nowMoney);
 			}
 		}
 	}
 </script>
 
 <style scoped lang="scss">
+	.btn.disabled {
+		opacity: 0.5;
+		background: rgba(255, 255, 255, 0.1) !important;
+		border-color: rgba(255, 255, 255, 0.3) !important;
+		color: rgba(255, 255, 255, 0.6) !important;
+		pointer-events: none; // 禁止点击
+	}
+
 .my-account{
   @include shallow-gradient(theme);
 }
-	.my-account .wrapper .header {
+
+	/* 新版UI样式 */
+	.new-header {
 		width: 100%;
-		height: 362rpx;
-    @include linear-gradient(theme);
 		margin: 0 auto;
-		box-sizing: border-box;
-		color: rgba(255, 255, 255, 0.6);
-		font-size: 24rpx;
-    position: relative;
+		color: #fff;
+		filter: drop-shadow(0 4rpx 10rpx rgba(255, 77, 140, 0.3));
 	}
-
-	.my-account .wrapper .header .headerCon {
-    padding-top: 36rpx;
-    .pictrue {
-      width: 290rpx;
-      height: 362rpx;
-      position: absolute;
-      right: 0;
-      bottom: 0;
-      image{
-        width: 100%;
-        height: 100%;
-      }
-    }
-	}
-
-	.my-account .wrapper .header .headerCon .account {
-    padding: 0 28rpx;
+	
+	.rate-card-top {
+		// 上半部分渐变:根据图示调整为更亮的粉色渐变
+		background: linear-gradient(90deg, #ff6b9f 0%, #FF4D8C 100%);
+		border-radius: 24rpx 24rpx 24rpx 24rpx; // 上部卡片其实也可以全圆角,看起来是两张卡叠在一起
+		padding: 25rpx 25rpx 25rpx 25rpx;
+		position: relative;
+		z-index: 2;
+		margin-bottom: 20rpx; // 给中间螺旋效果留空隙,或者实际上是紧贴的但通过z-index处理
+		margin-bottom: 14rpx; // 微调间距适应螺旋
 	}
-
-	.my-account .wrapper .header .headerCon .account .assets .money {
-    font-size: 64rpx;
-    color: #fff;
-    margin-top: 12rpx;
+	
+	.rate-title-row {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 24rpx;
+		
+		.title {
+			font-size: 30rpx;
+			font-weight: bold;
+			padding-bottom: 4rpx;
+			display: inline-block;
+			letter-spacing: 1px;
+		}
+		
+		.refresh-icon {
+			width: 40rpx;
+			height: 40rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			
+			.iconfont {
+				font-size: 34rpx;
+				font-weight: bold;
+			}
+		}
 	}
-
-	.my-account .wrapper .header .headerCon .account .recharge {
-    font-size: 24rpx;
-    width: 112rpx;
-    height: 56rpx;
-    border-radius: 50rpx;
-    background-color: rgba(255,255,255,0.8);
-    text-align: center;
-    line-height: 56rpx;
-    font-weight: 500;
+	
+	.rate-content {
+		display: flex;
+		justify-content: space-between;
+		align-items: flex-start;
+		position: relative;
+		
+		.rate-info {
+			flex: 1;
+			z-index: 2;
+		}
+		
+		.rate-row {
+			display: flex;
+			align-items: center;
+			font-size: 26rpx;
+			margin-bottom: 14rpx;
+			line-height: 1.2;
+			
+			.label {
+				width: 100rpx;
+				font-size: 30rpx;
+				opacity: 0.85;
+				font-weight: 100;  
+			}
+			
+			.value {
+				margin: 0 6rpx 0 20rpx; // value紧跟label后,还是有固定间距,看图是靠左
+				font-size: 30rpx;
+				min-width: 100rpx;
+				font-weight: 300;  
+			}
+			
+			.percent {
+				font-weight: 300; 
+				font-size: 30rpx;
+				margin-right: 4rpx;
+				
+				&.up { color: #fff; }
+				&.down { color: #fff; }
+			}
+			
+			.trend-icon {
+				width: 24rpx;
+				height: 24rpx;
+				margin-top: 4rpx;
+				margin-left: 6rpx;
+			}
+			
+			.icon-up { display: inline-block; }
+			.icon-down { display: inline-block; }
+		}
+		
+		.coin-img {
+			width: 160rpx;
+			height: 140rpx;
+			position: absolute;
+			right: 0;
+			top: -80rpx;
+			z-index: 1;
+			
+			image {
+				width: 100%;
+				height: 100%;
+			}
+		}
 	}
-
-	.font_color {
-		@include main_color(theme);
+	
+	// 螺旋视觉效果容器
+	.spiral-binding {
+		position: absolute;
+		bottom: -24rpx; // 调整位置以连接上下两部分
+		left: 0;
+		width: 100%;
+		height: 48rpx;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		z-index: 10;
+		
+		image {
+			width: 92%; // 根据实际图片宽度微调,留一点边距看起来更自然
+			height: 100%;
+		}
 	}
-
-	.icon_txt {
-		font-size: 43rpx;
-		@include main_color(theme);
+	
+	.rate-card-bottom {
+		// 下半部分渐变:稍微红一点
+		background: linear-gradient(135deg, #FF79A8 0%, #FF5993 100%);
+		border-radius: 24rpx 24rpx 24rpx 24rpx;
+	 
+		position: relative;
+		z-index: 1;
+		
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		min-height: 340rpx; // 保证高度一致
 	}
-
-	.my-account .wrapper .header .headerCon .cumulative {
-    width: 100%;
-    height: 142rpx;
-    background: rgba(255,255,255,0.1);
-    margin-top: 62rpx;
-    padding-left: 28rpx;
-    position: absolute;
-    left: 0;
-    bottom: 0;
+	
+	.balance-main {
+		display: flex;
+		align-items: center;
+		padding: 30rpx 0 20rpx 0;
+		flex: 1;
+		
+		.balance-item {
+			flex: 1;
+			text-align: center;
+			position: relative;
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			
+			// 中间分割线
+			&.border-right::after {
+				content: '';
+				position: absolute;
+				right: 0;
+				top: 50%;
+				transform: translateY(-50%);
+				height: 60rpx;
+				width: 2rpx;
+				background: rgba(255,255,255,0.2);
+			}
+			
+			.label {
+				font-size: 30rpx;
+				opacity: 0.8;
+				margin-bottom: 10rpx;
+				font-weight: 100;
+			}
+			
+			.num {
+				font-size: 45rpx; // 金额大号字体
+				font-weight: bold;
+				// font-family: 'DIN', sans-serif; // 如果有数字字体
+				margin-bottom: 24rpx;
+				text-shadow: 0 2rpx 4rpx rgba(0,0,0,0.05);
+			}
+			
+			.btn {
+				width: 200rpx;
+				height: 60rpx;
+				line-height: 56rpx; // 扣除border
+				border-radius: 34rpx;
+				border: 2rpx solid #fff;
+				font-size: 28rpx;
+				text-align: center;
+				background: rgba(255,255,255,0.15);
+				backdrop-filter: blur(4rpx);
+				box-sizing: border-box;
+				
+				&.btn-outline {
+					background: rgba(255,255,255,0.15); // 统一样式
+				}
+				
+				&:active {
+					opacity: 0.8;
+					transform: scale(0.98);
+				}
+			}
+		}
 	}
-
-	.my-account .wrapper .header .headerCon .cumulative .item {
-    position: static;
-    z-index: 9;
+	
+	.withdraw-tip {
+		text-align: center;
+		color: rgba(255, 255, 255, 0.8); // 颜色淡一点
+		font-size: 24rpx;
+		font-weight: 300; // 细体
+		margin-bottom: 20rpx;
+		letter-spacing: 1px;
 	}
-
-	.my-account .wrapper .header .headerCon .cumulative .item .money {
-    font-size: 40rpx;
-    color: #fff;
-    margin-top: 12rpx;
+	
+	.balance-sub {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		background: rgba(0, 0, 0, 0.05); // 底部深色条
+		padding: 24rpx 40rpx;
+		border-radius: 0 0 24rpx 24rpx; // 仅底部圆角
+		
+		.sub-item {
+			font-size: 24rpx;
+			display: flex;
+			align-items: center;
+			
+			.sub-label {
+				opacity: 0.9;
+				margin-right: 20rpx;
+				font-weight: 100;
+				font-size: 28rpx;
+			}
+			
+			.sub-value {
+				font-weight: 500;
+				font-size: 28rpx;
+			}
+		}
 	}
 	.my-account .wrapper .nav .item {
     font-size: 24rpx;

+ 1 - 1
crmeb_src/mer_uniapp/pages/users/user_payment/index.vue

@@ -4,7 +4,7 @@
 			<view class="payment-top acea-row row-column row-center-wrapper">
 				<span class="name1">我的余额</span>
 				<view class="pic">
-					<span class="pic-font semiBold">{{ nowMoney || 0 }}</span>
+					sL<span class="pic-font semiBold">{{ nowMoney || 0 }}</span>
 				</view>
 			</view>
 			<view v-if="!payShow" class="payment">

+ 492 - 0
crmeb_src/mer_uniapp/pages/users/user_withd_slgns/index.vue

@@ -0,0 +1,492 @@
+<template>
+	<view :data-theme="theme">
+		<!-- 头部背景区域 -->
+		<view class="header-bg">
+			<view class="balance-section">
+				<view class="left">
+					<view class="label">sLGNS余额</view>
+					<view class="value">{{sLGNS || 0}}</view>
+				</view>
+				<view class="right-pot">
+					<image src="/static/tabBar/2026-01-29_161511_590.png" mode="aspectFit"></image>
+				</view>
+			</view>
+			
+			<!-- 汇率卡片 -->
+			<view class="rate-card">
+				<view class="rate-title-row">
+					<view class="title">实时汇率</view>
+				</view>
+				<view class="rate-content">
+					<view class="rate-row">
+						<text class="label">SLGNS:</text>
+						<text class="val">¥{{globalData.daibiRateLgnsCny || '0.00'}}</text>
+					</view>
+				</view>
+			</view>
+		</view>
+		
+		<!-- 提现表单区域 -->
+		<view class="form-card">
+			<!-- 提现金额 -->
+			<view class="form-item">
+				<view class="label">提现金额</view>
+				<view class="input-wrap">
+					<input type="number" v-model="amount" @input="onAmountInput" placeholder="请输入提现金额" placeholder-class="ph-style" />
+					<view class="all-btn" @click="widthdrawAll">全部提现</view>
+				</view>
+			</view>
+			
+			<!-- 提现地址 -->
+			<view class="form-item">
+				<view class="label">提现地址</view>
+				<view class="input-wrap address-wrap">
+					<input type="text" v-model="address" placeholder="请输入提现地址" placeholder-class="ph-style" />
+					<view class="icons">
+                        <image src="/static/tabBar/2026-01-29_162016_793.png" style="width:40rpx;height:40rpx" class="scan-icon" @click="scanCode"></image>
+						<image src="/static/tabBar/2026-01-29_163022_466.png" style="width:35rpx;height:25rpx;" class="scan-icon" @click="openHistory"></image>
+					</view>
+				</view>
+			</view>
+			
+			<!-- 注意事项 -->
+			<view class="notes">
+				<view class="note-title">注意事项</view>
+				<view class="note-item">01.提现金额请填写整数;</view>
+				<view class="note-item">02.本次提现仅支持sLGNS币种;</view>
+				<view class="note-item">03.提现将收取5%的滑点费用;</view>
+				<view class="note-item">04.请仔细核对提现地址,地址填写错误导致的资产损失,平台不予负责;</view>
+                <view class="note-item">05.提现存在3~5分钟到账延迟,若超时未到账,请及时联系平台客服。</view>
+			</view>
+		</view>
+		
+		<!-- 历史地址弹窗 -->
+		<view class="popup-mask" v-if="showHistory" @click="closeHistory"></view>
+		<view class="history-popup" :class="{show: showHistory}">
+			<view class="popup-header">
+				<text>历史地址</text>
+				<text class="iconfont icon-guanbi" @click="closeHistory"></text>
+			</view>
+			<scroll-view scroll-y class="history-list">
+				<view class="history-item" v-for="(item, index) in historyList" :key="index" @click="selectAddress(item)">
+					<text class="address-text">{{item}}</text>
+					<text class="iconfont icon-guanbi5" @click.stop="deleteHistoryItem(index)">
+                        <image src="/static/tabBar/2026-01-29_165252_059.png" style="width:40rpx;height:40rpx;margin-top: 8rpx;"></image>
+                    </text>
+				</view>
+				<view class="empty-history" v-if="historyList.length === 0">
+					暂无历史记录
+				</view>
+			</scroll-view>
+		</view>
+		
+		<!-- 底部按钮 -->
+		<view class="footer-btn">
+			<button class="submit-btn" @click="submitWithdraw">立即提现</button>
+		</view>
+	</view>
+</template>
+
+<script>
+	import { mapGetters } from "vuex";
+	import { sLgnsWithdrawApi } from "@/api/user.js";
+	import { rmbToLgns, getRmbToLgnsRate } from "@/utils";
+	let app = getApp();
+	
+	export default {
+		data() {
+			return {
+				theme: app.globalData.theme,
+				amount: '',
+				address: '',
+                rate: '',
+				sLGNS: 0, // 余额
+				showHistory: false,
+				historyList: []
+			};
+		},
+		onLoad(options) {
+			if (options.lgns) {
+				this.sLGNS = options.lgns;
+				this.rate = getRmbToLgnsRate();
+			}
+			this.loadHistory();
+		},
+		computed: mapGetters(['globalData']),
+		methods: {
+			refreshRate() {
+				this.$store.dispatch('CheckExchangeRate').then(() => {
+					this.$util.Tips({title: '刷新成功'});
+				});
+			},
+			widthdrawAll() {
+				// 全部提现逻辑,向下取整
+				this.amount = Math.floor(this.sLGNS);
+			},
+			onAmountInput(e) {
+				// 只能输入整数
+				this.$nextTick(() => {
+					this.amount = e.detail.value.replace(/[^\d]/g, '');
+				});
+			},
+			scanCode() {
+				// 扫码逻辑
+				uni.scanCode({
+					success: (res) => {
+						this.address = res.result;
+					}
+				});
+			},
+			submitWithdraw() {
+				// 提交逻辑
+				if(!this.amount) return this.$util.Tips({title: '请输入提现金额'});
+				if(!this.address) return this.$util.Tips({title: '请输入提现地址'});
+                if(this.sLGNS - this.amount < 0) return this.$util.Tips({title: '提现金额超出余额'});
+                if(this.address.length < 30) return this.$util.Tips({title: '提现地址不合法'});
+
+				// 保存该地址到历史记录
+				this.saveAddressToHistory(this.address);
+
+				uni.showLoading({ title: '提现申请中...' });
+				sLgnsWithdrawApi({
+					amount: this.amount,
+					address: this.address,
+                    rate: this.rate
+				}).then(res => {
+                    if(res.data.status){
+						this.$util.Tips({title: '提现发起成功,提现结果请在消费记录中查看'}, {tab: 5, url: '/pages/users/user_money/index'});
+                    }else{
+                        this.$util.Tips({title: '提现发起失败['+res.data.remark+']'});
+                    }
+					uni.hideLoading();
+				}).catch(err => {
+					uni.hideLoading();
+					this.$util.Tips({title: "提现发起失败【"+err.msg+"】"});
+				});
+			},
+			openHistory() {
+				this.loadHistory();
+				this.showHistory = true;
+			},
+			closeHistory() {
+				this.showHistory = false;
+			},
+			loadHistory() {
+				const history = uni.getStorageSync('slgns_withdraw_history');
+				if (history) {
+					this.historyList = JSON.parse(history);
+				}
+			},
+			saveAddressToHistory(address) {
+				let history = uni.getStorageSync('slgns_withdraw_history');
+				let list = history ? JSON.parse(history) : [];
+				// 避免重复,如果存在先删除
+				const index = list.indexOf(address);
+				if (index > -1) {
+					list.splice(index, 1);
+				}
+				// 插入头部
+				list.unshift(address);
+				// 最多保留10条
+				if (list.length > 10) list = list.slice(0, 10);
+				
+				uni.setStorageSync('slgns_withdraw_history', JSON.stringify(list));
+				this.historyList = list;
+			},
+			selectAddress(addr) {
+				this.address = addr;
+				this.closeHistory();
+			},
+			deleteHistoryItem(index) {
+				this.historyList.splice(index, 1);
+				uni.setStorageSync('slgns_withdraw_history', JSON.stringify(this.historyList));
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	page {
+		background-color: #F5F5F5;
+	}
+	
+	.header-bg {
+		background: linear-gradient(180deg, #FF6B9F 0%, #FF4D8C 100%);
+		padding: 30rpx 30rpx 120rpx 30rpx; // 底部留白给卡片
+		position: relative;
+		border-radius: 0 0 40rpx 40rpx;
+	}
+	
+	.balance-section {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		color: #fff;
+		margin-bottom: 30rpx;
+		padding-top: 20rpx;
+		
+		.left {
+			.label {
+				font-size: 28rpx;
+				opacity: 0.9;
+				margin-bottom: 10rpx;
+			}
+			.value {
+				font-size: 64rpx;
+				font-weight: bold;
+			}
+		}
+		
+		.right-pot {
+			width: 180rpx;
+			height: 160rpx;
+			image {
+				width: 100%;
+				height: 100%;
+			}
+		}
+	}
+	
+	.rate-card {
+		background: rgba(255, 255, 255, 0.2);
+		border-radius: 20rpx;
+		padding: 24rpx;
+		backdrop-filter: blur(10px);
+		border: 1px solid rgba(255,255,255,0.3);
+		
+		.rate-title-row {
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			margin-bottom: 20rpx;
+			color: #fff;
+			
+			.title {
+				font-size: 30rpx;
+				font-weight: bold;
+			}
+			.refresh-icon .iconfont {
+				font-size: 32rpx;
+			}
+		}
+		
+		.rate-content {
+			.rate-row {
+				display: flex;
+				align-items: center;
+				color: #fff;
+				font-size: 26rpx;
+				margin-bottom: 12rpx;
+				
+				&:last-child {
+					margin-bottom: 0;
+				}
+				
+				.label {
+					width: 100rpx;
+					opacity: 0.9;
+				}
+				.val {
+					margin-right: 16rpx;
+					font-weight: bold;
+				}
+				.percent {
+					margin-right: 10rpx;
+					font-size: 24rpx;
+				}
+				.trend-icon {
+					width: 24rpx;
+					height: 24rpx;
+				}
+			}
+		}
+	}
+	
+	.form-card {
+		background: #fff;
+		margin: -80rpx 30rpx 200rpx 30rpx;
+		border-radius: 20rpx;
+		padding: 40rpx 30rpx;
+		position: relative;
+		z-index: 10;
+		box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.05);
+		
+		.form-item {
+			margin-bottom: 40rpx;
+			
+			.label {
+				font-size: 30rpx;
+				font-weight: bold;
+				color: #333;
+				margin-bottom: 20rpx;
+			}
+			
+			.input-wrap {
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				padding-bottom: 20rpx;
+				border-bottom: 1px solid #EEEEEE;
+				
+				input {
+					flex: 1;
+					font-size: 30rpx;
+					color: #333;
+				}
+				
+				.ph-style {
+					color: #CCCCCC;
+				}
+				
+				.all-btn {
+					color: #FF4D8C;
+					font-size: 28rpx;
+					font-weight: 500;
+				}
+				
+				&.address-wrap {
+					align-items: flex-end; // 底部对齐,或者 center 看效果,通常 vertical stack 会让高度变高
+					.icons {
+						display: flex;
+						flex-direction: column;
+						align-items: center;
+						margin-left: 20rpx;
+						
+						.scan-icon {
+							width: 40rpx;
+							height: 40rpx;
+							margin-left: 0;
+							
+							&:first-child {
+								margin-bottom: 24rpx; // 间距
+							}
+						}
+					}
+				}
+			}
+		}
+		
+		.notes {
+			margin-top: 50rpx;
+			color: #999;
+			font-size: 24rpx;
+			line-height: 1.6;
+			
+			.note-title {
+				font-size: 28rpx;
+				color: #333;
+				font-weight: bold;
+				margin-bottom: 16rpx;
+			}
+		}
+	}
+	
+	.footer-btn {
+        padding-top: 40rpx;
+        background-color: #f7f7f7;
+		position: fixed;
+		bottom: 40rpx;
+		left: 30rpx;
+		right: 30rpx;
+		z-index: 99; // 保证不遮挡
+		
+		.submit-btn {
+			background: #FF6B9F;
+			color: #ffffff;
+			border-radius: 50rpx;
+			height: 90rpx;
+			line-height: 90rpx;
+			font-size: 32rpx;
+			font-weight: bold;
+			border: none;
+			&::after {
+				border: none;
+			}
+		}
+	}
+	
+	// 弹窗样式
+	.popup-mask {
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		background: rgba(0,0,0,0.5);
+		z-index: 99;
+	}
+	
+	.history-popup {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		width: 100%;
+		background: #fff;
+		border-radius: 24rpx 24rpx 0 0;
+		z-index: 100;
+		transform: translateY(100%);
+		transition: transform 0.3s;
+		padding-bottom: 40rpx;
+		max-height: 40vh;
+		display: flex;
+		flex-direction: column;
+		
+		&.show {
+			transform: translateY(0);
+		}
+		
+		.popup-header {
+			padding: 30rpx 40rpx;
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			font-size: 32rpx;
+			font-weight: bold;
+			border-bottom: 1px solid #eee;
+			
+			.iconfont {
+				font-size: 32rpx;
+				color: #999;
+			}
+		}
+		
+		.history-list {
+			flex: 1;
+			overflow-y: auto;
+			padding: 0 40rpx;
+			min-height: 200rpx;
+			
+			.history-item {
+				padding: 30rpx 0;
+				border-bottom: 1px solid #f5f5f5;
+				font-size: 28rpx;
+				color: #333;
+				word-break: break-all;
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				
+				.address-text {
+					flex: 1;
+					margin-right: 20rpx;
+				}
+				
+				.icon-shanchu {
+					color: #999;
+					padding: 10rpx; // 增加点击区域
+				}
+				
+				&:active {
+					background-color: #f9f9f9;
+				}
+			}
+			
+			.empty-history {
+				text-align: center;
+				padding: 60rpx 0;
+				color: #999;
+				font-size: 26rpx;
+			}
+		}
+	}
+</style>

BIN
crmeb_src/mer_uniapp/static/tabBar/2026-01-29_145708_158.png


BIN
crmeb_src/mer_uniapp/static/tabBar/2026-01-29_161511_590.png


BIN
crmeb_src/mer_uniapp/static/tabBar/2026-01-29_162016_793.png


BIN
crmeb_src/mer_uniapp/static/tabBar/2026-01-29_163022_466.png


BIN
crmeb_src/mer_uniapp/static/tabBar/2026-01-29_165252_059.png


+ 53 - 30
crmeb_src/mer_uniapp/store/modules/app.js

@@ -32,7 +32,8 @@ import {
 	MERCHANT_EMPLOYEE_LIST,
 	SELECT_MERCHANT,
 	MANAGER_STATUS,
-	IS_EMPLOYEE
+	IS_EMPLOYEE,
+	EXCHANGE_RATE_CACHE
 } from '../../config/cache';
 import Cache from '../../utils/cache';
 import {
@@ -45,28 +46,28 @@ import {
 import store from "../index";
 import Routine from "../../libs/routine";
 let cartArr = [{
-		name: "微信支付",
-		icon: "icon-a-ic_wechatpay",
-		value: 'weixin',
-		title: '微信快捷支付',
-		payStatus: 1,
-	},
-	{
-		name: "余额支付",
-		icon: "icon-ic_Money2",
-		value: 'yue',
-		title: '可用余额:',
-		payStatus: 1,
-		userBalance: ''
-	},
-	// #ifndef MP
-	{
-		name: "支付宝支付",
-		icon: "icon-a-ic_alipay",
-		value: 'alipay',
-		title: '支付宝快捷支付',
-		payStatus: 1,
-	},
+	name: "微信支付",
+	icon: "icon-a-ic_wechatpay",
+	value: 'weixin',
+	title: '微信快捷支付',
+	payStatus: 1,
+},
+{
+	name: "余额支付",
+	icon: "icon-ic_Money2",
+	value: 'yue',
+	title: '可用余额:',
+	payStatus: 1,
+	userBalance: ''
+},
+// #ifndef MP
+{
+	name: "支付宝支付",
+	icon: "icon-a-ic_alipay",
+	value: 'alipay',
+	title: '支付宝快捷支付',
+	payStatus: 1,
+},
 	// #endif
 ];
 const state = {
@@ -80,7 +81,7 @@ const state = {
 	chatUrl: Cache.get('chatUrl') || '',
 	systemPlatform: Cache.get(PLATFORM) ? Cache.get(PLATFORM) : '',
 	productType: Cache.get('productType') || '',
-	globalData: Cache.get(GLOBAL_DATA)?JSON.parse(Cache.get(GLOBAL_DATA)): {},
+	globalData: Cache.get(GLOBAL_DATA) ? JSON.parse(Cache.get(GLOBAL_DATA)) : {},
 	merchantClassify: Cache.get('merchantClassify') ? JSON.parse(Cache.get('merchantClassify')) : [],
 	/** 商户分类 **/
 	merchantType: Cache.get('merchantType') ? JSON.parse(Cache.get('merchantType')) : [],
@@ -108,7 +109,7 @@ const mutations = {
 		Cache.set(MANAGER_STATUS, opt.managerToken);
 	},
 	// 工单管理token
-	SET_WORK_ORDER_TOKEN(state, token){
+	SET_WORK_ORDER_TOKEN(state, token) {
 		state.workOrderToken = token;
 		Cache.set('workOrderToken', token);
 	},
@@ -286,19 +287,19 @@ const mutations = {
 		Cache.set(GLOBAL_DATA, state.globalData);
 	},
 	// 颜色
-	Change_GLOBAL_theme(state,data){
+	Change_GLOBAL_theme(state, data) {
 		state.globalData.theme = data;
 		Cache.set(GLOBAL_DATA, state.globalData);
 	},
 	// 设置开屏广告显示
-	Change_Advertisement(state,data){
+	Change_Advertisement(state, data) {
 		state.isAdvertisement = data;
 		Cache.set('isAdvertisement', data);
 	}
 };
 
 /** tree去除 childList=[] 的结构**/
-const changeNodes = function(data) {
+const changeNodes = function (data) {
 	if (data.length > 0) {
 		for (var i = 0; i < data.length; i++) {
 			if (!data[i].childList || data[i].childList.length < 1) {
@@ -323,6 +324,8 @@ const actions = {
 			globalConfigApi().then(res => {
 				let data = res.data;
 				Cache.set('imgHost', data.imageDomain + '/');
+				// 设置汇率缓存时效,过期了通过CheckExchangeRate方法重新获取, 5分钟过期 项目中有定时器1分钟调用CheckExchangeRate检查一次
+				Cache.set(EXCHANGE_RATE_CACHE, 1, 60*5);
 				commit('Change_GLOBAL_DATA', data)
 			});
 		}).catch(err => {
@@ -331,6 +334,26 @@ const actions = {
 			});
 		});
 	},
+	/**
+	 * Greg
+	 * 检查并获取最新汇率 (15分钟缓存)
+	 * 如果缓存过期,则重新请求接口
+	 */
+	CheckExchangeRate({
+		dispatch
+	}) {
+		return new Promise(resolve => {
+			// 如果缓存存在(未过期),直接返回
+			if (Cache.has(EXCHANGE_RATE_CACHE)) {
+				resolve();
+			} else {
+				// 缓存过期,重新获取配置
+				dispatch('GetGlobalConfig').then(() => {
+					resolve();
+				});
+			}
+		});
+	},
 	//获取登录配置
 	GetLoginConfig({
 		state,
@@ -377,8 +400,8 @@ const actions = {
 			tokenIsExistApi().then(res => {
 				commit('TokenIsExist', res.data)
 				if (!res.data) {
-					 commit("LOGOUT");
-					 commit('updatePaidMember', false);
+					commit("LOGOUT");
+					commit('updatePaidMember', false);
 				}
 				reslove(res.data);
 			});

+ 92 - 92
crmeb_src/mer_uniapp/utils/cache.js

@@ -11,37 +11,36 @@
 import { EXPIRE } from '../config/app';
 
 class Cache {
-	
+
 	constructor(handler) {
-	    this.cacheSetHandler = uni.setStorageSync;
+		this.cacheSetHandler = uni.setStorageSync;
 		this.cacheGetHandler = uni.getStorageSync;
 		this.cacheClearHandler = uni.removeStorageSync;
 		this.cacheExpire = '_expire_2019_12_17_18_44';
 		this.name = 'storage';
 	}
-	
+
 	/**
 	 * 获取当前时间戳
 	 */
-	time()
-	{
+	time() {
 		return Math.round(new Date() / 1000);
 	}
-	
+
 	/**
 	 * 日期字符串转时间戳
 	 * @param {Object} expiresTime
 	 */
-	strTotime(expiresTime){
+	strTotime(expiresTime) {
 		let expires_time = expiresTime.substring(0, 19);
 		expires_time = expires_time.replace(/-/g, '/');
 		return Math.round(new Date(expires_time).getTime() / 1000);
 	}
-	
+
 	setExpireCaheTag(key, expire) {
 		expire = expire !== undefined ? expire : EXPIRE;
 		if (typeof expire === 'number') {
-			let tag = this.cacheGetHandler(this.cacheExpire), newTag = [],newKeys = [];
+			let tag = this.cacheGetHandler(this.cacheExpire), newTag = [], newKeys = [];
 			if (typeof tag === 'object' && tag.length) {
 				newTag = tag.map(item => {
 					newKeys.push(item.key);
@@ -50,7 +49,7 @@ class Cache {
 					}
 					return item;
 				});
-			} 
+			}
 			if (!newKeys.length || newKeys.indexOf(key) === -1) {
 				newTag.push({
 					key: key,
@@ -60,7 +59,7 @@ class Cache {
 			this.cacheSetHandler(this.cacheExpire, newTag);
 		}
 	}
-	
+
 	/**
 	 * 设置过期时间缓存
 	 * @param {Object} name key
@@ -68,44 +67,43 @@ class Cache {
 	 * @param {Object} expire 过期时间
 	 * @param {Object} startTime 记录何时将值存入缓存,毫秒级
 	 */
-	setItem(params){
-	    let obj = {
-	        name:'',
-	        value:'',
-	        expires:"",
-	        startTime:new Date().getTime()
-	    }
-	    let options = {};
-	    //将obj和传进来的params合并
-	    Object.assign(options,obj,params);
-	    if(options.expires){
+	setItem(params) {
+		let obj = {
+			name: '',
+			value: '',
+			expires: "",
+			startTime: new Date().getTime()
+		}
+		let options = {};
+		//将obj和传进来的params合并
+		Object.assign(options, obj, params);
+		if (options.expires) {
 			//如果options.expires设置了的话
 			//以options.name为key,options为值放进去
-	        // localStorage.setItem(options.name,JSON.stringify(options));
-			uni.setStorageSync(options.name,JSON.stringify(options));
-	    }else{
+			// localStorage.setItem(options.name,JSON.stringify(options));
+			uni.setStorageSync(options.name, JSON.stringify(options));
+		} else {
 			//如果options.expires没有设置,就判断一下value的类型
-	       	let type = Object.prototype.toString.call(options.value);
-	       	//如果value是对象或者数组对象的类型,就先用JSON.stringify转一下,再存进去
-	        if(Object.prototype.toString.call(options.value) == '[object Object]'){
-	            options.value = JSON.stringify(options.value);
-	        }
-	        if(Object.prototype.toString.call(options.value) == '[object Array]'){
-	            options.value = JSON.stringify(options.value);
-	        }
-	        // localStorage.setItem(options.name,options.value);
-			uni.setStorageSync(options.name,options.value);
-	    }
+			let type = Object.prototype.toString.call(options.value);
+			//如果value是对象或者数组对象的类型,就先用JSON.stringify转一下,再存进去
+			if (Object.prototype.toString.call(options.value) == '[object Object]') {
+				options.value = JSON.stringify(options.value);
+			}
+			if (Object.prototype.toString.call(options.value) == '[object Array]') {
+				options.value = JSON.stringify(options.value);
+			}
+			// localStorage.setItem(options.name,options.value);
+			uni.setStorageSync(options.name, options.value);
+		}
 	}
-	
+
 	/**
 	 * 缓存是否过期,过期自动删除
 	 * @param {Object} key
 	 * @param {Object} $bool true = 删除,false = 不删除
 	 */
-	getExpireCahe(key,$bool)
-	{
-		try{
+	getExpireCahe(key, $bool) {
+		try {
 			let time = this.cacheGetHandler(key + this.cacheExpire);
 			if (time) {
 				let newTime = parseInt(time);
@@ -120,44 +118,48 @@ class Cache {
 			} else {
 				return !!this.cacheGetHandler(key);
 			}
-		}catch(e){
+		} catch (e) {
 			return false;
 		}
 	}
-	
+
 	/**
 	 * 设置缓存
 	 * @param {Object} key
 	 * @param {Object} data
 	 */
-	set(key,data,expire){
-		if(typeof data === 'object')
+	set(key, data, expire) {
+		if (typeof data === 'object')
 			data = JSON.stringify(data);
-		try{
-			this.setExpireCaheTag(key,expire);
-			return this.cacheSetHandler(key,data); 
-		}catch(e){
+		try {
+			this.setExpireCaheTag(key, expire);
+			// 修复:写入独立的过期时间文件,以便 getExpireCahe 能正确读取
+			let effectiveExpire = expire !== undefined ? expire : EXPIRE;
+			if (typeof effectiveExpire === 'number' && effectiveExpire > 0) {
+				this.cacheSetHandler(key + this.cacheExpire, (this.time() + effectiveExpire) + "");
+			}
+			return this.cacheSetHandler(key, data);
+		} catch (e) {
 			return false;
 		}
 	}
-	
+
 	/**
 	 * 检测缓存是否存在
 	 * @param {Object} key
 	 */
-	has(key)
-	{
+	has(key) {
 		return this.getExpireCahe(key);
 	}
-	
+
 	/**
 	 * 获取缓存
 	 * @param {Object} key
 	 * @param {Object} $default
 	 * @param {Object} expire
 	 */
-	get(key,$default,expire){
-		try{
+	get(key, $default, expire) {
+		try {
 			let isBe = this.getExpireCahe(key);
 			let data = this.cacheGetHandler(key);
 			if (data && isBe) {
@@ -168,39 +170,37 @@ class Cache {
 			} else {
 				if (typeof $default === 'function') {
 					let value = $default();
-					this.set(key,value,expire);
+					this.set(key, value, expire);
 					return value;
 				} else {
-					this.set(key,$default,expire);
+					this.set(key, $default, expire);
 					return $default;
 				}
 			}
-		}catch(e){
+		} catch (e) {
 			return null;
 		}
 	}
-	
+
 	/**
 	 * 删除缓存
 	 * @param {Object} key
 	 */
-	clear(key)
-	{
-		try{
+	clear(key) {
+		try {
 			let cahceValue = this.cacheGetHandler(key + this.cacheExpire);
-			if(cahceValue)
+			if (cahceValue)
 				this.cacheClearHandler(key + this.cacheExpire);
 			return this.cacheClearHandler(key);
-		}catch(e){
+		} catch (e) {
 			return false;
 		}
 	}
-	
+
 	/**
 	 * 清除过期缓存
 	 */
-	clearOverdue()
-	{
+	clearOverdue() {
 		// let cacheList = uni.getStorageInfoSync(),that = this;
 		// if (typeof cacheList.keys === 'object'){
 		// 	cacheList.keys.forEach(item=>{
@@ -208,38 +208,38 @@ class Cache {
 		// 	})
 		// }
 	}
-	
+
 	/**
 	 * 获取缓存,调用后无需转换数据类型
 	 * @param {Object} key
 	 */
-	getItem(name){
-	    // let item = localStorage.getItem(name);
+	getItem(name) {
+		// let item = localStorage.getItem(name);
 		let item = uni.getStorageSync(name);
-	    //先将拿到的试着进行json转为对象的形式
-	    try{
-	        item = JSON.parse(item);
-	    }catch(error){
-	    //如果不行就不是json的字符串,就直接返回
-	        item = item;
-	    }
-	    //如果有startTime的值,说明设置了失效时间
-	    if(item.startTime){
-	        let date = new Date().getTime();
-	        //何时将值取出减去刚存入的时间,与item.expires比较,如果大于就是过期了,如果小于或等于就还没过期
-	        if(date - item.startTime > item.expires){
-	        //缓存过期,清除缓存,返回false
-	            // localStorage.removeItem(name);
+		//先将拿到的试着进行json转为对象的形式
+		try {
+			item = JSON.parse(item);
+		} catch (error) {
+			//如果不行就不是json的字符串,就直接返回
+			item = item;
+		}
+		//如果有startTime的值,说明设置了失效时间
+		if (item.startTime) {
+			let date = new Date().getTime();
+			//何时将值取出减去刚存入的时间,与item.expires比较,如果大于就是过期了,如果小于或等于就还没过期
+			if (date - item.startTime > item.expires) {
+				//缓存过期,清除缓存,返回false
+				// localStorage.removeItem(name);
 				uni.removeStorageSync(name);
-	            return false;
-	        }else{
-	        //缓存未过期,返回值
-	            return item.value;
-	        }
-	    }else{
-	    //如果没有设置失效时间,直接返回值
-	        return item;
-	    }
+				return false;
+			} else {
+				//缓存未过期,返回值
+				return item.value;
+			}
+		} else {
+			//如果没有设置失效时间,直接返回值
+			return item;
+		}
 	}
 }
 

+ 14 - 2
crmeb_src/mer_uniapp/utils/index.js

@@ -108,10 +108,22 @@ export function getCityList() {
 	});
 }
 
-export function rmbToLgns(rmb){
+// 人民币转Ls币
+export function rmbToLgns(rmb,mathType = "ceil"){
 	let rate = Store.getters.globalData.daibiRateLgnsCny
 	if(!rate) rate = 1
-	return (rmb / rate).toFixed(2)
+	if(mathType == "ceil") {
+		return (Math.ceil((rmb / rate) * 100) / 100).toFixed(2);
+	} else {
+		return (Math.floor((rmb / rate) * 100) / 100).toFixed(2);
+	}
+}
+
+// 获取人民币转Ls的汇率
+export function getRmbToLgnsRate(){
+	let rate = Store.getters.globalData.daibiRateLgnsCny
+	if(!rate) rate = 1
+	return rate
 }
 
 export default parseQuery;

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff