From f27f3a1da27ff11e3c12dc1841094a0419a4279a Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期五, 27 九月 2024 10:36:44 +0800
Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/mx_charging_pile

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java                             |  213 
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserTagClient.java                               |   32 
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/AccountingStrategyOrderFallbackFactory.java                 |   34 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TShoppingOrderServiceImpl.java                             |   91 
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TAppUserIntegralChange.java                               |    3 
 ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/ChargingPileClient.java                   |    7 
 ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java                           |   26 
 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java                                          |  391 
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/OrderFallbackFactory.java                                   |    3 
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/AccountingStrategyDetailOrderClient.java                |   10 
 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/dto/ExchangeBackDto.java                                     |    9 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TVipController.java                                          |    2 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserVipDetailController.java                         |    2 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TExchangeOrderController.java                                |    8 
 ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingGunFallbackFactory.java               |    8 
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/AccountingStrategyOrderClient.java                      |   26 
 ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/AccountingStrategyDetailFallbackFactory.java  |    8 
 ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/IntegrationFallbackFactory.java                 |    5 
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/UserSiteFallbackFactory.java                                |   14 
 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/PartnerServiceImpl.java                      |   22 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TExchangeOrderService.java                                      |    2 
 ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml                                              |   50 
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/OrderClient.java                                        |    3 
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/UserTagClient.java                                      |   25 
 ruoyi-api/ruoyi-api-order/pom.xml                                                                                               |    4 
 ruoyi-api/ruoyi-api-account/pom.xml                                                                                             |    4 
 ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java                          |   26 
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/UserTagFallbackFactory.java                                 |   33 
 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java                |    5 
 ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingPileFallbackFactory.java              |    5 
 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java                  |    6 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TCompanyController.java                                      |    2 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TShoppingOrderController.java                                |  126 
 ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml                                                                     |    4 
 ruoyi-api/ruoyi-api-account/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports |    3 
 ruoyi-api/ruoyi-api-payment/pom.xml                                                                                             |    4 
 ruoyi-api/ruoyi-api-system/pom.xml                                                                                              |    4 
 ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/vo/SiteInfoVO.java                                    |    2 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/PointDetailUtil.java                                           |    3 
 ruoyi-api/ruoyi-api-chargingPile/pom.xml                                                                                        |    4 
 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingGunController.java                    |   14 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TExchangeOrderServiceImpl.java                             |    7 
 ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/SendMessageFallbackFactory.java                 |   14 
 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/SysUserFallbackFactory.java                               |   14 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/RedisLock.java                                                     |   51 
 ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/AccountingStrategyFallbackFactory.java        |    8 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGoodsController.java                                        |   20 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/AccountingStrategyDetailOrderController.java                 |   15 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/AccountingStrategyOrderController.java                       |   35 
 ruoyi-api/ruoyi-api-order/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports   |    3 
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/CouponFallbackFactory.java                                  |   10 
 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/SiteController.java                            |   30 
 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java             |   13 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppCouponController.java                                |    5 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserController.java                                  |   75 
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyDetailOrder.java                            |    8 
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserTagController.java                               |   33 
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/GoodsFallbackFactory.java                                   |    8 
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserClient.java                                  |    4 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java                                |   49 
 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/filter/AuthFilter.java                                                |    2 
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyOrder.java                                  |    4 
 ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports   |    3 
 ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/IntegrationClient.java                      | 14707 +++++++++++++++++++++++++++++++++++++++++++++++++
 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/query/SysOperLogQuery.java                                            |    5 
 ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java                                                            |  222 
 ruoyi-api/ruoyi-api-other/pom.xml                                                                                               |    4 
 ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TUserTagController.java                                      |   16 
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserTagFallbackFactory.java                          |   40 
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/AccountingStrategyDetailOrderFallbackFactory.java           |    5 
 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/dto/PointChangeDto.java                                      |    1 
 ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TShoppingOrderMapper.xml                                              |    7 
 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java                                     |    1 
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserFallbackFactory.java                             |   13 
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserVipDetailFallbackFactory.java                    |   14 
 ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TChargingOrderRefund.java                                     |   11 
 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java                         |    5 
 ruoyi-api/ruoyi-api-integration/pom.xml                                                                                         |    4 
 ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java                |    2 
 ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/InvoiceTypeFallbackFactory.java                             |    8 
 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java                                  | 1076 +-
 81 files changed, 16,465 insertions(+), 1,330 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-account/pom.xml b/ruoyi-api/ruoyi-api-account/pom.xml
index 526cd85..773136f 100644
--- a/ruoyi-api/ruoyi-api-account/pom.xml
+++ b/ruoyi-api/ruoyi-api-account/pom.xml
@@ -28,10 +28,6 @@
                 </exclusion>
             </exclusions>
         </dependency>
-        <dependency>
-            <groupId>com.alibaba.cloud</groupId>
-            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
-        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserFallbackFactory.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserFallbackFactory.java
index e0b6d42..67b6a52 100644
--- a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserFallbackFactory.java
@@ -7,8 +7,6 @@
 import com.ruoyi.account.api.model.TAppUserAddress;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.core.dto.PointChangeDto;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -38,12 +36,6 @@
     
             @Override
             public R<TAppUser> getUserById(Long id) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("根据id查询用户失败:"+throwable.getMessage());
             }
 
@@ -57,10 +49,7 @@
                 return R.fail("修改用户失败:"+throwable.getMessage());
             }
 
-            @Override
-            public R change(PointChangeDto points) {
-                return null;
-            }
+
 
             @Override
             public R changeDown(PointChangeDto points) {
diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserTagFallbackFactory.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserTagFallbackFactory.java
new file mode 100644
index 0000000..e9cad57
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserTagFallbackFactory.java
@@ -0,0 +1,40 @@
+package com.ruoyi.account.api.factory;
+
+import com.ruoyi.account.api.feignClient.AppUserTagClient;
+import com.ruoyi.account.api.feignClient.InviteUserClient;
+import com.ruoyi.account.api.model.TAppUserTag;
+import com.ruoyi.account.api.model.TInviteUser;
+import com.ruoyi.account.api.vo.GetInviteUser;
+import com.ruoyi.common.core.domain.R;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+
+/**
+ *
+ * @author ruoyi
+ */
+@Component
+public class AppUserTagFallbackFactory implements org.springframework.cloud.openfeign.FallbackFactory<AppUserTagClient>
+{
+    private static final Logger log = LoggerFactory.getLogger(AppUserTagFallbackFactory.class);
+
+    @Override
+    public AppUserTagClient create(Throwable throwable) {
+        log.error("调用失败:{}", throwable.getMessage());
+        return new AppUserTagClient() {
+    
+    
+            @Override
+            public R<TAppUserTag> getUserTag(TAppUserTag appUserTag) {
+                return R.fail("获取用户标签关系失败:" + throwable.getMessage());
+            }
+
+            @Override
+            public void addUserTag(TAppUserTag appUserTag) {
+
+            }
+        };
+    }
+}
diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserVipDetailFallbackFactory.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserVipDetailFallbackFactory.java
index 21f6809..3a99a05 100644
--- a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserVipDetailFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserVipDetailFallbackFactory.java
@@ -4,8 +4,6 @@
 import com.ruoyi.account.api.model.TAppUserVipDetail;
 import com.ruoyi.account.api.vo.GetAppUserVipDetail;
 import com.ruoyi.common.core.domain.R;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -28,23 +26,11 @@
     
             @Override
             public R<TAppUserVipDetail> getAppUserVipDetail(GetAppUserVipDetail getAppUserVipDetail) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("获取用户当前有效的VIP明细调用失败:" + throwable.getMessage());
             }
     
             @Override
             public void updateAppUserVipDetail(TAppUserVipDetail appUserVipDetail) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 R.fail(throwable.getMessage());
             }
         };
diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserClient.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserClient.java
index 3cc881d..0f42ada 100644
--- a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserClient.java
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserClient.java
@@ -57,8 +57,8 @@
     @PostMapping("/t-app-user/user/updateAppUser")
     R updateAppUser(@RequestBody TAppUser appUser);
 
-    @PostMapping("/t-app-user/user/points/change")
-    R change(@RequestBody PointChangeDto points);
+//    @PostMapping("/t-app-user/user/points/change")
+//    R change(@RequestBody PointChangeDto points);
     @PostMapping("/t-app-user/user/points/change/down")
     R changeDown(@RequestBody PointChangeDto points);
 
diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserTagClient.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserTagClient.java
new file mode 100644
index 0000000..4a4966a
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserTagClient.java
@@ -0,0 +1,32 @@
+package com.ruoyi.account.api.feignClient;
+
+import com.ruoyi.account.api.factory.AppUserTagFallbackFactory;
+import com.ruoyi.account.api.model.TAppUserTag;
+import com.ruoyi.common.core.constant.ServiceNameConstants;
+import com.ruoyi.common.core.domain.R;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/9/25 16:17
+ */
+@FeignClient(contextId = "AppUserTagClient", value = ServiceNameConstants.ACCOUNT_SERVICE, fallbackFactory = AppUserTagFallbackFactory.class)
+public interface AppUserTagClient {
+	
+	/**
+	 * 获取用户标签关系
+	 * @param appUserTag
+	 * @return
+	 */
+	@PostMapping(value = "/t-app-user-tag/tags/getUserTag")
+	R<TAppUserTag> getUserTag(@RequestBody TAppUserTag appUserTag);
+	
+	/**
+	 * 添加用户标签关系数据
+	 * @param appUserTag
+	 */
+	@PostMapping(value = "/t-app-user-tag/tags/addUserTag")
+	void addUserTag(@RequestBody TAppUserTag appUserTag);
+}
diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TAppUserIntegralChange.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TAppUserIntegralChange.java
index abd7964..1b5f369 100644
--- a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TAppUserIntegralChange.java
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TAppUserIntegralChange.java
@@ -39,6 +39,9 @@
     @TableField("code")
     private String code;
 
+    @ApiModelProperty(value = "对应跳转订单号")
+    @TableField("order_code")
+    private String orderCode;
     @ApiModelProperty(value = "用户id")
     @TableField("app_user_id")
     private Long appUserId;
diff --git a/ruoyi-api/ruoyi-api-account/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-api/ruoyi-api-account/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index d32b3a0..385a667 100644
--- a/ruoyi-api/ruoyi-api-account/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-api/ruoyi-api-account/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -4,4 +4,5 @@
 com.ruoyi.account.api.factory.AppUserIntegralChangeFallbackFactory
 com.ruoyi.account.api.factory.AppUserAddressFallbackFactory
 com.ruoyi.account.api.factory.AppUserVipDetailFallbackFactory
-com.ruoyi.account.api.factory.InviteUserFallbackFactory
\ No newline at end of file
+com.ruoyi.account.api.factory.InviteUserFallbackFactory
+com.ruoyi.account.api.factory.AppUserTagFallbackFactory
\ No newline at end of file
diff --git a/ruoyi-api/ruoyi-api-chargingPile/pom.xml b/ruoyi-api/ruoyi-api-chargingPile/pom.xml
index c39d339..ac294c6 100644
--- a/ruoyi-api/ruoyi-api-chargingPile/pom.xml
+++ b/ruoyi-api/ruoyi-api-chargingPile/pom.xml
@@ -28,10 +28,6 @@
                 </exclusion>
             </exclusions>
         </dependency>
-        <dependency>
-            <groupId>com.alibaba.cloud</groupId>
-            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
-        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/AccountingStrategyDetailFallbackFactory.java b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/AccountingStrategyDetailFallbackFactory.java
index d8a1054..97e74d5 100644
--- a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/AccountingStrategyDetailFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/AccountingStrategyDetailFallbackFactory.java
@@ -4,8 +4,6 @@
 import com.ruoyi.chargingPile.api.feignClient.AccountingStrategyDetailClient;
 import com.ruoyi.chargingPile.api.model.TAccountingStrategyDetail;
 import com.ruoyi.common.core.domain.R;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -44,12 +42,6 @@
 			
 			@Override
 			public R<List<TAccountingStrategyDetail>> getListByAccountingStrategyId(Integer id) {
-				// 手动进行全局事务回滚
-				try {
-					GlobalTransactionContext.getCurrent().rollback();
-				} catch (TransactionException e) {
-					throw new RuntimeException(e);
-				}
 				return R.fail("根据计费策略主表id策略明细失败:" + throwable.getMessage());
 			}
 
diff --git a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/AccountingStrategyFallbackFactory.java b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/AccountingStrategyFallbackFactory.java
index 8d883c3..5cb8a3e 100644
--- a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/AccountingStrategyFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/AccountingStrategyFallbackFactory.java
@@ -3,8 +3,6 @@
 import com.ruoyi.chargingPile.api.feignClient.AccountingStrategyClient;
 import com.ruoyi.chargingPile.api.model.TAccountingStrategy;
 import com.ruoyi.common.core.domain.R;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -27,12 +25,6 @@
 			
 			@Override
 			public R<TAccountingStrategy> getAccountingStrategyById(Integer id) {
-				// 手动进行全局事务回滚
-				try {
-					GlobalTransactionContext.getCurrent().rollback();
-				} catch (TransactionException e) {
-					throw new RuntimeException(e);
-				}
 				return R.fail("根据id查询计费策略失败:" + throwable.getMessage());
 			}
 		};
diff --git a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingGunFallbackFactory.java b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingGunFallbackFactory.java
index ad57df7..56d4782 100644
--- a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingGunFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingGunFallbackFactory.java
@@ -7,8 +7,6 @@
 import com.ruoyi.chargingPile.api.model.TFaultMessage;
 import com.ruoyi.chargingPile.api.vo.SiteNameVO;
 import com.ruoyi.common.core.domain.R;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -38,12 +36,6 @@
     
             @Override
             public R<TChargingGun> getChargingGunById(Integer id) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("根据id获取充电枪失败:" + throwable.getMessage());
             }
 
diff --git a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingPileFallbackFactory.java b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingPileFallbackFactory.java
index 60dfdf2..cbb357e 100644
--- a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingPileFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingPileFallbackFactory.java
@@ -48,6 +48,11 @@
             }
 
             @Override
+            public R<SiteInfoVO> getSiteInfoByNumber1(String number) {
+                return R.fail("通过桩编号获取电站信息失败:"+throwable.getMessage());
+            }
+
+            @Override
             public R<TChargingPile> getChargingPileById(Integer id) {
                 return R.fail(throwable.getMessage());
             }
diff --git a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/ChargingPileClient.java b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/ChargingPileClient.java
index c85317a..f61dd25 100644
--- a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/ChargingPileClient.java
+++ b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/ChargingPileClient.java
@@ -7,6 +7,7 @@
 import com.ruoyi.common.core.domain.R;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -39,9 +40,11 @@
     @PostMapping(value = "/t-accounting-strategy/getServiceMoney")
     R<BigDecimal> getServiceMoney(@RequestParam("param") String param);
 
-    @PostMapping("/site/getSiteInfoByNumber")
-    @ApiOperation(value = "扫一扫后通过桩编号获取电站信息", tags = {"小程序-扫一扫"})
+    @GetMapping("/site/getSiteInfoByNumber")
     R<SiteInfoVO> getSiteInfoByNumber(@RequestParam("number") String number);
+
+    @PostMapping("/site/getSiteInfoByNumber1")
+    R<SiteInfoVO> getSiteInfoByNumber1(@RequestParam("number") String number);
     
     
     @PostMapping("/t-charging-pile/getChargingPileById/{id}")
diff --git a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/vo/SiteInfoVO.java b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/vo/SiteInfoVO.java
index f96faad..c3d2f73 100644
--- a/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/vo/SiteInfoVO.java
+++ b/ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/vo/SiteInfoVO.java
@@ -30,6 +30,8 @@
     private String spaceChargeExplain;
     @ApiModelProperty(value = "添加车辆最高可得积分 车辆信息为空 展示提示语")
     private Integer integral;
+    @ApiModelProperty(value = "充电模式(1=超级快充,2=快充,3=慢充")
+    private Integer chargeMode;
 
     @ApiModelProperty(value = "上次选择车辆logo")
     private String carLogo;
diff --git a/ruoyi-api/ruoyi-api-integration/pom.xml b/ruoyi-api/ruoyi-api-integration/pom.xml
index ac96969..d0c6f2d 100644
--- a/ruoyi-api/ruoyi-api-integration/pom.xml
+++ b/ruoyi-api/ruoyi-api-integration/pom.xml
@@ -32,10 +32,6 @@
                 </exclusion>
             </exclusions>
         </dependency>
-        <dependency>
-            <groupId>com.alibaba.cloud</groupId>
-            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
-        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/IntegrationFallbackFactory.java b/ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/IntegrationFallbackFactory.java
index 87a7d65..b30f0fe 100644
--- a/ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/IntegrationFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/IntegrationFallbackFactory.java
@@ -122,6 +122,11 @@
             public R<String> platformRemoteUpdate(PlatformRemoteUpdate platformRemoteUpdate) {
                 return R.fail("远程更新调用失败:" + throwable.getMessage());
             }
+
+            @Override
+            public R<String> setupBillingModel1(String deviceId) {
+                return R.fail("远程更新硬件:" + throwable.getMessage());
+            }
         };
     }
 }
diff --git a/ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/SendMessageFallbackFactory.java b/ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/SendMessageFallbackFactory.java
index c88ddbe..89f13bb 100644
--- a/ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/SendMessageFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/SendMessageFallbackFactory.java
@@ -6,8 +6,6 @@
 import com.ruoyi.integration.api.model.ChargingHandshake;
 import com.ruoyi.integration.api.model.PlatformStartCharging;
 import com.ruoyi.integration.api.model.PlatformStopCharging;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -31,23 +29,11 @@
     
             @Override
             public String platformStartCharging(PlatformStartCharging platformStartCharging) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return "远程启机失败";
             }
     
             @Override
             public String platformStopCharging(PlatformStopCharging platformStopCharging) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return "远程停机失败";
             }
         };
diff --git a/ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/IntegrationClient.java b/ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/IntegrationClient.java
index a6f1d64..8aae620 100644
--- a/ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/IntegrationClient.java
+++ b/ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/IntegrationClient.java
@@ -7,6 +7,7 @@
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
 
 /**
  * 充电服务
@@ -149,7 +150,7 @@
      * @param setupBillingModel 实体对象
      * @return
      */
-    @PostMapping("/sendMessage/sendMessagesetupBillingModel")
+    @PostMapping("/sendMessage/setupBillingModel")
     public R<String> setupBillingModel(@RequestBody SetupBillingModel setupBillingModel);
 
     /**
@@ -173,5 +174,14707 @@
      */
     @PostMapping("/sendMessage/sendMessageplatformRemoteUpdate")
     public R<String> platformRemoteUpdate(@RequestBody PlatformRemoteUpdate platformRemoteUpdate);
-    
+
+    @PostMapping("/iot/setupBillingModel")
+    public R<String> setupBillingModel1(@RequestParam("deviceId") String deviceId);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 }
diff --git a/ruoyi-api/ruoyi-api-order/pom.xml b/ruoyi-api/ruoyi-api-order/pom.xml
index d3feb2c..0a4b4ba 100644
--- a/ruoyi-api/ruoyi-api-order/pom.xml
+++ b/ruoyi-api/ruoyi-api-order/pom.xml
@@ -32,10 +32,6 @@
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-api-other</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.alibaba.cloud</groupId>
-            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
-        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/AccountingStrategyDetailOrderFallbackFactory.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/AccountingStrategyDetailOrderFallbackFactory.java
index d08a51c..d949791 100644
--- a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/AccountingStrategyDetailOrderFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/AccountingStrategyDetailOrderFallbackFactory.java
@@ -32,6 +32,11 @@
             public R<AccountingStrategyDetailOrder> getNowAccountingStrategyDetailOrder(Long orderId) {
                 return R.fail("根据订单id获取当前有效的策略失败:" + throwable.getMessage());
             }
+    
+            @Override
+            public R<List<AccountingStrategyDetailOrder>> getAllAccountingStrategyDetailOrder(Long orderId) {
+                return R.fail("获取订单对应的计费策略数据失败:" + throwable.getMessage());
+            }
         };
     }
 }
diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/AccountingStrategyOrderFallbackFactory.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/AccountingStrategyOrderFallbackFactory.java
new file mode 100644
index 0000000..dd92b7c
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/AccountingStrategyOrderFallbackFactory.java
@@ -0,0 +1,34 @@
+package com.ruoyi.order.api.factory;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.order.api.feignClient.AccountingStrategyDetailOrderClient;
+import com.ruoyi.order.api.feignClient.AccountingStrategyOrderClient;
+import com.ruoyi.order.api.model.AccountingStrategyDetailOrder;
+import com.ruoyi.order.api.model.AccountingStrategyOrder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * 充电订单服务降级处理
+ * 
+ * @author ruoyi
+ */
+@Component
+public class AccountingStrategyOrderFallbackFactory implements org.springframework.cloud.openfeign.FallbackFactory<AccountingStrategyOrderClient>
+{
+    private static final Logger log = LoggerFactory.getLogger(AccountingStrategyOrderFallbackFactory.class);
+
+    @Override
+    public AccountingStrategyOrderClient create(Throwable throwable) {
+        log.error("调用失败:{}", throwable.getMessage());
+        return new AccountingStrategyOrderClient() {
+    
+    
+            @Override
+            public R<AccountingStrategyOrder> getAccountingStrategyOrderById(Integer id) {
+                return R.fail("根据id获取计费策略失败:" + throwable.getMessage());
+            }
+        };
+    }
+}
diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/OrderFallbackFactory.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/OrderFallbackFactory.java
index 7f2650b..ab55bc6 100644
--- a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/OrderFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/OrderFallbackFactory.java
@@ -1,6 +1,7 @@
 package com.ruoyi.order.api.factory;
 
 import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.dto.ExchangeBackDto;
 import com.ruoyi.common.core.dto.ExchangeDto;
 import com.ruoyi.order.api.feignClient.OrderClient;
 import com.ruoyi.order.api.model.ChargingListQuery;
@@ -49,7 +50,7 @@
             }
 
             @Override
