wenhongquan 5 месяцев назад
Родитель
Сommit
0371e67370

+ 1 - 0
ruoyi-admin/src/main/resources/application.yml

@@ -131,6 +131,7 @@ security:
     - /system/dzbc/cargoOrder/**
     - /system/dzbc/driverTrip/qr/**
     - /system/dzbc/coze/chat/stream
+    - /system/dzbc/multiSitePath/list
 
 # 多租户配置
 tenant:

+ 6 - 0
ruoyi-modules/ruoyi-dzbc/pom.xml

@@ -153,6 +153,12 @@
             <artifactId>core</artifactId>
             <version>3.4.1</version>
         </dependency>
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-miniapp</artifactId>
+            <version>4.6.7.B</version>
+            <scope>compile</scope>
+        </dependency>
 
     </dependencies>
 

+ 51 - 0
ruoyi-modules/ruoyi-dzbc/src/main/java/org/dromara/system/controller/CommonDzbcOtherController.java

@@ -9,11 +9,15 @@ import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
 import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
 import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
 import com.github.binarywang.wxpay.service.WxPayService;
+import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor;
 import io.undertow.servlet.spec.HttpServletRequestImpl;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.error.WxErrorException;
 import org.apache.commons.io.IOUtils;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.log.annotation.Log;
@@ -25,6 +29,7 @@ import org.dromara.system.domain.bo.TblDzbcStatisticsBo;
 import org.dromara.system.domain.vo.TblDzbcOrderVo;
 import org.dromara.system.service.ITblDzbcBannerService;
 import org.dromara.system.service.ITblDzbcOrderService;
+import org.springframework.http.MediaType;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -50,6 +55,7 @@ public class CommonDzbcOtherController extends BaseController {
     private final ITblDzbcOrderService orderService;
     private final ITblDzbcCargoOrderService cargoOrderService;
     private final WxPayService wxPayService;
+    private final WxMaService wxMaService;
 
 
 
@@ -157,6 +163,51 @@ public class CommonDzbcOtherController extends BaseController {
         QrCodeUtil.generate(content, width, height, "png", response.getOutputStream());
     }
 
+    /**
+     * 生成小程序码(无限制)
+     * @param scene 场景值,最多32个可见字符
+     * @param page 页面路径,必须是已经发布的小程序存在的页面
+     * @param checkPath 检查page是否存在,默认true
+     * @param envVersion 环境版本:release正式版, trial体验版, develop开发版,默认release
+     * @param width 小程序码宽度,默认430
+     * @param autoColor 自动配置线条颜色,默认true
+     * @param isHyaline 是否需要透明底色,默认false
+     * @param appid 小程序appid,默认使用第一个配置的小程序
+     * @param response HttpServletResponse
+     */
+    @GetMapping("/wxma/qrcode/unlimited")
+    public void getUnlimitedQRCode(
+            @RequestParam String scene,
+            @RequestParam(defaultValue = "") String page,
+            @RequestParam(defaultValue = "true") boolean checkPath,
+            @RequestParam(defaultValue = "release") String envVersion,
+            @RequestParam(defaultValue = "430") int width,
+            @RequestParam(defaultValue = "true") boolean autoColor,
+            @RequestParam(defaultValue = "false") boolean isHyaline,
+            @RequestParam(defaultValue = "wx5c9baacf2aab55b8") String appid,
+            HttpServletResponse response) {
+        try {
+            // 切换到指定小程序
+            wxMaService.switchover(appid);
+            WxMaQrcodeService qrcodeService = wxMaService.getQrcodeService();
+
+            // 生成小程序码
+            // 参数顺序: scene, page, checkPath, envVersion, width, autoColor, lineColor, isHyaline
+            byte[] qrCodeBytes = qrcodeService.createWxaCodeUnlimitBytes(scene, page, checkPath, envVersion, width, autoColor, null, isHyaline);
+
+            // 返回图片
+            response.setContentType(MediaType.IMAGE_PNG_VALUE);
+            response.getOutputStream().write(qrCodeBytes);
+            response.getOutputStream().flush();
+        } catch (WxErrorException e) {
+            log.error("生成小程序码失败: {}", e.getMessage());
+            throw new RuntimeException("生成小程序码失败: " + e.getMessage());
+        } catch (IOException e) {
+            log.error("输出小程序码失败: {}", e.getMessage());
+            throw new RuntimeException("输出小程序码失败: " + e.getMessage());
+        }
+    }
+
 
     @ResponseBody
     @Log(title = "定制班车-订单微信退款回调", businessType = BusinessType.UPDATE)

+ 19 - 0
ruoyi-modules/ruoyi-dzbc/src/main/java/org/dromara/system/controller/TblDzbcOrderController.java

