puzhibing
2024-09-26 8b94c462ae127795cfa4a0495c723ca9b7041e10
Merge remote-tracking branch 'origin/master'
48个文件已修改
8个文件已添加
2741 ■■■■ 已修改文件
ruoyi-api/ruoyi-api-account/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserFallbackFactory.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserTagFallbackFactory.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserVipDetailFallbackFactory.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserTagClient.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-account/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/AccountingStrategyDetailFallbackFactory.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/AccountingStrategyFallbackFactory.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingGunFallbackFactory.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-integration/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/SendMessageFallbackFactory.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/AccountingStrategyDetailOrderFallbackFactory.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/AccountingStrategyOrderFallbackFactory.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/AccountingStrategyDetailOrderClient.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/AccountingStrategyOrderClient.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyDetailOrder.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyOrder.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-order/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/CouponFallbackFactory.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/GoodsFallbackFactory.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/InvoiceTypeFallbackFactory.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/UserSiteFallbackFactory.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/UserTagFallbackFactory.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/UserTagClient.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-other/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/AliPaymentFallbackFactory.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-payment/src/main/java/com/ruoyi/payment/api/factory/WxPaymentFallbackFactory.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/SysUserFallbackFactory.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java 222 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java 391 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/handler/GlobalExceptionHandler.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/filter/AuthFilter.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/query/SysOperLogQuery.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java 1076 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserTagController.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TChargingGunController.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/PartnerServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/TChargingPileServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/AccountingStrategyDetailOrderController.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/AccountingStrategyOrderController.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TShoppingOrderController.java 113 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TExchangeOrderService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java 207 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TExchangeOrderServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TShoppingOrderServiceImpl.java 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/RedisLock.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TUserTagController.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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>
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());
            }
ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserTagFallbackFactory.java
New file
@@ -0,0 +1,35 @@
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());
            }
        };
    }
}
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());
            }
        };
ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserTagClient.java
New file
@@ -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);
}
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
com.ruoyi.account.api.factory.InviteUserFallbackFactory
com.ruoyi.account.api.factory.AppUserTagFallbackFactory
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>
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());
            }
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());
            }
        };
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());
            }
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>
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 "远程停机失败";
            }
        };
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>
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());
            }
        };
    }
}
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/AccountingStrategyOrderFallbackFactory.java
New file
@@ -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());
            }
        };
    }
}
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);
}
ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/AccountingStrategyOrderClient.java
New file
@@ -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);
}
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")
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;
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
com.ruoyi.order.api.factory.AccountingStrategyDetailOrderFallbackFactory
com.ruoyi.order.api.factory.AccountingStrategyOrderFallbackFactory
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>
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("修改优惠券失败");
            }
        };
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("修改商品异常");
            }
        };
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());
            }
        };
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());
            }
        };
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/UserTagFallbackFactory.java
New file
@@ -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());
            }
        };
    }
}
ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/UserTagClient.java
New file
@@ -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();
}
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
com.ruoyi.other.api.factory.WebSocketFallbackFactory
com.ruoyi.other.api.factory.UserTagFallbackFactory
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>
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());
            }
        };
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());
            }
    
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>
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());
            }
        };
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, "注册成功");
    }
}
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;
    }
}
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());
    }
    
    /**
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());
        }
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);
    }
    
    
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;
}
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);
    }
}
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
ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserController.java
@@ -1033,5 +1033,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();
    }
}
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;
@@ -76,9 +77,28 @@
        }
        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);
    }
}
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();
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();
    }
    
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);
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);
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);
    }
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/AccountingStrategyOrderController.java
New file
@@ -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);
    }
}
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;
@@ -41,7 +42,7 @@
/**
 * <p>
 *  前端控制器
 * 前端控制器
 * </p>
 *
 * @author xiaochen
@@ -60,14 +61,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 +88,47 @@
            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());
            }
        }
        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 +138,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 +148,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 +167,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 +183,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 +197,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 +221,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 +252,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 +260,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 +272,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 +310,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();
    }
}
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;
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(()->{
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;
    }
}
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();
@@ -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();
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/RedisLock.java
New file
@@ -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;
    }
}
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;
@@ -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);
    }
}