-            public R<Long> exchangeCreate(ExchangeDto exchangeDto) {
+            public R<ExchangeBackDto> exchangeCreate(ExchangeDto exchangeDto) {
                 return R.fail("创建订单" + cause.getMessage());
             }
 
diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/AccountingStrategyDetailOrderClient.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/AccountingStrategyDetailOrderClient.java
index dd73fbc..a6d5018 100644
--- a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/AccountingStrategyDetailOrderClient.java
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/AccountingStrategyDetailOrderClient.java
@@ -8,6 +8,8 @@
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import java.util.List;
+
 /**
  * @author zhibing.pu
  * @Date 2024/9/4 16:11
@@ -23,4 +25,12 @@
 	 */
 	@PostMapping("/accountingStrategyDetailOrder/getNowAccountingStrategyDetailOrder")
 	R<AccountingStrategyDetailOrder> getNowAccountingStrategyDetailOrder(@RequestParam("orderId") Long orderId);
+	
+	/**
+	 * 获取订单对应的计费策略数据
+	 * @param orderId
+	 * @return
+	 */
+	@PostMapping("/accountingStrategyDetailOrder/getAllAccountingStrategyDetailOrder")
+	R<List<AccountingStrategyDetailOrder>> getAllAccountingStrategyDetailOrder(@RequestParam("orderId") Long orderId);
 }
diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/AccountingStrategyOrderClient.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/AccountingStrategyOrderClient.java
new file mode 100644
index 0000000..22a314c
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/AccountingStrategyOrderClient.java
@@ -0,0 +1,26 @@
+package com.ruoyi.order.api.feignClient;
+
+import com.ruoyi.common.core.constant.ServiceNameConstants;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.order.api.factory.AccountingStrategyOrderFallbackFactory;
+import com.ruoyi.order.api.model.AccountingStrategyOrder;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/9/26 9:09
+ */
+@FeignClient(contextId = "AccountingStrategyOrderClient", value = ServiceNameConstants.ORDER_SERVICE, fallbackFactory = AccountingStrategyOrderFallbackFactory.class)
+public interface AccountingStrategyOrderClient {
+	
+	
+	/**
+	 * 根据id获取数据
+	 * @param id
+	 * @return
+	 */
+	@PostMapping("/accountingStrategyOrder/getAccountingStrategyOrderById")
+	R<AccountingStrategyOrder> getAccountingStrategyOrderById(@RequestParam("id") Integer id);
+}
diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/OrderClient.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/OrderClient.java
index 9e49992..9678610 100644
--- a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/OrderClient.java
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/OrderClient.java
@@ -2,6 +2,7 @@
 
 import com.ruoyi.common.core.constant.ServiceNameConstants;
 import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.dto.ExchangeBackDto;
 import com.ruoyi.common.core.dto.ExchangeDto;
 import com.ruoyi.order.api.factory.OrderFallbackFactory;
 import com.ruoyi.order.api.model.ChargingListQuery;
@@ -38,7 +39,7 @@
     public R<Long> getExchangeById(@RequestParam("goodId") Integer goodId,@RequestParam("userId")  Long userId,@RequestParam("goodType") Integer goodType);
 
     @PostMapping("/t-exchange-order/create")
-    public R<Long> exchangeCreate(@RequestBody ExchangeDto exchangeDto);
+    public R<ExchangeBackDto> exchangeCreate(@RequestBody ExchangeDto exchangeDto);
     @PostMapping("/t-vip-order//addVipOrder")
     public R<Long> addVipOrder(@RequestBody TVipOrder vipOrder);
     @PostMapping("/t-shopping-order/create")
diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyDetailOrder.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyDetailOrder.java
index abe6a4f..776c46c 100644
--- a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyDetailOrder.java
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyDetailOrder.java
@@ -1,6 +1,8 @@
 package com.ruoyi.order.api.model;
 
+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.ApiModelProperty;
 import lombok.Data;
@@ -17,11 +19,11 @@
 	/**
 	 * 主键
 	 */
-	@TableField(value = "id")
+	@TableId(type = IdType.INPUT, value = "id")
 	private Integer id;
 	@ApiModelProperty(value = "策略id")
-	@TableField("accounting_strategy_id")
-	private Integer accountingStrategyId;
+	@TableField("accounting_strategy_order_id")
+	private Integer accountingStrategyOrderId;
 	
 	@ApiModelProperty(value = "阶段(1=尖阶段,2=峰阶段,3=平阶段,4=谷阶段)")
 	@TableField("type")
diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyOrder.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyOrder.java
index 2736da3..01633e8 100644
--- a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyOrder.java
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyOrder.java
@@ -21,6 +21,10 @@
 @TableName("t_accounting_strategy_order")
 public class AccountingStrategyOrder extends BasePojo {
 	
+	@ApiModelProperty(value = "策略id")
+	@TableId(type = IdType.INPUT, value = "id")
+	private Integer id;
+	
 	@ApiModelProperty(value = "站点id")
 	@TableField("site_id")
 	private Integer siteId;
diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TChargingOrderRefund.java b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TChargingOrderRefund.java
index c95a809..4f762b6 100644
--- a/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TChargingOrderRefund.java
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TChargingOrderRefund.java
@@ -5,6 +5,8 @@
 import java.time.LocalDateTime;
 import com.baomidou.mybatisplus.annotation.TableField;
 import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -56,6 +58,7 @@
 
     @ApiModelProperty(value = "退款成功时间")
     @TableField("refund_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime refundTime;
 
     @ApiModelProperty(value = "订单编号")
@@ -96,7 +99,11 @@
     private BigDecimal paymentAmount;
     @ApiModelProperty(value = "支付时间")
     @TableField(exist = false)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime payTime;
-
-
+    @ApiModelProperty(value = "订单id")
+    @TableField(exist = false)
+    private String orderId;
+    @TableField(exist = false)
+    private String userId;
 }
diff --git a/ruoyi-api/ruoyi-api-order/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-api/ruoyi-api-order/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index d5bf5d5..afa46fb 100644
--- a/ruoyi-api/ruoyi-api-order/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-api/ruoyi-api-order/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -2,4 +2,5 @@
 com.ruoyi.order.api.factory.OrderFallbackFactory
 com.ruoyi.order.api.factory.ExchangeOrderFallbackFactory
 com.ruoyi.order.api.factory.ChargingOrderAccountingStrategyFallbackFactory
-com.ruoyi.order.api.factory.AccountingStrategyDetailOrderFallbackFactory
\ No newline at end of file
+com.ruoyi.order.api.factory.AccountingStrategyDetailOrderFallbackFactory
+com.ruoyi.order.api.factory.AccountingStrategyOrderFallbackFactory
\ No newline at end of file
diff --git a/ruoyi-api/ruoyi-api-other/pom.xml b/ruoyi-api/ruoyi-api-other/pom.xml
index 3f6a651..df1d49e 100644
--- a/ruoyi-api/ruoyi-api-other/pom.xml
+++ b/ruoyi-api/ruoyi-api-other/pom.xml
@@ -32,10 +32,6 @@
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-api-account</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.alibaba.cloud</groupId>
-            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
-        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/CouponFallbackFactory.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/CouponFallbackFactory.java
index e61f478..71f33d3 100644
--- a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/CouponFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/CouponFallbackFactory.java
@@ -2,11 +2,7 @@
 
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.other.api.domain.TCoupon;
-import com.ruoyi.other.api.domain.TGoods;
 import com.ruoyi.other.api.feignClient.CouponClient;
-import com.ruoyi.other.api.feignClient.GoodsClient;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -40,12 +36,6 @@
 			
 			@Override
 			public R updateCoupon(TCoupon coupon) {
-				// 手动进行全局事务回滚
-				try {
-					GlobalTransactionContext.getCurrent().rollback();
-				} catch (TransactionException e) {
-					throw new RuntimeException(e);
-				}
 				return R.fail("修改优惠券失败");
 			}
 		};
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/GoodsFallbackFactory.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/GoodsFallbackFactory.java
index bb82c32..c59d9a9 100644
--- a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/GoodsFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/GoodsFallbackFactory.java
@@ -3,8 +3,6 @@
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.other.api.domain.TGoods;
 import com.ruoyi.other.api.feignClient.GoodsClient;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -38,12 +36,6 @@
 			
 			@Override
 			public R updateGoods(TGoods goods) {
-				// 手动进行全局事务回滚
-				try {
-					GlobalTransactionContext.getCurrent().rollback();
-				} catch (TransactionException e) {
-					throw new RuntimeException(e);
-				}
 				return R.fail("修改商品异常");
 			}
 		};
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/InvoiceTypeFallbackFactory.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/InvoiceTypeFallbackFactory.java
index 1a7c645..136fcda 100644
--- a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/InvoiceTypeFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/InvoiceTypeFallbackFactory.java
@@ -3,8 +3,6 @@
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.other.api.domain.TInvoiceType;
 import com.ruoyi.other.api.feignClient.InvoiceTypeClient;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -29,12 +27,6 @@
     
             @Override
             public R<TInvoiceType> getInvoiceType(Integer id) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail(throwable.getMessage());
             }
         };
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/UserSiteFallbackFactory.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/UserSiteFallbackFactory.java
index 06e0917..7e63bb3 100644
--- a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/UserSiteFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/UserSiteFallbackFactory.java
@@ -3,8 +3,6 @@
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.other.api.domain.TUserSite;
 import com.ruoyi.other.api.feignClient.UserSiteClient;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -33,23 +31,11 @@
     
             @Override
             public R addUserSite(List<TUserSite> userSite) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("添加用户站点失败:" + throwable.getMessage());
             }
     
             @Override
             public R delUserSite(Long userId) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("删除用户站点失败:" + throwable.getMessage());
             }
         };
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/UserTagFallbackFactory.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/UserTagFallbackFactory.java
new file mode 100644
index 0000000..7f31bc3
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/UserTagFallbackFactory.java
@@ -0,0 +1,33 @@
+package com.ruoyi.other.api.factory;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.other.api.domain.TUserTag;
+import com.ruoyi.other.api.feignClient.UserTagClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+
+/**
+ * 商品服务降级处理
+ * 
+ * @author ruoyi
+ */
+@Component
+public class UserTagFallbackFactory implements org.springframework.cloud.openfeign.FallbackFactory<UserTagClient> {
+    private static final Logger log = LoggerFactory.getLogger(UserTagFallbackFactory.class);
+
+    @Override
+    public UserTagClient create(Throwable throwable) {
+        log.error("调用失败:{}", throwable.getMessage());
+        return new UserTagClient() {
+    
+            @Override
+            public R<List<TUserTag>> getAllUserTag() {
+                return R.fail("获取所有用户标签数据失败:" + throwable.getMessage());
+            }
+        };
+    }
+}
diff --git a/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/UserTagClient.java b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/UserTagClient.java
new file mode 100644
index 0000000..3be9297
--- /dev/null
+++ b/ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/UserTagClient.java
@@ -0,0 +1,25 @@
+package com.ruoyi.other.api.feignClient;
+
+import com.ruoyi.common.core.constant.ServiceNameConstants;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.other.api.domain.TUserTag;
+import com.ruoyi.other.api.factory.UserTagFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+
+import java.util.List;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/9/25 15:53
+ */
+@FeignClient(contextId = "UserTagClient", value = ServiceNameConstants.OTHER_SERVICE, fallbackFactory = UserTagFallbackFactory.class)
+public interface UserTagClient {
+	
+	/**
+	 * 获取所有用户标签数据
+	 * @return
+	 */
+	@PostMapping(value = "/t-user-tag/getAllUserTag")
+	R<List<TUserTag>> getAllUserTag();
+}
diff --git a/ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index df6e634..1d2b67a 100644
--- a/ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -7,4 +7,5 @@
 com.ruoyi.other.api.factory.GoodsFallbackFactory
 com.ruoyi.other.api.factory.CouponFallbackFactory
 com.ruoyi.other.api.factory.InvoiceTypeFallbackFactory
-com.ruoyi.other.api.factory.WebSocketFallbackFactory
\ No newline at end of file
+com.ruoyi.other.api.factory.WebSocketFallbackFactory
+com.ruoyi.other.api.factory.UserTagFallbackFactory
\ No newline at end of file
diff --git a/ruoyi-api/ruoyi-api-payment/pom.xml b/ruoyi-api/ruoyi-api-payment/pom.xml
index 31bbeee..75a1088 100644
--- a/ruoyi-api/ruoyi-api-payment/pom.xml
+++ b/ruoyi-api/ruoyi-api-payment/pom.xml
@@ -28,10 +28,6 @@
                 </exclusion>
             </exclusions>
         </dependency>
-        <dependency>
-            <groupId>com.alibaba.cloud</groupId>
-            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
-        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java
index 3c7b402..58d0545 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java
@@ -7,8 +7,6 @@
 import com.ruoyi.payment.api.vo.AliPaymentReq;
 import com.ruoyi.payment.api.vo.AliPaymentResp;
 import com.ruoyi.payment.api.vo.AliQueryOrder;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -32,45 +30,21 @@
     
             @Override
             public R<AliPaymentResp> payment(AliPaymentReq req) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("调起支付宝小程序支付失败:" + throwable.getMessage());
             }
     
             @Override
             public R<AliQueryOrder> query(String outTradeNo) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("查询支付订单失败:" + throwable.getMessage());
             }
     
             @Override
             public void close(String outTradeNo) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 R.fail("关闭支付订单失败:" + throwable.getMessage());
             }
 
             @Override
             public R<RefundResp> refund(RefundReq dto) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("支付宝退款失败:" + throwable.getMessage());
             }
         };
diff --git a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java
index bab0b46..71c165e 100644
--- a/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java
@@ -6,8 +6,6 @@
 import com.ruoyi.payment.api.vo.NotifyV3PayDecodeRespBody;
 import com.ruoyi.payment.api.vo.PaymentOrder;
 import com.ruoyi.payment.api.vo.WxRefundNotifyResp;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cloud.openfeign.FallbackFactory;
@@ -33,23 +31,11 @@
     
             @Override
             public R<NotifyV3PayDecodeRespBody> queryOrderInfo(String orderId) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("查询支付订单信息失败:" + throwable.getMessage());
             }
     
             @Override
             public R<Map<String, Object>> orderPay(PaymentOrder paymentOrder) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("调起微信支付失败:" + throwable.getMessage());
             }
     
@@ -65,23 +51,11 @@
 
             @Override
             public void close(String outTradeNo) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 R.fail("关闭支付订单失败:" + throwable.getMessage());
             }
 
             @Override
             public R<String> refundOrderR(WxPaymentRefundModel model) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("微信退款失败:" + throwable.getMessage());
             }
     
diff --git a/ruoyi-api/ruoyi-api-system/pom.xml b/ruoyi-api/ruoyi-api-system/pom.xml
index b2f0bcd..2670f57 100644
--- a/ruoyi-api/ruoyi-api-system/pom.xml
+++ b/ruoyi-api/ruoyi-api-system/pom.xml
@@ -28,10 +28,6 @@
                 </exclusion>
             </exclusions>
         </dependency>
-        <dependency>
-            <groupId>com.alibaba.cloud</groupId>
-            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
-        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/SysUserFallbackFactory.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/SysUserFallbackFactory.java
index 44713a0..d8d4994 100644
--- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/SysUserFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/SysUserFallbackFactory.java
@@ -5,8 +5,6 @@
 import com.ruoyi.system.api.domain.SysUser;
 import com.ruoyi.system.api.feignClient.SysUserClient;
 import com.ruoyi.system.api.model.*;
-import io.seata.core.exception.TransactionException;
-import io.seata.tm.api.GlobalTransactionContext;
 import org.springframework.cloud.openfeign.FallbackFactory;
 import org.springframework.stereotype.Component;
 
@@ -29,12 +27,6 @@
 
             @Override
             public R<Boolean> updateSysUser(SysUser sysUser) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("更新用户失败:" + cause.getMessage());
             }
 
@@ -105,12 +97,6 @@
 
             @Override
             public R resetPassword(SysUser user) {
-                // 手动进行全局事务回滚
-                try {
-                    GlobalTransactionContext.getCurrent().rollback();
-                } catch (TransactionException e) {
-                    throw new RuntimeException(e);
-                }
                 return R.fail("重置用户密码失败:" + cause.getMessage());
             }
         };
diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java
index 3223a6b..c443059 100644
--- a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java
+++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java
@@ -22,125 +22,111 @@
 
 /**
  * 登录校验方法
- * 
+ *
  * @author ruoyi
  */
 @Component
-public class SysLoginService
-{
-    @Autowired
-    private RemoteUserService remoteUserService;
-
-    @Autowired
-    private SysPasswordService passwordService;
-
-    @Autowired
-    private SysRecordLogService recordLogService;
-
-    @Autowired
-    private RedisService redisService;
-
-    /**
-     * 登录
-     */
-    public LoginUser login(String username, String password, HttpServletRequest request) {
-        // 查询用户信息
-        R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
-    
-        if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData()))
-        {
-            recordLogService.recordLogininfor(request, null, username, Constants.LOGIN_FAIL_STATUS, "登录用户不存在");
-            throw new ServiceException("登录用户:" + username + " 不存在");
-        }
-        LoginUser userInfo = userResult.getData();
-        SysUser user = userResult.getData().getSysUser();
-        
-        // 用户名或密码为空 错误
-        if (StringUtils.isAnyBlank(username, password))
-        {
-            recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户/密码必须填写");
-            throw new ServiceException("用户/密码必须填写");
-        }
-        // 密码如果不在指定范围内 错误
-        if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
-                || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
-        {
-            recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户密码不在指定范围");
-            throw new ServiceException("用户密码不在指定范围");
-        }
-        // 用户名不在指定范围内 错误
-        if (username.length() < UserConstants.USERNAME_MIN_LENGTH
-                || username.length() > UserConstants.USERNAME_MAX_LENGTH)
-        {
-            recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户名不在指定范围");
-            throw new ServiceException("用户名不在指定范围");
-        }
-        // IP黑名单校验
-        String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST));
-        if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
-        {
-            recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "很遗憾,访问IP已被列入系统黑名单");
-            throw new ServiceException("很遗憾,访问IP已被列入系统黑名单");
-        }
-
-        if (R.FAIL == userResult.getCode())
-        {
-            throw new ServiceException(userResult.getMsg());
-        }
-        
-        
-        if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
-        {
-            recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "对不起,您的账号已被删除");
-            throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
-        }
-        if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
-        {
-            recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户已停用,请联系管理员");
-            throw new ServiceException("对不起,您的账号:" + username + " 已停用");
-        }
-        passwordService.validate(user, password, request);
-        recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_SUCCESS_STATUS, "登录成功");
-        return userInfo;
-    }
-
-    public void logout(String loginName, HttpServletRequest request)
-    {
-        recordLogService.recordLogininfor(request, null, loginName, Constants.LOGIN_SUCCESS_STATUS, "退出成功");
-    }
-
-    /**
-     * 注册
-     */
-    public void register(String username, String password, HttpServletRequest request)
-    {
-        // 用户名或密码为空 错误
-        if (StringUtils.isAnyBlank(username, password))
-        {
-            throw new ServiceException("用户/密码必须填写");
-        }
-        if (username.length() < UserConstants.USERNAME_MIN_LENGTH
-                || username.length() > UserConstants.USERNAME_MAX_LENGTH)
-        {
-            throw new ServiceException("账户长度必须在2到20个字符之间");
-        }
-        if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
-                || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
-        {
-            throw new ServiceException("密码长度必须在5到20个字符之间");
-        }
-
-        // 注册用户信息
-        SysUser sysUser = new SysUser();
-        sysUser.setUserName(username);
-        sysUser.setNickName(username);
-        sysUser.setPassword(SecurityUtils.encryptPassword(password));
-        R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER);
-
-        if (R.FAIL == registerResult.getCode())
-        {
-            throw new ServiceException(registerResult.getMsg());
-        }
-        recordLogService.recordLogininfor(request, sysUser.getUserId().intValue(), username, Constants.LOGIN_SUCCESS_STATUS, "注册成功");
-    }
+public class SysLoginService {
+	@Autowired
+	private RemoteUserService remoteUserService;
+	
+	@Autowired
+	private SysPasswordService passwordService;
+	
+	@Autowired
+	private SysRecordLogService recordLogService;
+	
+	@Autowired
+	private RedisService redisService;
+	
+	/**
+	 * 登录
+	 */
+	public LoginUser login(String username, String password, HttpServletRequest request) {
+		username = username.trim();
+		// 查询用户信息
+		R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
+		
+		if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData())) {
+			recordLogService.recordLogininfor(request, null, username, Constants.LOGIN_FAIL_STATUS, "登录用户不存在");
+			throw new ServiceException("登录用户:" + username + " 不存在");
+		}
+		LoginUser userInfo = userResult.getData();
+		SysUser user = userResult.getData().getSysUser();
+		
+		// 用户名或密码为空 错误
+		if (StringUtils.isAnyBlank(username, password)) {
+			recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户/密码必须填写");
+			throw new ServiceException("用户/密码必须填写");
+		}
+		// 密码如果不在指定范围内 错误
+		if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
+				|| password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
+			recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户密码不在指定范围");
+			throw new ServiceException("用户密码不在指定范围");
+		}
+		// 用户名不在指定范围内 错误
+		if (username.length() < UserConstants.USERNAME_MIN_LENGTH
+				|| username.length() > UserConstants.USERNAME_MAX_LENGTH) {
+			recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户名不在指定范围");
+			throw new ServiceException("用户名不在指定范围");
+		}
+		// IP黑名单校验
+		String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST));
+		if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) {
+			recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "很遗憾,访问IP已被列入系统黑名单");
+			throw new ServiceException("很遗憾,访问IP已被列入系统黑名单");
+		}
+		
+		if (R.FAIL == userResult.getCode()) {
+			throw new ServiceException(userResult.getMsg());
+		}
+		
+		
+		if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
+			recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "对不起,您的账号已被删除");
+			throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
+		}
+		if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
+			recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户已停用,请联系管理员");
+			throw new ServiceException("对不起,您的账号:" + username + " 已停用");
+		}
+		passwordService.validate(user, password, request);
+		recordLogService.recordLogininfor(request, user.getUserId().intValue(), username, Constants.LOGIN_SUCCESS_STATUS, "登录成功");
+		return userInfo;
+	}
+	
+	public void logout(String loginName, HttpServletRequest request) {
+		recordLogService.recordLogininfor(request, null, loginName, Constants.LOGIN_SUCCESS_STATUS, "退出成功");
+	}
+	
+	/**
+	 * 注册
+	 */
+	public void register(String username, String password, HttpServletRequest request) {
+		// 用户名或密码为空 错误
+		if (StringUtils.isAnyBlank(username, password)) {
+			throw new ServiceException("用户/密码必须填写");
+		}
+		if (username.length() < UserConstants.USERNAME_MIN_LENGTH
+				|| username.length() > UserConstants.USERNAME_MAX_LENGTH) {
+			throw new ServiceException("账户长度必须在2到20个字符之间");
+		}
+		if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
+				|| password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
+			throw new ServiceException("密码长度必须在5到20个字符之间");
+		}
+		
+		// 注册用户信息
+		SysUser sysUser = new SysUser();
+		sysUser.setUserName(username);
+		sysUser.setNickName(username);
+		sysUser.setPassword(SecurityUtils.encryptPassword(password));
+		R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER);
+		
+		if (R.FAIL == registerResult.getCode()) {
+			throw new ServiceException(registerResult.getMsg());
+		}
+		recordLogService.recordLogininfor(request, sysUser.getUserId().intValue(), username, Constants.LOGIN_SUCCESS_STATUS, "注册成功");
+	}
 }
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/dto/ExchangeBackDto.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/dto/ExchangeBackDto.java
new file mode 100644
index 0000000..102ecb9
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/dto/ExchangeBackDto.java
@@ -0,0 +1,9 @@
+package com.ruoyi.common.core.dto;
+
+import lombok.Data;
+
+@Data
+public class ExchangeBackDto {
+    private Long id;
+    private String code;
+}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/dto/PointChangeDto.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/dto/PointChangeDto.java
index 4a6d0fb..3417d40 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/dto/PointChangeDto.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/dto/PointChangeDto.java
@@ -8,4 +8,5 @@
     private Integer points;
     private String remark;
     private Integer type;
