Browse Source

Merge remote-tracking branch 'origin/dev_20260131' into dev_20260131

donglang 2 months ago
parent
commit
1afb935646

+ 19 - 7
sckw-auth/src/main/java/com/sckw/auth/service/impl/AuthServiceImpl.java

@@ -71,12 +71,8 @@ public class AuthServiceImpl implements IAuthService {
         /*运营端/企业端登录(PC/APP)*/
         if (loginBase.getSystemType() == SystemTypeEnum.MANAGE.getCode()
                 || loginBase.getSystemType() == SystemTypeEnum.COMPANY.getCode()) {
-            KwsUserResDto kwsUserResDto = systemService.queryByAccount(loginBase.getAccount());
-            if (Objects.nonNull(kwsUserResDto)) {
-                loginBase.setSystemType(SystemTypeEnum.COMPANY.getCode());
-                return this.commonAuth(loginBase);
-            }
-            return this.driverAuth(loginBase);
+           // KwsUserResDto kwsUserResDto = systemService.queryByAccount(loginBase.getAccount());
+            return this.commonAuth(loginBase);
         }
 
         /*司机端*/
@@ -917,6 +913,7 @@ public class AuthServiceImpl implements IAuthService {
         boolean isDoorKeeper = StringUtils.isNotBlank(roleName) && roleName.contains("门卫");
         boolean isForkliftDriver = StringUtils.isNotBlank(roleName) && roleName.contains("铲车司机");
         boolean isBuyer = StringUtils.isNotBlank(roleName) && roleName.contains("买家");
+        boolean isDriver = StringUtils.isNotBlank(roleName) && roleName.contains("司机");
         if (isDoorKeeper) {
             return buildDoorKeeperTabBar();
         }
@@ -926,10 +923,13 @@ public class AuthServiceImpl implements IAuthService {
         if (isBuyer) {
             return buildBuyerTabBar();
         }
+        if (isDriver){
+            return buildDefaultDriverTabBar();
+        }
         if (flag == 1) {
             return buildDefaultDriverTabBar();
         }
-        if (flag == 0 && !isDoorKeeper && !isForkliftDriver && !isBuyer){
+        if (flag == 0 && !isDoorKeeper && !isForkliftDriver && !isBuyer && !isDriver){
             return buildBuyerTabBar();
         }
         return List.of();
@@ -949,6 +949,18 @@ public class AuthServiceImpl implements IAuthService {
                 "/static/tabbar/trade.png",
                 "/pages/tradeOrder/index"
         ));
+        items.add(buildTabBarItem(
+                "物流订单",
+                "/static/tabbar/logOrder_select.png",
+                "/static/tabbar/logOrder.png",
+                "/pages/logistics/order/index"
+        ));
+        items.add(buildTabBarItem(
+                "物流运单",
+                "/static/tabbar/waybill_select.png",
+                "/static/tabbar/waybill.png",
+                "/pages/logistics/waybill/index"
+        ));
         items.add(buildTabBarItem(
                 "个人中心",
                 "/static/tabbar/my_select.png",

+ 22 - 8
sckw-modules/sckw-fleet/src/main/java/com/sckw/fleet/service/KwfDriverService.java

@@ -8,7 +8,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.sckw.contract.api.RemoteContractService;
 import com.sckw.contract.api.model.vo.KwcContractLogisticsDto;
-import com.google.common.collect.Maps;
 import com.sckw.core.common.enums.enums.DictEnum;
 import com.sckw.core.common.enums.enums.DictTypeEnum;
 import com.sckw.core.common.enums.enums.ErrorCodeEnum;
@@ -45,16 +44,17 @@ import com.sckw.transport.api.dubbo.TransportRemoteService;
 import com.sckw.transport.api.model.param.CapacityTruckParam;
 import com.sckw.transport.api.model.vo.RWaybillOrderVo;
 import com.sckw.transport.api.model.vo.WaybillOrderTaskVO;
+import io.seata.spring.annotation.GlobalTransactional;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.InputStream;
 import java.util.*;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -467,10 +467,12 @@ public class KwfDriverService {
 
     /**
      * @param params 参数
-     * @desc 新增司机
+     * @desc 新增司机(Seata 全局事务:车队库 + 远程 system 用户/角色库一致提交或回滚,需 Seata TC 与各服务数据源代理已就绪)
      * @author zk
      * @date 2023/7/6
      **/
+    @GlobalTransactional(name = "default_tx_group", rollbackFor = Exception.class)
+    @Transactional(rollbackFor = Exception.class)
     public HttpResult add(KwfDriverDto params) {
         /**司机信息**/
         KwfDriver driver = new KwfDriver();
@@ -492,30 +494,42 @@ public class KwfDriverService {
         KwfDriverCardDto driverCardDto = params.getDriverCard();
         if (driverCardDto != null) {
             driverCardDto.setDriverId(driver.getId());
-            driverCardEdit(driverCardDto);
+            requireBizSuccess(driverCardEdit(driverCardDto), "身份证信息");
         }
 
         /**司机驾驶证信息**/
         KwfDriverLicenseDto driverLicenseDto = params.getDriverLicense();
         if (driverLicenseDto != null) {
             driverLicenseDto.setDriverId(driver.getId());
-            driverLicenseEdit(driverLicenseDto);
+            requireBizSuccess(driverLicenseEdit(driverLicenseDto), "驾驶证信息");
         }
 
         /**司机从业资格证**/
         KwfDriverQualificationDto driverQualificationDto = params.getDriverQualification();
         if (driverQualificationDto != null) {
             driverQualificationDto.setDriverId(driver.getId());
-            driverQualificationEdit(driverQualificationDto);
+            requireBizSuccess(driverQualificationEdit(driverQualificationDto), "从业资格证信息");
         }
 
         /**车队班组绑定**/
-        driverFleetEdit(driver.getId(), params.getFleetId());
-        //同步信息到员工列表
+        requireBizSuccess(driverFleetEdit(driver.getId(), params.getFleetId()), "车队班组绑定");
+        //同步信息到员工列表(system 服务,参与同一全局事务)
         userEdit(params);
         return HttpResult.ok(result.getMsg(), driver);
     }
 
+    /**
+     * 全局事务下子步骤若仅用 {@link HttpResult} 表示失败而不抛异常,TM 仍会提交;失败时必须抛异常以驱动回滚。
+     */
+    private void requireBizSuccess(HttpResult result, String stepName) {
+        if (result == null || result.getCode() != HttpStatus.SUCCESS_CODE) {
+            String detail = result != null ? result.getMsg() : "未返回结果";
+            throw new SystemException(
+                    result != null ? result.getCode() : HttpStatus.CRUD_FAIL_CODE,
+                    stepName + "失败:" + detail);
+        }
+    }
+
     private void userEdit(KwfDriverDto params) {
         KwsUserReqDto kwsUserReqDto = new KwsUserReqDto();
         //密码为空时,以登录名作为密码

+ 12 - 1
sckw-modules/sckw-order/src/main/java/com/sckw/order/serivce/KwoTradeOrderService.java

@@ -87,6 +87,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.jetbrains.annotations.NotNull;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cloud.stream.function.StreamBridge;
 import org.springframework.stereotype.Service;
@@ -136,7 +137,8 @@ public class KwoTradeOrderService {
     @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
     protected RemoteFleetService remoteFleetService;
 
-    private final OfflineWalletFeignService offlineWalletFeignService;
+    @Autowired(required = false)
+    private OfflineWalletFeignService offlineWalletFeignService;
 
     private final KwoTradeOrderMapper kwoTradeOrderMapper;
     private final StreamBridge streamBridge;
@@ -2185,6 +2187,9 @@ public class KwoTradeOrderService {
     }
 
     private void walletFreeze(TradeOrderParam tradeOrderParam, KwoTradeOrder order,WalletFreezeDto freezeDto) {
+        if (offlineWalletFeignService == null) {
+            throw new BusinessException("线下钱包服务未配置,无法执行冻结操作");
+        }
 
         freezeDto.setFreezeAmount(tradeOrderParam.getAmount());
         freezeDto.setOrderNo(order.getTOrderNo());
@@ -2206,6 +2211,9 @@ public class KwoTradeOrderService {
     }
 
     private void checkWallet(KwoTradeOrder order) {
+        if (offlineWalletFeignService == null) {
+            throw new BusinessException("线下钱包服务未配置,无法查询余额");
+        }
         BaseResult<BigDecimal> balanceResult;
         try {
             balanceResult = offlineWalletFeignService.queryPrepaidBalance(LoginUserHolder.getEntId());
@@ -2256,6 +2264,9 @@ public class KwoTradeOrderService {
          freezeDto.setFreezeAmount(param.getFreezeAmount());
          freezeDto.setOrderNo(order.getTOrderNo());
 
+        if (offlineWalletFeignService == null) {
+            throw new BusinessException("线下钱包服务未配置,无法执行解冻操作");
+        }
         BaseResult<Boolean> balanceResult;
         try {
             balanceResult = offlineWalletFeignService.unfreezeBalance(freezeDto);

+ 73 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/dubbo/RemoteUserServiceImpl.java

@@ -7,6 +7,7 @@ import com.github.pagehelper.PageInfo;
 import com.sckw.core.exception.SystemException;
 import com.sckw.core.model.base.BaseModel;
 import com.sckw.core.model.constant.Global;
+import com.sckw.core.utils.IdWorker;
 import com.sckw.core.model.page.PageHelperUtil;
 import com.sckw.core.model.page.PageResult;
 import com.sckw.core.utils.BeanUtils;
@@ -28,6 +29,7 @@ import com.sckw.system.model.vo.res.KwsUserSystemTypeVo;
 import com.sckw.system.service.*;
 import jakarta.annotation.Resource;
 import org.apache.dubbo.config.annotation.DubboService;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.*;
 import java.util.stream.Collectors;
@@ -41,6 +43,8 @@ import java.util.stream.Collectors;
 @DubboService(group = "design", version = "1.0.0")
 public class RemoteUserServiceImpl implements RemoteUserService {
 
+    private static final String DRIVER_ROLE_NAME = "司机";
+
     @Resource
     private RemoteBaseService remoteBaseService;
 
@@ -74,6 +78,9 @@ public class RemoteUserServiceImpl implements RemoteUserService {
     @Resource
     private KwsUserDao userDao;
 
+    @Resource
+    private KwsRoleDao kwsRoleDao;
+
     @Resource
     private CommonService commonService;
 
@@ -471,6 +478,7 @@ public class RemoteUserServiceImpl implements RemoteUserService {
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void saveUser(KwsUserReqDto kwsUserReqDto) {
         KwsUser kwsUser = new KwsUser();
         BeanUtils.copyProperties(kwsUserReqDto, kwsUser);
@@ -485,6 +493,71 @@ public class RemoteUserServiceImpl implements RemoteUserService {
             kwsUser.setCreateTime(null);
             userDao.updateById(kwsUser);
         }
+        bindDriverUserRole(kwsUser, kwsUserReqDto);
+    }
+
+    /**
+     * 司机用户在 {@link KwsUser} 保存后关联企业下「司机」角色;若该企业尚不存在该角色则先初始化。
+     */
+    private void bindDriverUserRole(KwsUser kwsUser, KwsUserReqDto kwsUserReqDto) {
+        if (kwsUser.getId() == null || kwsUserReqDto.getEntId() == null) {
+            return;
+        }
+        KwsRole driverRole = kwsRoleDao.selectOne(Wrappers.<KwsRole>lambdaQuery()
+                .eq(KwsRole::getEntId, kwsUserReqDto.getEntId())
+                .eq(KwsRole::getName, DRIVER_ROLE_NAME)
+                .eq(KwsRole::getDelFlag, Global.NO)
+                .last("limit 1"));
+        if (driverRole == null) {
+            driverRole = initDriverRole(kwsUserReqDto);
+        }
+        List<KwsUserRole> userRoles = userRoleDao.findAllByUserId(kwsUser.getId());
+        if (!CollectionUtils.isEmpty(userRoles)) {
+            KwsRole finalDriverRole = driverRole;
+            boolean alreadyBound = userRoles.stream()
+                    .anyMatch(ur -> Objects.equals(ur.getRoleId(), finalDriverRole.getId()));
+            if (alreadyBound) {
+                return;
+            }
+        }
+        Date now = new Date();
+        KwsUserRole userRole = new KwsUserRole();
+        userRole.setId(new IdWorker(1L).nextId());
+        userRole.setUserId(kwsUser.getId());
+        userRole.setRoleId(driverRole.getId());
+        userRole.setRemark(kwsUserReqDto.getRemark());
+        userRole.setStatus(Global.NO);
+        userRole.setDelFlag(Global.NO);
+        userRole.setCreateBy(kwsUserReqDto.getCreateBy() != null ? kwsUserReqDto.getCreateBy() : -1L);
+        userRole.setCreateTime(kwsUserReqDto.getCreateTime() != null ? kwsUserReqDto.getCreateTime() : now);
+        userRole.setUpdateBy(kwsUserReqDto.getUpdateBy() != null ? kwsUserReqDto.getUpdateBy() : userRole.getCreateBy());
+        userRole.setUpdateTime(kwsUserReqDto.getUpdateTime() != null ? kwsUserReqDto.getUpdateTime() : now);
+        userRoleDao.insert(userRole);
+    }
+
+    /**
+     * 在当前企业下创建「司机」角色(admin_flag=2 非管理员),不绑定菜单; 相比为司机同步场景的最小初始化。
+     */
+    private KwsRole initDriverRole(KwsUserReqDto kwsUserReqDto) {
+        Date now = new Date();
+        KwsRole role = new KwsRole();
+        long roleId = new IdWorker(1L).nextId();
+        role.setId(roleId);
+        role.setEntId(kwsUserReqDto.getEntId());
+        role.setName(DRIVER_ROLE_NAME);
+        role.setAdminFlag(2);
+        role.setRemark("司机用户默认角色");
+        role.setStatus(Global.NO);
+        role.setDelFlag(Global.NO);
+        Long operator = kwsUserReqDto.getCreateBy() != null ? kwsUserReqDto.getCreateBy() : -1L;
+        role.setCreateBy(operator);
+        role.setCreateTime(kwsUserReqDto.getCreateTime() != null ? kwsUserReqDto.getCreateTime() : now);
+        role.setUpdateBy(kwsUserReqDto.getUpdateBy() != null ? kwsUserReqDto.getUpdateBy() : operator);
+        role.setUpdateTime(kwsUserReqDto.getUpdateTime() != null ? kwsUserReqDto.getUpdateTime() : now);
+        if (kwsRoleDao.insert(role) <= 0) {
+            throw new SystemException(HttpStatus.CRUD_FAIL_CODE, HttpStatus.INSERT_FAIL);
+        }
+        return role;
     }
 
     /**