package com.ruoyi.api.third.controller; import java.util.*; import java.util.stream.Collectors; import cn.hutool.json.JSONUtil; import com.ruoyi.cwgl.domain.DispatchOrder; import com.ruoyi.tms.mapper.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.api.third.util.ApiAuthUtil; import com.ruoyi.system.mapper.SysDictDataMapper; import com.ruoyi.tms.domain.*; import com.ruoyi.tms.domain.vo.*; import com.ruoyi.tms.service.ITmsDispatchOrderService; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; /** * AI调度专用第三方接口 (无需权限, 使用appId/secret认证) * * @author ruoyi * @date 2026-03-06 */ @RestController @RequestMapping("/api/third/aiDispatch") public class TmsAiDispatchController extends BaseController { @Resource private TransportRouteViMapper transportRouteViMapper; @Resource private TmsCustomerInfoMapper tmsCustomerInfoMapper; @Resource private TmsServiceProviderMapper tmsServiceProviderMapper; @Resource private TmsDriverMapper tmsDriverMapper; @Resource private TmsVehicleMapper tmsVehicleMapper; @Resource private TmsConsignorMapper tmsConsignorMapper; @Autowired private ITmsDispatchOrderService tmsDispatchOrderService; @Autowired private SysDictDataMapper sysDictDataMapper; @Autowired private ApiAuthUtil apiAuthUtil; /** * 验证客户是否存在,且返回客户信息接口 * @param customerName * @return */ @GetMapping("/getCustomerData") public AjaxResult getCustomerData( @RequestParam(value = "customerName", required = true) String customerName){ logger.info("getCustomerData:{}",customerName); TmsCustomerInfo tmsCustomerInfo = tmsCustomerInfoMapper.selectOne(new LambdaQueryWrapper() .like(TmsCustomerInfo::getCustomerFullName, customerName) .last("limit 1") ); if (tmsCustomerInfo == null){ return error("客户不存在"); }else{ return AjaxResult.success(tmsCustomerInfo); } } /** * 验证车辆是否存在,且返回车辆信息接口 * @param licensePlate * @param licenseHk * @param licenseMo * @return */ @GetMapping("/getVehicleData") public AjaxResult getVehicleData( @RequestParam(value = "licensePlate", required = false) String licensePlate, @RequestParam(value = "licenseHk", required = false) String licenseHk, @RequestParam(value = "licenseMo", required = false) String licenseMo ){ logger.info("getVehicleData:{},{},{}",licensePlate,licenseHk,licenseMo); TmsVehicle tmsCustomerInfo = tmsVehicleMapper.selectOne(new LambdaQueryWrapper() .like(StringUtils.isNotEmpty(licensePlate),TmsVehicle::getLicensePlate, licensePlate) .like(StringUtils.isNotEmpty(licenseHk),TmsVehicle::getLicenseHk, licenseHk) .like(StringUtils.isNotEmpty(licenseMo),TmsVehicle::getLicenseMo, licenseMo) .last("limit 1") ); if (tmsCustomerInfo == null){ return error("车辆不存在"); }else{ return AjaxResult.success(tmsCustomerInfo); } } /** * 获取司机接口 (公开接口, 无需认证) * 支持按名称筛选 * * @param driverName 司机名称(可选,模糊查询) * @return 司机列表 */ @GetMapping("/getDriverData") public AjaxResult getDriverData( @RequestParam(value = "driverName", required = true) String driverName) { logger.info("getVehicleData:{}",driverName); TmsDriver tmsDriver = tmsDriverMapper.selectOne(new LambdaQueryWrapper() .like(TmsDriver::getDriverName, driverName) .last("limit 1") ); if (tmsDriver == null){ return error("司机信息不存在"); }else{ return AjaxResult.success(tmsDriver); } } @GetMapping("/getVehicleProviderData") public AjaxResult getVehicleProviderData( @RequestParam(value = "serviceName", required = true) String serviceName) { logger.info("getVehicleProviderData:{}",serviceName); TmsServiceProvider provider = tmsServiceProviderMapper.selectOne(new LambdaQueryWrapper() .like(TmsServiceProvider::getServiceName, serviceName) .last("limit 1") ); if (provider == null){ return error("车辆服务商信息不存在"); }else{ return AjaxResult.success(provider); } } @GetMapping("/getConsignorData") public AjaxResult getConsignorData( @RequestParam(value = "consignorName", required = true) String consignorName, @RequestParam(value = "customerName", required = true) String customerName) { logger.info("getConsignorData:{}",consignorName); TmsConsignor tmsConsignor = tmsConsignorMapper.selectOne(new LambdaQueryWrapper() .like(TmsConsignor::getConsignorName, consignorName) .eq(TmsConsignor::getCustomerName, customerName) .last("limit 1") ); if (tmsConsignor == null){ return error("装卸货点不存在"); }else{ return AjaxResult.success(tmsConsignor); } } /** * 路线验证接口 (需要appId/secret认证) * * @param vo 路线验证请求 * @param request HTTP请求 * @return 验证结果 */ @PostMapping("/validateRoute") public AjaxResult validateRoute(@RequestBody RouteValidationVO vo, HttpServletRequest request) { logger.info("validateRoute:{}", JSONUtil.toJsonStr(vo)); AiValidationResultVO result = new AiValidationResultVO(); List errors = new ArrayList<>(); List warnings = new ArrayList<>(); // 验证必填字段 if (StringUtils.isEmpty(vo.getOriginCity())) { errors.add("起始城市不能为空"); } if (StringUtils.isEmpty(vo.getDestCity())) { errors.add("目的地城市不能为空"); } if (StringUtils.isEmpty(vo.getVehicleType())) { errors.add("车辆类型不能为空"); } // 如果有错误,直接返回 if (!errors.isEmpty()) { result.setIsValid(false); result.setErrors(errors); result.setWarnings(warnings); return success(result); } // 查询匹配的路线 LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); if (StringUtils.isNotEmpty(vo.getOriginCity())) { wrapper.like(TransportRouteVi::getTransportRoute, vo.getOriginCity()); } if (StringUtils.isNotEmpty(vo.getDestCity())) { wrapper.like(TransportRouteVi::getTransportRoute, vo.getDestCity()); } wrapper.eq(TransportRouteVi::getVehicleType, vo.getVehicleType()); wrapper.eq(TransportRouteVi::getCustomerFullName, vo.getCustomerName()); List routes = transportRouteViMapper.selectList(wrapper); Map data = new HashMap<>(); data.put("matchedRoutes", routes); data.put("routeCount", routes.size()); if (routes.isEmpty()) { warnings.add("未找到匹配的运输路线"); } result.setIsValid(routes.size() > 0); result.setErrors(errors); result.setWarnings(warnings); result.setData(data); return success(result); } /** * 创建调度单接口 (AI优化版, 需要appId/secret认证) * * @param vo AI调度单请求对象 * @param request HTTP请求 * @return 创建结果 */ @PostMapping("/createOrder") public AjaxResult createOrder(@RequestBody TmsDispatchOrder order, HttpServletRequest request) { // appId/secret 认证 if (!apiAuthUtil.validateAppAuth(request)) { return apiAuthUtil.getUnauthorizedResult(); } try { // 验证必填字段 if (order.getMainDriverId() == null || order.getLicensePlate() == null) { return error("派车信息不能为空"); } // 设置初始状态为待分配 (0) order.setStatus(0); // 保存订单 int result = tmsDispatchOrderService.insertTmsDispatchOrder2(order); if (result > 0) { // 返回新创建的订单信息 Map data = new HashMap<>(); data.put("orderNo", order.getDispatchNo()); data.put("customerName", order.getCustomerName()); data.put("originCity", order.getShipperRegionLabel()); data.put("destCity", order.getReceiverRegionLabel()); data.put("cargoName", order.getCargoName()); data.put("status", order.getStatus()); return success(data); } else { return error("创建调度单失败"); } } catch (Exception e) { logger.error("创建调度单异常: ", e); return error("创建调度单异常: " + e.getMessage()); } } /** * 获取字典数据接口 (公开接口, 无需认证) * 支持多个字典类型,用逗号分隔 * * @param dictTypes 字典类型,逗号分隔 * @return 字典数据 */ @GetMapping("/getDictData") public AjaxResult getDictData(@RequestParam(value = "dictTypes", required = false) String dictTypes) { Map> dictDataMap = new HashMap<>(); if (StringUtils.isNotEmpty(dictTypes)) { String[] types = dictTypes.split(","); for (String type : types) { String trimmedType = type.trim(); // 调用Mapper按字典类型查询字典数据 List dictDataList = sysDictDataMapper.selectDictDataByType(trimmedType); // 转换为VO列表 List voList = new ArrayList<>(); if (dictDataList != null && !dictDataList.isEmpty()) { voList = dictDataList.stream().map(dictData -> { DictDataVO vo = new DictDataVO( dictData.getDictLabel(), dictData.getDictValue(), dictData.getDictType() ); return vo; }).collect(Collectors.toList()); } dictDataMap.put(trimmedType, voList); } } return success(dictDataMap); } }