+    private String code;
 }
diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java
index e4f2dd0..a3220ef 100644
--- a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java
+++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java
@@ -31,219 +31,188 @@
 
 /**
  * 操作日志记录处理
- * 
+ *
  * @author ruoyi
  */
 @Aspect
 @Component
-public class LogAspect
-{
-    private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
-
-    /** 排除敏感属性字段 */
-    public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
-
-    /** 计算操作消耗时间 */
-    private static final ThreadLocal<Long> TIME_THREADLOCAL = new NamedThreadLocal<Long>("Cost Time");
-
-    @Autowired
-    private AsyncLogService asyncLogService;
-
-    /**
-     * 处理请求前执行
-     */
-    @Before(value = "@annotation(controllerLog)")
-    public void boBefore(JoinPoint joinPoint, Log controllerLog)
-    {
-        TIME_THREADLOCAL.set(System.currentTimeMillis());
-    }
-
-    /**
-     * 处理完请求后执行
-     *
-     * @param joinPoint 切点
-     */
-    @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
-    public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult)
-    {
-        handleLog(joinPoint, controllerLog, null, jsonResult);
-    }
-
-    /**
-     * 拦截异常操作
-     * 
-     * @param joinPoint 切点
-     * @param e 异常
-     */
-    @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
-    public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e)
-    {
-        handleLog(joinPoint, controllerLog, e, null);
-    }
-
-    protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult)
-    {
-        try
-        {
-            // *========数据库日志=========*//
-            SysOperLog operLog = new SysOperLog();
-            operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
-            // 请求的地址
-            String ip = IpUtils.getIpAddr();
-            operLog.setOperIp(ip);
-            operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
-            String username = SecurityUtils.getUsername();
-            if (StringUtils.isNotBlank(username))
-            {
-                operLog.setOperName(username);
-            }
-
-            if (e != null)
-            {
-                operLog.setStatus(BusinessStatus.FAIL.ordinal());
-                operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
-            }
-            // 设置方法名称
-            String className = joinPoint.getTarget().getClass().getName();
-            String methodName = joinPoint.getSignature().getName();
-            operLog.setMethod(className + "." + methodName + "()");
-            // 设置请求方式
-            operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
-            // 处理设置注解上的参数
-            getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
-            // 设置消耗时间
-            operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get());
-            // 保存数据库
-            asyncLogService.saveSysLog(operLog);
-        }
-        catch (Exception exp)
-        {
-            // 记录本地异常日志
-            log.error("异常信息:{}", exp.getMessage());
-            exp.printStackTrace();
-        }
-        finally
-        {
-            TIME_THREADLOCAL.remove();
-        }
-    }
-
-    /**
-     * 获取注解中对方法的描述信息 用于Controller层注解
-     * 
-     * @param log 日志
-     * @param operLog 操作日志
-     * @throws Exception
-     */
-    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception
-    {
-        // 设置action动作
-        operLog.setBusinessType(log.businessType().ordinal());
-        // 设置标题
-        operLog.setTitle(log.title());
-        // 设置操作人类别
-        operLog.setOperatorType(log.operatorType().ordinal());
-        // 是否需要保存request,参数和值
-        if (log.isSaveRequestData())
-        {
-            // 获取参数的信息,传入到数据库中。
-            setRequestValue(joinPoint, operLog, log.excludeParamNames());
-        }
-        // 是否需要保存response,参数和值
-        if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult))
-        {
-            operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000));
-        }
-    }
-
-    /**
-     * 获取请求的参数,放到log中
-     * 
-     * @param operLog 操作日志
-     * @throws Exception 异常
-     */
-    private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception
-    {
-        String requestMethod = operLog.getRequestMethod();
-        Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
-        if (StringUtils.isEmpty(paramsMap)
-                && (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)))
-        {
-            String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
-            operLog.setOperParam(StringUtils.substring(params, 0, 2000));
-        }
-        else
-        {
-            operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000));
-        }
-    }
-
-    /**
-     * 参数拼装
-     */
-    private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames)
-    {
-        String params = "";
-        if (paramsArray != null && paramsArray.length > 0)
-        {
-            for (Object o : paramsArray)
-            {
-                if (StringUtils.isNotNull(o) && !isFilterObject(o))
-                {
-                    try
-                    {
-                        String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames));
-                        params += jsonObj.toString() + " ";
-                    }
-                    catch (Exception e)
-                    {
-                    }
-                }
-            }
-        }
-        return params.trim();
-    }
-
-    /**
-     * 忽略敏感属性
-     */
-    public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames)
-    {
-        return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames));
-    }
-
-    /**
-     * 判断是否需要过滤的对象。
-     * 
-     * @param o 对象信息。
-     * @return 如果是需要过滤的对象,则返回true;否则返回false。
-     */
-    @SuppressWarnings("rawtypes")
-    public boolean isFilterObject(final Object o)
-    {
-        Class<?> clazz = o.getClass();
-        if (clazz.isArray())
-        {
-            return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
-        }
-        else if (Collection.class.isAssignableFrom(clazz))
-        {
-            Collection collection = (Collection) o;
-            for (Object value : collection)
-            {
-                return value instanceof MultipartFile;
-            }
-        }
-        else if (Map.class.isAssignableFrom(clazz))
-        {
-            Map map = (Map) o;
-            for (Object value : map.entrySet())
-            {
-                Map.Entry entry = (Map.Entry) value;
-                return entry.getValue() instanceof MultipartFile;
-            }
-        }
-        return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
-                || o instanceof BindingResult;
-    }
+public class LogAspect {
+	private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
+	
+	/**
+	 * 排除敏感属性字段
+	 */
+	public static final String[] EXCLUDE_PROPERTIES = {"password", "oldPassword", "newPassword", "confirmPassword"};
+	
+	/**
+	 * 计算操作消耗时间
+	 */
+	private static final ThreadLocal<Long> TIME_THREADLOCAL = new NamedThreadLocal<Long>("Cost Time");
+	
+	@Autowired
+	private AsyncLogService asyncLogService;
+	
+	/**
+	 * 处理请求前执行
+	 */
+	@Before(value = "@annotation(controllerLog)")
+	public void boBefore(JoinPoint joinPoint, Log controllerLog) {
+		TIME_THREADLOCAL.set(System.currentTimeMillis());
+	}
+	
+	/**
+	 * 处理完请求后执行
+	 *
+	 * @param joinPoint 切点
+	 */
+	@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
+	public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {
+		handleLog(joinPoint, controllerLog, null, jsonResult);
+	}
+	
+	/**
+	 * 拦截异常操作
+	 *
+	 * @param joinPoint 切点
+	 * @param e         异常
+	 */
+	@AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
+	public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
+		handleLog(joinPoint, controllerLog, e, null);
+	}
+	
+	protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
+		try {
+			// *========数据库日志=========*//
+			SysOperLog operLog = new SysOperLog();
+			operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
+			// 请求的地址
+			String ip = IpUtils.getIpAddr();
+			operLog.setOperIp(ip);
+			operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
+			String username = SecurityUtils.getUsername();
+			if (StringUtils.isNotBlank(username)) {
+				operLog.setOperName(username);
+			}
+			
+			if (e != null) {
+				operLog.setStatus(BusinessStatus.FAIL.ordinal());
+				operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
+			}
+			// 设置方法名称
+			String className = joinPoint.getTarget().getClass().getName();
+			String methodName = joinPoint.getSignature().getName();
+			operLog.setMethod(className + "." + methodName + "()");
+			// 设置请求方式
+			operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
+			// 处理设置注解上的参数
+			getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
+			// 设置消耗时间
+			operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get());
+			// 保存数据库
+			asyncLogService.saveSysLog(operLog);
+		} catch (Exception exp) {
+			// 记录本地异常日志
+			log.error("异常信息:{}", exp.getMessage());
+			exp.printStackTrace();
+		} finally {
+			TIME_THREADLOCAL.remove();
+		}
+	}
+	
+	/**
+	 * 获取注解中对方法的描述信息 用于Controller层注解
+	 *
+	 * @param log     日志
+	 * @param operLog 操作日志
+	 * @throws Exception
+	 */
+	public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception {
+		// 设置action动作
+		operLog.setBusinessType(log.businessType().ordinal());
+		// 设置标题
+		operLog.setTitle(log.title());
+		// 设置操作人类别
+		operLog.setOperatorType(log.operatorType().ordinal());
+		// 是否需要保存request,参数和值
+		if (log.isSaveRequestData()) {
+			// 获取参数的信息,传入到数据库中。
+			setRequestValue(joinPoint, operLog, log.excludeParamNames());
+		}
+		// 是否需要保存response,参数和值
+		if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) {
+			operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000));
+		}
+	}
+	
+	/**
+	 * 获取请求的参数,放到log中
+	 *
+	 * @param operLog 操作日志
+	 * @throws Exception 异常
+	 */
+	private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception {
+		String requestMethod = operLog.getRequestMethod();
+		Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
+		if (StringUtils.isEmpty(paramsMap)
+				&& (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))) {
+			String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
+			operLog.setOperParam(StringUtils.substring(params, 0, 2000));
+		} else {
+			operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000));
+		}
+	}
+	
+	/**
+	 * 参数拼装
+	 */
+	private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames) {
+		String params = "";
+		if (paramsArray != null && paramsArray.length > 0) {
+			for (Object o : paramsArray) {
+				if (StringUtils.isNotNull(o) && !isFilterObject(o)) {
+					try {
+						String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames));
+						params += jsonObj.toString() + " ";
+					} catch (Exception e) {
+					}
+				}
+			}
+		}
+		return params.trim();
+	}
+	
+	/**
+	 * 忽略敏感属性
+	 */
+	public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames) {
+		return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames));
+	}
+	
+	/**
+	 * 判断是否需要过滤的对象。
+	 *
+	 * @param o 对象信息。
+	 * @return 如果是需要过滤的对象,则返回true;否则返回false。
+	 */
+	@SuppressWarnings("rawtypes")
+	public boolean isFilterObject(final Object o) {
+		Class<?> clazz = o.getClass();
+		if (clazz.isArray()) {
+			return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
+		} else if (Collection.class.isAssignableFrom(clazz)) {
+			Collection collection = (Collection) o;
+			for (Object value : collection) {
+				return value instanceof MultipartFile;
+			}
+		} else if (Map.class.isAssignableFrom(clazz)) {
+			Map map = (Map) o;
+			for (Object value : map.entrySet()) {
+				Map.Entry entry = (Map.Entry) value;
+				return entry.getValue() instanceof MultipartFile;
+			}
+		}
+		return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
+				|| o instanceof BindingResult;
+	}
 }
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java
index d498093..1da5038 100644
--- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java
+++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java
@@ -34,9 +34,9 @@
 public class GlobalExceptionHandler {
 	private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
 	
-	@Value("${spring.servlet.multipart.max-file-size:50MB}")
+	@Value("${spring.servlet.multipart.max-file-size}")
 	private String maxFileSize;
-	@Value("${spring.servlet.multipart.max-request-size:100MB}")
+	@Value("${spring.servlet.multipart.max-request-size}")
 	private String maxRequestSize;
 	
 	
@@ -88,7 +88,7 @@
 	public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) {
 		String requestURI = request.getRequestURI();
 		log.error("请求地址'{}',发生未知异常.", requestURI, e);
-		throw new RuntimeException(e.getMessage());
+		return AjaxResult.error(e.getMessage());
 	}
 	
 	/**
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java
index 4780d71..752e3d0 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java
@@ -680,7 +680,6 @@
     @PostMapping("/addSysUser")
     @Transactional(rollbackFor = Exception.class)
     public R addSysUser(@RequestBody SysUser user) {
-        System.err.println("事务ID:" + RootContext.getXID());
         if(StringUtils.isEmpty(user.getUserName())){
             user.setUserName(user.getPhonenumber());
         }
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/filter/AuthFilter.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/filter/AuthFilter.java
index 392bd32..b7e595a 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/filter/AuthFilter.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/filter/AuthFilter.java
@@ -82,7 +82,7 @@
 				return;
 			}
 		}
-		filterChain.doFilter(request, response);
+		filterChain.doFilter(servletRequest, servletResponse);
 	}
 	
 	
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/query/SysOperLogQuery.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/query/SysOperLogQuery.java
index fcb7a5b..0dbb38e 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/query/SysOperLogQuery.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/query/SysOperLogQuery.java
@@ -5,6 +5,7 @@
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.time.LocalDateTime;
 
@@ -17,11 +18,11 @@
     private String title;
     @ApiModelProperty(value = "状态(0=正常,1=异常)")
     private Integer status;
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @ApiModelProperty(value = "操作开始时间", notes = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime startTime;
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @ApiModelProperty(value = "操作结束时间", notes = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime endTime;
 
 }
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
index 247bbe3..766820b 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -47,280 +47,254 @@
 
 /**
  * 用户 业务层处理
- * 
+ *
  * @author ruoyi
  */
 @Service