@@ -9,6 +9,7 @@ import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.github.binarywang.wxpay.bean.request.WxPayRefundQueryRequest;
 import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
@@ -19,8 +20,10 @@ import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.system.domain.TblDzbcDriverTrip;
 import org.dromara.system.domain.vo.SysSocialVo;
 import org.dromara.system.domain.vo.TblDzbcPathSchedulingVo;
+import org.dromara.system.mapper.TblDzbcDriverTripMapper;
 import org.dromara.system.service.ISysSocialService;
 import org.dromara.system.service.ITblDzbcPathSchedulingService;
 import org.springframework.beans.factory.annotation.Value;
@@ -61,6 +64,8 @@ public class TblDzbcOrderController extends BaseController {
 
     private final WxPayService wxPayService;
 
+    private final TblDzbcDriverTripMapper driverTripMapper;
+
     @Value("${baseUrl}")
     String baseUrl;
 
@@ -255,6 +260,20 @@ public class TblDzbcOrderController extends BaseController {
         }
         if (tblDzbcOrderVo == null) return R.fail("该订单不存在");
         if (tblDzbcOrderVo.getStatus().equals("1")) {
+            // 判断是否为固定路线(type=2),如果是则检查发车状态
+            TblDzbcPathSchedulingVo scheduling = tbspSchedulingService.queryById(tblDzbcOrderVo.getSchedulingId());
+            if (scheduling != null && scheduling.getType() != null && scheduling.getType() == 2) {
+                // 固定路线:通过 driverTrip 判断发车状态
+                TblDzbcDriverTrip trip = driverTripMapper.selectOne(
+                    new LambdaQueryWrapper<TblDzbcDriverTrip>()
+                        .apply("ext2->'$.schedulingId' = {0}", tblDzbcOrderVo.getSchedulingId())
+                        .last("LIMIT 1")
+                );
+                if (trip != null && trip.getStatus() != null && trip.getStatus() >= 1) {
+                    // status: 0-待发车 1-运行中 2-已完成 3-已取消
+                    return R.fail("该班次已发车,无法退款");
+                }
+            }
             //判断订单时间 订单时间距离发车>60分钟可以取消
             double bl = 1;
             try {

+ 9 - 0
ruoyi-modules/ruoyi-dzbc/src/main/java/org/dromara/system/service/impl/TblDzbcDriverTripServiceImpl.java

@@ -269,6 +269,15 @@ public class TblDzbcDriverTripServiceImpl implements ITblDzbcDriverTripService {
         lqw.eq(bo.getDriverId() != null, TblDzbcDriverTrip::getDriverId, bo.getDriverId());
         lqw.like(StrUtil.isNotBlank(bo.getTripNo()), TblDzbcDriverTrip::getTripNo, bo.getTripNo());
         lqw.eq(bo.getStatus() != null, TblDzbcDriverTrip::getStatus, bo.getStatus());
+        // startTime 时间范围筛选
+        if (bo.getParams() != null) {
+            if (bo.getParams().containsKey("beginStartTime")) {
+                lqw.ge(TblDzbcDriverTrip::getStartTime, bo.getParams().get("beginStartTime"));
+            }
+            if (bo.getParams().containsKey("endStartTime")) {
+                lqw.le(TblDzbcDriverTrip::getStartTime, bo.getParams().get("endStartTime"));
+            }
+        }
         lqw.orderByDesc(TblDzbcDriverTrip::getCreateTime);
         return lqw;
     }

+ 93 - 10
ruoyi-modules/ruoyi-dzbc/src/main/java/org/dromara/system/service/impl/TblDzbcPathSchedulingServiceImpl.java

@@ -315,30 +315,46 @@ public class TblDzbcPathSchedulingServiceImpl implements ITblDzbcPathSchedulingS
      */
     @Override
     public Boolean updateByBo(TblDzbcPathSchedulingBo bo) {
+        // 固定班次(type=2)校验:已发车或完成的不允许修改
+        if (bo.getType() != null && bo.getType() == 2 && bo.getId() != null) {
+            TblDzbcDriverTrip trip = driverTripMapper.selectOne(
+                new LambdaQueryWrapper<TblDzbcDriverTrip>()
+                    .apply("ext2->'$.schedulingId' = {0}", bo.getId())
+                    .last("LIMIT 1")
+            );
+            if (trip != null && trip.getStatus() != null && trip.getStatus() >= 1) {
+                // status: 0-待发车 1-运行中 2-已完成 3-已取消
+                String statusMsg = trip.getStatus() == 1 ? "已发车" : (trip.getStatus() == 2 ? "已完成" : "已取消");
+                throw new RuntimeException("该排班" + statusMsg + ",不允许修改");
+            }
+        }
+
         TblDzbcPathScheduling update = MapstructUtils.convert(bo, TblDzbcPathScheduling.class);
         validEntityBeforeSave(update);
         int c = baseMapper.updateById(update) ;
         if(c>0){
             Map<String, Object> params = bo.getParams();
             TblDzbcPathScheduling add = baseMapper.selectById(update.getId());
+            SysUserVo driverVo = null;
+            TblDzbcCarVo carVo = null;
             if(add.getCarId()!=null){
-                TblDzbcCarVo carVo =  carMapper.selectVoById(bo.getCarId());
+                carVo =  carMapper.selectVoById(bo.getCarId());
 
                 if(carVo == null){
                     throw new RuntimeException("车辆不存在");
                 }
                 SysUserVo userVo = userMapper.selectUserById(carVo.getDriverId());
-                SysUserVo userVo1 = new SysUserVo();
-                userVo1.setUserId(userVo.getUserId());
-                userVo1.setUserName(userVo.getUserName());
-                userVo1.setNickName(userVo.getNickName());
-                userVo1.setPhonenumber(userVo.getPhonenumber());
-                userVo1.setEmail(userVo.getEmail());
-                userVo1.setSex(userVo.getSex());
+                driverVo = new SysUserVo();
+                driverVo.setUserId(userVo.getUserId());
+                driverVo.setUserName(userVo.getUserName());
+                driverVo.setNickName(userVo.getNickName());
+                driverVo.setPhonenumber(userVo.getPhonenumber());
+                driverVo.setEmail(userVo.getEmail());
+                driverVo.setSex(userVo.getSex());
                 if(userVo.getAvatar()!=null){
-                    userVo1.setAvatarUrl(ossService.selectUrlByIds(userVo.getAvatar().toString()));
+                    driverVo.setAvatarUrl(ossService.selectUrlByIds(userVo.getAvatar().toString()));
                 }
-                params.put("driverInfo",userVo1);
+                params.put("driverInfo",driverVo);
                 params.put("carInfo",carVo);
             }
             if(add.getPathId()!=null){
@@ -377,11 +393,78 @@ public class TblDzbcPathSchedulingServiceImpl implements ITblDzbcPathSchedulingS
             add.setExt1(JSONUtil.toJsonStr(params));
             baseMapper.updateById(add);
 
+            // 固定班次(type=2)修改后,同步更新对应的司机任务
+            if (bo.getType() != null && bo.getType() == 2) {
+                updateDriverTrip(add, driverVo, carVo);
+            }
+
             SysCache();
         }
         return c> 0;
     }
 
+    /**
+     * 更新司机任务(排班修改时同步更新)
+     */
+    private void updateDriverTrip(TblDzbcPathScheduling scheduling, SysUserVo driver, TblDzbcCarVo carVo) {
+        try {
+            // 查找该排班关联的司机任务
+            TblDzbcDriverTrip trip = driverTripMapper.selectOne(
+                new LambdaQueryWrapper<TblDzbcDriverTrip>()
+                    .apply("ext2->'$.schedulingId' = {0}", scheduling.getId())
+                    .last("LIMIT 1")
+            );
+
+            if (trip == null) {
+                // 如果不存在司机任务,则创建一个新的
+                Map<String, Object> params = new HashMap<>();
+                params.put("driverInfo", driver);
+                params.put("carInfo", carVo);
+                createDriverTrip(scheduling, params);
+                return;
+            }
+
+            // 如果司机任务已发车或已完成,不允许修改
+            if (trip.getStatus() != null && trip.getStatus() >= 1) {
+                return;
+            }
+
+            // 更新司机任务信息
+            TblDzbcDriverTrip updateTrip = new TblDzbcDriverTrip();
+            updateTrip.setId(trip.getId());
+            updateTrip.setPathId(scheduling.getPathId());
+
+            if (driver != null) {
+                updateTrip.setDriverId(driver.getUserId());
+                updateTrip.setDriverName(driver.getNickName());
+                updateTrip.setDriverPhone(driver.getPhonenumber());
+            }
+
+            if (carVo != null) {
+                updateTrip.setCarId(carVo.getId());
+            }
+
+            // 更新开始时间 (mdate + mtime)
+            if (scheduling.getMdate() != null && StrUtil.isNotBlank(scheduling.getMtime())) {
+                String dateStr = DateUtil.formatDate(scheduling.getMdate());
+                String timeStr = scheduling.getMtime();
+                if (StringUtils.countMatches(timeStr, ":") == 1) {
+                    timeStr += ":00";
+                }
+                String dateTimeStr = dateStr + " " + timeStr;
+                LocalDateTime startTime = LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                updateTrip.setStartTime(startTime);
+            }
+
+            // 更新 ext1 存储排班快照
+            updateTrip.setExt1(JSONUtil.toJsonStr(scheduling));
+
+            driverTripMapper.updateById(updateTrip);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
 
 
     @Override