-public class SysUserServiceImpl  extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService
-{
-    private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class);
-
-    @Resource
-    private SysUserMapper userMapper;
-
-    @Resource
-    private SysRoleMapper roleMapper;
-
-    @Resource
-    private SysPostMapper postMapper;
-
-    @Resource
-    private SysUserRoleMapper userRoleMapper;
-
-    @Resource
-    private SysUserPostMapper userPostMapper;
-
-    @Resource
-    private ISysConfigService configService;
-
-    @Resource
-    protected Validator validator;
-    
-    @Resource
-    private ISysUserRoleService sysUserRoleService;
-    
-    @Resource
-    private RoleSiteClient roleSiteClient;
-    
-    @Resource
-    private UserSiteClient userSiteClient;
-    
-    @Resource
-    private SiteClient siteClient;
-
-    @Resource
-    private ISysRoleService sysRoleService;
-    
-    
-    
-
-    /**
-     * 根据条件分页查询用户列表
-     * 
-     * @param user 用户信息
-     * @return 用户信息集合信息
-     */
-    @Override
-    @DataScope(deptAlias = "d", userAlias = "u")
-    public List<SysUser> selectUserList(SysUser user)
-    {
-        return userMapper.selectUserList(user);
-    }
-
-    /**
-     * 根据条件分页查询已分配用户角色列表
-     * 
-     * @param user 用户信息
-     * @return 用户信息集合信息
-     */
-    @Override
-    @DataScope(deptAlias = "d", userAlias = "u")
-    public List<SysUser> selectAllocatedList(SysUser user)
-    {
-        return userMapper.selectAllocatedList(user);
-    }
-
-    /**
-     * 根据条件分页查询未分配用户角色列表
-     * 
-     * @param user 用户信息
-     * @return 用户信息集合信息
-     */
-    @Override
-    @DataScope(deptAlias = "d", userAlias = "u")
-    public List<SysUser> selectUnallocatedList(SysUser user)
-    {
-        return userMapper.selectUnallocatedList(user);
-    }
-
-    /**
-     * 通过用户名查询用户
-     * 
-     * @param userName 用户名
-     * @return 用户对象信息
-     */
-    @Override
-    public SysUser selectUserByUserName(String userName)
-    {
-        return userMapper.selectUserByUserName(userName);
-    }
-
-    /**
-     * 通过用户ID查询用户
-     * 
-     * @param userId 用户ID
-     * @return 用户对象信息
-     */
-    @Override
-    public SysUser selectUserById(Long userId)
-    {
-        return userMapper.selectUserById(userId);
-    }
-
-    /**
-     * 查询用户所属角色组
-     * 
-     * @param userName 用户名
-     * @return 结果
-     */
-    @Override
-    public String selectUserRoleGroup(String userName)
-    {
-        List<SysRole> list = roleMapper.selectRolesByUserName(userName);
-        if (CollectionUtils.isEmpty(list))
-        {
-            return StringUtils.EMPTY;
-        }
-        return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(","));
-    }
-
-    /**
-     * 查询用户所属岗位组
-     * 
-     * @param userName 用户名
-     * @return 结果
-     */
-    @Override
-    public String selectUserPostGroup(String userName)
-    {
-        List<SysPost> list = postMapper.selectPostsByUserName(userName);
-        if (CollectionUtils.isEmpty(list))
-        {
-            return StringUtils.EMPTY;
-        }
-        return list.stream().map(SysPost::getPostName).collect(Collectors.joining(","));
-    }
-
-    /**
-     * 校验用户名称是否唯一
-     * 
-     * @param user 用户信息
-     * @return 结果
-     */
-    @Override
-    public boolean checkUserNameUnique(SysUser user)
-    {
-        Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
-        SysUser info = userMapper.checkUserNameUnique(user.getUserName());
-        if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue())
-        {
-            return UserConstants.NOT_UNIQUE;
-        }
-        return UserConstants.UNIQUE;
-    }
-
-    /**
-     * 校验手机号码是否唯一
-     *
-     * @param user 用户信息
-     * @return
-     */
-    @Override
-    public boolean checkPhoneUnique(SysUser user)
-    {
-        Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
-        SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber());
-        if (StringUtils.isNotNull(info) )
-        {
-            return UserConstants.NOT_UNIQUE;
-        }
-        return UserConstants.UNIQUE;
-    }
-    
-    
-    /**
-     * 校验email是否唯一
-     *
-     * @param user 用户信息
-     * @return
-     */
-    @Override
-    public boolean checkEmailUnique(SysUser user)
-    {
-        Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
-        SysUser info = userMapper.checkEmailUnique(user.getEmail());
-        if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue())
-        {
-            return UserConstants.NOT_UNIQUE;
-        }
-        return UserConstants.UNIQUE;
-    }
-
-    /**
-     * 校验用户是否允许操作
-     * 
-     * @param user 用户信息
-     */
-    @Override
-    public void checkUserAllowed(SysUser user)
-    {
-        if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin())
-        {
-            throw new ServiceException("不允许操作超级管理员用户");
-        }
-    }
-
-    /**
-     * 校验用户是否有数据权限
-     * 
-     * @param userId 用户id
-     */
-    @Override
-    public void checkUserDataScope(Long userId)
-    {
-        if (!SysUser.isAdmin(SecurityUtils.getUserId()))
-        {
-            SysUser user = new SysUser();
-            user.setUserId(userId);
-            List<SysUser> users = SpringUtils.getAopProxy(this).selectUserList(user);
-            if (StringUtils.isEmpty(users))
-            {
-                throw new ServiceException("没有权限访问用户数据!");
-            }
-        }
-    }
-
-    /**
-     * 新增保存用户信息
-     * 
-     * @param user 用户信息
-     * @return 结果
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int insertUser(SysUser user)
-    {
-        // 新增用户信息
-        int rows = userMapper.insertUser(user);
+public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
+	private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class);
+	
+	@Resource
+	private SysUserMapper userMapper;
+	
+	@Resource
+	private SysRoleMapper roleMapper;
+	
+	@Resource
+	private SysPostMapper postMapper;
+	
+	@Resource
+	private SysUserRoleMapper userRoleMapper;
+	
+	@Resource
+	private SysUserPostMapper userPostMapper;
+	
+	@Resource
+	private ISysConfigService configService;
+	
+	@Resource
+	protected Validator validator;
+	
+	@Resource
+	private ISysUserRoleService sysUserRoleService;
+	
+	@Resource
+	private RoleSiteClient roleSiteClient;
+	
+	@Resource
+	private UserSiteClient userSiteClient;
+	
+	@Resource
+	private SiteClient siteClient;
+	
+	@Resource
+	private ISysRoleService sysRoleService;
+	
+	
+	/**
+	 * 根据条件分页查询用户列表
+	 *
+	 * @param user 用户信息
+	 * @return 用户信息集合信息
+	 */
+	@Override
+	@DataScope(deptAlias = "d", userAlias = "u")
+	public List<SysUser> selectUserList(SysUser user) {
+		return userMapper.selectUserList(user);
+	}
+	
+	/**
+	 * 根据条件分页查询已分配用户角色列表
+	 *
+	 * @param user 用户信息
+	 * @return 用户信息集合信息
+	 */
+	@Override
+	@DataScope(deptAlias = "d", userAlias = "u")
+	public List<SysUser> selectAllocatedList(SysUser user) {
+		return userMapper.selectAllocatedList(user);
+	}
+	
+	/**
+	 * 根据条件分页查询未分配用户角色列表
+	 *
+	 * @param user 用户信息
+	 * @return 用户信息集合信息
+	 */
+	@Override
+	@DataScope(deptAlias = "d", userAlias = "u")
+	public List<SysUser> selectUnallocatedList(SysUser user) {
+		return userMapper.selectUnallocatedList(user);
+	}
+	
+	/**
+	 * 通过用户名查询用户
+	 *
+	 * @param userName 用户名
+	 * @return 用户对象信息
+	 */
+	@Override
+	public SysUser selectUserByUserName(String userName) {
+		return userMapper.selectUserByUserName(userName);
+	}
+	
+	/**
+	 * 通过用户ID查询用户
+	 *
+	 * @param userId 用户ID
+	 * @return 用户对象信息
+	 */
+	@Override
+	public SysUser selectUserById(Long userId) {
+		return userMapper.selectUserById(userId);
+	}
+	
+	/**
+	 * 查询用户所属角色组
+	 *
+	 * @param userName 用户名
+	 * @return 结果
+	 */
+	@Override
+	public String selectUserRoleGroup(String userName) {
+		List<SysRole> list = roleMapper.selectRolesByUserName(userName);
+		if (CollectionUtils.isEmpty(list)) {
+			return StringUtils.EMPTY;
+		}
+		return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(","));
+	}
+	
+	/**
+	 * 查询用户所属岗位组
+	 *
+	 * @param userName 用户名
+	 * @return 结果
+	 */
+	@Override
+	public String selectUserPostGroup(String userName) {
+		List<SysPost> list = postMapper.selectPostsByUserName(userName);
+		if (CollectionUtils.isEmpty(list)) {
+			return StringUtils.EMPTY;
+		}
+		return list.stream().map(SysPost::getPostName).collect(Collectors.joining(","));
+	}
+	
+	/**
+	 * 校验用户名称是否唯一
+	 *
+	 * @param user 用户信息
+	 * @return 结果
+	 */
+	@Override
+	public boolean checkUserNameUnique(SysUser user) {
+		Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
+		SysUser info = userMapper.checkUserNameUnique(user.getUserName());
+		if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
+			return UserConstants.NOT_UNIQUE;
+		}
+		return UserConstants.UNIQUE;
+	}
+	
+	/**
+	 * 校验手机号码是否唯一
+	 *
+	 * @param user 用户信息
+	 * @return
+	 */
+	@Override
+	public boolean checkPhoneUnique(SysUser user) {
+		Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
+		SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber());
+		if (StringUtils.isNotNull(info)) {
+			return UserConstants.NOT_UNIQUE;
+		}
+		return UserConstants.UNIQUE;
+	}
+	
+	
+	/**
+	 * 校验email是否唯一
+	 *
+	 * @param user 用户信息
+	 * @return
+	 */
+	@Override
+	public boolean checkEmailUnique(SysUser user) {
+		Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
+		SysUser info = userMapper.checkEmailUnique(user.getEmail());
+		if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
+			return UserConstants.NOT_UNIQUE;
+		}
+		return UserConstants.UNIQUE;
+	}
+	
+	/**
+	 * 校验用户是否允许操作
+	 *
+	 * @param user 用户信息
+	 */
+	@Override
+	public void checkUserAllowed(SysUser user) {
+		if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) {
+			throw new ServiceException("不允许操作超级管理员用户");
+		}
+	}
+	
+	/**
+	 * 校验用户是否有数据权限
+	 *
+	 * @param userId 用户id
+	 */
+	@Override
+	public void checkUserDataScope(Long userId) {
+		if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
+			SysUser user = new SysUser();
+			user.setUserId(userId);
+			List<SysUser> users = SpringUtils.getAopProxy(this).selectUserList(user);
+			if (StringUtils.isEmpty(users)) {
+				throw new ServiceException("没有权限访问用户数据!");
+			}
+		}
+	}
+	
+	/**
+	 * 新增保存用户信息
+	 *
+	 * @param user 用户信息
+	 * @return 结果
+	 */
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public int insertUser(SysUser user) {
+		// 新增用户信息
+		int rows = userMapper.insertUser(user);
 //        // 新增用户岗位关联
 //        insertUserPost(user);
 //        // 新增用户与角色管理
 //        insertUserRole(user);
-        return rows;
-    }
-
-    /**
-     * 注册用户信息
-     * 
-     * @param user 用户信息
-     * @return 结果
-     */
-    @Override
-    public boolean registerUser(SysUser user)
-    {
-        return userMapper.insertUser(user) > 0;
-    }
-
-    /**
-     * 修改保存用户信息
-     * 
-     * @param user 用户信息
-     * @return 结果
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int updateUser(SysUser user)
-    {
+		return rows;
+	}
+	
+	/**
+	 * 注册用户信息
+	 *
+	 * @param user 用户信息
+	 * @return 结果
+	 */
+	@Override
+	public boolean registerUser(SysUser user) {
+		return userMapper.insertUser(user) > 0;
+	}
+	
+	/**
+	 * 修改保存用户信息
+	 *
+	 * @param user 用户信息
+	 * @return 结果
+	 */
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public int updateUser(SysUser user) {
 //        Long userId = user.getUserId();
 //        // 删除用户与角色关联
 //        userRoleMapper.deleteUserRoleByUserId(userId);
@@ -330,307 +304,277 @@
 //        userPostMapper.deleteUserPostByUserId(userId);
 //        // 新增用户与岗位管理
 //        insertUserPost(user);
-        return userMapper.updateUser(user);
-    }
-
-    /**
-     * 用户授权角色
-     * 
-     * @param userId 用户ID
-     * @param roleIds 角色组
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void insertUserAuth(Long userId, Long[] roleIds)
-    {
-        userRoleMapper.deleteUserRoleByUserId(userId);
-        insertUserRole(userId, roleIds);
-    }
-
-    /**
-     * 修改用户状态
-     * 
-     * @param user 用户信息
-     * @return 结果
-     */
-    @Override
-    public int updateUserStatus(SysUser user)
-    {
-        return userMapper.updateUser(user);
-    }
-
-    /**
-     * 修改用户基本信息
-     * 
-     * @param user 用户信息
-     * @return 结果
-     */
-    @Override
-    public int updateUserProfile(SysUser user)
-    {
-        return userMapper.updateUser(user);
-    }
-
-    /**
-     * 修改用户头像
-     * 
-     * @param userName 用户名
-     * @param avatar 头像地址
-     * @return 结果
-     */
-    @Override
-    public boolean updateUserAvatar(String userName, String avatar)
-    {
-        return userMapper.updateUserAvatar(userName, avatar) > 0;
-    }
-
-    /**
-     * 重置用户密码
-     * 
-     * @param user 用户信息
-     * @return 结果
-     */
-    @Override
-    public int resetPwd(SysUser user)
-    {
-        return userMapper.updateUser(user);
-    }
-
-    /**
-     * 重置用户密码
-     * 
-     * @param userName 用户名
-     * @param password 密码
-     * @return 结果
-     */
-    @Override
-    public int resetUserPwd(String userName, String password)
-    {
-        return userMapper.resetUserPwd(userName, password);
-    }
-
-    /**
-     * 新增用户角色信息
-     * 
-     * @param user 用户对象
-     */
-    public void insertUserRole(SysUser user)
-    {
-        this.insertUserRole(user.getUserId(), user.getRoleIds());
-    }
-
-    /**
-     * 新增用户岗位信息
-     * 
-     * @param user 用户对象
-     */
-    public void insertUserPost(SysUser user)
-    {
-        Long[] posts = user.getPostIds();
-        if (StringUtils.isNotEmpty(posts))
-        {
-            // 新增用户与岗位管理
-            List<SysUserPost> list = new ArrayList<SysUserPost>();
-            for (Long postId : posts)
-            {
-                SysUserPost up = new SysUserPost();
-                up.setUserId(user.getUserId());
-                up.setPostId(postId);
-                list.add(up);
-            }
-            userPostMapper.batchUserPost(list);
-        }
-    }
-
-    /**
-     * 新增用户角色信息
-     * 
-     * @param userId 用户ID
-     * @param roleIds 角色组
-     */
-    public void insertUserRole(Long userId, Long[] roleIds)
-    {
-        if (StringUtils.isNotEmpty(roleIds))
-        {
-            // 新增用户与角色管理
-            List<SysUserRole> list = new ArrayList<SysUserRole>();
-            for (Long roleId : roleIds)
-            {
-                SysUserRole ur = new SysUserRole();
-                ur.setUserId(userId);
-                ur.setRoleId(roleId);
-                list.add(ur);
-            }
-            userRoleMapper.batchUserRole(list);
-        }
-    }
-
-    /**
-     * 通过用户ID删除用户
-     * 
-     * @param userId 用户ID
-     * @return 结果
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int deleteUserById(Long userId)
-    {
-        // 删除用户与角色关联
-        userRoleMapper.deleteUserRoleByUserId(userId);
-        // 删除用户与岗位表
-        userPostMapper.deleteUserPostByUserId(userId);
-        return userMapper.deleteUserById(userId);
-    }
-
-    /**
-     * 批量删除用户信息
-     * 
-     * @param userIds 需要删除的用户ID
-     * @return 结果
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public int deleteUserByIds(Long[] userIds)
-    {
-        for (Long userId : userIds)
-        {
-            checkUserAllowed(new SysUser(userId));
+		return userMapper.updateUser(user);
+	}
+	
+	/**
+	 * 用户授权角色
+	 *
+	 * @param userId  用户ID
+	 * @param roleIds 角色组
+	 */
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void insertUserAuth(Long userId, Long[] roleIds) {
+		userRoleMapper.deleteUserRoleByUserId(userId);
+		insertUserRole(userId, roleIds);
+	}
+	
+	/**
+	 * 修改用户状态
+	 *
+	 * @param user 用户信息
+	 * @return 结果
+	 */
+	@Override
+	public int updateUserStatus(SysUser user) {
+		return userMapper.updateUser(user);
+	}
+	
+	/**
+	 * 修改用户基本信息
+	 *
+	 * @param user 用户信息
+	 * @return 结果
+	 */
+	@Override
+	public int updateUserProfile(SysUser user) {
+		return userMapper.updateUser(user);
+	}
+	
+	/**
+	 * 修改用户头像
+	 *
+	 * @param userName 用户名
+	 * @param avatar   头像地址
+	 * @return 结果
+	 */
+	@Override
+	public boolean updateUserAvatar(String userName, String avatar) {
+		return userMapper.updateUserAvatar(userName, avatar) > 0;
+	}
+	
+	/**
+	 * 重置用户密码
+	 *
+	 * @param user 用户信息
+	 * @return 结果
+	 */
+	@Override
+	public int resetPwd(SysUser user) {
+		return userMapper.updateUser(user);
+	}
+	
+	/**
+	 * 重置用户密码
+	 *
+	 * @param userName 用户名
+	 * @param password 密码
+	 * @return 结果
+	 */
+	@Override
+	public int resetUserPwd(String userName, String password) {
+		return userMapper.resetUserPwd(userName, password);
+	}
+	
+	/**
+	 * 新增用户角色信息
+	 *
+	 * @param user 用户对象
+	 */
+	public void insertUserRole(SysUser user) {
+		this.insertUserRole(user.getUserId(), user.getRoleIds());
+	}
+	
+	/**
+	 * 新增用户岗位信息
+	 *
+	 * @param user 用户对象
+	 */
+	public void insertUserPost(SysUser user) {
+		Long[] posts = user.getPostIds();
+		if (StringUtils.isNotEmpty(posts)) {
+			// 新增用户与岗位管理
+			List<SysUserPost> list = new ArrayList<SysUserPost>();
+			for (Long postId : posts) {
+				SysUserPost up = new SysUserPost();
+				up.setUserId(user.getUserId());
+				up.setPostId(postId);
+				list.add(up);
+			}
+			userPostMapper.batchUserPost(list);
+		}
+	}
+	
+	/**
+	 * 新增用户角色信息
+	 *
+	 * @param userId  用户ID
+	 * @param roleIds 角色组
+	 */
+	public void insertUserRole(Long userId, Long[] roleIds) {
+		if (StringUtils.isNotEmpty(roleIds)) {
+			// 新增用户与角色管理
+			List<SysUserRole> list = new ArrayList<SysUserRole>();
+			for (Long roleId : roleIds) {
+				SysUserRole ur = new SysUserRole();
+				ur.setUserId(userId);
+				ur.setRoleId(roleId);
+				list.add(ur);
+			}
+			userRoleMapper.batchUserRole(list);
+		}
+	}
+	
+	/**
+	 * 通过用户ID删除用户
+	 *
+	 * @param userId 用户ID
+	 * @return 结果
+	 */
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public int deleteUserById(Long userId) {
+		// 删除用户与角色关联
+		userRoleMapper.deleteUserRoleByUserId(userId);
+		// 删除用户与岗位表
+		userPostMapper.deleteUserPostByUserId(userId);
+		return userMapper.deleteUserById(userId);
+	}
+	
+	/**
+	 * 批量删除用户信息
+	 *
+	 * @param userIds 需要删除的用户ID
+	 * @return 结果
+	 */
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public int deleteUserByIds(Long[] userIds) {
+		for (Long userId : userIds) {
+			checkUserAllowed(new SysUser(userId));
 //            checkUserDataScope(userId);
-        }
-        // 删除用户与角色关联
+		}
+		// 删除用户与角色关联
 //        userRoleMapper.deleteUserRole(userIds);
 //        // 删除用户与岗位关联
 //        userPostMapper.deleteUserPost(userIds);
-        return userMapper.deleteUserByIds(userIds);
-    }
-
-    /**
-     * 导入用户数据
-     * 
-     * @param userList 用户数据列表
-     * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据
-     * @param operName 操作用户
-     * @return 结果
-     */
-    @Override
-    public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName)
-    {
-        if (StringUtils.isNull(userList) || userList.size() == 0)
-        {
-            throw new ServiceException("导入用户数据不能为空!");
-        }
-        int successNum = 0;
-        int failureNum = 0;
-        StringBuilder successMsg = new StringBuilder();
-        StringBuilder failureMsg = new StringBuilder();
-        String password = configService.selectConfigByKey("sys.user.initPassword");
-        for (SysUser user : userList)
-        {
-            try
-            {
-                // 验证是否存在这个用户
-                SysUser u = userMapper.selectUserByUserName(user.getUserName());
-                if (StringUtils.isNull(u))
-                {
-                    BeanValidators.validateWithException(validator, user);
-                    user.setPassword(SecurityUtils.encryptPassword(password));
-                    user.setCreateBy(operName);
-                    userMapper.insertUser(user);
-                    successNum++;
-                    successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 导入成功");
-                }
-                else if (isUpdateSupport)
-                {
-                    BeanValidators.validateWithException(validator, user);
-                    checkUserAllowed(u);
-                    checkUserDataScope(u.getUserId());
-                    user.setUserId(u.getUserId());
-                    user.setUpdateBy(operName);
-                    userMapper.updateUser(user);
-                    successNum++;
-                    successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 更新成功");
-                }
-                else
-                {
-                    failureNum++;
-                    failureMsg.append("<br/>" + failureNum + "、账号 " + user.getUserName() + " 已存在");
-                }
-            }
-            catch (Exception e)
-            {
-                failureNum++;
-                String msg = "<br/>" + failureNum + "、账号 " + user.getUserName() + " 导入失败:";
-                failureMsg.append(msg + e.getMessage());
-                log.error(msg, e);
-            }
-        }
-        if (failureNum > 0)
-        {
-            failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
-            throw new ServiceException(failureMsg.toString());
-        }
-        else
-        {
-            successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
-        }
-        return successMsg.toString();
-    }
-
-    @Override
-    public PageInfo<SysUser> getList(PageInfo<SysUser> pageInfo, GetSysUserList getSysUserList) {
-        List<SysUser> list = this.baseMapper.getList(pageInfo, getSysUserList);
-        for (SysUser sysUser : list) {
-            List<SysUserRole> list1 = sysUserRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, sysUser.getUserId()));
-            List<Integer> data1 = userSiteClient.getSiteIds(sysUser.getUserId()).getData();
-            if(null == data1){
-                data1 = new ArrayList<>();
-            }
-            for (SysUserRole sysUserRole : list1) {
-                List<Integer> data = roleSiteClient.getSiteIds(sysUserRole.getRoleId()).getData();
-                if (null == data){
-                    continue;
-                }
-                data1.addAll(data);
-            }
-            Set<Integer> siteIds = new HashSet<>(data1);
-            sysUser.setSiteIds(siteIds.stream().collect(Collectors.toList()));
-            List<Site> data = siteClient.getSiteByIds(siteIds.stream().collect(Collectors.toList())).getData();
-            if(null != data){
-                List<String> siteNames = data.stream().map(Site::getName).collect(Collectors.toList());
-                sysUser.setSiteNames(siteNames);
-            }
-            List<String> roleNames = new ArrayList<>();
-            for (SysUserRole sysUserRole : list1) {
-                SysRole sysRole = sysRoleService.selectRoleById(sysUserRole.getRoleId());
-                roleNames.add(sysRole.getRoleName());
-            }
-            Long[] roleIds = new Long[]{};
-            sysUser.setRoleIds(list1.stream().map(SysUserRole::getRoleId).collect(Collectors.toList()).toArray(roleIds));
-            sysUser.setRoleNames(roleNames);
-        }
-        return pageInfo.setRecords(list);
-    }
-
-    @Override
-    public PageInfo<SysUser> getAllList(PageInfo<SysUser> pageInfo, List<Integer> collect) {
-        return this.baseMapper.getAllList(pageInfo,collect);
-    }
-
-    @Override
-    public List<Long> getSysUserFromPhone(String phoneNumber) {
-        return this.baseMapper.getSysUserFromPhone(phoneNumber);
-    }
-
-    @Override
-    public void deleteSysUser(ArrayList<Integer> userIds) {
-        this.baseMapper.deleteSysUser(userIds);
-    }
-
-    @Override
-    public PageInfo<SysUser> getChangeUserList(ChangeUserQuery query) {
-        PageInfo<SysUser> pageInfo = new PageInfo<>(query.getPageCurr(), query.getPageSize());
-        List<SysUser> list = this.baseMapper.getChangeUserList(pageInfo, query);
-        return pageInfo.setRecords(list);
-    }
-
+		return userMapper.deleteUserByIds(userIds);
+	}
+	
+	/**
+	 * 导入用户数据
+	 *
+	 * @param userList        用户数据列表
+	 * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据
+	 * @param operName        操作用户
+	 * @return 结果
+	 */
+	@Override
+	public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName) {
+		if (StringUtils.isNull(userList) || userList.size() == 0) {
+			throw new ServiceException("导入用户数据不能为空!");
+		}
+		int successNum = 0;
+		int failureNum = 0;
+		StringBuilder successMsg = new StringBuilder();
+		StringBuilder failureMsg = new StringBuilder();
+		String password = configService.selectConfigByKey("sys.user.initPassword");
+		for (SysUser user : userList) {
+			try {
+				// 验证是否存在这个用户
+				SysUser u = userMapper.selectUserByUserName(user.getUserName());
+				if (StringUtils.isNull(u)) {
+					BeanValidators.validateWithException(validator, user);
+					user.setPassword(SecurityUtils.encryptPassword(password));
+					user.setCreateBy(operName);
+					userMapper.insertUser(user);
+					successNum++;
+					successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 导入成功");
+				} else if (isUpdateSupport) {
+					BeanValidators.validateWithException(validator, user);
+					checkUserAllowed(u);
+					checkUserDataScope(u.getUserId());
+					user.setUserId(u.getUserId());
+					user.setUpdateBy(operName);
+					userMapper.updateUser(user);
+					successNum++;
+					successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 更新成功");
+				} else {
+					failureNum++;
+					failureMsg.append("<br/>" + failureNum + "、账号 " + user.getUserName() + " 已存在");
+				}
+			} catch (Exception e) {
+				failureNum++;
+				String msg = "<br/>" + failureNum + "、账号 " + user.getUserName() + " 导入失败:";
+				failureMsg.append(msg + e.getMessage());
+				log.error(msg, e);
+			}
+		}
+		if (failureNum > 0) {
+			failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
+			throw new ServiceException(failureMsg.toString());
+		} else {
+			successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
+		}
+		return successMsg.toString();
+	}
+	
+	@Override
+	public PageInfo<SysUser> getList(PageInfo<SysUser> pageInfo, GetSysUserList getSysUserList) {
+		List<SysUser> list = this.baseMapper.getList(pageInfo, getSysUserList);
+		for (SysUser sysUser : list) {
+			List<SysUserRole> list1 = sysUserRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, sysUser.getUserId()));
+			List<Integer> data1 = userSiteClient.getSiteIds(sysUser.getUserId()).getData();
+			if (null == data1) {
+				data1 = new ArrayList<>();
+			}
+			for (SysUserRole sysUserRole : list1) {
+				List<Integer> data = roleSiteClient.getSiteIds(sysUserRole.getRoleId()).getData();
+				if (null == data) {
+					continue;
+				}
+				data1.addAll(data);
+			}
+			Set<Integer> siteIds = new HashSet<>(data1);
+			sysUser.setSiteIds(siteIds.stream().collect(Collectors.toList()));
+			List<Site> data = siteClient.getSiteByIds(siteIds.stream().collect(Collectors.toList())).getData();
+			if (null != data) {
+				List<String> siteNames = data.stream().map(Site::getName).collect(Collectors.toList());
+				sysUser.setSiteNames(siteNames);
+			}
+			List<String> roleNames = new ArrayList<>();
+			for (SysUserRole sysUserRole : list1) {
+				SysRole sysRole = sysRoleService.selectRoleById(sysUserRole.getRoleId());
+				roleNames.add(sysRole.getRoleName());
+			}
+			Long[] roleIds = new Long[]{};
+			sysUser.setRoleIds(list1.stream().map(SysUserRole::getRoleId).collect(Collectors.toList()).toArray(roleIds));
+			sysUser.setRoleNames(roleNames);
+		}
+		return pageInfo.setRecords(list);
+	}
+	
+	@Override
+	public PageInfo<SysUser> getAllList(PageInfo<SysUser> pageInfo, List<Integer> collect) {
+		return this.baseMapper.getAllList(pageInfo, collect);
+	}
+	
+	@Override
+	public List<Long> getSysUserFromPhone(String phoneNumber) {
+		return this.baseMapper.getSysUserFromPhone(phoneNumber);
+	}
+	
+	@Override
+	public void deleteSysUser(ArrayList<Integer> userIds) {
+		this.baseMapper.deleteSysUser(userIds);
+	}
+	
+	@Override
+	public PageInfo<SysUser> getChangeUserList(ChangeUserQuery query) {
+		PageInfo<SysUser> pageInfo = new PageInfo<>(query.getPageCurr(), query.getPageSize());
+		List<SysUser> list = this.baseMapper.getChangeUserList(pageInfo, query);
+		return pageInfo.setRecords(list);
+	}
+	
 }
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml
index 30c1036..d837d2b 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml
@@ -25,8 +25,8 @@
         service: ${spring.application.name}
         group: DEFAULT_GROUP
         namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb
-      username: nacos
-      password: nacos
+        username: nacos
+        password: nacos
       config:
         # 配置中心地址
         server-addr: 192.168.110.169:8848
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppCouponController.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppCouponController.java
index aed6abb..e17f179 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppCouponController.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppCouponController.java
@@ -106,12 +106,13 @@
      * @return
      */
     @ApiOperation(value = "通过充电枪id和预付金额获取电站详情", tags = {"小程序-扫一扫"})
-    @GetMapping(value = "/scan/siteInfo")
+    @PostMapping(value = "/scan/siteInfo")
     public AjaxResult<SiteInfoVO> siteInfo(Integer id, BigDecimal money) {
         TChargingGun chargingGun = chargingGunClient.getChargingGunById(id).getData();
         TChargingPile chargingPile = chargingPileClient.getChargingPileById(chargingGun.getChargingPileId()).getData();
-        SiteInfoVO data = chargingPileClient.getSiteInfoByNumber(chargingPile.getNumber().toString()).getData();
+        SiteInfoVO data = chargingPileClient.getSiteInfoByNumber1(chargingPile.getCode().toString()).getData();
         data.setChargingGunId(id);
+        data.setChargeMode(chargingGun.getChargeMode());
         List<TAppUserCar> cars = appUserCarService.list(new QueryWrapper<TAppUserCar>()
                 .eq("app_user_id",tokenService.getLoginUserApplet().getUserId())
                 .orderByDesc("create_time"));
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserController.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserController.java
index 3b77098..4ab4162 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserController.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserController.java
@@ -198,6 +198,10 @@
     @DeleteMapping(value = "/unit/delete")
     @Log(title = "【单位管理】删除单位", businessType = BusinessType.DELETE,operatorType = OperatorType.MANAGE)
     public R add(@RequestParam String ids) {
+        List<TAppUser> list = appUserService.lambdaQuery().in(TAppUser::getCompanyId, Arrays.asList(ids.split(","))).list();
+        if (!list.isEmpty()){
+            return R.fail("当前单位已存在用户,无法删除!");
+        }
         String[] split = ids.split(",");
         for (String s : split) {
             otherClient.unitDelete(Integer.valueOf(s));
@@ -219,7 +223,7 @@
         Page<TAppUser> page = appUserService.lambdaQuery()
                 .like(userListQueryDto.getUserPhone() != null && !"".equals(userListQueryDto.getUserPhone()), TAppUser::getPhone, userListQueryDto.getUserPhone())
                 .eq(userListQueryDto.getCompanyId() != null, TAppUser::getCompanyId, userListQueryDto.getCompanyId())
-                .like(userListQueryDto.getProvinceCode() != null && !"".equals(userListQueryDto.getProvinceCode()), TAppUser::getProvinceCode, userListQueryDto.getProvinceCode())
+                .eq(userListQueryDto.getProvinceCode() != null && !"".equals(userListQueryDto.getProvinceCode()), TAppUser::getProvinceCode, userListQueryDto.getProvinceCode())
                 .eq(userListQueryDto.getCityCode() != null && !"".equals(userListQueryDto.getCityCode()), TAppUser::getCityCode, userListQueryDto.getCityCode())
                 .eq(userListQueryDto.getStatus() != null, TAppUser::getStatus, userListQueryDto.getStatus())
                 .eq(userListQueryDto.getVipTypeId() != null, TAppUser::getVipId, userListQueryDto.getVipTypeId())
@@ -278,16 +282,25 @@
         if (userListQueryDto.getUserTagId() != null){
             userIds = appUserTagService.lambdaQuery().eq(TAppUserTag::getUserTagId, userListQueryDto.getUserTagId()).list().stream().map(TAppUserTag::getAppUserId).collect(Collectors.toList());
         }
+        LocalDateTime end1 = null;
+        LocalDateTime end2 = null ;
+        if (userListQueryDto.getVipEndTime1()!=null) {
+            end1 =    LocalDateTime.now().plusDays(userListQueryDto.getVipEndTime1());
+        }
+        if (userListQueryDto.getVipEndTime2()!=null){
+            end2 = LocalDateTime.now().plusDays(userListQueryDto.getVipEndTime2());
+        }
         //列表查询
         Page<TAppUser> page = appUserService.lambdaQuery()
                 .ge(TAppUser::getVipEndTime, LocalDateTime.now())
                 .like(userListQueryDto.getUserPhone() != null && !"".equals(userListQueryDto.getUserPhone()), TAppUser::getPhone, userListQueryDto.getUserPhone())
                 .eq(userListQueryDto.getCompanyId() != null, TAppUser::getCompanyId, userListQueryDto.getCompanyId())
+                .eq(userListQueryDto.getProvinceCode() != null && !"".equals(userListQueryDto.getProvinceCode()), TAppUser::getProvinceCode, userListQueryDto.getProvinceCode())
                 .eq(userListQueryDto.getCityCode() != null && !"".equals(userListQueryDto.getCityCode()), TAppUser::getCityCode, userListQueryDto.getCityCode())
                 .eq(userListQueryDto.getStatus() != null, TAppUser::getStatus, userListQueryDto.getStatus())
                 .eq(userListQueryDto.getVipTypeId() != null, TAppUser::getVipId, userListQueryDto.getVipTypeId())
-                .ge(userListQueryDto.getVipEndTime1() != null, TAppUser::getVipEndTime, userListQueryDto.getVipEndTime1() == null ? null : LocalDateTime.now().plusDays(userListQueryDto.getVipEndTime1()))
-                .le(userListQueryDto.getVipEndTime2() != null, TAppUser::getVipEndTime, userListQueryDto.getVipEndTime2() == null ? null : LocalDateTime.now().plusDays(userListQueryDto.getVipEndTime2()))
+                .ge(userListQueryDto.getVipEndTime1() != null, TAppUser::getVipEndTime, end1 )
+                .le(userListQueryDto.getVipEndTime2() != null, TAppUser::getVipEndTime, end2)
                 .in(!userIds.isEmpty(), TAppUser::getId, userIds)
                 .page(Page.of(userListQueryDto.getPageCurr(), userListQueryDto.getPageSize()));
         if (page.getRecords().isEmpty()){
@@ -407,6 +420,11 @@
                 }
             }
 
+        }else {
+           List<TAppUser> list = appUserService.lambdaQuery().eq(TAppUser::getPhone, tAppUser.getPhone()).list();
+           if (!list.isEmpty()){
+               return R.fail("该手机号已注册");
+           }
         }
         appUserService.saveOrUpdate(tAppUser);
         return R.ok();
@@ -416,12 +434,16 @@
     @GetMapping(value = "/user/detail/{id}")
     public R<UserDetailDto> userDetail(@PathVariable Long id) {
         TAppUser user = appUserService.getById(id);
-        UserDetailDto userDetailDto =  new UserDetailDto();
-        BeanUtils.copyProperties(user,userDetailDto);
-        if (user.getVipId()!=null) {
-            R<Map<Integer, String>> vipMap = otherClient.getVipMap(Arrays.asList(user.getVipId()));
+        R<Map<Integer, String>> vipMap = otherClient.getVipMap(Collections.singletonList(user.getVipId()));
+        if (user.getVipEndTime()!=null&&user.getVipEndTime().isAfter(LocalDateTime.now())) {
+            //匹配vipMap的值
             user.setVipName(vipMap.getData().get(user.getVipId()));
         }
+
+
+        UserDetailDto userDetailDto =  new UserDetailDto();
+        BeanUtils.copyProperties(user,userDetailDto);
+
         //获取累计充电数量
         R<Long> useOrderCount = chargingOrderClient.useOrderCount(user.getId());
         userDetailDto.setOrderCount(useOrderCount.getData());
@@ -437,6 +459,9 @@
         userDetailDto.setTagName(tagMap.getData().values()
                 .stream()
                 .collect(Collectors.joining(",")));
+
+
+
         return R.ok(userDetailDto);
     }
 
@@ -552,7 +577,7 @@
         Long count = signService.lambdaQuery().eq(TAppUserSign::getAppUserId,userId).eq(TAppUserSign::getSignDay, LocalDate.now()).count();
         appUserInfoDto.setIsSign(count>0?1:0);
         //获取当前拥有的优惠卷数量
-        Long coupons = appCouponService.lambdaQuery().eq(TAppCoupon::getAppUserId, userId).eq(TAppCoupon::getStatus, 1).count();
+        Long coupons = appCouponService.lambdaQuery().eq(TAppCoupon::getAppUserId, userId).ge(TAppCoupon::getEndTime, LocalDateTime.now()).eq(TAppCoupon::getStatus, 1).count();
         appUserInfoDto.setCouponNum(Math.toIntExact(coupons));
         //当前绑定的车辆
         List<TAppUserCar> list = carService.lambdaQuery().eq(TAppUserCar::getAppUserId, userId).list();
@@ -835,7 +860,7 @@
                 signService.updateById(appUserSign);
             }
         }
-        pointDetailUtil.addDetail(byId.getPoints(),byId.getPoints()+points,1,userId,"每日签到","JF");
+        pointDetailUtil.addDetail(byId.getPoints(),byId.getPoints()+points,1,userId,"每日签到","JF","");
         byId.setPoints(byId.getPoints()+points);
         appUserService.updateById(byId);
         return R.ok();
@@ -874,19 +899,19 @@
 
 
     //积分变化记录用
-    @PostMapping(value = "/user/points/change")
-    public R change(@RequestBody PointChangeDto points) {
-        TAppUser byId = appUserService.getById(points.getUserId());
-        pointDetailUtil.addDetail(byId.getPoints(),byId.getPoints()+points.getPoints(),points.getType(),points.getUserId(),points.getRemark(),"JF");
-        byId.setPoints(byId.getPoints()+points.getPoints());
-        appUserService.updateById(byId);
-        return R.ok();
-    }
+//    @PostMapping(value = "/user/points/change")
+//    public R change(@RequestBody PointChangeDto points) {
+//        TAppUser byId = appUserService.getById(points.getUserId());
+//        pointDetailUtil.addDetail(byId.getPoints(),byId.getPoints()+points.getPoints(),points.getType(),points.getUserId(),points.getRemark(),"JF");
+//        byId.setPoints(byId.getPoints()+points.getPoints());
+//        appUserService.updateById(byId);
+//        return R.ok();
+//    }
 
     @PostMapping(value = "/user/points/change/down")
     public R changeDown(@RequestBody PointChangeDto points) {
         TAppUser byId = appUserService.getById(points.getUserId());
-        pointDetailUtil.addDetail(byId.getPoints(),byId.getPoints()-points.getPoints(),points.getType(),points.getUserId(),points.getRemark(),"JF");
+        pointDetailUtil.addDetail(byId.getPoints(),byId.getPoints()-points.getPoints(),points.getType(),points.getUserId(),points.getRemark(),"JF",points.getCode());
         byId.setPoints(byId.getPoints()-points.getPoints());
         appUserService.updateById(byId);
         return R.ok();
@@ -950,7 +975,7 @@
                 }
 
             //增加积分记录
-            pointDetailUtil.addDetail(byId.getPoints(),byId.getPoints()+point,5,userId,appUserCar.getLicensePlate(),"");
+            pointDetailUtil.addDetail(byId.getPoints(),byId.getPoints()+point,5,userId,appUserCar.getLicensePlate(),"","");
             byId.setPoints(byId.getPoints()+point);
             byId.setFirstAdd(1);
 
@@ -1033,5 +1058,17 @@
 
         return R.ok(jsonObject.getJSONObject("data"));
     }
+    
+    
+    
+    
+    @PostMapping(value = "/user/editAppUserInfo")
+    @ApiOperation(value = "修改个人信息", tags = {"小程序-个人中心"})
+    public AjaxResult editAppUserInfo(@RequestBody TAppUser appUser){
+        Long userId = tokenService.getLoginUserApplet().getUserId();
+        appUser.setId(userId);
+        appUserService.updateById(appUser);
+        return AjaxResult.success();
+    }
 }
 
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserTagController.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserTagController.java
index ec0648d..6c8218b 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserTagController.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserTagController.java
@@ -1,6 +1,7 @@
 package com.ruoyi.account.controller;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.log.annotation.Log;
 import com.ruoyi.common.log.enums.BusinessType;
@@ -71,14 +72,38 @@
     public R delete(String ids) {
         //拿到单位列表
         String[] split = ids.split(",");
+
+         List<TAppUserTag> list = appUserTagService.lambdaQuery().in(TAppUserTag::getUserTagId).list();
+         if (!list.isEmpty()){
+             return R.fail("当前标签已有用户获取,无法删除");
+         }
         for (String id : split) {
         otherClient.deleteTag(Integer.valueOf(id));
         }
         return R.ok();
     }
-
-
-
-
+    
+    
+    /**
+     * 获取用户标签关系
+     * @param appUserTag
+     * @return
+     */
+    @PostMapping(value = "/tags/getUserTag")
+    public R<TAppUserTag> getUserTag(@RequestBody TAppUserTag appUserTag){
+        TAppUserTag one = appUserTagService.getOne(new LambdaQueryWrapper<TAppUserTag>().eq(TAppUserTag::getAppUserId, appUserTag.getAppUserId())
+                .eq(TAppUserTag::getUserTagId, appUserTag.getUserTagId()));
+        return R.ok(one);
+    }
+    
+    
+    /**
+     * 保存用户标签关系数据
+     * @param appUserTag
+     */
+    @PostMapping(value = "/tags/addUserTag")
+    public void addUserTag(@RequestBody TAppUserTag appUserTag){
+        appUserTagService.save(appUserTag);
+    }
 }
 
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserVipDetailController.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserVipDetailController.java
index 47aab16..2bedb36 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserVipDetailController.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserVipDetailController.java
@@ -48,7 +48,7 @@
 	@ApiOperation(value = "生效会员列表", tags = {"小程序-个人中心"})
 	public R<List<TAppUserVipDetail>> getVipUseDetail(){
         Long userId = tokenService.getLoginUserApplet().getUserId();
-        List<TAppUserVipDetail> list = appUserVipDetailService.lambdaQuery().eq(TAppUserVipDetail::getAppUserId, userId).last(" and now() between start_time and end_time order by start_time desc").list();
+        List<TAppUserVipDetail> list = appUserVipDetailService.lambdaQuery().eq(TAppUserVipDetail::getAppUserId, userId).last(" and now() between start_time and end_time order by start_time asc").list();
 
 		for (TAppUserVipDetail tAppUserVipDetail : list) {
             if(null != tAppUserVipDetail.getVipId()){
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/PointDetailUtil.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/PointDetailUtil.java
index 4b935ac..54fd849 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/PointDetailUtil.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/util/PointDetailUtil.java
@@ -12,7 +12,7 @@
 public class PointDetailUtil {
     @Resource
     private TAppUserIntegralChangeService appUserIntegralChangeService;
-    public void addDetail(Integer old,Integer now,Integer type,Long userId,String extension,String code){
+    public void addDetail(Integer old,Integer now,Integer type,Long userId,String extension,String code,String orderCode){
 
         TAppUserIntegralChange tAppUserIntegralChange= new TAppUserIntegralChange();
         tAppUserIntegralChange.setCode(OrderCodeUtil.getOrderCode(code));
@@ -22,6 +22,7 @@
         tAppUserIntegralChange.setCurrentIntegral(now);
         tAppUserIntegralChange.setCreateTime(LocalDateTime.now());
         tAppUserIntegralChange.setExtension(extension);
+        tAppUserIntegralChange.setOrderCode(orderCode);
         appUserIntegralChangeService.save(tAppUserIntegralChange);
 
 
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/SiteController.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/SiteController.java
index 0efa30d..1add52d 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/SiteController.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/SiteController.java
@@ -111,6 +111,35 @@
 	@ApiOperation(value = "扫一扫后通过桩编号获取电站信息", tags = {"小程序-扫一扫"})
 	public R<SiteInfoVO> getSiteInfoByNumber(@RequestParam("number") String number){
 		SiteInfoVO siteInfoVO = new SiteInfoVO();
+		String chargingPileCode = number.substring(0, number.length() - 2);
+		String chargingGunCode = number.substring(number.length() - 2);
+		TChargingPile one = chargingPileService.lambdaQuery().eq(TChargingPile::getCode, chargingPileCode).one();
+		TChargingGun chargingGun = chargingGunService.getOne(new LambdaQueryWrapper<TChargingGun>().eq(TChargingGun::getCode, chargingGunCode).eq(TChargingGun::getChargingPileId, one.getId()));
+		Site byId = siteService.getById(one.getSiteId());
+		TAccountingStrategy byId1 = accountingStrategyService.getById(byId.getAccountingStrategyId());
+		List<TAccountingStrategyDetail> list = accountingStrategyDetailService.lambdaQuery().eq(TAccountingStrategyDetail::getAccountingStrategyId, byId1.getId()).list();
+		for (TAccountingStrategyDetail tAccountingStrategyDetail : list) {
+			// 当前时间属于那个阶段 取哪个阶段的电价
+			if(LocalTime.now().isAfter(LocalTime.parse(tAccountingStrategyDetail.getStartTime())) && LocalTime.now().isBefore(LocalTime.parse(tAccountingStrategyDetail.getEndTime()))){
+				siteInfoVO.setElectrovalence(tAccountingStrategyDetail.getElectrovalence());
+				siteInfoVO.setVipElectrovalence(tAccountingStrategyDetail.getElectrovalence().multiply(byId1.getDiscount()).setScale(4, BigDecimal.ROUND_HALF_UP));
+			}
+		}
+		siteInfoVO.setChargingGunId(chargingGun.getId());
+		siteInfoVO.setChargingPileId(one.getId());
+		siteInfoVO.setName(byId.getName());
+		siteInfoVO.setNumber(one.getNumber().toString());
+		siteInfoVO.setSpaceChargeExplain(byId.getSpaceChargeExplain());
+		return R.ok(siteInfoVO);
+	}
+	/**
+	 * 通过桩编号获取电站信息 遠程調用
+	 * @param number
+	 * @return
+	 */
+	@PostMapping("/getSiteInfoByNumber1")
+	public R<SiteInfoVO> getSiteInfoByNumber1(@RequestParam("number") String number){
+		SiteInfoVO siteInfoVO = new SiteInfoVO();
 		TChargingPile one = chargingPileService.lambdaQuery().eq(TChargingPile::getCode, number).one();
 		Site byId = siteService.getById(one.getSiteId());
 		TAccountingStrategy byId1 = accountingStrategyService.getById(byId.getAccountingStrategyId());
@@ -128,7 +157,6 @@
 		siteInfoVO.setSpaceChargeExplain(byId.getSpaceChargeExplain());
 		return R.ok(siteInfoVO);
 	}
-
 	
 	@GetMapping("/getSiteList")
 	@ApiOperation(value = "获取站点列表", tags = {"管理后台-站点管理"})
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java
index fc961ec..1316ac6 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java
@@ -4,6 +4,7 @@
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.ruoyi.chargingPile.api.dto.TAccountingStrategyDTO;
 import com.ruoyi.chargingPile.api.model.*;
+import com.ruoyi.chargingPile.api.query.BatchSetAccountingStrategy;
 import com.ruoyi.chargingPile.api.query.TAccountingStrategyQuery;
 import com.ruoyi.chargingPile.api.vo.TAccountingStrategyDetailVO;
 import com.ruoyi.chargingPile.api.vo.TAccountingStrategyVO;
@@ -18,7 +19,10 @@
 import com.ruoyi.common.log.annotation.Log;
 import com.ruoyi.common.log.enums.BusinessType;
 import com.ruoyi.common.log.enums.OperatorType;
+import com.ruoyi.common.security.service.TokenService;
 import com.ruoyi.common.security.utils.SecurityUtils;
+import com.ruoyi.integration.api.feignClient.IntegrationClient;
+import com.ruoyi.system.api.domain.SysUser;
 import com.ruoyi.system.api.feignClient.SysUserClient;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.BeanUtils;
@@ -56,8 +60,9 @@
     private TChargingPileService chargingPileService;
     @Autowired
     private ISiteService siteService;
-    @Resource
+    @Autowired
     private SysUserClient sysUserClient;
+
 
     @Autowired
     public TAccountingStrategyController(TAccountingStrategyService accountingStrategyService, TAccountingStrategyDetailService accountingStrategyDetailService) {
@@ -293,6 +298,8 @@
 
         return AjaxResult.ok(accountingStrategyService.pageList(query));
     }
+    @Resource
+    private IntegrationClient integrationClient;
 
     @ApiOperation(tags = {"后台-申请表单-计费模板审核"},value = "审核")
     @PostMapping(value = "/auth/pass")
@@ -329,6 +336,10 @@
                 }
 
                 //硬件
+                 List<TChargingPile> list = chargingPileService.lambdaQuery().eq(TChargingPile::getSiteId, byId.getSiteId()).list();
+                for (TChargingPile tChargingPile : list) {
+                    integrationClient.setupBillingModel1(tChargingPile.getCode());
+                }
 
 
             }
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingGunController.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingGunController.java
index ecb1330..b8db1ec 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingGunController.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingGunController.java
@@ -14,6 +14,7 @@
 import com.ruoyi.chargingPile.api.vo.GunStatusStatisticsVO;
 import com.ruoyi.chargingPile.api.vo.SiteNameVO;
 import com.ruoyi.chargingPile.api.vo.TChargingGunVO;
+import com.ruoyi.chargingPile.config.FileUploadConfig;
 import com.ruoyi.chargingPile.service.ISiteService;
 import com.ruoyi.chargingPile.service.TChargingGunService;
 import com.ruoyi.chargingPile.service.TChargingPileService;
@@ -63,13 +64,16 @@
 
     @Autowired
     private TChargingGunService chargingGunService;
-    @Autowired
+    @Resource
     private ChargingOrderClient chargingOrderClient;
 
     @Resource
     private TChargingPileService chargingPileService;
     @Resource
     private ISiteService siteService;
+    
+    @Autowired
+    private FileUploadConfig fileUploadConfig;
 
     /**
      * 查询充电枪列表
@@ -152,11 +156,13 @@
     public void downloadQRCode(@PathVariable Integer id, HttpServletResponse response){
         try {
             TChargingGun chargingGun = chargingGunService.getById(id);
-            String fileName = URLEncoder.encode(chargingGun.getCode(), "UTF-8") + ".jpg";
+            TChargingPile chargingPile = chargingPileService.getById(chargingGun.getId());
+            String code = chargingPile.getCode() + chargingGun.getCode();
+            String fileName = URLEncoder.encode(code, "UTF-8") + ".jpg";
             response.setContentType("application/force-download");
             response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
-            String url = "https://www.baidu.com?id=" + id;
-            String filePath = "D:/Program Files/nginx-1.20.2/html";
+            String url = "https://mxcd.zhinenganguan.com?No=" + code;
+            String filePath = fileUploadConfig.getLocation();
             QRCodeUtils.encode(url, filePath);
             FileInputStream inputStream = new FileInputStream(filePath);
             ServletOutputStream out = response.getOutputStream();
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/PartnerServiceImpl.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/PartnerServiceImpl.java
index ae3830e..2ad2b83 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/PartnerServiceImpl.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/PartnerServiceImpl.java
@@ -28,6 +28,7 @@
 import io.seata.core.context.RootContext;
 import io.seata.core.exception.TransactionException;
 import io.seata.spring.annotation.GlobalTransactional;
+import io.seata.tm.api.GlobalTransaction;
 import io.seata.tm.api.GlobalTransactionContext;
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
@@ -114,7 +115,6 @@
 	@Override
 	@GlobalTransactional(rollbackFor = Exception.class)//分布式事务
 	public AjaxResult addPartner(Partner partner) {
-		System.err.println("事务ID:" + RootContext.getXID());
 		//校验参数和重复数据
 		AjaxResult ajaxResult = addPartnerParameterCheck(partner);
 		if(ajaxResult.isError()){
@@ -134,8 +134,6 @@
 		if(null != one){
 			return AjaxResult.error("登录账号不能重复");
 		}
-		//添加新数据
-		this.save(partner);
 		//添加登录账户
 		SysUser user = new SysUser();
 		user.setPhonenumber(partner.getPhoneOne());
@@ -149,15 +147,11 @@
 		user.setRoleType(2);
 		user.setObjectId(partner.getId());
 		R r = sysUserClient.addSysUser(user);
-		if(r.getCode() != 200){
-			// 手动进行全局事务回滚
-			try {
-				GlobalTransactionContext.getCurrent().rollback();
-			} catch (TransactionException e) {
-				throw new RuntimeException(e);
-			}
-			return AjaxResult.error(r.getMsg());
+		if(200 != r.getCode()){
+			throw new RuntimeException(r.getMsg());
 		}
+		//添加新数据
+		this.save(partner);
 		return AjaxResult.success();
 	}
 	
@@ -245,9 +239,6 @@
 		}
 		Partner oldPartner = this.getById(partner.getId());
 		SysUser user = sysUserClient.queryUserByUserName(oldPartner.getAccount()).getData();
-		
-		//修改数据
-		this.updateById(partner);
 		//修改登录账户
 		if(null == user){
 			user = new SysUser();
@@ -277,6 +268,9 @@
 				throw new RuntimeException(r.getMsg());
 			}
 		}
+		
+		//修改数据
+		this.updateById(partner);
 		return AjaxResult.success();
 	}
 	
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java
index 1c0a150..80b0d10 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java
@@ -257,9 +257,10 @@
 	public AjaxResult delSite(Integer[] ids) {
 		//查询是否有关联数据
 		//充电桩
-		long count1 = chargingPileService.count(new LambdaQueryWrapper<TChargingPile>().eq(TChargingPile::getSiteId, Arrays.asList(ids)).eq(TChargingPile::getDelFlag, 0));
+		long count1 = chargingPileService.count(new LambdaQueryWrapper<TChargingPile>().in(TChargingPile::getSiteId, Arrays.asList(ids))
+				.eq(TChargingPile::getDelFlag, 0));
 		if(count1 > 0){
-			return AjaxResult.error("该站点有关联充电桩,删除失败!");
+			return AjaxResult.error("该站点已添加充电桩,不可删除。");
 		}
 		for (Integer id : ids) {
 			Site site = this.getById(id);
diff --git a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java
index 9536258..d5b88bc 100644
--- a/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java
+++ b/ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java
@@ -228,9 +228,10 @@
 	public AjaxResult delChargingPile(Integer[] ids) {
 		//检查是否有关联数据
 		//接口
-		long count = chargingGunService.count(new LambdaQueryWrapper<TChargingGun>().eq(TChargingGun::getChargingPileId, Arrays.asList(ids)).eq(TChargingGun::getDelFlag, 0));
+		long count = chargingGunService.count(new LambdaQueryWrapper<TChargingGun>().in(TChargingGun::getChargingPileId, Arrays.asList(ids))
+				.eq(TChargingGun::getDelFlag, 0));
 		if(count > 0){
-			return AjaxResult.error("该充电桩有关联的接口数据,删除失败!");
+			return AjaxResult.error("该充电桩已添加接口,不可删除。");
 		}
 		for (Integer id : ids) {
 			TChargingPile chargingPile = this.getById(id);
diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java
index e43d689..c3961f0 100644
--- a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java
@@ -351,6 +351,8 @@
         return R.ok(message);
     }
 
+
+
     @ApiOperation(value = "远程重启",tags = {"硬件接口"})
     @PostMapping(value = "/platformRestart")
     public R platformRestart(String deviceId) {
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/AccountingStrategyDetailOrderController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/AccountingStrategyDetailOrderController.java
index ce14d4a..db9167d 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/AccountingStrategyDetailOrderController.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/AccountingStrategyDetailOrderController.java
@@ -11,6 +11,7 @@
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import java.util.List;
 
 /**
  * @author zhibing.pu
@@ -36,4 +37,18 @@
 				.last(" and DATE_FORMAT(now(), '%H:%i') between start_time and end_time"));
 		return R.ok(one);
 	}
+	
+	
+	/**
+	 * 获取订单对应的计费策略数据
+	 * @param orderId
+	 * @return
+	 */
+	@PostMapping("/getAllAccountingStrategyDetailOrder")
+	public R<List<AccountingStrategyDetailOrder>> getAllAccountingStrategyDetailOrder(@RequestParam("orderId") Long orderId){
+		List<AccountingStrategyDetailOrder> one = accountingStrategyDetailOrderService.list(new LambdaQueryWrapper<AccountingStrategyDetailOrder>()
+				.eq(AccountingStrategyDetailOrder::getChargingOrderId, orderId)
+				.orderByAsc(AccountingStrategyDetailOrder::getStartTime));
+		return R.ok(one);
+	}
 }
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/AccountingStrategyOrderController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/AccountingStrategyOrderController.java
new file mode 100644
index 0000000..7630c81
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/AccountingStrategyOrderController.java
@@ -0,0 +1,35 @@
+package com.ruoyi.order.controller;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.order.api.model.AccountingStrategyOrder;
+import com.ruoyi.order.service.AccountingStrategyOrderService;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/9/25 18:33
+ */
+@RequestMapping("/accountingStrategyOrder")
+@RestController
+public class AccountingStrategyOrderController {
+	
+	@Resource
+	private AccountingStrategyOrderService accountingStrategyOrderService;
+	
+	
+	/**
+	 * 根据id获取数据
+	 * @param id
+	 * @return
+	 */
+	@PostMapping("/getAccountingStrategyOrderById")
+	public R<AccountingStrategyOrder> getAccountingStrategyOrderById(@RequestParam("id") Integer id){
+		AccountingStrategyOrder accountingStrategyOrder = accountingStrategyOrderService.getById(id);
+		return R.ok(accountingStrategyOrder);
+	}
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
index 16e7970..d37b582 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
@@ -584,7 +584,7 @@
     }
 
     @ResponseBody
-    @GetMapping(value = "/work/shop")
+    @PostMapping(value = "/work/shop")
     @ApiOperation(value = "购物收入", tags = {"后台-工作台"})
     public R workShop(@RequestBody ChargingStatisticsQueryDto statisticsQueryDto) {
         //count近6个月的数据
@@ -971,19 +971,50 @@
             siteIds.add(statisticsQueryDto.getSiteId());
         }
         if (statisticsQueryDto.getDayType()==1) {
-          List<Map<String,Object>> charMap = chargingOrderService.getHourType(siteIds,statisticsQueryDto);
+          List<Map<String,Object>> charMap1 = chargingOrderService.getHourType(siteIds,statisticsQueryDto);
+            List<Map<String, Object>> charMap = new ArrayList<>();
+            // 生成从 "00:00" 到 "23:00" 的时间数据
+            for (int hour = 0; hour < 24; hour++) {
+                String time = String.format("%02d:00", hour);
+                 Map<String, Object> mapWithTimeValue = findMapWithTimeValue(charMap1, time);
+                if (mapWithTimeValue!=null){
+                    charMap.add(mapWithTimeValue);
+                }else {
+                    Map<String, Object> timeMap = new HashMap<>();
+                    timeMap.put("time", time); // 初始化值为 null
+                    timeMap.put("electrovalence", 0);
+                    timeMap.put("orderCount", 0);
+                    timeMap.put("servicecharge", 0);
+                    timeMap.put("electricity", 0);
+                    charMap.add(timeMap);
+                }
+            }
           return R.ok(charMap);
         }else if (statisticsQueryDto.getDayType()==2){
             List<Map<String,Object>> charMap =  chargingOrderService.getDateType(siteIds,statisticsQueryDto);
             return R.ok(charMap);
         }else if (statisticsQueryDto.getDayType()==3){
             List<Map<String,Object>> charMap =  chargingOrderService.getMonthType(siteIds,statisticsQueryDto);
-        }
+            return R.ok(charMap);
 
+        }
         return R.ok();
 
 
     }
+
+    private static Map<String, Object> findMapWithTimeValue(List<Map<String, Object>> charMap1,String timeValue) {
+        for (Map<String, Object> map : charMap1) {
+            if (map.containsKey("time") && map.get("time").equals(timeValue)) {
+                return map;
+            }
+        }
+        return null; // 如果没有找到,返回 null
+    }
+
+
+
+
 
     @ResponseBody
     @PostMapping(value = "/work/use")
@@ -1019,9 +1050,9 @@
     @Resource
     private TOrderInvoiceService invoiceService;
     @ResponseBody
-    @PostMapping(value = "/work/shopOrder")
+    @GetMapping(value = "/work/shopOrder")
     @ApiOperation(value = "购物订单统计", tags = {"管理后台-工作台"})
-    public R shopOrder(@RequestBody ChargingStatisticsQueryDto statisticsQueryDto) {
+    public R shopOrder() {
         Long count = shoppingOrderService.lambdaQuery().eq(TShoppingOrder::getStatus, 1).count();
         Long count1 = shoppingOrderService.lambdaQuery().eq(TShoppingOrder::getStatus, 2).count();
         List<Long> counts = new ArrayList<>();
@@ -1031,9 +1062,9 @@
     }
 
     @ResponseBody
-    @PostMapping(value = "/work/invoice")
+    @GetMapping(value = "/work/invoice")
     @ApiOperation(value = "开票统计", tags = {"管理后台-工作台"})
-    public R invoice(@RequestBody ChargingStatisticsQueryDto statisticsQueryDto) {
+    public R invoice() {
         Long count = invoiceService.lambdaQuery().eq(TOrderInvoice::getStatus, 1).count();
         Long count1 = invoiceService.lambdaQuery().eq(TOrderInvoice::getStatus, 3).count();
         List<Long> counts = new ArrayList<>();
@@ -1043,9 +1074,9 @@
     }
 
     @ResponseBody
-    @PostMapping(value = "/work/users/count")
+    @GetMapping(value = "/work/users/count")
     @ApiOperation(value = "用户数量", tags = {"管理后台-工作台"})
-    public R usersCount(@RequestBody ChargingStatisticsQueryDto statisticsQueryDto) {
+    public R usersCount() {
        List<Map<String,Object>>  userMap  =    chargingOrderService.countAllUserData();
             return R.ok(userMap);
 
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TExchangeOrderController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TExchangeOrderController.java
index c07353a..26c049f 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TExchangeOrderController.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TExchangeOrderController.java
@@ -9,6 +9,7 @@
 import com.ruoyi.chargingPile.api.feignClient.ChargingPileClient;
 import com.ruoyi.chargingPile.api.model.TChargingPile;
 import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.dto.ExchangeBackDto;
 import com.ruoyi.common.core.web.domain.AjaxResult;
 import com.ruoyi.common.core.web.page.PageInfo;
 import com.ruoyi.common.security.service.TokenService;
@@ -265,7 +266,7 @@
     }
 
     @PostMapping("/create")
-    public R<Long> exchangeCreate(@RequestBody ExchangeDto exchangeDto){
+    public R<ExchangeBackDto> exchangeCreate(@RequestBody ExchangeDto exchangeDto){
         TExchangeOrder tExchangeOrder = new TExchangeOrder();
         tExchangeOrder.setCode(OrderCodeUtil.getOrderCode("DH"));
         tExchangeOrder.setAppUserId(exchangeDto.getUserId());
@@ -287,7 +288,10 @@
         tExchangeOrder.setCreateTime(LocalDateTime.now());
         tExchangeOrder.setDelFlag(false);
         exchangeOrderService.save(tExchangeOrder);
-        return R.ok(tExchangeOrder.getId());
+        ExchangeBackDto exchangeBackDto = new ExchangeBackDto();
+        exchangeBackDto.setId(tExchangeOrder.getId());
+        exchangeBackDto.setCode(tExchangeOrder.getCode());
+        return R.ok(exchangeBackDto);
 
     }
     
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TShoppingOrderController.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TShoppingOrderController.java
index 83ea8cf..1d39329 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TShoppingOrderController.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TShoppingOrderController.java
@@ -1,4 +1,5 @@
 package com.ruoyi.order.controller;
+
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 
@@ -19,6 +20,8 @@
 import com.ruoyi.order.api.query.ShoppingOrderQuery;
 import com.ruoyi.order.dto.*;
 import com.ruoyi.order.service.TShoppingOrderService;
+import com.ruoyi.other.api.domain.TCoupon;
+import com.ruoyi.other.api.domain.TGoods;
 import com.ruoyi.other.api.feignClient.CouponClient;
 import com.ruoyi.other.api.feignClient.GoodsClient;
 import com.ruoyi.payment.api.feignClient.AliPaymentClient;
@@ -41,7 +44,7 @@
 
 /**
  * <p>
- *  前端控制器
+ * 前端控制器
  * </p>
  *
  * @author xiaochen
@@ -60,14 +63,24 @@
 	private GoodsClient goodsClient;
 	@Resource
 	private CouponClient couponClient;
-
-
+	@Resource
+	private TokenService tokenService;
+	@Resource
+	private AliPaymentClient aliPaymentClient;
+	@Resource
+	private WxPaymentClient wxPaymentClient;
+	@Resource
+	private AppCouponClient appCouponClient;
+	@Resource
+	private SysUserClient sysUserClient;
+	
+	
 	@PostMapping("/getShoppingOrderList")
 	@ApiOperation(value = "列表查询", tags = {"管理后台-购物订单"})
 	public AjaxResult<PageInfo<TShoppingOrder>> getShoppingOrderList(@RequestBody ShoppingOrderQuery query) {
 		if (StringUtils.hasLength(query.getPhone())) {
 			List<Long> data = appUserClient.getUserIdsByPhone(query.getPhone()).getData();
-			if (data.isEmpty()){
+			if (data.isEmpty()) {
 				return AjaxResult.success(new PageInfo<TShoppingOrder>());
 			}
 			query.setUserIds(data);
@@ -77,54 +90,58 @@
 			query.setGoodsIds(data);
 			List<Integer> data1 = couponClient.getCouponIdsByName(query.getName()).getData();
 			query.setCouponIds(data1);
-			if (data.isEmpty() && data1.isEmpty()){
+			if (data.isEmpty() && data1.isEmpty()) {
 				return AjaxResult.success(new PageInfo<TShoppingOrder>());
 			}
 		}
 		PageInfo<TShoppingOrder> res = shoppingOrderService.pageList(query);
 		return AjaxResult.success(res);
 	}
-	@Resource
-	private SysUserClient sysUserClient;
+	
 	@GetMapping("/getShoppingOrderInfoById")
 	@ApiOperation(value = "根据订单id查看订单详情", tags = {"管理后台-购物订单"})
 	public AjaxResult<TShoppingOrder> getShoppingOrderList(String id) {
 		TShoppingOrder byId = shoppingOrderService.getById(id);
-		if (byId.getConsignerId()!=null){
+		if (byId.getConsignerId() != null) {
 			SysUser data = sysUserClient.getSysUser(byId.getConsignerId()).getData();
-			if (data!=null){
+			if (data != null) {
 				byId.setConsignerName(data.getUserName());
 			}
 		}
-		if (byId.getCancellationId()!=null){
+		if (byId.getCancellationId() != null) {
 			SysUser data = sysUserClient.getSysUser(byId.getCancellationId()).getData();
-			if (data!=null){
+			if (data != null) {
 				byId.setCancellationName(data.getUserName());
 			}
 		}
-		if (byId.getAppUserAddressId()!=null){
+		if (byId.getAppUserAddressId() != null) {
 			TAppUserAddress data = appUserClient.getAddressById(byId.getAppUserAddressId()).getData();
-			if (data!=null){
-				byId.setReceivingName(data.getName()+"-"+data.getPhone());
+			if (data != null) {
+				byId.setReceivingName(data.getName() + "-" + data.getPhone());
 				byId.setReceivingAddress(data.getAddress());
 			}
 		}
+		if (byId.getOrderType()==1){
+			TGoods data = goodsClient.getGoodsById(byId.getGoodsId()).getData();
+			if (data!=null){
+				byId.setName(data.getName());
+			}
+		}else {
+		 TCoupon data = couponClient.getCouponById1(byId.getCouponId()).getData();
+		 if (data!=null){
+			 byId.setName(data.getName());
+		 }
+		}
 		return AjaxResult.success(byId);
 	}
+	
 	@GetMapping("/deleteShoppingOrder")
 	@ApiOperation(value = "批量删除订单", tags = {"管理后台-购物订单"})
 	public AjaxResult<TShoppingOrder> deleteShoppingOrder(String ids) {
 		shoppingOrderService.removeBatchByIds(Arrays.asList(ids.split(",")));
 		return AjaxResult.success();
 	}
-	@Resource
-	private TokenService tokenService;
-	@Resource
-	private AliPaymentClient aliPaymentClient;
-	@Resource
-	private WxPaymentClient wxPaymentClient;
-	@Resource
-	private AppCouponClient appCouponClient;
+	
 	@GetMapping("/cancelShoppingOrder")
 	@ApiOperation(value = "取消订单", tags = {"管理后台-购物订单"})
 	public AjaxResult cancelShoppingOrder(String id) {
@@ -134,7 +151,7 @@
 		byId.setCancellationId(userid);
 		byId.setCancellationTime(LocalDateTime.now());
 		byId.setStatus(4);
-		switch (byId.getPaymentType()){
+		switch (byId.getPaymentType()) {
 			case 1:
 				// 微信
 				WxPaymentRefundModel wxPaymentRefundModel = new WxPaymentRefundModel();
@@ -144,8 +161,8 @@
 				// todo 部署到线上之后写回调地址
 //				wxPaymentRefundModel.setNotify_url("");
 				String string = byId.getPaymentAmount().multiply(new BigDecimal("100")).toString();
-				if (string.contains(".")){
-					string = string.substring(0,string.indexOf("."));
+				if (string.contains(".")) {
+					string = string.substring(0, string.indexOf("."));
 				}
 				int i = Integer.parseInt(string);
 				WxPaymentRefundModel.RefundAmount refundAmount = new WxPaymentRefundModel.RefundAmount();
@@ -163,10 +180,10 @@
 				refundReq.setRefundAmount(byId.getPaymentAmount().toString());
 				refundReq.setRefundReason("后台退款");
 				RefundResp data = aliPaymentClient.refund(refundReq).getData();
-				if (data!=null){
+				if (data != null) {
 					// 退款成功 回退优惠券
 //					byId.setStatus(4);
-					if (byId.getAppCouponId()!=null){
+					if (byId.getAppCouponId() != null) {
 						appCouponClient.refund(byId.getAppCouponId().toString());
 						byId.setRefundCode(gw);
 						byId.setRefundAmount(byId.getPaymentAmount());
@@ -179,9 +196,10 @@
 		shoppingOrderService.updateById(byId);
 		return AjaxResult.success();
 	}
+	
 	@GetMapping("/consignerShoppingOrder")
 	@ApiOperation(value = "发货", tags = {"管理后台-购物订单"})
-	public AjaxResult consignerShoppingOrder(String id,String companyName,String code) {
+	public AjaxResult consignerShoppingOrder(String id, String companyName, String code) {
 		TShoppingOrder byId = shoppingOrderService.getById(id);
 		byId.setExpressCompany(companyName);
 		byId.setExpressNumber(code);
@@ -192,16 +210,17 @@
 		shoppingOrderService.updateById(byId);
 		return AjaxResult.success();
 	}
+	
 	@GetMapping("/getMyShoppingOrderList")
 	@ApiOperation(value = "获取购买订单列表", tags = {"小程序-商城购买订单"})
-	public AjaxResult<Map<String, Object>> getMyShoppingOrderList(GetMyShoppingOrderList query){
+	public AjaxResult<Map<String, Object>> getMyShoppingOrderList(GetMyShoppingOrderList query) {
 		Map<String, Object> list = shoppingOrderService.getMyShoppingOrderList(query);
 		return AjaxResult.success(list);
 	}
-
+	
 	@GetMapping("/getMyShoppingOrderListNum")
 	@ApiOperation(value = "获取购买订单列表数量", tags = {"小程序-商城购买订单"})
-	public AjaxResult<Map<String, Object>> getMyShoppingOrderListNum(){
+	public AjaxResult<Map<String, Object>> getMyShoppingOrderListNum() {
 		Long userId = tokenService.getLoginUserApplet().getUserId();
 		long dfh = shoppingOrderService.count(new LambdaQueryWrapper<TShoppingOrder>().eq(TShoppingOrder::getDelFlag, 0)
 				.eq(TShoppingOrder::getStatus, 1).eq(TShoppingOrder::getAppUserId, userId));
@@ -215,29 +234,27 @@
 		map.put("ywc", ywc);
 		return AjaxResult.success(map);
 	}
-
 	
 	
 	@GetMapping("/getMyShoppingOrderInfo/{id}")
-	@ApiOperation(value = "获取购买订单详情", tags = {"小程序-商城购买订单","管理后台-支付订单-订单信息"})
-	public AjaxResult<MyShoppingOrderInfo> getMyShoppingOrderInfo(@PathVariable String id){
+	@ApiOperation(value = "获取购买订单详情", tags = {"小程序-商城购买订单", "管理后台-支付订单-订单信息"})
+	public AjaxResult<MyShoppingOrderInfo> getMyShoppingOrderInfo(@PathVariable String id) {
 		MyShoppingOrderInfo info = shoppingOrderService.getMyShoppingOrderInfo(id);
 		return AjaxResult.success(info);
 	}
 	
 	
-	
 	@PutMapping("/confirmReceipt/{id}")
 	@ApiOperation(value = "确认收货操作", tags = {"小程序-商城购买订单"})
-	public AjaxResult confirmReceipt(@PathVariable String id){
+	public AjaxResult confirmReceipt(@PathVariable String id) {
 		TShoppingOrder shoppingOrder = shoppingOrderService.getById(id);
-		if(shoppingOrder.getStatus() == 3){
+		if (shoppingOrder.getStatus() == 3) {
 			return AjaxResult.error("不能重复确认收货");
 		}
-		if(shoppingOrder.getStatus() == 1){
+		if (shoppingOrder.getStatus() == 1) {
 			return AjaxResult.error("订单还未发货呢");
 		}
-		if(shoppingOrder.getStatus() == 4){
+		if (shoppingOrder.getStatus() == 4) {
 			return AjaxResult.error("订单已取消,不允许操作。");
 		}
 		shoppingOrder.setStatus(3);
@@ -248,7 +265,7 @@
 	
 	@PutMapping("/cancelOrder/{id}")
 	@ApiOperation(value = "取消订单操作", tags = {"小程序-商城购买订单"})
-	public AjaxResult cancelOrder(@PathVariable String id){
+	public AjaxResult cancelOrder(@PathVariable String id) {
 		return shoppingOrderService.cancelOrder(id);
 	}
 	
@@ -256,9 +273,9 @@
 	 * 商城订单取消微信退款回调
 	 */
 	@PostMapping("/cancelShoppingOrderWxRefund")
-	public void cancelShoppingOrderWxRefund(HttpServletRequest request){
+	public void cancelShoppingOrderWxRefund(HttpServletRequest request) {
 		WxRefundNotifyResp data = wxPaymentClient.refundNotify(request).getData();
-		if(null != data){
+		if (null != data) {
 			String out_refund_no = data.getOut_refund_no();
 			String refund_id = data.getRefund_id();
 			String tradeState = data.getTradeState();
@@ -268,31 +285,30 @@
 	}
 	
 	
-	
 	@ResponseBody
 	@GetMapping(value = "/getNoInvoicedOrder")
 	@ApiOperation(value = "获取未开票的订单数据", tags = {"小程序-充电发票"})
-	public AjaxResult<List<MyShoppingOrderList>> getNoInvoicedOrder(GetNoInvoicedOrder query){
+	public AjaxResult<List<MyShoppingOrderList>> getNoInvoicedOrder(GetNoInvoicedOrder query) {
 		List<MyShoppingOrderList> list = shoppingOrderService.getNoInvoicedOrder(query);
 		return AjaxResult.success(list);
 	}
-
+	
 	@PostMapping("/create")
-	public R<TShoppingOrder> shopCreate(@RequestBody ExchangeDto exchangeDto){
+	public R<TShoppingOrder> shopCreate(@RequestBody ExchangeDto exchangeDto) {
 		TShoppingOrder shoppingOrder = new TShoppingOrder();
 		shoppingOrder.setTitle(exchangeDto.getTitle());
 		shoppingOrder.setCode(OrderCodeUtil.getOrderCode("GW"));
 		shoppingOrder.setAppUserId(exchangeDto.getUserId());
 		shoppingOrder.setOrderType(exchangeDto.getGoodType());
-		if (exchangeDto.getGoodType()==1) {
+		if (exchangeDto.getGoodType() == 1) {
 			shoppingOrder.setGoodsId(exchangeDto.getGoodId());
-		}else {
+		} else {
 			shoppingOrder.setCouponId(exchangeDto.getGoodId());
 		}
 		shoppingOrder.setPurchaseQuantity(exchangeDto.getNum());
 		shoppingOrder.setAppUserAddressId(exchangeDto.getAddressId());
 		shoppingOrder.setOrderAmount(exchangeDto.getOrderPrice());
-		if (exchangeDto.getCouponId()!=null) {
+		if (exchangeDto.getCouponId() != null) {
 			shoppingOrder.setAppCouponId(exchangeDto.getCouponId());
 		}
 		shoppingOrder.setCouponDiscountAmount(exchangeDto.getDiscountPrice());
@@ -307,16 +323,16 @@
 		shoppingOrder.setCreateTime(LocalDateTime.now());
 		shoppingOrder.setDelFlag(false);
 		shoppingOrderService.save(shoppingOrder);
-
+		
 		return R.ok(shoppingOrder);
-
+		
 	}
-
+	
 	@PostMapping("/callBack")
-	public R callBack(@RequestParam("code")String code,@RequestParam("outTradeNo")String outTradeNo){
-		shoppingOrderService.callBack(code,outTradeNo);
+	public R callBack(@RequestParam("code") String code, @RequestParam("outTradeNo") String outTradeNo) {
+		shoppingOrderService.callBack(code, outTradeNo);
 		return R.ok();
-
+		
 	}
 }
 
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TExchangeOrderService.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TExchangeOrderService.java
index ce4ae13..56c3688 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TExchangeOrderService.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TExchangeOrderService.java
@@ -1,12 +1,14 @@
 package com.ruoyi.order.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.common.core.web.domain.AjaxResult;
 import com.ruoyi.common.core.web.page.PageInfo;
 import com.ruoyi.order.api.model.TExchangeOrder;
 import com.ruoyi.order.api.query.ShoppingOrderQuery;
 import com.ruoyi.order.dto.ExchangeOrderGoodsInfo;
 import com.ruoyi.order.dto.GetMyExchangeOrder;
 import com.ruoyi.order.dto.MyExchangeOrderList;
+import org.springframework.web.bind.annotation.PathVariable;
 
 import java.util.List;
 import java.util.Map;
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
index 7fabc18..486a730 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -33,6 +33,7 @@
 import com.ruoyi.integration.api.vo.GetPlatformStopChargingReply;
 import com.ruoyi.order.api.dto.SettlementConfirmAdd;
 import com.ruoyi.order.api.feignClient.AccountingStrategyDetailOrderClient;
+import com.ruoyi.order.api.feignClient.AccountingStrategyOrderClient;
 import com.ruoyi.order.api.feignClient.ChargingOrderAccountingStrategyClient;
 import com.ruoyi.order.api.model.*;
 import com.ruoyi.order.api.query.ChargingOrderQuery;
@@ -47,11 +48,8 @@
 import com.ruoyi.order.service.TChargingOrderService;
 import com.ruoyi.order.service.TOrderEvaluateService;
 import com.ruoyi.order.service.*;
-import com.ruoyi.other.api.domain.TCoupon;
-import com.ruoyi.other.api.domain.TGoods;
+import com.ruoyi.other.api.domain.*;
 import com.ruoyi.order.vo.ChargingOrderListInfoVO;
-import com.ruoyi.other.api.domain.TIntegralRule;
-import com.ruoyi.other.api.domain.TVip;
 import com.ruoyi.other.api.feignClient.*;
 import com.ruoyi.payment.api.feignClient.AliPaymentClient;
 import com.ruoyi.payment.api.feignClient.WxPaymentClient;
@@ -153,6 +151,9 @@
 
 	@Resource
 	private AccountingStrategyDetailOrderClient accountingStrategyDetailOrderClient;
+	
+	@Resource
+	private AccountingStrategyOrderClient accountingStrategyOrderClient;
 
 	@Resource
 	private AccountingStrategyClient accountingStrategyClient;
@@ -183,6 +184,12 @@
 	
 	@Resource
 	private VipClient vipClient;
+	
+	@Resource
+	private UserTagClient userTagClient;
+	
+	@Resource
+	private AppUserTagClient appUserTagClient;
 
 	//计数器
 	private Map<String, Integer> counter_map = new HashMap<>();
@@ -433,7 +440,28 @@
 		chargingOrder.setRechargePaymentStatus(1);
 		chargingOrder.setRechargeAmount(addChargingOrder.getPaymentAmount());
 		chargingOrder.setAppCouponId(addChargingOrder.getAppUserCouponId());
-		if(null != appUser.getVipId()){
+		chargingOrder.setVipDiscount(new BigDecimal(10));
+		chargingOrder.setVipDiscountAmount(BigDecimal.ZERO);
+		
+		Site site = siteClient.getSiteByIds(Arrays.asList(tChargingGun.getSiteId())).getData().get(0);
+		Integer accountingStrategyId = tChargingGun.getAccountingStrategyId();
+		if(null == accountingStrategyId){
+			//查询站点上面的计费策略
+			accountingStrategyId = site.getAccountingStrategyId();
+		}
+		TAccountingStrategy accountingStrategy = accountingStrategyClient.getAccountingStrategyById(accountingStrategyId).getData();
+		
+		//直营站点才可以享受会员折扣
+		if(null != appUser.getVipId() && 1 == site.getBusinessCategory()){
+			TVip vip = vipClient.getInfo(appUser.getVipId()).getData();
+			BigDecimal discount = null;
+			if(1 == vip.getType()){
+				//普通会员折扣使用积分策略上的折扣,且有最高优惠金额
+				discount = accountingStrategy.getDiscount();
+			}else{
+				//内部会员使用会员信息设置的折扣,没有最高优惠金额
+				discount = vip.getDiscount();
+			}
 			GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
 			getAppUserVipDetail.setAppUserId(appUser.getId());
 			getAppUserVipDetail.setVipId(appUser.getVipId());
@@ -441,24 +469,13 @@
 			if(null != vipDetail){
 				Integer chargeNum = vipDetail.getChargeNum();
 				if(0 > chargeNum){
-					chargingOrder.setVipDiscount(vipDetail.getDiscount());
-					BigDecimal discountAmount = addChargingOrder.getPaymentAmount().multiply((new BigDecimal(10)
-							.subtract(vipDetail.getDiscount())).divide(new BigDecimal(10))).setScale(4, BigDecimal.ROUND_HALF_EVEN);
-					chargingOrder.setVipDiscountAmount(discountAmount);
+					chargingOrder.setVipDiscount(discount);
 				}
 			}
-
 		}
 		this.save(chargingOrder);
 
 		//添加订单的计费策略
-		Integer accountingStrategyId = tChargingGun.getAccountingStrategyId();
-		if(null == accountingStrategyId){
-			//查询站点上面的计费策略
-			Site site = siteClient.getSiteByIds(Arrays.asList(tChargingGun.getSiteId())).getData().get(0);
-			accountingStrategyId = site.getAccountingStrategyId();
-		}
-		TAccountingStrategy accountingStrategy = accountingStrategyClient.getAccountingStrategyById(accountingStrategyId).getData();
 		List<TAccountingStrategyDetail> strategyDetailList = accountingStrategyDetailClient.getListByAccountingStrategyId(accountingStrategyId).getData();
 		AccountingStrategyOrder accountingStrategyOrder = new AccountingStrategyOrder();
 		BeanUtils.copyProperties(accountingStrategy, accountingStrategyOrder);
@@ -532,42 +549,84 @@
 		
 		//根据当前充值的金额和计费模板算出充电的金额
 		BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
-		//计算充电金额,会员需要将折扣金额加入到充电总金额中
-		TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
-		AccountingStrategyDetailOrder strategyDetail = accountingStrategyDetailOrderClient.getNowAccountingStrategyDetailOrder(chargingOrder.getId()).getData();
-		//总单价
-		BigDecimal totalUnitPrice = strategyDetail.getServiceCharge().add(strategyDetail.getElectrovalence());
-		//计算能充电的度数
-		BigDecimal degrees = rechargeAmount.divide(totalUnitPrice);
+		BigDecimal rechargeAmount1 = new BigDecimal(rechargeAmount.toString());
+		Long now = System.currentTimeMillis();
+		//根据支付金额,获取出使用的计费策略明细
 		//计算电费金额和服务费
-		BigDecimal serviceCharge = strategyDetail.getServiceCharge().multiply(degrees);
-		BigDecimal electrovalence = strategyDetail.getElectrovalence().multiply(degrees);
-
-		//再处理会员折扣
-		BigDecimal discount = BigDecimal.ZERO;
+		BigDecimal serviceCharge = BigDecimal.ZERO;
+		BigDecimal electrovalence = BigDecimal.ZERO;
+		BigDecimal discountAmount = BigDecimal.ZERO;
+		BigDecimal discount = chargingOrder.getVipDiscount();
+		//先根据额定功率计算出每秒充电度数,然后计算出支付金额能充多少度电
+		TChargingGun tChargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
+		BigDecimal s_degrees = tChargingGun.getRatedPower().divide(new BigDecimal(3600));
+		
+		
 		TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
-		if(null != appUser.getVipId()){
-			GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
-			getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
-			getAppUserVipDetail.setVipId(appUser.getVipId());
-			TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
-			if(data.getChargeNum() > 0){
-				discount = serviceCharge.multiply(data.getDiscount().divide(new BigDecimal(10)));
-				data.setChargeNum(data.getChargeNum() - 1);
-				appUserVipDetailClient.updateAppUserVipDetail(data);
+		List<AccountingStrategyDetailOrder> list = accountingStrategyDetailOrderClient.getAllAccountingStrategyDetailOrder(chargingOrder.getId()).getData();
+		for (AccountingStrategyDetailOrder accountingStrategyDetailOrder : list) {
+			AccountingStrategyOrder accountingStrategyOrder = accountingStrategyOrderClient.getAccountingStrategyOrderById(accountingStrategyDetailOrder.getAccountingStrategyOrderId()).getData();
+			Integer start = Integer.valueOf(accountingStrategyDetailOrder.getStartTime().replaceAll(":", ""));
+			String[] split = accountingStrategyDetailOrder.getEndTime().split(":");
+			if(now >= start){
+				Calendar calendar = Calendar.getInstance();
+				calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
+				calendar.set(Calendar.MINUTE, Integer.valueOf(split[1]));
+				//到此策略结束的秒数
+				long m = (calendar.getTimeInMillis() - now) / 1000;
+				//每度电的单价
+				BigDecimal total_unit = accountingStrategyDetailOrder.getElectrovalence().add(accountingStrategyDetailOrder.getServiceCharge());
+				//每秒需要支付的金额
+				BigDecimal multiply = s_degrees.multiply(total_unit);
+				//计算充值金额能充多长时间的电
+				long times = rechargeAmount1.divide(multiply, 0, RoundingMode.DOWN).longValue();
+				if(times > m){
+					//充电时间跨度两个计费策略,需要继续对下一个策略进行计算
+					electrovalence = accountingStrategyDetailOrder.getElectrovalence().multiply(s_degrees).multiply(new BigDecimal(m));
+					serviceCharge = accountingStrategyDetailOrder.getServiceCharge().multiply(s_degrees).multiply(new BigDecimal(m));
+					discountAmount = discountAmount.add(serviceCharge.multiply((new BigDecimal(10).subtract(discount)).divide(new BigDecimal(10))));
+					rechargeAmount1 = rechargeAmount1.subtract(multiply.multiply(new BigDecimal(m)));
+				}else{
+					electrovalence = accountingStrategyDetailOrder.getElectrovalence().multiply(s_degrees).multiply(new BigDecimal(times));
+					serviceCharge = accountingStrategyDetailOrder.getServiceCharge().multiply(s_degrees).multiply(new BigDecimal(times));
+					discountAmount = discountAmount.add(serviceCharge.multiply((new BigDecimal(10).subtract(discount)).divide(new BigDecimal(10))));
+					break;
+				}
 			}
 		}
-		electrovalence = electrovalence.add(discount);
+		if(discountAmount.compareTo(BigDecimal.ZERO) >= 0){
+			//计算会员最大优惠金额
+			if(null != appUser.getVipId()){
+				TVip vip = vipClient.getInfo(appUser.getVipId()).getData();
+				BigDecimal maximumDeduction = vip.getMaximumDeduction();
+				//普通会员有最高优惠限制
+				if(vip.getType() == 1 && discountAmount.compareTo(maximumDeduction) > 0){
+					discountAmount = maximumDeduction;
+				}
+				
+				//判断会员是否还有充电优惠次数
+				GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
+				getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
+				getAppUserVipDetail.setVipId(appUser.getVipId());
+				TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
+				if(data.getChargeNum() > 0){
+					data.setChargeNum(data.getChargeNum() - 1);
+					appUserVipDetailClient.updateAppUserVipDetail(data);
+					//会员有充电优惠次数,直接将优惠金额加入到充电费用中增加充电时长
+					electrovalence = electrovalence.add(discountAmount);
+				}
+			}
+		}
 		chargingOrder.setChargeAmount(electrovalence);
+		chargingOrder.setVipDiscountAmount(discountAmount);
 		this.updateById(chargingOrder);
-
-
-		TChargingPile chargingPile = chargingPileClient.getChargingPileById(chargingGun.getChargingPileId()).getData();
+		
+		TChargingPile chargingPile = chargingPileClient.getChargingPileById(tChargingGun.getChargingPileId()).getData();
 		//调用远程启动充电消息
 		PlatformStartCharging platformStartCharging = new PlatformStartCharging();
 		platformStartCharging.setTransaction_serial_number(chargingOrder.getCode());
 		platformStartCharging.setCharging_pile_code(chargingPile.getCode());
-		platformStartCharging.setCharging_gun_code(chargingGun.getCode());
+		platformStartCharging.setCharging_gun_code(tChargingGun.getCode());
 		//使用订单id作为逻辑卡号
 		platformStartCharging.setCard_number(chargingOrder.getId().toString());
 		platformStartCharging.setAccount_balance(electrovalence);
@@ -586,7 +645,7 @@
 				PreChargeCheck preChargeCheck1 = redisService.getCacheObject(key);
 				//状态为5的时候,硬件会间隔60秒后再次检测,依然未插枪,则不启动充电
 				//因这里是间隔5秒执行检测,所以累计次数在30次以上
-				if(failure_cause == 5 && null == counter || counter < 35){
+				if(failure_cause == 5 && (null == counter || counter < 35)){
 					counter++;
 					counter_map.put(code, counter);
 					//启动失败
@@ -767,7 +826,65 @@
 		chargingOrder.setStatus(4);
 		chargingOrder.setEndMode(1);
 		this.updateById(chargingOrder);
-
+		
+		//处理用户标签数据
+		List<TUserTag> data = userTagClient.getAllUserTag().getData();
+		//累计充电次数
+		long count1 = this.count(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, chargingOrder.getAppUserId())
+				.eq(TChargingOrder::getRechargePaymentStatus, 2).isNotNull(TChargingOrder::getPaymentAmount).eq(TChargingOrder::getDelFlag, 0));
+		List<TUserTag> userTagList1 = data.stream().filter(s -> s.getStandardCondition() == 1).collect(Collectors.toList());
+		int old_times = 0;
+		Integer userTagId = null;
+		for (TUserTag tUserTag : userTagList1) {
+			Integer times = JSON.parseObject(tUserTag.getConditions()).getInteger("times");
+			//加上本次充电
+			//获取最大值标签
+			if((count1 + 1) >= times && old_times < times){
+				userTagId = tUserTag.getId();
+				old_times = times;
+			}
+		}
+		if(null != userTagId){
+			TAppUserTag appUserTag = new TAppUserTag();
+			appUserTag.setAppUserId(chargingOrder.getAppUserId());
+			appUserTag.setUserTagId(userTagId);
+			TAppUserTag data1 = appUserTagClient.getUserTag(appUserTag).getData();
+			if(null == data1){
+				data1 = new TAppUserTag();
+				data1.setAppUserId(chargingOrder.getAppUserId());
+				data1.setUserTagId(userTagId);
+				data1.setCreateTime(LocalDateTime.now());
+				appUserTagClient.addUserTag(data1);
+			}
+		}
+		//充电评率
+		List<TUserTag> userTagList2 = data.stream().filter(s -> s.getStandardCondition() == 2).collect(Collectors.toList());
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		for (TUserTag tUserTag : userTagList2) {
+			TAppUserTag appUserTag = new TAppUserTag();
+			appUserTag.setAppUserId(chargingOrder.getAppUserId());
+			appUserTag.setUserTagId(tUserTag.getId());
+			TAppUserTag data1 = appUserTagClient.getUserTag(appUserTag).getData();
+			if(null == data1){
+				Integer day = JSON.parseObject(tUserTag.getConditions()).getInteger("day");
+				Integer times = JSON.parseObject(tUserTag.getConditions()).getInteger("times");
+				Calendar start = Calendar.getInstance();
+				start.set(Calendar.DAY_OF_YEAR, start.get(Calendar.DAY_OF_YEAR) + day);
+				count1 = this.count(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, chargingOrder.getAppUserId())
+						.eq(TChargingOrder::getRechargePaymentStatus, 2).isNotNull(TChargingOrder::getPaymentAmount)
+						.between(TChargingOrder::getStartTime, sdf.format(start.getTime()), sdf.format(new Date())).eq(TChargingOrder::getDelFlag, 0));
+				//加上本次充电
+				if(count1 >= times){
+					data1 = new TAppUserTag();
+					data1.setAppUserId(chargingOrder.getAppUserId());
+					data1.setUserTagId(tUserTag.getId());
+					data1.setCreateTime(LocalDateTime.now());
+					appUserTagClient.addUserTag(data1);
+				}
+			}
+		}
+		
+		
 		//异步线程处理停机
 		ExecutorService cachedThreadPool = Executors.newFixedThreadPool(1);
 		cachedThreadPool.execute(()->{
@@ -998,7 +1115,7 @@
 				model.setOut_trade_no(chargingOrder.getCode());
 				model.setOut_refund_no(chargingOrderRefund.getRefundCode());
 				model.setReason("充电完成退款");
-				model.setNotify_url("http://221.182.45.100:9000/order/t-charging-order/chargingOrderStartupFailureWxRefund");
+				model.setNotify_url("/order/t-charging-order/chargingOrderStartupFailureWxRefund");
 				WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
 				amount.setRefund(refundAmount.multiply(new BigDecimal(100)).intValue());
 				amount.setTotal(rechargeAmount.multiply(new BigDecimal(100)).intValue());
@@ -1783,7 +1900,7 @@
 					model.setOut_refund_no(chargingOrderRefund.getRefundCode());
 					model.setTransaction_id(tChargingOrder.getRechargeSerialNumber());
 					model.setReason("取消订单");
-					model.setNotify_url("http://221.182.45.100:9000/order/t-shopping-order/cancelShoppingOrderWxRefund");
+					model.setNotify_url("/order/t-shopping-order/cancelShoppingOrderWxRefund");
 					WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
 					amount.setRefund(payOrderQueryDto.getRefundAmount().multiply(new BigDecimal(100)).intValue());
 					amount.setTotal(tChargingOrder.getPaymentAmount().multiply(new BigDecimal(100)).intValue());
@@ -1838,7 +1955,7 @@
 					model.setOut_refund_no(chargingOrderRefund.getRefundCode());
 					model.setTransaction_id(tChargingOrder.getSerialNumber());
 					model.setReason("取消订单");
-					model.setNotify_url("http://221.182.45.100:9000/order/t-shopping-order/cancelShoppingOrderWxRefund");
+					model.setNotify_url("/order/t-shopping-order/cancelShoppingOrderWxRefund");
 					WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
 					amount.setRefund(payOrderQueryDto.getRefundAmount().multiply(new BigDecimal(100)).intValue());
 					amount.setTotal(tChargingOrder.getPaymentAmount().multiply(new BigDecimal(100)).intValue());
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TExchangeOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TExchangeOrderServiceImpl.java
index 9a29276..7b112a6 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TExchangeOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TExchangeOrderServiceImpl.java
@@ -4,8 +4,11 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.account.api.feignClient.AppUserAddressClient;
 import com.ruoyi.account.api.feignClient.AppUserClient;
+import com.ruoyi.account.api.feignClient.AppUserIntegralChangeClient;
 import com.ruoyi.account.api.model.TAppUser;
 import com.ruoyi.account.api.model.TAppUserAddress;
+import com.ruoyi.account.api.model.TAppUserIntegralChange;
+import com.ruoyi.common.core.web.domain.AjaxResult;
 import com.ruoyi.common.core.web.page.PageInfo;
 import com.ruoyi.common.security.service.TokenService;
 import com.ruoyi.order.api.model.TExchangeOrder;
@@ -56,6 +59,9 @@
 
 	@Resource
 	private AppUserClient appUserClient;
+	
+	@Resource
+	private AppUserIntegralChangeClient appUserIntegralChangeClient;
 	
 	
 	
@@ -205,4 +211,5 @@
 		pageInfo.setRecords(list);
 		return pageInfo;
     }
+	
 }
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TShoppingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TShoppingOrderServiceImpl.java
index 6141449..30d8358 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TShoppingOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TShoppingOrderServiceImpl.java
@@ -25,6 +25,7 @@
 import com.ruoyi.order.mapper.TShoppingOrderMapper;
 import com.ruoyi.order.service.TShoppingOrderRefundService;
 import com.ruoyi.order.service.TShoppingOrderService;
+import com.ruoyi.order.util.RedisLock;
 import com.ruoyi.other.api.domain.TCoupon;
 import com.ruoyi.other.api.domain.TGoods;
 import com.ruoyi.other.api.feignClient.CouponClient;
@@ -37,6 +38,8 @@
 import com.ruoyi.payment.api.vo.AliQueryOrder;
 import com.ruoyi.payment.api.vo.NotifyV3PayDecodeRespBody;
 import io.seata.spring.annotation.GlobalTransactional;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
@@ -85,6 +88,9 @@
     
     @Resource
     private TShoppingOrderRefundService shoppingOrderRefundService;
+    
+    @Autowired
+    public RedisTemplate redisTemplate;
     
     
     
@@ -309,7 +315,7 @@
     
         //退款金额
         BigDecimal refundAmount = shoppingOrder.getPaymentAmount().subtract(bigDecimal);
-    
+        
         //先查询第三方订单状态订单是否退款
         //支付方式(1=微信,2=支付宝)
         Integer paymentType = shoppingOrder.getPaymentType();
@@ -364,7 +370,7 @@
             model.setTransaction_id(shoppingOrder.getSerialNumber());
             model.setOut_refund_no(shoppingOrderRefund.getRefundCode());
             model.setReason("取消订单");
-            model.setNotify_url("http://221.182.45.100:9000/order/t-shopping-order/cancelShoppingOrderWxRefund");
+            model.setNotify_url("/order/t-shopping-order/cancelShoppingOrderWxRefund");
             WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
             amount.setRefund(refundAmount.multiply(new BigDecimal(100)).intValue());
             amount.setTotal(shoppingOrder.getPaymentAmount().multiply(new BigDecimal(100)).intValue());
@@ -387,6 +393,44 @@
                 AjaxResult success = cancelShoppingOrderWxRefund(resp.getOutTradeNo(), resp.getTradeNo(), "SUCCESS", sdf1.format(new Date()));
                 if(success.isSuccess()){
                     shoppingOrderRefundService.save(shoppingOrderRefund);
+                    //商品
+                    if(shoppingOrder.getOrderType() == 1){
+                        //redis锁 和支付使用同一个锁
+                        RedisLock redisLock = new RedisLock(redisTemplate, "SHOPPING_GOODS_LOCK", 5, 30000);
+                        try {
+                            redisLock.lock();
+                            TGoods goods = goodsClient.getGoodsById(shoppingOrder.getGoodsId()).getData();
+                            Integer inventory = goods.getInventory();
+                            if(-1 != inventory){
+                                goods.setInventory(inventory + shoppingOrder.getPurchaseQuantity());
+                                goodsClient.updateGoods(goods);
+                            }
+                        }catch (Exception e){
+                            e.printStackTrace();
+                        }finally {
+                            //解锁
+                            redisLock.unlock();
+                        }
+                    }
+                    //优惠券
+                    if(shoppingOrder.getOrderType() == 2){
+                        //redis锁 和支付使用同一个锁
+                        RedisLock redisLock = new RedisLock(redisTemplate, "SHOPPING_COUPON_LOCK", 5, 30000);
+                        try {
+                            redisLock.lock();
+                            TCoupon coupon = couponClient.getCouponById1(shoppingOrder.getCouponId()).getData();
+                            Integer inventory = coupon.getInventoryQuantity();
+                            if(-1 != inventory){
+                                coupon.setInventoryQuantity(inventory + shoppingOrder.getPurchaseQuantity());
+                                couponClient.updateCoupon(coupon);
+                            }
+                        }catch (Exception e){
+                            e.printStackTrace();
+                        }finally {
+                            //解锁
+                            redisLock.unlock();
+                        }
+                    }
                 }
             }
         }
@@ -415,26 +459,41 @@
             TShoppingOrder shoppingOrder = this.getById(one.getShoppingOrderId());
             //商品
             if(shoppingOrder.getOrderType() == 1){
-                // todo 需完善redis锁
                 //redis锁 和支付使用同一个锁
-                TGoods goods = goodsClient.getGoodsById(shoppingOrder.getGoodsId()).getData();
-                Integer inventory = goods.getInventory();
-                if(-1 != inventory){
-                    goods.setInventory(inventory + shoppingOrder.getPurchaseQuantity());
-                    goodsClient.updateGoods(goods);
+                RedisLock redisLock = new RedisLock(redisTemplate, "SHOPPING_GOODS_LOCK", 5, 30000);
+                try {
+                    redisLock.lock();
+                    TGoods goods = goodsClient.getGoodsById(shoppingOrder.getGoodsId()).getData();
+                    Integer inventory = goods.getInventory();
+                    if(-1 != inventory){
+                        goods.setInventory(inventory + shoppingOrder.getPurchaseQuantity());
+                        goodsClient.updateGoods(goods);
+                    }
+                }catch (Exception e){
+                    e.printStackTrace();
+                }finally {
+                    //解锁
+                    redisLock.unlock();
                 }
-                //解锁
             }
             //优惠券
             if(shoppingOrder.getOrderType() == 2){
-                //redis锁
-                TCoupon coupon = couponClient.getCouponById1(shoppingOrder.getCouponId()).getData();
-                Integer inventory = coupon.getInventoryQuantity();
-                if(-1 != inventory){
-                    coupon.setInventoryQuantity(inventory + shoppingOrder.getPurchaseQuantity());
-                    couponClient.updateCoupon(coupon);
+                //redis锁 和支付使用同一个锁
+                RedisLock redisLock = new RedisLock(redisTemplate, "SHOPPING_COUPON_LOCK", 5, 30000);
+                try {
+                    redisLock.lock();
+                    TCoupon coupon = couponClient.getCouponById1(shoppingOrder.getCouponId()).getData();
+                    Integer inventory = coupon.getInventoryQuantity();
+                    if(-1 != inventory){
+                        coupon.setInventoryQuantity(inventory + shoppingOrder.getPurchaseQuantity());
+                        couponClient.updateCoupon(coupon);
+                    }
+                }catch (Exception e){
+                    e.printStackTrace();
+                }finally {
+                    //解锁
+                    redisLock.unlock();
                 }
-                //解锁
             }
         }
         return AjaxResult.success();
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/RedisLock.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/RedisLock.java
new file mode 100644
index 0000000..b9954c8
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/RedisLock.java
@@ -0,0 +1,51 @@
+package com.ruoyi.order.util;
+
+import org.springframework.data.redis.core.RedisTemplate;
+
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author zhibing.pu
+ * @Date 2024/9/26 18:43
+ */
+public class RedisLock {
+	private RedisTemplate<String, String> redisTemplate;
+	private String lockKey;
+	private int expireTime; // 锁的超时时间
+	private int timeout; // 获取锁的超时时间
+	
+	
+	public RedisLock(RedisTemplate<String, String> redisTemplate, String lockKey, int expireTime, int timeout) {
+		this.redisTemplate = redisTemplate;
+		this.lockKey = lockKey;
+		this.expireTime = expireTime;
+		this.timeout = timeout;
+	}
+	
+	public boolean lock() {
+		String identifier = UUID.randomUUID().toString();
+		long end = System.currentTimeMillis() + timeout;
+		while (System.currentTimeMillis() < end) {
+			if (redisTemplate.opsForValue().setIfAbsent(lockKey, identifier, expireTime, TimeUnit.SECONDS)) {
+				return true;
+			}
+			// 可以使用延时来减少CPU占用
+			try {
+				Thread.sleep(100);
+			} catch (InterruptedException e) {
+				Thread.currentThread().interrupt();
+			}
+		}
+		return false;
+	}
+	
+	public boolean unlock() {
+		String identifier = redisTemplate.opsForValue().get(lockKey);
+		if (identifier != null && identifier.equals(UUID.randomUUID().toString())) {
+			redisTemplate.delete(lockKey);
+			return true;
+		}
+		return false;
+	}
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml b/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml
index d5d5760..ed7f52c 100644
--- a/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml
+++ b/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml
@@ -109,12 +109,11 @@
         </if>
     </select>
     <select id="payOrderQuery" resultType="com.ruoyi.order.dto.PayOrderDto">
-        SELECT * FROM (SELECT
+        SELECT o.*,i.phone FROM (SELECT
         id,
         `code`,
         1 as type,
         title,
-        phone,
         `status`,
         order_amount,
         payment_amount ,
@@ -123,7 +122,8 @@
         pay_time,
         refund_status,
         (payment_amount-refund_amount) as final_amount,
-        del_flag
+        del_flag,
+        app_user_id
         FROM
         charging_pile_order.t_charging_order
         where  recharge_payment_status = 2
@@ -133,7 +133,6 @@
         `code`,
         2 as type,
         title,
-        phone,
         `status`,
         order_amount,
         payment_amount ,
@@ -142,7 +141,8 @@
         pay_time,
         refund_status,
         (payment_amount-refund_amount) as final_amount,
-        del_flag
+        del_flag,
+        app_user_id
         FROM
         charging_pile_order.t_shopping_order
         where payment_status = 2
@@ -152,7 +152,6 @@
         `code`,
         3 as type,
         title,
-        phone,
         payment_status AS `status`,
         order_amount,
         payment_amount ,
@@ -161,7 +160,8 @@
         pay_time,
         refund_status,
         (payment_amount-refund_amount) as final_amount,
-        del_flag
+        del_flag,
+        app_user_id
 
         FROM
         charging_pile_order.t_vip_order
@@ -172,7 +172,6 @@
         `code`,
         4 as type,
         title,
-        phone,
         `status`,
         order_amount ,
         order_amount as payment_amount,
@@ -181,9 +180,11 @@
         out_parking_time as pay_time,
         null as refund_status,
         0 as final_amount,
-        0 as del_flag
+        0 as del_flag,
+        app_user_id
         FROM
         charging_pile_service.t_parking_record ) o
+        LEFT JOIN  `charging_pile_account`.`t_app_user` i on o.app_user_id = i.id
                 <where>
                     o.del_flag = 0
                     <if test="data.code != null and data.code != ''">
@@ -207,6 +208,13 @@
                             #{id}
                         </foreach>
                     </if>
+                    <if test="data.isRefund == 1">
+                        AND o.refund_status is not null
+                    </if>
+                    <if test="data.isRefund == 1">
+                        AND o.refund_status is null
+                    </if>
+
                 </where>
         ORDER BY o.create_time desc
 
@@ -226,7 +234,9 @@
         re.refund_remark,
         co.recharge_serial_number as serail_number,
         co.payment_amount,
-        co.pay_time
+        co.create_time as pay_time,
+        co.id as order_id,
+        co.app_user_id as user_id
         FROM t_charging_order_refund re
         LEFT JOIN t_charging_order  co ON re.charging_order_id = co.id
         UNION ALL
@@ -243,7 +253,9 @@
         re.refund_remark,
         so.serial_number,
         so.payment_amount,
-        so.pay_time
+        so.create_time as pay_time,
+        so.id as order_id,
+        so.app_user_id as user_id
         FROM t_shopping_order_refund re
         LEFT JOIN t_shopping_order so on re.shopping_order_id = so.id
         UNION ALL
@@ -260,7 +272,9 @@
         vr.refund_remark,
         vo.serial_number,
         vo.payment_amount,
-        vo.pay_time
+        vo.create_time as pay_time,
+        vo.id as order_id,
+        vo.app_user_id as user_id
         FROM t_vip_order_refund vr
         LEFT JOIN t_vip_order vo on vr.vip_order_id = vo.id
 
@@ -274,7 +288,7 @@
                 AND o.refund_code LIKE CONCAT('%',#{data.refundCode},'%')
             </if>
         </where>
-
+        order by o.refund_time desc
 
     </select>
     <select id="chargingOrderGroup" resultType="com.ruoyi.common.core.dto.ChargingOrderGroup">
@@ -1285,9 +1299,10 @@
         <if test="statisticsQueryDto.type == 2">
             end_time
         </if>
-        , '%Y-%m-%d %H' ) as time,
+        , '%H:00' ) as time,
 	SUM(service_charge) as servicecharge,
 	SUM(electrovalence) as electrovalence,
+    SUM(electricity) as electricity,
     count(1) as orderCount
         FROM
             t_charging_order
@@ -1323,10 +1338,10 @@
         , '%Y-%m-%d' ) as time,
         SUM(service_charge) as servicecharge,
         SUM(electrovalence) as electrovalence,
-        count(1) as orderCount
+        count(1) as orderCount,
+        SUM(electricity) as electricity
         FROM
         t_charging_order
-
         WHERE     del_flag = 0 and recharge_payment_status = 2  and DATE(
         <if test="statisticsQueryDto.type == 1">
             start_time
@@ -1358,7 +1373,8 @@
         , '%Y-%m' ) as time,
         SUM(service_charge) as servicecharge,
         SUM(electrovalence) as electrovalence,
-        count(1) as orderCount
+        count(1) as orderCount,
+        SUM(electricity) as electricity
         FROM
         t_charging_order
 
diff --git a/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TShoppingOrderMapper.xml b/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TShoppingOrderMapper.xml
index 1ef90a5..9ca89fb 100644
--- a/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TShoppingOrderMapper.xml
+++ b/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TShoppingOrderMapper.xml
@@ -306,17 +306,16 @@
         payment_amount
         FROM
         t_shopping_order
-        <where>
-            WHERE del_flag = 0 and payment_status = 2 and ISNULL(refund_status) and status!=4
+            WHERE del_flag = 0 and payment_status = 2 and ISNULL(refund_status) and status!=4 and
 
                 DATE_FORMAT(create_time, '%Y-%m-%d') between #{statisticsQueryDto.startTime} and #{statisticsQueryDto.endTime}
 
 
-        </where>
+
 
         ) AS subquery
         GROUP BY
-        DATE_FORMAT( subquery.create_time, '%Y-%m-%d' );
+        DATE_FORMAT( subquery.create_time, '%Y-%m-%d' )
 
 
     </select>
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TCompanyController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TCompanyController.java
index d355f5c..36138e4 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TCompanyController.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TCompanyController.java
@@ -31,7 +31,7 @@
 	public R<Page<TCompany>> unitPage(@RequestBody UnitListQueryDto unitListQueryDto) {
 		Page<TCompany> page = companyService.lambdaQuery()
 				.orderByDesc(TCompany::getCreateTime)
-				.like(unitListQueryDto.getCompanyName() != null && unitListQueryDto.getCompanyName().isEmpty(), TCompany::getName, unitListQueryDto.getCompanyName())
+				.like(unitListQueryDto.getCompanyName() != null && unitListQueryDto.getCompanyName()!="", TCompany::getName, unitListQueryDto.getCompanyName())
 				.page(Page.of(unitListQueryDto.getPageCurr(), unitListQueryDto.getPageSize()));
 		return R.ok(page);
 	}
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGoodsController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGoodsController.java
index 97901b7..1eb1e82 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGoodsController.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TGoodsController.java
@@ -12,6 +12,7 @@
 import com.ruoyi.account.api.model.TAppUser;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.core.dto.AppGoodQuery;
+import com.ruoyi.common.core.dto.ExchangeBackDto;
 import com.ruoyi.common.core.dto.PointChangeDto;
 import com.ruoyi.common.core.web.domain.AjaxResult;
 import com.ruoyi.common.core.web.page.BasePage;
@@ -184,8 +185,7 @@
         return R.ok();
 
     }
-    @ApiOperation(tags = {"小程序-" +
-            "兑换商城"},value = "积分兑换商品")
+    @ApiOperation(tags = {"小程序-兑换商城"},value = "积分兑换商品")
     @PostMapping(value = "/app/shop")
     public AjaxResult<PageInfo<TGoods>> shop(@RequestBody ExchangeDto exchangeDto) {
         //检查当前用户积分是否够
@@ -201,6 +201,9 @@
             Long count = orderClient.getExchangeById(exchangeDto.getGoodId(), userId,exchangeDto.getGoodType()).getData();
             if (good.getLimitExchangeTimes() != -1 && count >= good.getLimitExchangeTimes()) {
                 return AjaxResult.error("当前用户已兑换"+count+"张");
+            }else {
+                //减少库存
+                good.setInventory(good.getInventory()-exchangeDto.getNum());
             }
         if (user.getPoints()<good.getRedeemPoints()){
             return AjaxResult.error("当前用户积分不足");
@@ -210,17 +213,21 @@
             point = coupon.getRedeemPoints();
 
             Long count = orderClient.getExchangeById(exchangeDto.getGoodId(), userId,exchangeDto.getGoodType()).getData();
-            if (coupon.getInventoryQuantity() != -1 && count >= coupon.getInventoryQuantity()) {
-                return AjaxResult.error("当前用户已到达兑换"+coupon+"次");
-            }
             if (user.getPoints()<point){
                 return AjaxResult.error("当前用户积分不足");
             }
+            if (coupon.getInventoryQuantity() != -1 && count >= coupon.getInventoryQuantity()) {
+                return AjaxResult.error("当前用户已到达兑换"+coupon+"次");
+            }else {
+                coupon.setInventoryQuantity(coupon.getInventoryQuantity()-exchangeDto.getNum());
+            }
+
+
         }
         exchangeDto.setPoint(point);
         exchangeDto.setUserId(userId);
         //生成积分兑换成功的订单
-        R<Long> longR = orderClient.exchangeCreate(exchangeDto);
+        R<ExchangeBackDto> longR = orderClient.exchangeCreate(exchangeDto);
         if (exchangeDto.getGoodType()==2) {
             TCoupon coupon = couponService.getById(exchangeDto.getGoodId());
 
@@ -247,6 +254,7 @@
         pointChangeDto.setPoints(point);
         pointChangeDto.setRemark(longR.getData().toString());
         pointChangeDto.setType(6);
+        pointChangeDto.setCode(longR.getData().getCode());
         appUserClient.changeDown(pointChangeDto);
         return AjaxResult.success();
 
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TUserTagController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TUserTagController.java
index 2a669b4..a4f5fa9 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TUserTagController.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TUserTagController.java
@@ -1,6 +1,7 @@
 package com.ruoyi.other.controller;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.account.api.dto.TagListQueryDto;
 import com.ruoyi.account.api.dto.UnitListQueryDto;
@@ -36,7 +37,7 @@
     public R<Page<TUserTag>> page(@RequestBody TagListQueryDto tagListQueryDto) {
         Page<TUserTag> page = tUserTagService.lambdaQuery()
                 .orderByDesc(TUserTag::getCreateTime)
-                .like(tagListQueryDto.getTagName()!=null&& tagListQueryDto.getTagName().isEmpty(), TUserTag::getName, tagListQueryDto.getTagName())
+                .like(tagListQueryDto.getTagName()!=null&& tagListQueryDto.getTagName()!="", TUserTag::getName, tagListQueryDto.getTagName())
                 .page(Page.of(tagListQueryDto.getPageCurr(), tagListQueryDto.getPageSize()));
         return R.ok(page);
 
@@ -73,8 +74,17 @@
 
         return R.ok(tUserTagService.getById(id));
     }
-
-
+    
+    
+    /**
+     * 获取所有有效数据
+     * @return
+     */
+    @PostMapping(value = "/getAllUserTag")
+    public R<List<TUserTag>> getAllUserTag(){
+        List<TUserTag> list = tUserTagService.list(new LambdaQueryWrapper<TUserTag>().eq(TUserTag::getDelFlag, 0));
+        return R.ok(list);
+    }
 
 }
 
diff --git a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TVipController.java b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TVipController.java
index 797da3c..a6a0e64 100644
--- a/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TVipController.java
+++ b/ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TVipController.java
@@ -217,6 +217,8 @@
     }
 
 
+
+
     @ApiOperation(value = "购买会员", tags = {"小程序-个人中心"})
     @GetMapping("/vipInfo/pay")
     public R vipInfoPay(@RequestParam("vipId")Integer vipId,@RequestParam("buyType") Integer buyType,

--
Gitblit v1.7.1