first commit

This commit is contained in:
陈现府
2025-11-20 10:45:16 +08:00
commit 8355431361
2643 changed files with 291314 additions and 0 deletions
@@ -0,0 +1,24 @@
package com.linke.transport;
import com.mhd.common.core.annotation.fieldsetvalue.CommonService;
import com.mhd.common.core.annotation.fieldsetvalue.SetFeildValueAspect;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication(scanBasePackages = {"com.mhd", "com.linke.transport"})
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.mhd","com.linke.transport.infrastructure.feign"})
@MapperScan({"com.linke.transport.domain.**.mapper","com.linke.transport.infrastructure.**.persistence"})
@Import({SetFeildValueAspect.class, CommonService.class})
@EnableAsync
public class TransportApplication {
public static void main(String[] args) {
SpringApplication.run(TransportApplication.class, args);
}
}
@@ -0,0 +1,165 @@
package com.linke.transport.application.service.common;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.linke.transport.domain.common.entity.DataPermission;
import com.linke.transport.infrastructure.feign.ProductServiceFeign;
import com.linke.transport.infrastructure.feign.SystemServiceFeign;
import com.linke.transport.infrastructure.feign.UserServiceFeign;
import com.mhd.common.core.constant.CacheConstants;
import com.mhd.common.core.domain.dto.UserDataPermissionQueryDTO;
import com.mhd.common.core.domain.po.UserConfigSwitchPo;
import com.mhd.common.core.domain.po.UserDataPermissionPO;
import com.mhd.common.core.domain.po.UserPo;
import com.mhd.common.core.enums.RoleEnum;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.redis.service.RedisService;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* 公共 应用服务层
* <p>
* 本层可以综合应用各种业务间的组合
* <p>
* 2023-01-11
*
* @author 王子豪
*/
@Service
@Slf4j
public class CommonApplicationService {
@Resource
private ProductServiceFeign productServiceFeign;
@Resource
private UserServiceFeign userServiceFeign;
@Resource
private RedisService redisService;
@Resource
private SystemServiceFeign systemServiceFeign;
/**
* 判断当前登录人的数据权限
*
*/
public DataPermission dataPermission(Long permissionMenuId) {
DataPermission dataPermission = new DataPermission();
//获取登录人信息
LoginUser loginUser = SecurityUtils.getLoginUser();
Long userId;
Long organizationId;
if(loginUser.getUserPo() != null){
userId = loginUser.getUserid();
organizationId = loginUser.getUserPo().getOrganizationId();
//判断当前用户是否是超级管理员/租户管理员还是普通用户,如果是超级管理员则返回全部组织,租户管理员则返回租户所属组织的全部组织,普通用户需要判断数据权限
if(loginUser.getUserPo().getRoleCode().contains(RoleEnum.SUPER_ADMIN.getCode())){
//全部不加限制条件
}else if(loginUser.getUserPo().getRoleCode().contains(RoleEnum.PLAT_ADMIN.getCode())) {
//获取当前组织全部下级组织id
AjaxResult ajaxResult = productServiceFeign.getOrganizationIdsByOrganizationId(organizationId);
if("200".equals(String.valueOf(ajaxResult.get("code")))){
List<Long> longs = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), Long.class);
dataPermission.setOrganizationIdList(longs);
}
}else {
List<Long> orgId = new ArrayList<>();
orgId.add(loginUser.getUserPo().getOrganizationId());
dataPermission.setOrganizationIdList(orgId);
//获取当前用户数据权限
// UserDataPermissionQueryDTO userDataPermissionQueryDTO = new UserDataPermissionQueryDTO();
// userDataPermissionQueryDTO.setMenuId(permissionMenuId);
// userDataPermissionQueryDTO.setOrganizationId(organizationId);
// userDataPermissionQueryDTO.setUserId(userId);
// AjaxResult info = userServiceFeign.findUserDataPermission(userDataPermissionQueryDTO);
// if("200".equals(String.valueOf(info.get("code")))){
// UserDataPermissionPO userDataPermissionPO = JSONObject.parseObject(JSONObject.toJSONString(info.get("data")), UserDataPermissionPO.class);
// if(userDataPermissionPO.getUserDataOrganizationStatus() != null){
// //1表示可以查询当前组织及下级组织的数据,反之只能看到自己创建的数据
// if(userDataPermissionPO.getUserDataOrganizationStatus() == 1){
// Long topOrganizationId = new Long("2");
// //获取当前组织最上级
// AjaxResult topId = productServiceFeign.selectTopId(organizationId);
// if("200".equals(String.valueOf(topId.get("code")))){
// topOrganizationId = JSONObject.parseObject(JSONObject.toJSONString(topId.get("data")), Long.class);
// }
// //获取当前组织全部下级组织id
// AjaxResult ajaxResult = productServiceFeign.getOrganizationIdsByOrganizationId(topOrganizationId);
// if("200".equals(String.valueOf(ajaxResult.get("code")))){
// List<Long> longs = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), Long.class);
// dataPermission.setOrganizationIdList(longs);
// }
// }else {
// dataPermission.setCreateBy(userId);
// }
// }else {
// dataPermission.setCreateBy(userId);
// }
// }
}
}
return dataPermission;
}
/**
* 获取用户所在组织的开关配置信息
* @return
*/
public UserConfigSwitchPo getUserConfigSwitch() {
//获取登录人信息
UserConfigSwitchPo userConfigSwitchPo;
LoginUser loginUser = SecurityUtils.getLoginUser();
UserPo userPo = loginUser.getUserPo();
Long organizationId = userPo.getOrganizationId();
userConfigSwitchPo = redisService.getCacheObject(CacheConstants.USER_COMFIG_SWITCH_KEY + organizationId);
if(null == userConfigSwitchPo || userConfigSwitchPo.getUserConfigSwitchId() == null){
//查询数据库,并且存到redis中
AjaxResult ajaxResult = systemServiceFeign.getUserConfigSwitchInfo();
if("200".equals(String.valueOf(ajaxResult.get("code")))){
userConfigSwitchPo = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserConfigSwitchPo.class);
if(null != userConfigSwitchPo){
//存入redis中
redisService.setCacheObject(CacheConstants.USER_COMFIG_SWITCH_KEY + organizationId ,userConfigSwitchPo);
}
}
}
return userConfigSwitchPo;
}
/**
* 判断当前登录人的数据权限
*
*/
public DataPermission dataBindPermission() {
DataPermission dataPermission = new DataPermission();
//获取登录人信息
LoginUser loginUser = SecurityUtils.getLoginUser();
// LoginUser loginUser = new LoginUser();
Long userId = new Long("19");
Long organizationId = new Long("2");
// if(1 == 1){
if(loginUser.getUserPo() != null){
userId = loginUser.getUserid();
organizationId = loginUser.getUserPo().getOrganizationId();
// UserPo userpo = new UserPo();
// userpo.setRoleCode("plat_admin");
// loginUser.setUserPo(userpo);
//获取当前组织全部下级组织id
AjaxResult ajaxResult = productServiceFeign.getOrganizationIdsByOrganizationId(organizationId);
if("200".equals(String.valueOf(ajaxResult.get("code")))){
List<Long> longs = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), Long.class);
dataPermission.setOrganizationIdList(longs);
}
}
return dataPermission;
}
}
@@ -0,0 +1,33 @@
package com.linke.transport.application.service.common;
import com.mhd.common.core.domain.dto.open.SystemOpenApiLogDTO;
import com.mhd.common.core.feign.ThirdPartyServiceFeign;
import com.mhd.system.api.SystemServiceFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author ZhouGY
* @title OpenApiLogApplicationService
* @description: TODO
* @date 2024/1/26 17:15
**/
@Service
public class OpenApiLogApplicationService {
@Autowired
private SystemServiceFeign systemServiceFeign;
/**
* @description 保存服务日志
* @author ZhouGY
* @date 2024/1/26 17:17
* @param systemOpenApiLogDTO
*/
public void saveLog(SystemOpenApiLogDTO systemOpenApiLogDTO) {
// 实现日志保存逻辑
systemServiceFeign.saveLog(systemOpenApiLogDTO);
}
}
@@ -0,0 +1,29 @@
package com.linke.transport.application.service.feign;
import com.linke.transport.domain.warehouse.material.exception.MaterialDomainException;
import com.linke.transport.infrastructure.feign.UserServiceFeign;
import com.mhd.common.core.domain.entity.R;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import java.util.Objects;
@Service
@Log4j2
@AllArgsConstructor
public class UserServiceFeignService {
private final UserServiceFeign userServiceFeign;
public String findUserNameByUserId(Long ownerId,String errorMessage){
R<String> result = userServiceFeign.finShipperEnterpriseNamedByUserId(ownerId);
String data = result.getData();
if (result.getCode() != 200 && Objects.isNull(data)){
log.warn("{} msg: {}",errorMessage,result.getMsg());
throw new MaterialDomainException(errorMessage + "msg: " + result.getMsg());
}
return data;
}
}
@@ -0,0 +1,266 @@
package com.linke.transport.application.service.vehicle;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.linke.transport.domain.vehicle.entity.Vehicle;
import com.linke.transport.infrastructure.feign.ProductServiceFeign;
import com.mhd.common.core.constant.SourceConstants;
import com.mhd.common.core.domain.dto.open.*;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.domain.po.SysTenantsPo;
import com.mhd.common.core.domain.po.thirdparty.SysDepartInterfaceInfoPo;
import com.mhd.common.core.domain.thirdparty.SysDepartInterfaceInfoDTO;
import com.mhd.common.core.enums.TmsServerEnum;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.feign.ThirdPartyServiceFeign;
import com.mhd.common.core.utils.StringUtils;
import com.mhd.system.api.event.listener.ThirdPartyServiceReqLogEvent;
import com.mhd.common.core.utils.AESUtil;
import com.mhd.common.core.utils.SignatureUtil;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j
@Service
public class OpenTmsVehicleApplicationService {
@Autowired
private ProductServiceFeign productServiceFeign;
@Autowired
private ThirdPartyServiceFeign thirdPartyServiceFeign;
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
/**
* 新增/修改车辆信息
* @param driverEnterpriseCode
* @param vehicle
*/
public void vehicleAuth(String driverEnterpriseCode, Vehicle vehicle) {
boolean flag = isPushTms();
if (!flag){
log.info("未开启推送TMS,不进行推送新增/修改车辆信息");
return;
}
OpenTmsVehicleDto openTmsVehicleDto = new OpenTmsVehicleDto();
openTmsVehicleDto.setDriverEnterpriseCode(driverEnterpriseCode);
openTmsVehicleDto.setVehicleApprovedLoadQuantity(vehicle.getVehicleApprovedLoadQuantity());
openTmsVehicleDto.setVehicleLicensePlateNumber(vehicle.getVehicleLicensePlateNumber());
openTmsVehicleDto.setVehicleEngineNumber(vehicle.getVehicleEngineNumber());
sendHttp(TmsServerEnum.VEHICLE_AUTH, JSONUtil.toJsonStr(openTmsVehicleDto));
}
/**
* 删除车辆
* @param driverEnterpriseCode
* @param vehicleLicensePlateNumber
*/
public void deleteVehicle(String driverEnterpriseCode, String vehicleLicensePlateNumber) {
boolean flag = isPushTms();
if (!flag){
log.info("未开启推送TMS,不进行推送删除车辆");
return;
}
OpenTmsDeleteVehicleDto openTmsDeleteVehicleDto = new OpenTmsDeleteVehicleDto();
openTmsDeleteVehicleDto.setDriverEnterpriseCode(driverEnterpriseCode);
openTmsDeleteVehicleDto.setVehicleLicensePlateNumber(vehicleLicensePlateNumber);
sendHttp(TmsServerEnum.DELETE_VEHICLE, JSONUtil.toJsonStr(openTmsDeleteVehicleDto));
}
/**
* @param params
* @description 发送tms请求
* @author ZhouGY
* @date 2024/2/3 10:36
*/
public RespParamsDTO sendHttp(TmsServerEnum tmsServerEnum, String params) {
R<SysTenantsPo> sysTenantsPoR = productServiceFeign.getTenantsInfoByOpen();
if (R.SUCCESS != sysTenantsPoR.getCode()) {
throw new ServiceException("未获取到组织配置信息");
}
SysTenantsPo sysTenantsPo = sysTenantsPoR.getData();
//从三方配置表中取值
SysDepartInterfaceInfoDTO sysDepartInterfaceInfoDTO = new SysDepartInterfaceInfoDTO();
sysDepartInterfaceInfoDTO.setTopOrganizationId(sysTenantsPo.getTopOrganizationId());
sysDepartInterfaceInfoDTO.setInterfaceType("openApi");
List<SysDepartInterfaceInfoPo> sysDepartInterfaceInfoPos = thirdPartyServiceFeign.queryListByFeign(sysDepartInterfaceInfoDTO);
Map<String, SysDepartInterfaceInfoPo> stringSysDepartInterfaceInfoPoMap = sysDepartInterfaceInfoPos.stream().collect(Collectors.toMap(SysDepartInterfaceInfoPo::getInterfaceTypeKey, Function.identity()));
ReqParamsDTO tmsReqParamsDTO = new ReqParamsDTO();
tmsReqParamsDTO.setServerName(tmsServerEnum.getServerName());
tmsReqParamsDTO.setSignType("SHA256");
tmsReqParamsDTO.setSignTimestamp(DateUtil.format(new Date(), "yyyyMMddHHmmss"));
tmsReqParamsDTO.setSignNonce(RandomUtil.randomString(8));
//从三方配置表中取值
String tmsUrl = stringSysDepartInterfaceInfoPoMap.get("tmsUrl").getInterfaceTypeValue();
//报文加密
String secret = stringSysDepartInterfaceInfoPoMap.get(SignatureUtil.SECRET_KEY).getInterfaceTypeValue();
String iv = stringSysDepartInterfaceInfoPoMap.get(SignatureUtil.IV_KEY).getInterfaceTypeValue();
log.info("加密前数据:{}", params);
String encryptContent = AESUtil.encrypt(params, secret, iv);
log.info("加密后数据:{}",encryptContent);
tmsReqParamsDTO.setEncryptContent(encryptContent);
String sign = SignatureUtil.getSign(tmsReqParamsDTO, secret);
log.info("秘钥值:{}", secret);
log.info("签名值:{}",sign);
tmsReqParamsDTO.setSignValue(sign);
String body = JSONUtil.toJsonStr(tmsReqParamsDTO);
log.info("请求参数:{}", body);
//执行异步事件 --- start ---
ThirdPartyServiceReqLogDTO thirdPartyServiceReqLogDTO = new ThirdPartyServiceReqLogDTO();
thirdPartyServiceReqLogDTO.setOrganizationId(sysTenantsPo.getOrganizationId());
thirdPartyServiceReqLogDTO.setOrganizationName(sysTenantsPo.getOrganizationName());
thirdPartyServiceReqLogDTO.setTopOrganizationId(sysTenantsPo.getTopOrganizationId());
thirdPartyServiceReqLogDTO.setInterfaceCode(tmsServerEnum.getServerName());
thirdPartyServiceReqLogDTO.setInterfaceName(tmsServerEnum.getDesc());
thirdPartyServiceReqLogDTO.setOperUrl(tmsUrl);
thirdPartyServiceReqLogDTO.setOperParam(params);
thirdPartyServiceReqLogDTO.setWaybillSource(SourceConstants.YUNLIZHONGTAI.getCode());
thirdPartyServiceReqLogDTO.setWaybillSourceName(SourceConstants.YUNLIZHONGTAI.getName());
//获取对应的关联信息
setThirdPartyServiceReqLogOrderNumber(tmsServerEnum, thirdPartyServiceReqLogDTO);
RespParamsDTO respParamsDTO = null;
try {
//发送请求
String rest = HttpRequest.post(tmsUrl).body(body).execute().body();
log.info("返回结果:{}",rest);
thirdPartyServiceReqLogDTO.setJsonResult(rest);
respParamsDTO = JSONUtil.toBean(rest, RespParamsDTO.class);
} catch (Exception e){
if (StringUtils.isBlank(thirdPartyServiceReqLogDTO.getJsonResult())){
thirdPartyServiceReqLogDTO.setJsonResult("请求发送异常");
}
log.error("同步" + tmsServerEnum.getDesc() + "失败",e);
} finally {
if (respParamsDTO != null && respParamsDTO.getCode() == 200){
thirdPartyServiceReqLogDTO.setStatus(2);
}else {
thirdPartyServiceReqLogDTO.setStatus(1);
}
//执行异步事件
pushLogsEvent(thirdPartyServiceReqLogDTO);
}
//执行异步事件 --- end ---
if (respParamsDTO == null){
throw new ServiceException("同步" + tmsServerEnum.getDesc() + "失败");
}
if (respParamsDTO.getCode() != 200){
throw new ServiceException(respParamsDTO.getMsg());
}
return respParamsDTO;
}
/**
* @description 执行异步事件
* @author ZhouGY
* @date 2024/2/16 15:41
* @param thirdPartyServiceReqLogDTO
*/
private void pushLogsEvent(ThirdPartyServiceReqLogDTO thirdPartyServiceReqLogDTO ){
//执行异步事件
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null){
thirdPartyServiceReqLogDTO.setCreateBy(loginUser.getUserid());
thirdPartyServiceReqLogDTO.setCreateByName(loginUser.getUsername());
}
thirdPartyServiceReqLogDTO.setCreateTime(new Date());
ThirdPartyServiceReqLogEvent thirdPartyServiceReqLogEvent = new ThirdPartyServiceReqLogEvent(thirdPartyServiceReqLogDTO);
thirdPartyServiceReqLogEvent.setThirdPartyServiceReqLogDTO(thirdPartyServiceReqLogDTO);
applicationEventPublisher.publishEvent(thirdPartyServiceReqLogEvent);
}
/**
* @return boolean
* @description 判断是否开启tms开关
* @author ZhouGY
* @date 2024/2/16 16:22
*/
private boolean isPushTms() {
R<SysTenantsPo> sysTenantsPoR = productServiceFeign.getTenantsInfoByOpen();
if (R.SUCCESS != sysTenantsPoR.getCode()) {
throw new ServiceException("未获取到组织配置信息");
}
SysTenantsPo sysTenantsPo = sysTenantsPoR.getData();
SysDepartInterfaceInfoDTO sysDepartInterfaceInfoDTO = new SysDepartInterfaceInfoDTO();
sysDepartInterfaceInfoDTO.setTopOrganizationId(sysTenantsPo.getTopOrganizationId());
sysDepartInterfaceInfoDTO.setInterfaceType("switchConfig");
List<SysDepartInterfaceInfoPo> sysDepartInterfaceInfoPos = thirdPartyServiceFeign.queryListByFeign(sysDepartInterfaceInfoDTO);
Map<String, SysDepartInterfaceInfoPo> sysDepartInterfaceInfoPoMap = sysDepartInterfaceInfoPos.stream().collect(Collectors.toMap(SysDepartInterfaceInfoPo::getInterfaceTypeKey, Function.identity()));
SysDepartInterfaceInfoPo sysDepartInterfaceInfoPo = sysDepartInterfaceInfoPoMap.get("isPushTms");
//是否开启推送
if ("1".equals(sysDepartInterfaceInfoPo.getInterfaceTypeValue())) {
return true;
}
return false;
}
/**
* @description 获取日志关联标致
* @author ZhouGY
* @date 2024/2/22 16:48
* @param tmsServerEnum
* @param thirdPartyServiceReqLogDTO
*/
private void setThirdPartyServiceReqLogOrderNumber(TmsServerEnum tmsServerEnum, ThirdPartyServiceReqLogDTO thirdPartyServiceReqLogDTO){
JSONObject jsonObject = JSONUtil.parseObj(thirdPartyServiceReqLogDTO.getOperParam());
switch (tmsServerEnum){
case USER_DRIVER_AUTH:
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("userIdcardNumber"));
break;
case VEHICLE_AUTH:
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("vehicleLicensePlateNumber"));
break;
case USER_ENTERPRISE_AUTH:
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("driverEnterpriseCode"));
break;
case DELETE_USER:
if (StringUtils.isNotBlank(jsonObject.getStr("driverEnterpriseCode")) && StringUtils.isNotBlank(jsonObject.getStr("driveCode"))){
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("driveCode"));
}else if (StringUtils.isNotBlank(jsonObject.getStr("driverEnterpriseCode")) && StringUtils.isBlank(jsonObject.getStr("driveCode"))){
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("driverEnterpriseCode"));
} else {
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("driveCode"));
}
break;
case DELETE_VEHICLE:
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("vehicleLicensePlateNumber"));
break;
case DRIVER_ROB_SINGLE:
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("workCode"));
break;
case STATUS_FEEDBACK_FILL:
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("schedulingBillCode"));
break;
case STATUS_FEEDBACK_SIGN:
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("schedulingBillCode"));
break;
case RECEIPT_SIGN:
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("orderNumber"));
break;
case CANCEL_SIGN:
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("orderNumber"));
break;
case FREIGHT_PAYMENT:
thirdPartyServiceReqLogDTO.setOrderNumber(jsonObject.getStr("schedulingBillCode"));
break;
}
}
}
@@ -0,0 +1,138 @@
package com.linke.transport.application.service.vehicle;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONObject;
import com.linke.transport.domain.vehicle.entity.Vehicle;
import com.linke.transport.domain.vehicle.service.VehicleDomainService;
import com.linke.transport.domain.vehicle.service.VehicleWlhyDomainService;
import com.linke.transport.infrastructure.feign.ProductServiceFeign;
import com.linke.transport.infrastructure.feign.UserServiceFeign;
import com.mhd.common.core.domain.dto.open.OpenVehicleDto;
import com.mhd.common.core.domain.entity.DriverVehicleBind;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.domain.po.SysTenantsPo;
import com.mhd.common.core.domain.po.UserDriverEnterprisePo;
import com.mhd.common.core.domain.po.UserDriverPo;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.utils.IgnoreNullUtil;
import com.mhd.common.core.utils.bean.BeanUtils;
import com.mhd.common.core.web.domain.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
/**
* 对外开放接口Service - 车辆
*/
@Slf4j
@Service
public class OpenVehicleApplicationService {
@Autowired
private VehicleDomainService vehicleDomainService;
@Resource
private VehicleWlhyDomainService vehicleWlhyDomainService;
@Resource
private ProductServiceFeign productServiceFeign;
@Autowired
private UserServiceFeign userServiceFeign;
/**
* 新增/修改车辆
*/
@Transactional(rollbackFor = Exception.class)
public void vehicleAuth(OpenVehicleDto openVehicleDto) {
//获取配置的组织ID
R<SysTenantsPo> sysTenantsPoR = productServiceFeign.getTenantsInfoByOpen();
if (R.SUCCESS != sysTenantsPoR.getCode()) {
throw new ServiceException("未获取到组织配置信息");
}
SysTenantsPo sysTenantsPo = sysTenantsPoR.getData();
BeanUtils.copyProperties(sysTenantsPo,openVehicleDto, IgnoreNullUtil.getNullPropertyNames(sysTenantsPo));
//判断承运商是否存在
AjaxResult<?> enterprise = userServiceFeign.getInfoByEnterpriseCode(openVehicleDto.getDriverEnterpriseCode());
if(!"200".equals(String.valueOf(enterprise.get("code")))) {
throw new ServiceException("未找到承运商信息");
}
UserDriverEnterprisePo userDriverEnterprisePo = JSONUtil.toBean(JSONUtil.toJsonStr(enterprise.get("data")), UserDriverEnterprisePo.class);
//根据车牌号是否存在判断操作类型
String plateNumber = openVehicleDto.getVehicleLicensePlateNumber(); //车牌号
Vehicle vehicle = vehicleDomainService.selectVehicleByPlateNumber(plateNumber);
if (ObjectUtil.isNull(vehicle)) {
//新增
Vehicle saveVehicle = new Vehicle();
BeanUtils.copyProperties(openVehicleDto, saveVehicle);
saveVehicle.setUserId(userDriverEnterprisePo.getUserId());
saveVehicle.setUserName(userDriverEnterprisePo.getDriverEnterpriseName());
saveVehicle.setUserPhone(userDriverEnterprisePo.getDriverEnterprisePhone());
boolean b = vehicleDomainService.saveVehicle(saveVehicle);
if (!b) {
throw new ServiceException("车辆数据落库失败");
}
} else {
//修改
Vehicle updateVehicle = new Vehicle();
BeanUtils.copyProperties(openVehicleDto, updateVehicle);
updateVehicle.setVehicleId(vehicle.getVehicleId());
updateVehicle.setUserId(userDriverEnterprisePo.getUserId());
updateVehicle.setUserName(userDriverEnterprisePo.getDriverEnterpriseName());
updateVehicle.setUserPhone(userDriverEnterprisePo.getDriverEnterprisePhone());
boolean b = vehicleDomainService.updateById(updateVehicle);
if (!b) {
throw new ServiceException("车辆数据修改失败");
}
}
//开始同步网货车辆信息
vehicleWlhyDomainService.openSynchronizeVehicle(openVehicleDto);
}
/**
* 删除车辆
*/
@Transactional(rollbackFor = Exception.class)
public void deleteVehicle(OpenVehicleDto openVehicleDto) {
String plateNumber = openVehicleDto.getVehicleLicensePlateNumber();
String driverEnterpriseCode = openVehicleDto.getDriverEnterpriseCode();
//判断承运商是否存在
AjaxResult<?> enterprise = userServiceFeign.getInfoByEnterpriseCode(openVehicleDto.getDriverEnterpriseCode());
if (!"200".equals(String.valueOf(enterprise.get("code")))) {
throw new ServiceException("未找到承运商信息");
}
//判断数据是否存在
Vehicle vehicle = vehicleDomainService.getInfoByOpen(plateNumber, driverEnterpriseCode);
if (ObjectUtil.isNull(vehicle)) {
throw new ServiceException("未找到车辆信息");
}
//判断车辆是否绑定
AjaxResult<?> bindList = userServiceFeign.getBindListByVid(vehicle.getVehicleId());
if ("200".equals(String.valueOf(bindList.get("code")))) {
List<DriverVehicleBind> data = JSONUtil.toList(JSONUtil.toJsonStr(bindList.get("data")), DriverVehicleBind.class);
if (CollUtil.isNotEmpty(data)) {
throw new ServiceException("车辆已绑定司机,无法删除");
}
}
Boolean b = vehicleDomainService.deleteVehicleByVehicleId(vehicle.getVehicleId());
if (!b) {
throw new ServiceException("车辆数据删除失败");
}
//删除网货车辆信息
vehicleWlhyDomainService.openDelVehicle(openVehicleDto);
}
}
@@ -0,0 +1,67 @@
package com.linke.transport.application.service.warehouse;
import com.linke.transport.application.service.warehouse.inBoundOrder.InboundOrderService;
import com.linke.transport.application.service.warehouse.inventory.InventoryService;
import com.linke.transport.application.service.warehouse.inventoryLedger.InventoryLedgerService;
import com.linke.transport.application.service.warehouse.material.command.MaterialCommandService;
import com.linke.transport.application.service.warehouse.outBoundOrder.OutboundOrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Log4j2
@Service
@RequiredArgsConstructor
public class WarehouseApplicationService {
private final MaterialCommandService materialCommandService;
private final InboundOrderService inboundOrderService;
private final InventoryService inventoryService;
private final OutboundOrderService outboundOrderService;
private final InventoryLedgerService inventoryLedgerService;
@Async
@Transactional
public void processShipperNameUpdate(Long ownerId, String ownerName) {
log.info("开始更新货主名称,ownerId: {}, 新名称: {}", ownerId, ownerName);
int totalUpdated = 0;
// 更新物料信息
int materialUpdated = materialCommandService.updateOwnerNameByOwnerId(ownerId, ownerName);
log.info("物料信息更新完成,更新记录数: {}", materialUpdated);
totalUpdated += materialUpdated;
// 更新入库单信息
int inboundUpdated = inboundOrderService.updateOwnerNameByOwnerId(ownerId, ownerName);
log.info("入库单信息更新完成,更新记录数: {}", inboundUpdated);
totalUpdated += inboundUpdated;
// 更新出库单信息
int outboundUpdated = outboundOrderService.updateOwnerNameByOwnerId(ownerId, ownerName);
log.info("出库单信息更新完成,更新记录数: {}", outboundUpdated);
totalUpdated += outboundUpdated;
// 更新库存信息
int inventoryUpdated = inventoryService.updateOwnerNameByOwnerId(ownerId, ownerName);
log.info("库存信息更新完成,更新记录数: {}", inventoryUpdated);
totalUpdated += inventoryUpdated;
// 更新库存流水信息
int ledgerUpdated = inventoryLedgerService.updateOwnerNameByOwnerId(ownerId, ownerName);
log.info("库存流水信息更新完成,更新记录数: {}", ledgerUpdated);
totalUpdated += ledgerUpdated;
log.info("货主名称更新完成,总计更新记录数: {}", totalUpdated);
}
}
@@ -0,0 +1,437 @@
package com.linke.transport.application.service.warehouse.inBoundOrder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linke.transport.application.service.feign.UserServiceFeignService;
import com.linke.transport.application.service.warehouse.inBoundOrder.vo.InboundOrderVO;
import com.linke.transport.application.service.warehouse.inBoundOrder.vo.InboundOrderVO.Detail;
import com.linke.transport.domain.warehouse.inboundOrder.event.pojo.InboundCompletedEvent;
import com.linke.transport.domain.warehouse.inboundOrder.model.InboundOrder;
import com.linke.transport.domain.warehouse.inboundOrder.model.InboundOrderDetail;
import com.linke.transport.domain.warehouse.inventory.model.Inventory;
import com.linke.transport.domain.warehouse.material.model.Material;
import com.linke.transport.domain.warehouse.material.repository.MaterialRepository;
import com.linke.transport.infrastructure.warehouse.inboundOrder.persistence.InboundOrderDetailMapper;
import com.linke.transport.infrastructure.warehouse.inboundOrder.persistence.InboundOrderMapper;
import com.linke.transport.infrastructure.warehouse.inventory.persistence.InventoryMapper;
import com.linke.transport.interfaces.dto.warehouse.inBoundOrder.InboundOrderDTO;
import com.linke.transport.interfaces.dto.warehouse.inBoundOrder.InboundOrderDTO.Create;
import com.mhd.common.core.utils.OrderSequence;
import com.mhd.common.security.utils.SecurityUtils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
* <p>
* 入库单 服务实现类
* </p>
*
* @author YourName
* @since YYYY-MM-DD
*/
@Slf4j
@Service
@RequiredArgsConstructor // 使用 Lombok 自动注入 final 字段
public class InboundOrderService extends ServiceImpl<InboundOrderMapper, InboundOrder> {
private final InventoryMapper inventoryMapper;
private final InboundOrderDetailMapper inboundOrderDetailMapper;
private final MaterialRepository materialRepository; // 注入物料仓库
private final ApplicationEventPublisher eventPublisher; // 用于发布事件
private final InboundOrderMapper inboundOrderMapper;
private final UserServiceFeignService userServiceFeignService;
/**
* 创建入库单
*
* @param createDTO 创建请求体
* @return 创建成功后的入库单详情
*/
@Transactional // 开启事务
public Long createInboundOrder(Create createDTO) {
String ownerName = userServiceFeignService.findUserNameByUserId(createDTO.getOwnerId(),"创建入库单-调用用户中心findUserNameByUserId错误");
log.info("开始创建入库单,货主: {}", ownerName);
// 1. 创建入库单主表信息
InboundOrder inboundOrder = new InboundOrder();
BeanUtils.copyProperties(createDTO, inboundOrder);
inboundOrder.setInboundOrderNo(OrderSequence.getOrderCode("RK")); // 生成入库单号
inboundOrder.setCreatedBy(SecurityUtils.getUsername());
inboundOrder.setOwnerName(ownerName);
// 保存主表
this.save(inboundOrder); // 使用了 Mybatis-Plus 的 ServiceImpl 方法
log.info("入库单主表保存成功, ID: {}, 单号: {}", inboundOrder.getId(),
inboundOrder.getInboundOrderNo());
// 2. 处理入库单明细
List<InboundOrderDetail> savedDetails = new ArrayList<>();
for (InboundOrderDTO.Detail detailDTO : createDTO.getDetails()) {
// 2.1 校验物料是否存在
Optional<Material> materialOpt = materialRepository.findById(detailDTO.getMaterialId());
if (!materialOpt.isPresent()) {
log.error("物料校验失败: 物料ID {} 不存在", detailDTO.getMaterialId());
throw new IllegalArgumentException(
"物料ID " + detailDTO.getMaterialId() + " 不存在");
}
Material material = materialOpt.get();
// 2.2 校验整机编号管理
if (material.isCodeManaged()) { // 如果物料需要编号管理
if (!StringUtils.hasText(detailDTO.getMachineSerialNo())) {
log.error("物料校验失败: 物料 '{}' 需要整机编号,但未提供", material.getName());
throw new IllegalArgumentException(
"物料 '" + material.getName() + "' 需要整机编号");
}
// 校验数量必须为 1
if (detailDTO.getQuantity().compareTo(BigDecimal.ONE) != 0) {
log.error("物料校验失败: 编号管理的物料 '{}' 数量必须为 1, 实际为 {}",
material.getName(),
detailDTO.getQuantity());
throw new IllegalArgumentException(
"编号管理的物料 '" + material.getName() + "' 数量必须为 1");
}
// 检查当前入库单内整机编号是否在库存中存在
boolean existsInStock = checkSerialNumberExistsInStock(createDTO.getOwnerId(),
detailDTO.getMaterialId(), detailDTO.getMachineSerialNo());
if (existsInStock) {
throw new IllegalArgumentException(
"当前货主ID " + createDTO.getOwnerId() + "货主名称:" + ownerName + " (" + ownerName
+ ") 的整机编号为"
+ detailDTO.getMachineSerialNo() + "的货物已在库存中");
}
} else { // 如果物料不需要编号管理
if (StringUtils.hasText(detailDTO.getMachineSerialNo())) {
log.warn("物料 '{}' 不需要编号管理,但提供了整机编号 '{}',将忽略",
material.getName(),
detailDTO.getMachineSerialNo());
detailDTO.setMachineSerialNo(null); // 清空编号
}
if (detailDTO.getQuantity().compareTo(BigDecimal.ZERO) <= 0) {
log.error("物料校验失败: 物料 '{}' 数量必须大于 0, 实际为 {}",
material.getName(),
detailDTO.getQuantity());
throw new IllegalArgumentException(
"物料 '" + material.getName() + "' 数量必须大于 0");
}
}
// 2.3 创建并保存入库单明细
InboundOrderDetail detail = new InboundOrderDetail();
detail.setInboundOrderId(inboundOrder.getId());
detail.setMaterialId(detailDTO.getMaterialId());
detail.setQuantity(detailDTO.getQuantity());
detail.setMachineSerialNo(detailDTO.getMachineSerialNo());
detail.setCreatedBy(SecurityUtils.getUsername());
// 持久化入库明细单
inboundOrderDetailMapper.insert(detail);
savedDetails.add(detail);
}
log.info("入库单明细保存完成,共 {} 条", savedDetails.size());
// 3. 发布入库完成事件 (解耦库存和流水操作)
try {
eventPublisher.publishEvent(new InboundCompletedEvent(createDTO.getTmsOrderNo(),inboundOrder, savedDetails));
log.info("入库完成事件已发布, 入库单号: {}", inboundOrder.getInboundOrderNo());
} catch (Exception e) {
// 如果事件发布失败,或者下游监听器处理失败(且监听器抛出异常),事务会回滚
log.error("发布入库完成事件失败或事件处理失败, 入库单号: {}, 错误: {}",
inboundOrder.getInboundOrderNo(), e.getMessage(), e);
// 根据业务决定是否需要特定处理,但通常事务回滚是期望行为
throw e; // 重新抛出异常以确保事务回滚
}
// 5. 组装并返回结果
return inboundOrder.getId();
}
/**
* 根据入库单ID获取入库单详情信息
*
* @param id 入库单ID
* @return 入库单详情列表,包含物料信息
* @throws NoSuchElementException 如果入库单ID不存在
*/
public List<InboundOrderVO.Detail> getDetailsByInBoundOrderId(Long id) {
// 1. 查询主表
InboundOrder inboundOrder = this.getById(id);
if (Objects.isNull(inboundOrder)) {
log.warn("查询入库单详情失败: ID {} 不存在", id);
throw new NoSuchElementException("入库单ID " + id + " 不存在");
}
// 2. 查询明细表
List<InboundOrderDetail> details = inboundOrderDetailMapper.selectList(
new LambdaQueryWrapper<InboundOrderDetail>()
.eq(InboundOrderDetail::getInboundOrderId, id));
// 3. 查询关联的物料信息
List<Long> materialIds = details.stream()
.map(InboundOrderDetail::getMaterialId)
.distinct()
.collect(Collectors.toList());
Map<Long, Material> materialMap = new HashMap<>();
if (!CollectionUtils.isEmpty(materialIds)) {
Optional<List<Material>> materials = materialRepository.findByIdIn(materialIds);
materials.ifPresent(list -> materialMap.putAll(list.stream()
.collect(Collectors.toMap(Material::getId, Function.identity()))));
}
// 复制明细基础信息
return details
.stream()
.map(convertResult(materialMap))
.collect(Collectors.toList());
}
private static Function<InboundOrderDetail, Detail> convertResult(
Map<Long, Material> materialMap) {
return detail -> {
Detail detailVO = new Detail();
BeanUtils.copyProperties(detail, detailVO); // 复制明细基础信息
Material material = materialMap.get(detail.getMaterialId());
if (material != null) {
detailVO.setMaterialName(material.getName());
detailVO.setMaterialCategory(material.getCategory());
detailVO.setSerialNoManaged(material.isCodeManaged());
detailVO.setUnit(material.getUnit());
} else {
// 处理物料未找到的情况
detailVO.setMaterialName("物料已删除或不存在");
log.info("入库单明细 {} 关联的物料ID {} 未找到", detail.getId(),
detail.getMaterialId()); // 修改为 info 级别
}
return detailVO;
};
}
/**
* 更新入库单信息 (仅货主和备注)
*
* @param updateDTO 更新请求体
* @return 更新后的入库单id
*/
@Transactional
public Long updateInboundOrderInfo(InboundOrderDTO.Update updateDTO) {
log.info("开始更新入库单信息, ID: {}", updateDTO.getId());
// 1. 查找入库单
InboundOrder existingOrder = this.getById(updateDTO.getId());
if (existingOrder == null) {
log.error("更新失败: 入库单ID {} 不存在", updateDTO.getId());
throw new NoSuchElementException("入库单ID " + updateDTO.getId() + " 不存在");
}
// 2. 更新允许修改的字段
existingOrder.setOwnerId(updateDTO.getOwnerId());
existingOrder.setOwnerName(updateDTO.getOwnerName());
existingOrder.setRemarks(updateDTO.getRemarks());
// updatedBy, updatedAt 将由 MetaObjectHandler 自动填充
// 3. 保存更新
this.updateById(existingOrder);
log.info("入库单信息更新成功, ID: {}", existingOrder.getId());
// 4. 返回更新后的完整信息
return existingOrder.getId();
}
/**
* 分页查询入库单子
*
* @param queryDTO 查询条件
* @return 分页查询结果
*/
public IPage<InboundOrderVO.ListSummary> listInboundOrders(InboundOrderDTO.Query queryDTO) {
// 1. 构建分页对象
Page<InboundOrder> page = new Page<>(queryDTO.getPageNo(), queryDTO.getPageSize());
// 2. 构建查询条件(函数式封装)
LambdaQueryWrapper<InboundOrder> wrapper = buildQueryWrapper(queryDTO);
// 3. 执行分页查询 (主表)
IPage<InboundOrder> resultPage = this.page(page, wrapper);
// 4. 处理查询结果(链式调用 + 函数式组合)
List<InboundOrderVO.ListSummary> summaryList = Optional.ofNullable(resultPage.getRecords())
.filter(records -> !records.isEmpty())
.map(this::processRecords)
.orElse(Collections.emptyList());
// 5. 构建并返回分页 VO(函数式创建)
return createSummaryPage(resultPage, summaryList);
}
// ---------------- 私有辅助方法(函数式分解)----------------
/**
* 构建查询条件(函数式封装)
*/
private LambdaQueryWrapper<InboundOrder> buildQueryWrapper(InboundOrderDTO.Query queryDTO) {
return new LambdaQueryWrapper<InboundOrder>()
.like(StringUtils.hasText(queryDTO.getInboundOrderNo()),
InboundOrder::getInboundOrderNo, queryDTO.getInboundOrderNo())
.eq(Objects.nonNull(queryDTO.getOwnerId()),
InboundOrder::getOwnerId, queryDTO.getOwnerId())
.like(StringUtils.hasText(queryDTO.getOwnerName()),
InboundOrder::getOwnerName, queryDTO.getOwnerName())
.like(StringUtils.hasText(queryDTO.getRemarks()),
InboundOrder::getRemarks, queryDTO.getRemarks())
.ge(Objects.nonNull(queryDTO.getInboundTimeStart()),
InboundOrder::getInboundTime,queryDTO.getInboundTimeStart())
.lt(Objects.nonNull(queryDTO.getInboundTimeEnd()),
InboundOrder::getInboundTime,queryDTO.getInboundTimeEnd())
.orderByDesc(InboundOrder::getInboundTime);
}
/**
* 处理主表记录(函数式流水线)
*/
private List<InboundOrderVO.ListSummary> processRecords(List<InboundOrder> records) {
// 提取订单ID集合
List<Long> orderIds = records.stream()
.map(InboundOrder::getId)
.collect(Collectors.toList());
// 并行获取明细数据
Map<Long, List<InboundOrderDetail>> detailsMap = getDetailsMap(orderIds);
// 并行获取物料数据
Map<Long, Material> materialMap = getMaterialMap(detailsMap.values().stream()
.flatMap(List::stream)
.map(InboundOrderDetail::getMaterialId)
.distinct()
.collect(Collectors.toList()));
// 流水线式组装VO
return records
.stream()
.map(order -> createSummary(
order,
detailsMap.getOrDefault(order.getId(), Collections.emptyList()),
materialMap))
.collect(Collectors.toList());
}
/**
* 获取明细分组(函数式封装)
*/
private Map<Long, List<InboundOrderDetail>> getDetailsMap(List<Long> orderIds) {
return Optional.ofNullable(inboundOrderDetailMapper.selectList(
new LambdaQueryWrapper<InboundOrderDetail>()
.in(InboundOrderDetail::getInboundOrderId, orderIds)))
.orElse(Collections.emptyList())
.stream()
.collect(Collectors.groupingBy(InboundOrderDetail::getInboundOrderId));
}
/**
* 获取物料映射(函数式封装)
*/
private Map<Long, Material> getMaterialMap(List<Long> materialIds) {
return materialRepository.findByIdIn(materialIds)
.map(list -> list.stream()
.collect(Collectors.toMap(Material::getId, Function.identity())))
.orElseGet(HashMap::new);
}
/**
* 创建单个Summary(纯函数)
*/
private InboundOrderVO.ListSummary createSummary(
InboundOrder order,
List<InboundOrderDetail> details,
Map<Long, Material> materialMap) {
InboundOrderVO.ListSummary summary = new InboundOrderVO.ListSummary();
BeanUtils.copyProperties(order, summary);
// 计算总数量(函数式折叠)
BigDecimal totalQuantity = details.stream()
.map(detail -> Optional.ofNullable(detail.getQuantity()).orElse(BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
summary.setTotalQuantity(totalQuantity);
// 生成物料概要(函数式拼接)
String materialSummary = details.stream()
.map(detail -> formatMaterialDetail(detail, materialMap))
.collect(Collectors.joining(", "));
summary.setMaterialSummary(materialSummary);
return summary;
}
/**
* 格式化单个物料详情(纯函数)
*/
private String formatMaterialDetail(InboundOrderDetail detail, Map<Long, Material> materialMap) {
String materialName = Optional.ofNullable(materialMap.get(detail.getMaterialId()))
.map(Material::getName)
.orElse("未知物料");
return materialName + "*" + Optional.ofNullable(detail.getQuantity())
.map(q -> q.stripTrailingZeros().toPlainString())
.orElse("0");
}
/**
* 构建分页响应(函数式封装)
*/
private IPage<InboundOrderVO.ListSummary> createSummaryPage(IPage<InboundOrder> resultPage,
List<InboundOrderVO.ListSummary> summaryList) {
return new Page<InboundOrderVO.ListSummary>(resultPage.getCurrent(), resultPage.getSize(),
resultPage.getTotal())
.setPages(resultPage.getPages())
.setRecords(summaryList);
}
private boolean checkSerialNumberExistsInStock(Long ownerId, Long materialId,
String machineSerialNo) {
LambdaQueryWrapper<Inventory> wrapper = Wrappers.<Inventory>lambdaQuery()
.eq(Inventory::getOwnerId, ownerId)
.eq(Inventory::getMaterialId, materialId)
.eq(Inventory::getMachineSerialNo, machineSerialNo);
Inventory inventory = inventoryMapper.selectOne(wrapper);
return Objects.nonNull(inventory);
}
/**
* 根据货主ID更新货主名称
* @param ownerId 货主ID
* @param ownerName 新的货主名称
* @return 更新记录数
*/
@Transactional
public int updateOwnerNameByOwnerId(Long ownerId, String ownerName) {
LambdaUpdateWrapper<InboundOrder> wrapper = Wrappers.<InboundOrder>lambdaUpdate()
.eq(InboundOrder::getOwnerId, ownerId)
.set(InboundOrder::getOwnerName, ownerName);
return inboundOrderMapper.update(null,wrapper);
}
}
@@ -0,0 +1,105 @@
package com.linke.transport.application.service.warehouse.inBoundOrder.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
public class InboundOrderVO {
@Data
@ApiModel(value = "InboundOrderListVO", description = "入库单列表展示项")
public static class ListSummary {
@ApiModelProperty(value = "入库单ID", example = "1")
private Long id;
@ApiModelProperty(value = "入库时间", example = "2025-01-01 01:01:00")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") // 控制日期格式
private Date inboundTime;
@ApiModelProperty(value = "入库单号", example = "RK2501010001")
private String inboundOrderNo;
@ApiModelProperty(value = "货主用户Id")
private Long ownerId;
@ApiModelProperty(value = "货主", example = "临工")
private String ownerName;
@ApiModelProperty(value = "入库总数量", example = "30")
private BigDecimal totalQuantity; // 需要Service计算
@ApiModelProperty(value = "入库物料概要", example = "装载机L916H*10, 资料*10")
private String materialSummary; // 需要Service拼接
@ApiModelProperty(value = "创建人", example = "王经理")
private String createdBy;
@ApiModelProperty(value = "备注", example = "首批到货")
private String remarks;
}
@Data
@ApiModel(value = "InboundOrderDetailVO", description = "入库单明细视图对象")
public static class Detail {
@ApiModelProperty(value = "入库明细ID", example = "10")
private Long id; // 明细ID
@ApiModelProperty(value = "物料ID", example = "101")
private Long materialId;
@ApiModelProperty(value = "物料名称", example = "装载机L916H")
private String materialName; // 来自物料表
@ApiModelProperty(value = "物料分类", example = "整机")
private String materialCategory; // 来自物料表
@ApiModelProperty(value = "是否按编号管理", example = "true")
private Boolean serialNoManaged; // 来自物料表
@ApiModelProperty(value = "入库数量", example = "10")
private BigDecimal quantity;
@ApiModelProperty(value = "物料单位", example = "")
private String unit; // 来自物料表
@ApiModelProperty(value = "整机编号", example = "ZJ0000000001")
private String machineSerialNo;
}
@Data
@ApiModel(value = "InboundOrderFullVO", description = "入库单完整详情视图对象")
public static class FullDetail {
@ApiModelProperty(value = "入库单ID", example = "1")
private Long id;
@ApiModelProperty(value = "入库单号", example = "RK2501010001")
private String inboundOrderNo;
@ApiModelProperty(value = "货主名称", example = "山东临工")
private String ownerName;
@ApiModelProperty(value = "入库时间", example = "2025-01-01 01:01:00")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date inboundTime;
@ApiModelProperty(value = "备注", example = "首批入库")
private String remarks;
@ApiModelProperty(value = "创建人", example = "王经理")
private String createdBy;
@ApiModelProperty(value = "创建时间", example = "2025-01-01 01:01:00")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdAt;
@ApiModelProperty(value = "入库物料明细列表")
private List<Detail> details;
}
}
@@ -0,0 +1,175 @@
package com.linke.transport.application.service.warehouse.inventory;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linke.transport.application.service.warehouse.inventory.vo.InventoryVO;
import com.linke.transport.domain.warehouse.inboundOrder.model.InboundOrder;
import com.linke.transport.domain.warehouse.inventory.event.pojo.InventoryAdjustedEvent;
import com.linke.transport.domain.warehouse.inventory.model.Inventory;
import com.linke.transport.domain.warehouse.material.model.Material;
import com.linke.transport.domain.warehouse.material.repository.MaterialRepository;
import com.linke.transport.infrastructure.warehouse.inventory.persistence.InventoryMapper;
import com.linke.transport.interfaces.dto.warehouse.inventory.InventoryDTO;
import com.mhd.common.security.utils.SecurityUtils;
import java.math.BigDecimal;
import java.util.List;
import java.util.NoSuchElementException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* 库存信息表 服务实现类
* </p>
*
* @author YourName
* @since YYYY-MM-DD
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class InventoryService extends ServiceImpl<InventoryMapper, Inventory> {
private final InventoryMapper inventoryMapper;
private final MaterialRepository materialRepository;
private final ApplicationEventPublisher eventPublisher;
/**
* 分页查询库存列表
*
* @param queryDTO 查询条件及分页参数
* @return 分页结果
*/
public Page<InventoryVO> listInventory(InventoryDTO.Query queryDTO) {
// 1. 创建分页请求对象 (注意泛型是 VO)
Page<InventoryVO> page = new Page<>(queryDTO.getPageNo(), queryDTO.getPageSize());
// 2. 调用 Mapper 的自定义分页查询方法 (该方法执行 JOIN)
return inventoryMapper.findInventoryList(page, queryDTO);
}
public List<InventoryVO> listAllInventory(Long ownerId,String machineSerialNo) {
return inventoryMapper.findAllInventoryList(ownerId,machineSerialNo);
}
/**
* 调整库存数量
*
* @param adjustDTO 调整请求体
*/
@Transactional // 开启事务
public void adjustInventory(InventoryDTO.Adjust adjustDTO) {
log.info("开始调整库存, 库存ID: {}, 方向: {}, 数量: {}",
adjustDTO.getInventoryId(), adjustDTO.getDirection(), adjustDTO.getQuantity());
// 1.获取方向参数
boolean isIncrease = "INCREASE".equalsIgnoreCase(adjustDTO.getDirection());
boolean isDecrease = "DECREASE".equalsIgnoreCase(adjustDTO.getDirection());
// 2. 获取库存记录
Inventory inventory = inventoryMapper.selectById(adjustDTO.getInventoryId());
if (inventory == null) { // 检查是否被逻辑删除
log.error("库存调整失败: 库存记录ID {} 不存在或已被删除", adjustDTO.getInventoryId());
throw new NoSuchElementException("库存记录ID " + adjustDTO.getInventoryId() + " 不存在");
}
// 3. 获取物料信息并校验是否允许调整
Material material = materialRepository.findById(inventory.getMaterialId())
.orElseThrow(() -> {
log.error("库存调整失败: 关联的物料ID {} 不存在", inventory.getMaterialId());
return new IllegalStateException("库存记录关联的物料不存在");
});
if (material.isCodeManaged()) {
log.error("库存调整失败: 物料 '{}' (ID:{}) 是编号管理物料,不允许直接调整库存",
material.getName(), material.getId());
throw new IllegalArgumentException("编号管理的物料不允许直接调整库存,请通过出库操作");
}
// 4. 执行库存更新 (原子操作)
BigDecimal quantityBeforeChange = inventory.getQuantity();
BigDecimal changeQuantity = adjustDTO.getQuantity();
BigDecimal quantityAfterChange;
int updatedRows;
String operator = SecurityUtils.getUsername(); // 示例,应从安全上下文获取
if (isIncrease) {
quantityAfterChange = quantityBeforeChange.add(changeQuantity);
updatedRows = inventoryMapper.increaseQuantity(inventory.getId(), changeQuantity, operator);
} else { // isDecrease
quantityAfterChange = quantityBeforeChange.subtract(changeQuantity);
if (quantityAfterChange.compareTo(BigDecimal.ZERO) < 0) {
log.error("库存调整失败: 库存不足。库存ID: {}, 当前数量: {}, 尝试扣减: {}",
inventory.getId(), quantityBeforeChange, changeQuantity);
throw new IllegalArgumentException("库存不足,无法完成扣减操作");
}
// 使用原子扣减方法
updatedRows = inventoryMapper.decreaseQuantity(inventory.getId(), changeQuantity, operator);
}
// 5. 检查更新结果
if (updatedRows <= 0) {
// 可能原因:并发修改导致记录版本变化(乐观锁),或扣减时库存不足(decreaseQuantity 的 where 条件)
log.error("库存调整失败: 更新数据库失败 (影响行数 {}), 库存ID: {}", updatedRows,
inventory.getId());
// 需要根据具体失败原因决定是抛出库存不足异常还是并发异常
// 如果是 decreaseQuantity 返回 0,很可能是库存不足
if (isDecrease) {
throw new IllegalArgumentException("库存不足或并发修改导致扣减失败");
} else {
throw new IllegalStateException("库存增加操作更新失败,可能存在并发问题");
}
}
log.info("库存记录 {} 更新成功, 数量从 {} 变为 {}", inventory.getId(), quantityBeforeChange,
quantityAfterChange);
// 6. 发布库存调整事件 (用于记录流水)
try {
InventoryAdjustedEvent event = new InventoryAdjustedEvent(
inventory.getId(),
inventory.getOwnerId(),
inventory.getOwnerName(),
inventory.getMaterialId(),
inventory.getMachineSerialNo(), // 虽然是非编号管理,但保持字段一致性
material, // 传递物料信息给监听器
isIncrease ? "INCREASE" : "DECREASE",
changeQuantity,
quantityBeforeChange,
quantityAfterChange, // 使用计算出的理论值或重新查询一次获取精确值
adjustDTO.getReason(),
operator);
eventPublisher.publishEvent(event);
log.info("库存调整事件已发布, 库存ID: {}", inventory.getId());
} catch (Exception e) {
log.error("发布库存调整事件失败, 库存ID: {}, 错误: {}", inventory.getId(), e.getMessage(), e);
// 事件发布失败不应影响主事务,但需要记录日志
}
}
public List<Inventory> getInventoryItemByInboundOrderId(Long inboundOrderId) {
return this.list(Wrappers.<Inventory>lambdaQuery().eq(Inventory::getInBoundOrderId, inboundOrderId));
}
/**
* 根据货主ID更新货主名称
* @param ownerId 货主ID
* @param ownerName 新的货主名称
* @return 更新记录数
*/
@Transactional
public int updateOwnerNameByOwnerId(Long ownerId, String ownerName) {
LambdaUpdateWrapper<Inventory> wrapper = Wrappers.<Inventory>lambdaUpdate()
.eq(Inventory::getOwnerId, ownerId)
.set(Inventory::getOwnerName, ownerName);
return inventoryMapper.update(null,wrapper);
}
}
@@ -0,0 +1,57 @@
package com.linke.transport.application.service.warehouse.inventory.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
@Data
@ApiModel(value = "InventoryListItemVO", description = "库存列表展示项")
public class InventoryVO {
@ApiModelProperty(value = "库存记录ID (用于调整)", example = "5")
private Long id;
@ApiModelProperty("库存单号")
private String inventoryOrderNo;
@ApiModelProperty(value = "货主ID", example = "1001")
private Long ownerId;
@ApiModelProperty(value = "货主", example = "山东临工")
private String ownerName;
// --- 物料信息 ---
@ApiModelProperty(value = "物料ID", example = "102")
private Long materialId;
@ApiModelProperty(value = "物料价值", example = "20.2")
private BigDecimal value;
@ApiModelProperty(value = "物料分类", example = "零件")
private String materialCategory;
@ApiModelProperty(value = "物料名称", example = "发动机滤芯")
private String materialName;
@ApiModelProperty(value = "物料型号", example = "LX001")
private String materialModel;
@ApiModelProperty(value = "重量", example = "22")
private BigDecimal weight;
// --- 库存信息 ---
@ApiModelProperty(value = "库存数量", example = "100")
private BigDecimal quantity;
@ApiModelProperty(value = "库存单位", example = "")
private String unit;
@ApiModelProperty(value = "是否按编号管理", example = "false")
private Boolean codeManaged;
@ApiModelProperty(value = "整机编号 (仅编号管理物料有值)", example = "ZJ0000000001")
private String machineSerialNo;
@ApiModelProperty(value = "创建时间")
private Date createdAt;
}
@@ -0,0 +1,78 @@
package com.linke.transport.application.service.warehouse.inventoryLedger;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linke.transport.application.service.warehouse.inventoryLedger.vo.InventoryLedgerVO;
import com.linke.transport.domain.warehouse.inboundOrder.model.InboundOrder;
import com.linke.transport.domain.warehouse.inventoryLedger.model.InventoryLedger;
import com.linke.transport.domain.warehouse.outboundOrder.model.OutboundOrder;
import com.linke.transport.infrastructure.warehouse.inventoryLedger.persistence.InventoryLedgerMapper;
import com.linke.transport.interfaces.dto.warehouse.inventoryLedger.InventoryLedgerDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Objects;
@Service
@RequiredArgsConstructor
public class InventoryLedgerService extends ServiceImpl<InventoryLedgerMapper, InventoryLedger> {
private final InventoryLedgerMapper inventoryLedgerMapper;
public IPage<InventoryLedgerVO> listInventoryLedger(InventoryLedgerDTO.Query query) {
LambdaQueryWrapper<InventoryLedger> wrapper = Wrappers.<InventoryLedger>lambdaQuery()
.eq(StringUtils.hasText(query.getType()), InventoryLedger :: getType, query.getType())
.like(StringUtils.hasText(query.getOwnerName()), InventoryLedger :: getOwnerName,
query.getOwnerName())
.like(StringUtils.hasText(query.getOrderNo()), InventoryLedger :: getOrderNo,
query.getOrderNo())
.like(StringUtils.hasText(query.getMaterialCode()), InventoryLedger :: getMaterialCode,
query.getMaterialCode())
.like(StringUtils.hasText(query.getMaterialName()), InventoryLedger :: getMaterialName,
query.getMaterialName())
.like(StringUtils.hasText(query.getMaterialCategory()), InventoryLedger :: getMaterialCategory,
query.getMaterialCategory())
.like(StringUtils.hasText(query.getMaterialModel()), InventoryLedger :: getMaterialModel,
query.getMaterialModel())
.eq(StringUtils.hasText(query.getChangeType()), InventoryLedger :: getChangeType,
query.getChangeType())
.like(StringUtils.hasText(query.getTmsOrderNo()), InventoryLedger :: getTmsOrderNo,
query.getTmsOrderNo())
.like(StringUtils.hasText(query.getRemarks()), InventoryLedger :: getRemarks,
query.getRemarks())
.ge(Objects.nonNull(query.getEventTimeStart()),
InventoryLedger::getEventTime,query.getEventTimeStart())
.lt(Objects.nonNull(query.getEventTimeEnd()),
InventoryLedger::getEventTime,query.getEventTimeEnd())
.orderByDesc(InventoryLedger :: getId);
return this.page(new Page<>(query.getPageNo(), query.getPageSize()), wrapper)
.convert(item -> {
InventoryLedgerVO vo = new InventoryLedgerVO();
BeanUtils.copyProperties(item, vo);
return vo;
});
}
/**
* 根据货主ID更新货主名称
* @param ownerId 货主ID
* @param ownerName 新的货主名称
* @return 更新记录数
*/
@Transactional
public int updateOwnerNameByOwnerId(Long ownerId, String ownerName) {
LambdaUpdateWrapper<InventoryLedger> wrapper = Wrappers.<InventoryLedger>lambdaUpdate()
.eq(InventoryLedger::getOwnerId, ownerId)
.set(InventoryLedger::getOwnerName, ownerName);
return inventoryLedgerMapper.update(null,wrapper);
}
}
@@ -0,0 +1,65 @@
package com.linke.transport.application.service.warehouse.inventoryLedger.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@ApiModel(value = "InventoryLedgerVO", description = "库存流水table参数")
public class InventoryLedgerVO {
@ApiModelProperty(value = "发生时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
private Date eventTime;
@ApiModelProperty(value = "流水类型 (INBOUND:入库, OUTBOUND:出库, ADJUSTMENT:库存调整, TMS_USAGE:订单出库)")
private String type; // 考虑后续使用枚举类型
@ApiModelProperty(value = "关联单号 (入库/出库单号)")
private String orderNo;
@ApiModelProperty(value = "货主名称")
private String ownerName;
@ApiModelProperty(value = "物料编码 (冗余)")
private String materialCode;
@ApiModelProperty(value = "物料名称 (冗余)")
private String materialName;
@ApiModelProperty(value = "物料分类 (冗余)")
private String materialCategory;
@ApiModelProperty(value = "物料型号 (冗余)")
private String materialModel;
@ApiModelProperty(value = "库存单位 (冗余)")
private String unit;
@ApiModelProperty(value = "库存增减类型 (INCREASE:增加, DECREASE:减少)")
private String changeType; // 考虑后续使用枚举类型
@ApiModelProperty(value = "本次变动数量 (正数)")
private BigDecimal changeQuantity;
@ApiModelProperty(value = "变动后库存数量")
private BigDecimal quantityAfterChange;
@ApiModelProperty(value = "整机编号 (如果涉及)")
private String machineSerialNo;
@ApiModelProperty(value = "关联的TMS运输订单号 (当type为TMS_USAGE时)")
private String tmsOrderNo;
@ApiModelProperty(value = "操作人")
private String createdBy;
@ApiModelProperty(value = "备注 (例如 调整原因)")
private String remarks;
}
@@ -0,0 +1,48 @@
package com.linke.transport.application.service.warehouse.material.command;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Data
@ApiModel(description = "创建物料")
public class CreateMaterialCommand {
@ApiModelProperty("货主Id")
@NotNull(message = "货主Id不可以为空")
private Long ownerId;
@ApiModelProperty("分类")
@NotBlank(message = "分类不能为空")
private String category;
@ApiModelProperty(value = "物料名称")
@NotBlank(message = "名称不能为空")
private String name;
@ApiModelProperty(value = "物料型号")
private String model;
@NotBlank(message = "物料单位不能为空")
@ApiModelProperty(value = "物料单位")
private String unit;
@DecimalMin(value = "0.0", message = "物料价值不能为负")
@ApiModelProperty(value = "物料价值")
private BigDecimal value;
@DecimalMin(value = "0.0", message = "物料重量不能为负")
@ApiModelProperty(value = "物料重量")
private BigDecimal weight;
@NotNull(message = "编号管理状态不能为空")
@ApiModelProperty(value = "编号管理状态")
private Boolean codeManaged;
@ApiModelProperty(value = "备注")
private String remark;
}
@@ -0,0 +1,83 @@
package com.linke.transport.application.service.warehouse.material.command;
import com.linke.transport.application.service.feign.UserServiceFeignService;
import com.linke.transport.domain.warehouse.material.MaterialCodeGenerator;
import com.linke.transport.domain.warehouse.material.exception.MaterialDomainException;
import com.linke.transport.domain.warehouse.material.model.Material;
import com.linke.transport.domain.warehouse.material.repository.MaterialRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Log4j2
@RequiredArgsConstructor
public class MaterialCommandService {
private final MaterialRepository materialRepository;
private final MaterialCodeGenerator codeGenerator;
private final UserServiceFeignService userServiceFeignService;
/**
* 创建物料
*/
public Long handle(CreateMaterialCommand command) {
String shipper = userServiceFeignService.findUserNameByUserId(command.getOwnerId(),"物料模块-调用RPC错误");
Material material = Material.create(
command.getOwnerId(), shipper,
command.getCategory(),
command.getName(),
command.getModel(),
command.getUnit(),
command.getValue(),
command.getCodeManaged(),
command.getWeight(),
command.getRemark(),
codeGenerator
);
return materialRepository.save(material).getId();
}
/**
* 更新物料
*/
public void handle(UpdateMaterialCommand command) {
Material material = materialRepository.findById(command.getId())
.orElseThrow(() -> new MaterialDomainException("物料不存在"));
String shipper = userServiceFeignService.findUserNameByUserId(command.getOwnerId(),"物料模块-调用RPC错误");
material.update(command.getOwnerId(),shipper,
command.getCategory(),
command.getName(),
command.getModel(),
command.getUnit(),
command.getValue(),
command.getCodeManaged(),
command.getWeight(),
command.getRemark()
);
materialRepository.update(material);
}
/**
* 删除物料
*/
public void deleteMaterial(Long id) {
materialRepository.deleteById(id);
}
/**
* 根据货主ID更新货主名称
* @param ownerId 货主ID
* @param ownerName 新的货主名称
* @return 更新记录数
*/
@Transactional
public int updateOwnerNameByOwnerId(Long ownerId, String ownerName) {
return materialRepository.updateOwnerNameByOwnerId(ownerId, ownerName);
}
}
@@ -0,0 +1,41 @@
package com.linke.transport.application.service.warehouse.material.command;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Data
@ApiModel("更新参数")
public class UpdateMaterialCommand {
@ApiModelProperty("货主Id")
private Long ownerId;
@NotNull(message = "物料ID不能为空")
@ApiModelProperty("物料ID")
private Long id;
@ApiModelProperty("分类")
private String category;
@ApiModelProperty(value = "物料名称")
private String name;
@ApiModelProperty(value = "物料型号")
private String model;
@ApiModelProperty(value = "物料单位")
private String unit;
@DecimalMin(value = "0.0", message = "物料价值不能为负")
private BigDecimal value;
@DecimalMin(value = "0.0", message = "物料重量不能为负")
private BigDecimal weight;
@ApiModelProperty(value = "编号管理状态")
private Boolean codeManaged;
@ApiModelProperty(value = "备注")
private String remark;
}
@@ -0,0 +1,30 @@
package com.linke.transport.application.service.warehouse.material.query;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
@ApiModel("查询参数")
public class MaterialQueryCommand {
@ApiModelProperty(name = "货主")
private String shipper;
@ApiModelProperty(name = "分类")
private String category;
@ApiModelProperty(name = "名称")
private String name;
@ApiModelProperty(name = "型号")
private String model;
@ApiModelProperty("物料编码")
private String materialCode;
@ApiModelProperty("编号管理状态")
private Boolean codeManaged;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty(name = "当前页")
private Long pageNo = 1L;
@ApiModelProperty(name = "每页条数")
private Long pageSize = 10L;
}
@@ -0,0 +1,58 @@
package com.linke.transport.application.service.warehouse.material.query;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.linke.transport.application.service.warehouse.material.vo.MaterialVO;
import com.linke.transport.domain.warehouse.material.exception.MaterialDomainException;
import com.linke.transport.domain.warehouse.material.repository.MaterialRepository;
import com.linke.transport.infrastructure.warehouse.material.converter.MaterialConverter;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class MaterialQueryService {
private final MaterialRepository materialRepository;
/**
* 分页查询物料
*/
public IPage<MaterialVO> queryMaterials(MaterialQueryCommand param) {
return materialRepository.search(
param.getShipper(),
param.getCategory(),
param.getName(),
param.getModel(),
param.getMaterialCode(),
param.getCodeManaged(),
param.getRemark(),
param.getPageNo(),
param.getPageSize()
).convert(MaterialConverter :: convertToVO);
}
/**
* 获取物料详情
*/
public MaterialVO getMaterialDetail(Long id) {
return materialRepository.findById(id)
.map(MaterialConverter :: convertToVO)
.orElseThrow(() -> new MaterialDomainException("物料不存在"));
}
/**
* 获取所有材料信息
* <p>
* 此方法从材料仓库中获取所有材料信息,并将其转换为MaterialVO对象列表
* 使用Stream API对获取到的数据进行处理,提高了代码的可读性和效率
*
* @return 所有材料的列表,以MaterialVO形式表示
*/
public List<MaterialVO> getAllMaterials(Long ownerId) {
return materialRepository.findAllMaterials(ownerId)
.stream()
.map(MaterialConverter :: convertToVO)
.collect(Collectors.toList());
}
}
@@ -0,0 +1,48 @@
package com.linke.transport.application.service.warehouse.material.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
@Data
public class MaterialVO{
@ApiModelProperty("主键ID")
private Long id;
@ApiModelProperty("物料编码")
private String materialCode;
@ApiModelProperty("货主")
private String shipper;
@ApiModelProperty("分类")
private String category;
@ApiModelProperty("货主ID")
private Long ownerId;
@ApiModelProperty("货主名称")
private String ownerName;
@ApiModelProperty("名称")
private String name;
@ApiModelProperty("型号")
private String model;
@ApiModelProperty("单位")
private String unit;
@ApiModelProperty("价值")
private BigDecimal value;
@ApiModelProperty("重量")
private BigDecimal weight;
@ApiModelProperty("编号管理状态")
private Boolean codeManaged;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("创建时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@ApiModelProperty("更新时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
}
@@ -0,0 +1,430 @@
package com.linke.transport.application.service.warehouse.outBoundOrder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linke.transport.application.service.feign.UserServiceFeignService;
import com.linke.transport.domain.warehouse.inboundOrder.model.InboundOrder;
import com.linke.transport.domain.warehouse.inventory.model.Inventory;
import com.linke.transport.domain.warehouse.material.model.Material;
import com.linke.transport.domain.warehouse.material.repository.MaterialRepository;
import com.linke.transport.domain.warehouse.outboundOrder.evnet.pojo.OutboundCompletedEvent;
import com.linke.transport.domain.warehouse.outboundOrder.model.OutboundOrder;
import com.linke.transport.domain.warehouse.outboundOrder.model.OutboundOrderDetail;
import com.linke.transport.infrastructure.warehouse.inventory.persistence.InventoryMapper;
import com.linke.transport.infrastructure.warehouse.outboundOrder.persistence.OutboundOrderDetailMapper;
import com.linke.transport.infrastructure.warehouse.outboundOrder.persistence.OutboundOrderMapper;
import com.linke.transport.interfaces.dto.warehouse.outBoundOrder.OutboundOrderDTO;
import com.linke.transport.interfaces.dto.warehouse.outBoundOrder.OutboundOrderDTO.Create;
import com.mhd.common.core.utils.OrderSequence;
import com.mhd.common.security.utils.SecurityUtils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
* <p>
* 出库单 服务实现类
* </p>
*
* @author YourName
* @since YYYY-MM-DD
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class OutboundOrderService extends ServiceImpl<OutboundOrderMapper, OutboundOrder> {
private final OutboundOrderDetailMapper outboundOrderDetailMapper;
private final InventoryMapper inventoryMapper;
private final MaterialRepository materialRepository;
private final ApplicationEventPublisher eventPublisher;
private final OutboundOrderMapper outboundOrderMapper;
private final UserServiceFeignService userServiceFeignService;
/**
* 创建出库单
*
* @param createDTO 创建请求体
* @return 创建成功的出库单ID
*/
@Transactional
public Long createOutboundOrder(Create createDTO) {
String ownerName = userServiceFeignService.findUserNameByUserId(createDTO.getOwnerId(), "创建出库单-调用用户中心findUserNameByUserId错误");
log.info("开始创建出库单 (基于库存ID),货主ID: {}, 货主: {}, 类型: {}", createDTO.getOwnerId(), ownerName,
createDTO.getType());
// 1. 创建出库单主表信息
OutboundOrder outboundOrder = new OutboundOrder();
BeanUtils.copyProperties(createDTO,outboundOrder);
outboundOrder.setOwnerName(ownerName);
outboundOrder.setOutboundTime(new Date());
outboundOrder.setOutboundOrderNo(OrderSequence.getOrderCode("CK"));
outboundOrder.setCreatedBy(SecurityUtils.getUsername());
this.save(outboundOrder);
log.info("出库单主表保存成功, ID: {}, 单号: {}", outboundOrder.getId(), outboundOrder.getOutboundOrderNo());
// 2. 处理出库单明细 (基于库存ID)
List<OutboundOrderDetail> savedDetails = new ArrayList<>();
// 用于记录扣减前的库存量,传递给事件 (Key: Detail ID, Value: Quantity Before Decrease)
Map<Long, BigDecimal> quantityBeforeDecreaseMap = new HashMap<>();
// 用于收集需要发布的事件明细 (因为 detail ID 在插入后才有)
List<OutboundOrderDetail> detailsForEvent = new ArrayList<>();
for (OutboundOrderDTO.Detail detailDTO : createDTO.getDetails()) {
// 2.1 查询指定的库存记录
Inventory inventoryRecord = inventoryMapper.selectById(detailDTO.getInventoryId());
if (Objects.isNull(inventoryRecord)) {
log.error("出库失败: 找不到或无效的库存记录 ID: {}", detailDTO.getInventoryId());
throw new IllegalArgumentException("找不到或无效的库存记录 ID: " + detailDTO.getInventoryId());
}
// 2.2 校验货主归属 (基于ownerId进行精确匹配)
if (!Objects.equals(inventoryRecord.getOwnerId(), createDTO.getOwnerId())) {
log.error("出库失败: 库存记录 {} 的货主ID '{}' 与订单货主ID '{}' 不匹配",
detailDTO.getInventoryId(), inventoryRecord.getOwnerId(), createDTO.getOwnerId());
throw new IllegalArgumentException("库存记录 " + detailDTO.getInventoryId() + " 不属于货主ID " + createDTO.getOwnerId());
}
// 2.3 获取物料信息 (用于记录和可能的校验)
Material material = materialRepository.findById(inventoryRecord.getMaterialId())
.orElseThrow(() -> new IllegalStateException(
"库存记录 " + inventoryRecord.getId() + " 关联的物料ID " + inventoryRecord.getMaterialId() + " 不存在"));
// 2.4 核心库存校验
BigDecimal requestedQuantity = detailDTO.getQuantity();
BigDecimal availableQuantity = inventoryRecord.getQuantity();
if (availableQuantity.compareTo(requestedQuantity) < 0) {
log.error("出库失败: 库存记录 {} (物料: {}) 库存不足。需求: {}, 可用: {}",
detailDTO.getInventoryId(), material.getName(), requestedQuantity, availableQuantity);
throw new IllegalArgumentException(
"库存记录 " + detailDTO.getInventoryId() + " (物料: " + material.getName() + ") 库存不足");
}
// 2.5 执行原子库存扣减
String operator = SecurityUtils.getUsername();
int updatedRows = inventoryMapper.decreaseQuantity(inventoryRecord.getId(), requestedQuantity, operator);
if (updatedRows <= 0) {
// 可能并发导致库存不足
log.error("库存扣减失败 (影响行数 {}), 库存ID: {}", updatedRows, inventoryRecord.getId());
throw new IllegalStateException("库存扣减失败,可能由于并发操作导致库存不足 (库存ID: " + inventoryRecord.getId() + ")");
}
log.info("库存扣减成功, 库存ID: {}, 扣减数量: {}", inventoryRecord.getId(), requestedQuantity);
// **** 当物料库存为0时删除 ****
BigDecimal quantityAfter = availableQuantity.subtract(requestedQuantity);
// 检查:库存是否<=0 并且 是整机管理的物料
if (quantityAfter.compareTo(BigDecimal.ZERO) <= 0 && Objects.nonNull(inventoryRecord.getMachineSerialNo())) {
log.info("整机编号物料库存记录 {} 数量已减至0或以下,执行逻辑删除。", inventoryRecord.getId());
int deletedRows = inventoryMapper.deleteById(inventoryRecord.getId());
if (deletedRows > 0) {
log.info("库存记录 {} 逻辑删除成功。", inventoryRecord.getId());
} else {
log.warn("尝试逻辑删除库存记录 {} 失败。", inventoryRecord.getId());
}
}
// 2.7 创建并保存出库明细
OutboundOrderDetail detail = new OutboundOrderDetail();
detail.setOutboundOrderId(outboundOrder.getId());
detail.setMaterialId(inventoryRecord.getMaterialId()); // 从库存记录获取物料ID
detail.setQuantity(requestedQuantity); // 请求的出库数量
detail.setMachineSerialNo(inventoryRecord.getMachineSerialNo()); // 从库存记录获取序列号
detail.setCreatedBy(operator);
outboundOrderDetailMapper.insert(detail); // 保存明细以获取 ID
savedDetails.add(detail); // 添加到列表
// 记录扣减前数量,使用 detail 的 ID 作为 key
quantityBeforeDecreaseMap.put(detail.getId(), availableQuantity);
detailsForEvent.add(detail); // 添加到用于发布事件的列表
}
log.info("出库单明细处理完成,共 {} 条", savedDetails.size());
// 3. 发布出库完成事件
try {
// 使用 detailsForEvent 列表,其中包含了已保存并获得 ID 的明细对象
eventPublisher.publishEvent(new OutboundCompletedEvent(
outboundOrder,
detailsForEvent, // 使用包含 ID 的列表
quantityBeforeDecreaseMap,
createDTO.getType(),
createDTO.getTmsOrderNo()));
log.info("出库完成事件已发布, 出库单号: {}", outboundOrder.getOutboundOrderNo());
} catch (Exception e) {
log.error("发布出库完成事件失败或事件处理失败, 出库单号: {}, 错误: {}", outboundOrder.getOutboundOrderNo(), e.getMessage(), e);
throw e; // 回滚事务
}
return outboundOrder.getId();
}
/**
* 根据出库单ID获取出库单详情信息
*
* @param id 出库单ID
* @return 出库单详情列表
*/
public List<OutboundOrderVO.Detail> getDetailsByOutBoundOrderId(Long id) {
// 1. 验证主单是否存在
OutboundOrder outboundOrder = this.getById(id);
if (Objects.isNull(outboundOrder)) {
log.warn("查询出库单详情失败: ID {} 不存在", id);
throw new NoSuchElementException("出库单ID " + id + " 不存在");
}
// 2. 查询明细
List<OutboundOrderDetail> details = outboundOrderDetailMapper.selectList(
new LambdaQueryWrapper<OutboundOrderDetail>()
.eq(OutboundOrderDetail::getOutboundOrderId, id));
// 3. 查询物料信息
Map<Long, Material> materialMap = getMaterialMapForDetails(details);
// 4. 转换并返回VO列表 (复用入库的转换逻辑)
return details.stream()
.map(convertDetailToVO(materialMap))
.collect(Collectors.toList());
}
/**
* 分页查询出库单列表
*
* @param queryDTO 查询条件
* @return 分页结果
*/
public IPage<OutboundOrderVO.ListSummary> listOutboundOrders(OutboundOrderDTO.Query queryDTO) {
// 1. 构建分页请求
IPage<OutboundOrder> pageRequest = new Page<>(queryDTO.getPageNo(), queryDTO.getPageSize());
// 2. 构建查询条件
LambdaQueryWrapper<OutboundOrder> queryWrapper = buildListQueryWrapper(queryDTO);
// 3. 执行分页查询 (主表)
IPage<OutboundOrder> resultPage = this.page(pageRequest, queryWrapper);
// 4. 处理结果记录
List<OutboundOrderVO.ListSummary> summaryList = processOutboundRecords(resultPage.getRecords());
// 5. 构建并返回分页响应
return createSummaryPage(resultPage, summaryList);
}
// --- 私有辅助方法 ---
/**
* 根据 货主ID、物料ID、序列号 查找库存记录
*/
private Inventory findInventoryBySerialNumber(Long ownerId, Long materialId,
String machineSerialNo) {
return inventoryMapper.selectOne(new LambdaQueryWrapper<Inventory>()
.eq(Inventory::getOwnerId, ownerId)
.eq(Inventory::getMaterialId, materialId)
.eq(Inventory::getMachineSerialNo, machineSerialNo));
}
/**
* 根据 货主ID、物料ID 查找非序列号管理的库存记录
*/
private Inventory findInventoryByMaterial(Long ownerId, Long materialId) {
return inventoryMapper.selectOne(new LambdaQueryWrapper<Inventory>()
.eq(Inventory::getOwnerId, ownerId)
.eq(Inventory::getMaterialId, materialId)
.isNull(Inventory::getMachineSerialNo)); // 非序列号管理
}
/**
* 获取出库明细关联的物料信息 Map
*/
private Map<Long, Material> getMaterialMapForDetails(List<OutboundOrderDetail> details) {
if (CollectionUtils.isEmpty(details)) {
return Collections.emptyMap();
}
List<Long> materialIds = details.stream()
.map(OutboundOrderDetail::getMaterialId)
.distinct()
.collect(Collectors.toList());
return getMaterialMap(materialIds); // 复用入库的辅助方法
}
/**
* 获取物料映射(复用入库逻辑)
*/
private Map<Long, Material> getMaterialMap(List<Long> materialIds) {
return materialRepository.findByIdIn(materialIds)
.map(list -> list.stream()
.collect(Collectors.toMap(Material::getId, Function.identity())))
.orElseGet(HashMap::new);
}
/**
* 将 OutboundOrderDetail 转换为 VO (复用入库逻辑)
*/
private Function<OutboundOrderDetail, OutboundOrderVO.Detail> convertDetailToVO(
Map<Long, Material> materialMap) {
return detail -> {
OutboundOrderVO.Detail detailVO = new OutboundOrderVO.Detail();
BeanUtils.copyProperties(detail, detailVO);
Material material = materialMap.get(detail.getMaterialId());
if (material != null) {
detailVO.setMaterialName(material.getName());
detailVO.setMaterialCategory(material.getCategory());
detailVO.setSerialNoManaged(material.isCodeManaged());
detailVO.setMaterialModel(material.getModel());
detailVO.setUnit(material.getUnit());
} else {
detailVO.setMaterialName("物料已删除或不存在");
log.warn("出库单明细 {} 关联的物料ID {} 未找到", detail.getId(), detail.getMaterialId());
}
return detailVO;
};
}
/**
* 构建出库列表查询条件
*/
private LambdaQueryWrapper<OutboundOrder> buildListQueryWrapper(OutboundOrderDTO.Query queryDTO) {
return new LambdaQueryWrapper<OutboundOrder>()
.like(StringUtils.hasText(queryDTO.getOutboundOrderNo()),
OutboundOrder::getOutboundOrderNo, queryDTO.getOutboundOrderNo())
.eq(Objects.nonNull(queryDTO.getOwnerId()),
OutboundOrder::getOwnerId, queryDTO.getOwnerId())
.like(StringUtils.hasText(queryDTO.getOwnerName()), OutboundOrder::getOwnerName,
queryDTO.getOwnerName())
.like(StringUtils.hasText(queryDTO.getRemarks()),
OutboundOrder::getRemarks, queryDTO.getRemarks())
.ge(Objects.nonNull(queryDTO.getOutboundTimeStart()),
OutboundOrder::getOutboundTime,queryDTO.getOutboundTimeStart())
.lt(Objects.nonNull(queryDTO.getOutboundTimeEnd()),
OutboundOrder::getOutboundTime,queryDTO.getOutboundTimeEnd())
// 添加时间等其他查询条件
.orderByDesc(OutboundOrder::getOutboundTime); // 按出库时间降序
}
/**
* 处理出库主表记录列表,转换为 ListSummary VO 列表
*/
private List<OutboundOrderVO.ListSummary> processOutboundRecords(List<OutboundOrder> records) {
if (CollectionUtils.isEmpty(records)) {
return Collections.emptyList();
}
// 提取订单ID
List<Long> orderIds = records.stream().map(OutboundOrder::getId).collect(Collectors.toList());
// 批量获取明细
Map<Long, List<OutboundOrderDetail>> detailsMap = getOutboundDetailsMap(orderIds);
// 批量获取物料
Map<Long, Material> materialMap = getMaterialMapForDetails(
detailsMap.values().stream().flatMap(List::stream).collect(Collectors.toList()));
// 组装 ListSummary
return records.stream()
.map(order -> createOutboundSummary(order,
detailsMap.getOrDefault(order.getId(), Collections.emptyList()), materialMap))
.collect(Collectors.toList());
}
/**
* 获取出库明细 Map
*/
private Map<Long, List<OutboundOrderDetail>> getOutboundDetailsMap(List<Long> orderIds) {
if (CollectionUtils.isEmpty(orderIds)) {
return Collections.emptyMap();
}
List<OutboundOrderDetail> details = outboundOrderDetailMapper.selectList(
new LambdaQueryWrapper<OutboundOrderDetail>()
.in(OutboundOrderDetail::getOutboundOrderId, orderIds));
return details.stream()
.collect(Collectors.groupingBy(OutboundOrderDetail::getOutboundOrderId));
}
/**
* 创建单个出库 ListSummary VO
*/
private OutboundOrderVO.ListSummary createOutboundSummary(OutboundOrder order,
List<OutboundOrderDetail> details, Map<Long, Material> materialMap) {
OutboundOrderVO.ListSummary summary = new OutboundOrderVO.ListSummary();
BeanUtils.copyProperties(order, summary);
// 计算总数量
BigDecimal totalQuantity = details.stream()
.map(d -> Optional.ofNullable(d.getQuantity()).orElse(BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
summary.setTotalQuantity(totalQuantity);
// 拼接物料概要 (复用入库逻辑)
String materialSummary = details.stream()
.map(detail -> formatMaterialDetail(detail, materialMap)) // 复用格式化方法
.collect(Collectors.joining(", "));
summary.setMaterialSummary(materialSummary);
return summary;
}
/**
* 格式化单个物料详情(复用入库逻辑)
*/
private String formatMaterialDetail(OutboundOrderDetail detail, Map<Long, Material> materialMap) {
String materialName = Optional.ofNullable(materialMap.get(detail.getMaterialId()))
.map(Material::getName)
.orElse("未知物料");
return materialName + "*" + Optional.ofNullable(detail.getQuantity())
.map(q -> q.stripTrailingZeros().toPlainString())
.orElse("0");
}
/**
* 构建分页响应(复用入库逻辑)
*/
private IPage<OutboundOrderVO.ListSummary> createSummaryPage(IPage<OutboundOrder> resultPage,
List<OutboundOrderVO.ListSummary> summaryList) {
return new Page<OutboundOrderVO.ListSummary>(resultPage.getCurrent(), resultPage.getSize(),
resultPage.getTotal())
.setPages(resultPage.getPages()) // setPages 可能在新版 MP 中不需要
.setRecords(summaryList);
}
/**
* 根据货主ID更新货主名称
*
* @param ownerId 货主ID
* @param ownerName 新的货主名称
* @return 更新记录数
*/
@Transactional
public int updateOwnerNameByOwnerId(Long ownerId, String ownerName) {
LambdaUpdateWrapper<OutboundOrder> wrapper = Wrappers.<OutboundOrder>lambdaUpdate()
.eq(OutboundOrder::getOwnerId, ownerId)
.set(OutboundOrder::getOwnerName, ownerName);
return outboundOrderMapper.update(null, wrapper);
}
}
@@ -0,0 +1,75 @@
package com.linke.transport.application.service.warehouse.outBoundOrder;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
public class OutboundOrderVO {
@Data
@ApiModel(value = "OutboundOrderListSummary", description = "出库单列表展示项")
public static class ListSummary {
@ApiModelProperty(value = "出库单ID", example = "1")
private Long id;
@ApiModelProperty(value = "出库时间", example = "2025-01-01 01:01:00")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date outboundTime;
@ApiModelProperty(value = "出库单号", example = "CK2501010001")
private String outboundOrderNo;
@ApiModelProperty(value = "货主用户Id")
private Long ownerId;
@ApiModelProperty(value = "货主", example = "临工")
private String ownerName;
@ApiModelProperty(value = "出库总数量", example = "15")
private BigDecimal totalQuantity; // 需要Service计算
@ApiModelProperty(value = "出库物料概要", example = "装载机L916H*5, 资料*10")
private String materialSummary; // 需要Service拼接
@ApiModelProperty(value = "创建人", example = "李经理")
private String createdBy;
@ApiModelProperty(value = "备注", example = "项目领用")
private String remarks;
}
@Data
@ApiModel(value = "OutboundOrderDetailVO", description = "出库单明细视图对象")
public static class Detail {
@ApiModelProperty(value = "出库明细ID", example = "20")
private Long id; // 明细ID
@ApiModelProperty(value = "物料ID", example = "101")
private Long materialId;
@ApiModelProperty(value = "物料名称", example = "装载机L916H")
private String materialName; // 来自物料表
@ApiModelProperty(value = "物料分类", example = "整机")
private String materialCategory; // 来自物料表
@ApiModelProperty(value = "是否按编号管理", example = "true")
private Boolean serialNoManaged; // 来自物料表
@ApiModelProperty(value = "出库数量", example = "5")
private BigDecimal quantity;
@ApiModelProperty(value = "物料单位", example = "")
private String unit; // 来自物料表
@ApiModelProperty(value = "整机编号", example = "ZJ0000000001")
private String machineSerialNo;
@ApiModelProperty(value = "物料型号", example = "xh-092")
private String materialModel;
}
}
@@ -0,0 +1,22 @@
package com.linke.transport.domain.common.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* 数据权限判断 po
*
* 2023-01-11
*
* @author 王子豪
*/
@Data
public class DataPermission
{
@ApiModelProperty(value = "创建者")
private Long createBy;
@ApiModelProperty(name = "组织ID集合")
private List<Long> organizationIdList;
}
@@ -0,0 +1,24 @@
package com.linke.transport.domain.security.annotation;
import java.lang.annotation.*;
/**
* @author ZhouGY
* @title Encrypt
* @description: 加密注解
* @date 2024/1/25 15:37
**/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Encrypt {
/**
* 入参是否解密,默认解密
*/
boolean in() default true;
/**
* 返回是否加密,默认加密
*/
boolean out() default true;
}
@@ -0,0 +1,29 @@
package com.linke.transport.domain.security.annotation;
import java.lang.annotation.*;
/**
* 自定义操作日志记录注解
*
* @author mhd
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OpenApiLog {
/**
* 模块
*/
public String title() default "";
/**
* 是否保存请求的参数
*/
public boolean isSaveRequestData() default true;
/**
* 是否保存响应的参数
*/
public boolean isSaveResponseData() default true;
}
@@ -0,0 +1,187 @@
package com.linke.transport.domain.security.aspect;
import cn.hutool.json.JSONUtil;
import com.linke.transport.domain.security.annotation.Encrypt;
import com.linke.transport.infrastructure.feign.ProductServiceFeign;
import com.mhd.common.core.domain.entity.DecryptRequestDO;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.domain.po.SysTenantsPo;
import com.mhd.common.core.domain.po.thirdparty.SysDepartInterfaceInfoPo;
import com.mhd.common.core.domain.thirdparty.SysDepartInterfaceInfoDTO;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.feign.ThirdPartyServiceFeign;
import com.mhd.common.core.utils.AESUtil;
import com.mhd.common.core.utils.SignatureUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.rmi.ServerException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author ZhouGY
* @title DecryptRequestBodyAdvice
* @description post请求的加密参数进行解密,返回一个JSONObject对象
* @date 2023/8/17
**/
@ControllerAdvice(basePackages = "com.linke.transport.interfaces.facade.openApi")
@Slf4j
public class DecryptRequestBodyAdvice implements RequestBodyAdvice {
@Autowired
private ThirdPartyServiceFeign thirdPartyServiceFeign;
@Autowired
private ProductServiceFeign productServiceFeign;
/**
* 该方法用于判断当前请求,是否要执行beforeBodyRead方法
* methodParameter: 方法的参数对象
* type: 方法的参数类型
* aClass: 将会使用到的Http消息转换器类类型
* 注意:此判断方法,会在beforeBodyRead 和 afterBodyRead方法前都触发一次。
*
* @return 返回true则会执行beforeBodyRead
*/
@Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
//获取配置的组织ID
R<SysTenantsPo> sysTenantsPoR = productServiceFeign.getTenantsInfoByOpen();
if (R.SUCCESS != sysTenantsPoR.getCode()) {
throw new ServiceException("未获取到组织配置信息");
}
SysTenantsPo sysTenantsPo = sysTenantsPoR.getData();
//从三方配置表中取值
SysDepartInterfaceInfoDTO sysDepartInterfaceInfoDTO = new SysDepartInterfaceInfoDTO();
sysDepartInterfaceInfoDTO.setTopOrganizationId(sysTenantsPo.getTopOrganizationId());
sysDepartInterfaceInfoDTO.setInterfaceType("openApi");
sysDepartInterfaceInfoDTO.setInterfaceTypeKey("encrypt");
List<SysDepartInterfaceInfoPo> sysDepartInterfaceInfoPos = thirdPartyServiceFeign.queryListByFeign(sysDepartInterfaceInfoDTO);
if (sysDepartInterfaceInfoPos.isEmpty()){
return false;
}
SysDepartInterfaceInfoPo sysDepartInterfaceInfoPo = sysDepartInterfaceInfoPos.get(0);
//是否开启加密
if(!"true".equals(sysDepartInterfaceInfoPo.getInterfaceTypeValue())) {
return false;
}
log.info("【进入-RequestBody-supports】");
boolean encode = false;
// 判断该方法是否含有@Encrypt注解
if (Objects.requireNonNull(methodParameter.getMethod()).isAnnotationPresent(Encrypt.class)) {
//获取注解配置的包含和去除字段
Encrypt serializedField = methodParameter.getMethodAnnotation(Encrypt.class);
if (serializedField != null && serializedField.in()) {
//入参是否需要解密
encode = true;
}
}
return encode;
}
/**
* 在Http消息转换器执转换,之前执行
* inputMessage: 客户端的请求数据
* methodParameter: 方法的参数对象
* type: 方法的参数类型
* aClass: 将会使用到的Http消息转换器类类型
*
* @return 返回 一个自定义的HttpInputMessage
*/
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
log.info("【进入-RequestBody-beforeBodyRead】");
// 解密-使用解密后的数据,构造新的读取流
return new DecryptHttpInputMessage(inputMessage);
}
/**
* 在Http消息转换器执转换,之后执行
* o: 转换后的对象
* httpInputMessage: 客户端的请求数据
* methodParameter: handler方法的参数类型
* type: handler方法的参数类型
* aClass: 使用的Http消息转换器类类型
*
* @return 返回一个新的对象
*/
@Override
public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
log.info("【进入-RequestBody-afterBodyRead】");
return o;
}
/**
* 参数与afterBodyRead相同,不过这个方法处理的是,body为空的情况
*/
@Override
public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
log.info("【进入-RequestBody-handleEmptyBody】");
return o;
}
/**
* 解密-使用解密后的数据,构造新的读取流
*/
class DecryptHttpInputMessage implements HttpInputMessage {
private HttpInputMessage inputMessage;
public DecryptHttpInputMessage(HttpInputMessage inputMessage) {
this.inputMessage = inputMessage;
}
@Override
public InputStream getBody() throws IOException {
//获取配置的组织ID
R<SysTenantsPo> sysTenantsPoR = productServiceFeign.getTenantsInfoByOpen();
if (R.SUCCESS != sysTenantsPoR.getCode()) {
throw new RuntimeException("未获取到组织配置信息");
}
SysTenantsPo sysTenantsPo = sysTenantsPoR.getData();
//从三方配置表中取值
SysDepartInterfaceInfoDTO sysDepartInterfaceInfoDTO = new SysDepartInterfaceInfoDTO();
sysDepartInterfaceInfoDTO.setTopOrganizationId(sysTenantsPo.getTopOrganizationId());
sysDepartInterfaceInfoDTO.setInterfaceType("openApi");
List<SysDepartInterfaceInfoPo> sysDepartInterfaceInfoPos = thirdPartyServiceFeign.queryListByFeign(sysDepartInterfaceInfoDTO);
Map<String, SysDepartInterfaceInfoPo> stringSysDepartInterfaceInfoPoMap = sysDepartInterfaceInfoPos.stream().collect(Collectors.toMap(SysDepartInterfaceInfoPo::getInterfaceTypeKey, Function.identity()));
// 1.参数解密处理
String body = StringUtils.defaultString(IOUtils.toString(inputMessage.getBody(), "UTF-8"));
log.info("解密前 请求参数:" + body);
DecryptRequestDO decryptRequestDO = JSONUtil.toBean(JSONUtil.parseObj(body), DecryptRequestDO.class);
//2.验证参数
String secret = stringSysDepartInterfaceInfoPoMap.get(SignatureUtil.SECRET_KEY).getInterfaceTypeValue();
boolean flag = SignatureUtil.validateSign(decryptRequestDO, secret);
if (!flag){
throw new RuntimeException("未通过签名验证,请检查签名信息是否有误");
}
// 4.用服务端私钥进行解密
String iv = stringSysDepartInterfaceInfoPoMap.get(SignatureUtil.IV_KEY).getInterfaceTypeValue();
String result = AESUtil.decrypt(decryptRequestDO.getEncryptContent(),secret,iv);
log.info("解密后 请求参数:{}", result);
return IOUtils.toInputStream(result, "UTF-8");
}
@Override
public HttpHeaders getHeaders() {
return inputMessage.getHeaders();
}
}
}
@@ -0,0 +1,176 @@
package com.linke.transport.domain.security.aspect;
import com.alibaba.fastjson2.JSON;
import com.linke.transport.application.service.common.OpenApiLogApplicationService;
import com.linke.transport.domain.security.annotation.OpenApiLog;
import com.linke.transport.infrastructure.feign.ProductServiceFeign;
import com.mhd.common.core.domain.dto.open.SystemOpenApiLogDTO;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.domain.po.SysTenantsPo;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.utils.ServletUtils;
import com.mhd.common.core.utils.StringUtils;
import com.mhd.common.core.utils.ip.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
/**
* 操作日志记录处理
*
* @author mhd
*/
@Slf4j
@Aspect
@Component
public class OpenApiLogAspect {
@Autowired
private ProductServiceFeign productServiceFeign;
@Autowired
private OpenApiLogApplicationService openApiLogApplicationService;
/**
* 处理完请求后执行
*
* @param joinPoint 切点
*/
@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, OpenApiLog controllerLog, Object jsonResult) {
handleLog(joinPoint, controllerLog, jsonResult);
}
protected void handleLog(final JoinPoint joinPoint, OpenApiLog controllerLog, Object jsonResult) {
try {
// *========数据库日志=========*//
SystemOpenApiLogDTO systemOpenApiLogDTO = new SystemOpenApiLogDTO();
systemOpenApiLogDTO.setServiceCode("transportApi");
systemOpenApiLogDTO.setServiceName("运力服务");
// 请求的地址
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
systemOpenApiLogDTO.setOperIp(ip);
systemOpenApiLogDTO.setOperUrl(ServletUtils.getRequest().getRequestURI());
//根据当前登录获取客户信息 TODO
//获取配置的组织ID
R<SysTenantsPo> sysTenantsPoR = productServiceFeign.getTenantsInfoByOpen();
if (R.SUCCESS != sysTenantsPoR.getCode()) {
throw new ServiceException("未获取到组织配置信息");
}
SysTenantsPo sysTenantsPo = sysTenantsPoR.getData();
systemOpenApiLogDTO.setTopOrganizationId(sysTenantsPo.getTopOrganizationId());
systemOpenApiLogDTO.setOrganizationId(sysTenantsPo.getOrganizationId());
systemOpenApiLogDTO.setOrganizationName(sysTenantsPo.getOrganizationName());
systemOpenApiLogDTO.setCreateTime(new Date());
// 设置方法名称
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
systemOpenApiLogDTO.setMethod(className + "." + methodName + "()");
// 设置请求方式
systemOpenApiLogDTO.setRequestMethod(ServletUtils.getRequest().getMethod());
// 处理设置注解上的参数
getControllerMethodDescription(joinPoint, controllerLog, systemOpenApiLogDTO, jsonResult);
// 保存数据库
openApiLogApplicationService.saveLog(systemOpenApiLogDTO);
} catch (Exception exp) {
// 记录本地异常日志
log.error("==前置通知异常==");
log.error("异常信息:{}", exp.getMessage());
exp.printStackTrace();
}
}
/**
* 获取注解中对方法的描述信息 用于Controller层注解
*
* @param log 日志
* @param systemOpenApiLogDTO 操作日志
* @throws Exception
*/
public void getControllerMethodDescription(JoinPoint joinPoint, OpenApiLog log, SystemOpenApiLogDTO systemOpenApiLogDTO, Object jsonResult) throws Exception {
// 设置标题
systemOpenApiLogDTO.setTitle(log.title());
// 是否需要保存request,参数和值
if (log.isSaveRequestData()) {
// 获取参数的信息,传入到数据库中。
setRequestValue(joinPoint, systemOpenApiLogDTO);
}
// 是否需要保存response,参数和值
if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) {
systemOpenApiLogDTO.setJsonResult(JSON.toJSONString(jsonResult));
}
}
/**
* 获取请求的参数,放到log中
*
* @param openApiLogDO 操作日志
* @throws Exception 异常
*/
private void setRequestValue(JoinPoint joinPoint, SystemOpenApiLogDTO openApiLogDO) throws Exception {
String requestMethod = openApiLogDO.getRequestMethod();
if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
String params = argsArrayToString(joinPoint.getArgs());
openApiLogDO.setOperParam(params);
}
}
/**
* 参数拼装
*/
private String argsArrayToString(Object[] paramsArray) {
String params = "";
if (paramsArray != null && paramsArray.length > 0) {
for (Object o : paramsArray) {
if (StringUtils.isNotNull(o) && !isFilterObject(o)) {
try {
Object jsonObj = JSON.toJSON(o);
params += jsonObj.toString() + " ";
} catch (Exception e) {
}
}
}
}
return params.trim();
}
/**
* 判断是否需要过滤的对象。
*
* @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;
}
}
@@ -0,0 +1,326 @@
package com.linke.transport.domain.vehicle.entity;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mhd.common.core.web.domain.BaseVOEntity;
import com.mhd.common.core.annotation.fieldsetvalue.NeedSetValue;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
/**
* 车辆管理 实体
*
* 2022-12-9
*
* @author 王子豪
*/
@Data
@TableName("vehicle")
public class Vehicle extends BaseVOEntity implements Serializable
{
@ApiModelProperty(name = "车辆id")
@TableId(type = IdType.AUTO)
private Long vehicleId;
@ApiModelProperty(name = "车牌号")
private String vehicleLicensePlateNumber;
@ApiModelProperty(name = "车辆类别:1-个人车辆 2-企业车辆")
private Integer vehicleCategory;
@ApiModelProperty(name = "车辆类型(数据字典id)")
private String vehicleTypeId;
@ApiModelProperty(name = "车辆类型(数据字典name)")
private String vehicleTypeName;
@ApiModelProperty(name = "车辆来源(数据字典id)")
private String vehicleSourceId;
@ApiModelProperty(name = "车辆来源(数据字典name)")
private String vehicleSourceName;
@ApiModelProperty(name = "使用人")
private String vehicleUsePerson;
@ApiModelProperty(name = "住址")
private String vehicleAddress;
@ApiModelProperty(name = "使用性质")
private String vehicleUseNature;
@ApiModelProperty(name = "品牌类型")
private String vehicleBrandType;
@ApiModelProperty(name = "车辆识别代号")
private String vehicleIdentificationNumber;
@ApiModelProperty(name = "发动机号码")
private String vehicleEngineNumber;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "注册日期")
private Date vehicleRegistrationDate;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "发证日期")
private Date vehicleIssueDate;
@ApiModelProperty(name = "发证机关")
private String vehicleLicenceIssuingAuthority;
@ApiModelProperty(name = "档案编号")
private String vehicleFileNumber;
@ApiModelProperty(name = "总质量")
private BigDecimal vehicleTotalMass;
@ApiModelProperty(name = "核定载质量")
private BigDecimal vehicleApprovedLoadQuantity;
@ApiModelProperty(name = "外廓尺寸(长)")
private Integer vehicleGabariteOne;
@ApiModelProperty(name = "外廓尺寸(宽)")
private Integer vehicleGabariteTwo;
@ApiModelProperty(name = "外廓尺寸(高)")
private Integer vehicleGabariteThree;
@ApiModelProperty(name = "能源类型(字典id")
private String vehicleEnergyTypeId;
@ApiModelProperty(name = "能源类型(字典name")
private String vehicleEnergyTypeName;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "检验有效期")
private Date vehicleCheckoutPeriodValidity;
@ApiModelProperty(name = "备注")
private String vehicleRemark;
@NeedSetValue
@ApiModelProperty(name = "行驶证主页")
private String vehicleDrivingLicenseMain;
@NeedSetValue
@ApiModelProperty(name = "行驶证副页")
private String vehicleDrivingLicenseDeputy;
@NeedSetValue
@ApiModelProperty(name = "行驶证副页反面")
private String vehicleDrivingLicenseDeputyAgainst;
@ApiModelProperty(name = "是否挂车(0-无状态,1-挂车,2-不挂车)")
private Integer trailerStatus;
@ApiModelProperty(name = "挂车车牌号")
private String trailerLicensePlateNumber;
@ApiModelProperty(name = "挂车车辆类型(数据字典id)")
private String trailerVehicleTypeId;
@ApiModelProperty(name = "挂车车辆类型(数据字典name)")
private String trailerVehicleTypeName;
@ApiModelProperty(name = "挂车车牌颜色(数据字典id)")
private String trailerLicensePlateColorId;
@ApiModelProperty(name = "挂车车牌颜色(数据字典name)")
private String trailerLicensePlateColorName;
@ApiModelProperty(name = "挂车总质量")
private BigDecimal trailerTotalMass;
@ApiModelProperty(name = "挂车核定载质量")
private BigDecimal trailerApprovedLoadQuantity;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "挂车行驶证到期时间")
private Date trailerDrivingLicenseExpireDate;
@ApiModelProperty(name = "挂车行驶证是否长期(0-无状态,1-长期,2-不长期)")
private Integer trailerDrivingLicenseLongStatus;
@ApiModelProperty(name = "挂车道路运输证号")
private String trailerRoadTransportCertificateNo;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "挂车道路运输证有效期")
private Date trailerRoadTransportCertificateExpireDate;
@ApiModelProperty(name = "挂车道路运输证是否长期(0-无状态,1-长期,2-不长期)")
private Integer trailerRoadTransportCertificateLongStatus;
@NeedSetValue
@ApiModelProperty(name = "挂车行驶证主页")
private String trailerDrivingLicenseMain;
@NeedSetValue
@ApiModelProperty(name = "挂车行驶证副页")
private String trailerDrivingLicenseDeputy;
@NeedSetValue
@ApiModelProperty(name = "挂车道路运输证照片")
private String trailerRoadTransportCertificateImage;
@ApiModelProperty(name = "车牌颜色(数据字典id)")
private String otherLicensePlateColorId;
@ApiModelProperty(name = "车牌颜色(数据字典name)")
private String otherLicensePlateColorName;
@ApiModelProperty(name = "能源类型(字典id")
private String otherEnergyTypeId;
@ApiModelProperty(name = "能源类型(字典name")
private String otherEnergyTypeName;
@ApiModelProperty(name = "车轴轴数(字典id")
private String otherAxlesNumberId;
@ApiModelProperty(name = "车轴轴数(字典name")
private String otherAxlesNumberName;
@ApiModelProperty(name = "车辆长度(字典id")
private String otherCarLengthId;
@ApiModelProperty(name = "车辆长度(字典name")
private String otherCarLengthName;
@ApiModelProperty(name = "车辆容积(字典id")
private String otherVehicleVolumeId;
@ApiModelProperty(name = "车辆容积(字典name")
private String otherVehicleVolumeName;
@NeedSetValue
@ApiModelProperty(name = "车头照片")
private String otherHeadstockImage;
@NeedSetValue
@ApiModelProperty(name = "车身照片")
private String otherBodyworkImage;
@NeedSetValue
@ApiModelProperty(name = "人车合影照片")
private String otherPersonCarImage;
@ApiModelProperty(name = "道路运输证号")
private String roadTransportCertificateNo;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "道路运输证有效期")
private Date roadTransportCertificateExpireDate;
@ApiModelProperty(name = "道路运输证是否长期(0-无状态,1-长期,2-不长期)")
private Integer roadTransportCertificateLongStatus;
@NeedSetValue
@ApiModelProperty(name = "道路运输证照片")
private String roadTransportCertificateImage;
@ApiModelProperty(name = "经营许可证号")
private String businessLicenseNumber;
@ApiModelProperty(name = "业户名称")
private String specializedHouseholdsName;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "经营许可证件有效期(开始)")
private Date businessLicenseExpireStartDate;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "经营许可证件有效期(结束)")
private Date businessLicenseExpireEndDate;
@ApiModelProperty(name = "经营许可证件是否长期(0-无状态,1-长期,2-不长期)")
private Integer businessLicenseLongStatus;
@NeedSetValue
@ApiModelProperty(name = "经营许可证件照片")
private String businessLicenseImage;
@ApiModelProperty(name = "车辆审核状态(0-无状态,1-未认证,2-等待审核,3-已通过,4-已驳回)")
private Integer authenticationStatus;
@ApiModelProperty(name = "驳回原因")
private String rejectReason;
@ApiModelProperty(name = "承运人id")
private Long userId;
@ApiModelProperty(name = "承运人姓名")
private String userName;
@ApiModelProperty(name = "承运人手机号")
private String userPhone;
@ApiModelProperty(name = "车队id")
private Long motorcadeId;
@ApiModelProperty(name = "车队名称")
private String motorcadeName;
@ApiModelProperty(name = "运载状态(0-无状态,1-空载,2-负载)")
private Integer carryStatus;
@ApiModelProperty(name = "道路运输证校验状态(0-无状态,1-未核验,2-核验通过,3-核验失败)")
private Integer roadTransportCertificateCheckoutStatus;
@ApiModelProperty(name = "经营许可证件校验状态(0-无状态,1-未核验,2-核验通过,3-核验失败)")
private Integer businessLicenseCheckoutStatus;
@ApiModelProperty(name = "入网核验状态(0-无状态,1-未核验,2-已入网,3-未入网)")
private Integer netInStatus;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "入网查询时间")
private Date netInDate;
@ApiModelProperty(name = "使用状态(0-无状态,1-正常,2-黑名单)")
private Integer useStatus;
@ApiModelProperty(name = "归属组织id")
private Long organizationId;
@ApiModelProperty(name = "最高组织id")
private Long topOrganizationId;
@ApiModelProperty(name = "归属组织name")
private String organizationName;
@ApiModelProperty(name = "审核人员id")
private Long checkoutPersonId;
@ApiModelProperty(name = "审核人员name")
private String checkoutPersonName;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "审核时间")
private Date checkoutDate;
@ApiModelProperty(name = "行驶证认证状态(0-无状态,1-未认证,2-已认证)")
private Integer vehicleDrivingLicenseAuthStatus;
@ApiModelProperty(name = "车辆认证状态(0-无状态,1-未认证,2-已认证)")
private Integer vehicleAuthStatus;
@ApiModelProperty(name = "挂车认证状态(0-无状态,1-未认证,2-已认证)")
private Integer trailerLicensePlateAuthStatus;
@ApiModelProperty(name = "道路运输证认证状态(0-无状态,1-未认证,2-已认证)")
private Integer roadTransportCertificateAuthStatus;
@ApiModelProperty(name = "经营许可证认证状态(0-无状态,1-未认证,2-已认证)")
private Integer businessLicenseExpireAuthStatus;
@ApiModelProperty(name = "车辆总认证状态(0-无状态,1-未认证,2-已认证)")
private Integer authStatus;
@ApiModelProperty(name = "道路运输证审核状态(0-无状态,1-未认证,2-等待审核,3-已通过,4-已驳回)")
private Integer roadTransportCertificateCheckStatus;
@ApiModelProperty(name = "经营许可证审核状态(0-无状态,1-未认证,2-等待审核,3-已通过,4-已驳回)")
private Integer businessLicenseExpireCheckStatus;
@ApiModelProperty(name = "黑名单状态(0-无状态,1-不是,2-是)")
private Integer blacklistStatus;
@ApiModelProperty(name = "黑名单备注")
private String blacklistRemark;
@ApiModelProperty(value = "校验记录")
private java.lang.String checkRecord;
@ApiModelProperty(value = "查询车辆是否入网时间(是平台查询时间,不是入网时间)")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date checkTruckExistDate;
@ApiModelProperty(value = "查询车辆是否入网人员手机")
private String checkTruckExistUser;
@ApiModelProperty(value = "道路运输证字")
private String roadTransportCertificateWord;
@ApiModelProperty(value = "车辆道路运输证核验时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date checkRtcNoTime;
@ApiModelProperty(value = "企业道路运输经营许可证校验V3:0-未核验,1-已核验通过,2-核验失败(证件号错误/所有人错误),3-已过期,4-经营状态异常")
private Integer checkEnterpriseRoadLicense;
@ApiModelProperty(value = "企业道路运输经营许可证校验时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date checkEnterpriseRoadLicenseTime;
@ApiModelProperty(value = "实际承运人统一社会信用代码或证件号码")
private String actualcarrierid;
@ApiModelProperty(value = "道路运输许可证副页图片地址")
private String transportPermitBackImgUrl;
@ApiModelProperty(value = "车辆入网确认时间(最新定位时间)")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date checkTruckConfirmDate;
@ApiModelProperty(value = "标记状态id")
private String markerStateId;
@ApiModelProperty(value = "标记状态名称")
private String markerStateName;
@ApiModelProperty(value = "行驶证号")
private String drivingPermitNumber;
/**黑名单操作人*/
@ApiModelProperty(value = "黑名单操作人")
private java.lang.String blacklistBy;
@ApiModelProperty(value = "黑名单操作时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private java.util.Date blacklistDate;
@ApiModelProperty(value = "承运商编码(TMS)用于区别是哪个承运商下的车辆")
private String driverEnterpriseCode;
@ApiModelProperty(value = "数据来源(1-数字物流 2-TMS)")
private Integer dataSources;
@ApiModelProperty(name = "tms推送状态: 1-未推送 2- 已推送")
private Integer tmsPushStatus;
@ApiModelProperty(value = "车辆来源 0-自由车辆 1-社会车辆")
private Integer vehicleSource;
@ApiModelProperty(name = "部门Id")
private String departmentId;
@ApiModelProperty(name = "部门名称")
private String departmentName;
@ApiModelProperty(value = "年检有效期")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date annualValidityPeriod;
@ApiModelProperty(value = "保险有效期")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date insuranceValidityPeriod;
}
@@ -0,0 +1,284 @@
package com.linke.transport.domain.vehicle.entity;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* 车辆Excel
*/
@Data
public class VehicleExcel {
@ExcelProperty(index = 0)
@ApiModelProperty(name = "用户账号")
private String userAccount;
@ExcelProperty(index = 1)
@ApiModelProperty(name = "行驶证主页图片")
private String vehicleDrivingLicenseMain;
@ExcelProperty(index = 2)
@ApiModelProperty(name = "行驶证副页图片")
private String vehicleDrivingLicenseDeputy;
@ExcelProperty(index = 3)
@ApiModelProperty(name = "行驶证副页反面")
private String vehicleDrivingLicenseDeputyAgainst;
@ExcelProperty(index = 4)
@ApiModelProperty(name = "车牌号")
private String vehicleLicensePlateNumber;
@ExcelIgnore
@ApiModelProperty(name = "车辆类型(数据字典id)")
private String vehicleTypeId;
@ExcelProperty(index = 5)
@ApiModelProperty(name = "车辆类型(数据字典name)")
private String vehicleTypeName;
@ExcelProperty(index = 6)
@ApiModelProperty(name = "使用人")
private String vehicleUsePerson;
@ExcelProperty(index = 7)
@ApiModelProperty(name = "住址")
private String vehicleAddress;
@ExcelProperty(index = 8)
@ApiModelProperty(name = "使用性质")
private String vehicleUseNature;
@ExcelProperty(index = 9)
@ApiModelProperty(name = "品牌型号")
private String vehicleBrandType;
@ExcelProperty(index = 10)
@ApiModelProperty(name = "车辆识别代号")
private String vehicleIdentificationNumber;
@ExcelProperty(index = 11)
@ApiModelProperty(name = "发动机号码")
private String vehicleEngineNumber;
@ExcelProperty(index = 12)
@ApiModelProperty(name = "注册日期")
private String vehicleRegistrationString;
@ExcelProperty(index = 13)
@ApiModelProperty(name = "发证日期")
private String vehicleIssueString;
@ExcelProperty(index = 14)
@ApiModelProperty(name = "发证机关")
private String vehicleLicenceIssuingAuthority;
@ExcelProperty(index = 15)
@ApiModelProperty(name = "档案编号")
private String vehicleFileNumber;
@ExcelProperty(index = 16)
@ApiModelProperty(name = "总质量")
private BigDecimal vehicleTotalMass;
@ExcelProperty(index = 17)
@ApiModelProperty(name = "核定载质量")
private BigDecimal vehicleApprovedLoadQuantity;
@ExcelProperty(index = 18)
@ApiModelProperty(name = "外廓尺寸(长)")
private Integer vehicleGabariteOne;
@ExcelProperty(index = 19)
@ApiModelProperty(name = "外廓尺寸(宽)")
private Integer vehicleGabariteTwo;
@ExcelProperty(index = 20)
@ApiModelProperty(name = "外廓尺寸(高)")
private Integer vehicleGabariteThree;
@ExcelIgnore
@ApiModelProperty(name = "能源类型(字典id")
private String vehicleEnergyTypeId;
@ExcelProperty(index = 21)
@ApiModelProperty(name = "能源类型(字典name")
private String vehicleEnergyTypeName;
@ExcelProperty(index = 22)
@ApiModelProperty(name = "检验有效期")
private String vehicleCheckoutPeriodValidity;
@ExcelProperty(index = 23)
@ApiModelProperty(name = "备注")
private String vehicleRemark;
@ExcelProperty(index = 24)
@ApiModelProperty(value = "校验记录")
private String checkRecord;
@ExcelProperty(index = 25)
@ApiModelProperty(value = "行驶证号")
private String drivingPermitNumber;
@ExcelProperty(index = 26)
@ApiModelProperty(name = "挂车行驶证主页")
private String trailerDrivingLicenseMain;
@ExcelProperty(index = 27)
@ApiModelProperty(name = "挂车行驶证副页")
private String trailerDrivingLicenseDeputy;
@ExcelProperty(index = 28)
@ApiModelProperty(name = "挂车道路运输证照片")
private String trailerRoadTransportCertificateImage;
@ExcelProperty(index = 29)
@ApiModelProperty(name = "挂车车牌号")
private String trailerLicensePlateNumber;
@ExcelIgnore
@ApiModelProperty(name = "挂车车辆类型(数据字典id)")
private String trailerVehicleTypeId;
@ExcelProperty(index = 30)
@ApiModelProperty(name = "挂车车辆类型(数据字典name)")
private String trailerVehicleTypeName;
@ExcelIgnore
@ApiModelProperty(name = "挂车车牌颜色(数据字典id)")
private Long trailerLicensePlateColorId;
@ExcelProperty(index = 31)
@ApiModelProperty(name = "挂车车牌颜色(数据字典name)")
private String trailerLicensePlateColorName;
@ExcelProperty(index = 32)
@ApiModelProperty(name = "挂车总质量")
private BigDecimal trailerTotalMass = BigDecimal.ZERO;
@ExcelProperty(index = 33)
@ApiModelProperty(name = "挂车核定载质量")
private BigDecimal trailerApprovedLoadQuantity = BigDecimal.ZERO;
@ExcelProperty(index = 34)
@ApiModelProperty(name = "挂车行驶证到期时间")
private String trailerDrivingLicenseExpireDate;
@ExcelIgnore
@ApiModelProperty(name = "挂车行驶证是否长期(0-无状态,1-长期,2-不长期)")
private Integer trailerDrivingLicenseLongStatus;
@ExcelProperty(index = 35)
@ApiModelProperty(name = "挂车道路运输证号")
private String trailerRoadTransportCertificateNo;
@ExcelProperty(index = 36)
@ApiModelProperty(name = "挂车道路运输证有效期")
private String trailerRoadTransportCertificateExpireDate;
@ExcelIgnore
@ApiModelProperty(name = "挂车道路运输证是否长期(0-无状态,1-长期,2-不长期)")
private Integer trailerRoadTransportCertificateLongStatus;
@ExcelProperty(index = 37)
@ApiModelProperty(name = "其他车辆车头照片")
private String otherHeadstockImage;
@ExcelProperty(index = 38)
@ApiModelProperty(name = "其他车辆车身照片")
private String otherBodyworkImage;
@ExcelProperty(index = 39)
@ApiModelProperty(name = "其他车辆人车合影照片")
private String otherPersonCarImage;
@ExcelIgnore
@ApiModelProperty(name = "其他车辆车牌颜色(1-蓝色,2-黄色,2-绿色)")
private String otherLicensePlateColorId;
@ExcelProperty(index = 40)
@ApiModelProperty(name = "其他车辆车牌颜色")
private String otherLicensePlateColorName;
@ExcelIgnore
@ApiModelProperty(name = "车轴轴数(字典id")
private String otherAxlesNumberId;
@ExcelProperty(index = 41)
@ApiModelProperty(name = "车轴轴数(字典name")
private String otherAxlesNumberName;
@ExcelIgnore
@ApiModelProperty(name = "车辆长度(字典id")
private String otherCarLengthId;
@ExcelProperty(index = 42)
@ApiModelProperty(name = "车辆长度(字典name")
private String otherCarLengthName;
@ExcelIgnore
@ApiModelProperty(name = "车辆容积(字典id")
private String otherVehicleVolumeId;
@ExcelProperty(index = 43)
@ApiModelProperty(name = "车辆容积(字典name")
private String otherVehicleVolumeName;
@ExcelProperty(index = 44)
@ApiModelProperty(name = "道路运输证照片")
private String roadTransportCertificateImage;
@ExcelProperty(index = 45)
@ApiModelProperty(name = "道路运输证号")
private String roadTransportCertificateNo;
@ExcelProperty(index = 46)
@ApiModelProperty(value = "道路运输证到期日期")
private String transportPermitExpString;
@ExcelProperty(index = 47)
@ApiModelProperty(name = "经营许可证件照片")
private String businessLicenseImage;
@ExcelProperty(index = 48)
@ApiModelProperty(name = "经营许可证号")
private String businessLicenseNumber;
@ExcelProperty(index = 49)
@ApiModelProperty(name = "业户名称")
private String specializedHouseholdsName;
@ExcelProperty(index = 50)
@ApiModelProperty(name = "经营许可证件有效期(开始)")
private String businessLicenseExpireStartDate;
@ExcelProperty(index = 51)
@ApiModelProperty(name = "经营许可证件有效期(结束)")
private String businessLicenseExpireEndDate;
@ExcelIgnore
@ApiModelProperty(name = "经营许可证件是否长期(0-无状态,1-长期,2-不长期)")
private Integer businessLicenseLongStatus;
@ExcelProperty(index = 52)
@ApiModelProperty(value = "道路运输证字")
private String roadTransportCertificateWord;
@ExcelIgnore
@ApiModelProperty(value = "企业道路运输经营许可证校验V3:0-未核验,1-已核验通过,2-核验失败(证件号错误/所有人错误),3-已过期,4-经营状态异常")
private Integer checkEnterpriseRoadLicense;
@ExcelProperty(index = 53)
@ApiModelProperty(value = "企业道路运输经营许可证校验V3:0-未核验,1-已核验通过,2-核验失败(证件号错误/所有人错误),3-已过期,4-经营状态异常")
private String checkEnterpriseRoadLicenseStr;
@ExcelProperty(index = 54)
@ApiModelProperty(value = "企业道路运输经营许可证校验时间")
private String checkEnterpriseRoadLicenseTime;
}
@@ -0,0 +1,108 @@
package com.linke.transport.domain.vehicle.repository.facade;
import java.util.List;
import com.linke.transport.domain.vehicle.repository.po.DriverVehicleBindPo;
import com.linke.transport.domain.vehicle.repository.po.VehicleAppPo;
import com.baomidou.mybatisplus.extension.service.IService;
import com.linke.transport.domain.vehicle.repository.po.VehiclePo;
import com.linke.transport.domain.vehicle.entity.Vehicle;
import com.linke.transport.interfaces.dto.vehicle.VehicleDto;
import com.mhd.common.core.domain.dto.DriverVehicleBindDto;
import org.apache.ibatis.annotations.Param;
/**
* 车辆 业务层
*
* 2022-12-9
*
* @author 王子豪
*/
public interface VehicleServiceRepositoryInterface extends IService<Vehicle>
{
/**
* 查询车辆管理
*
* @param vehicleId 车辆管理主键
* @return 车辆管理
*/
public VehiclePo selectVehicleByVehicleId(Long vehicleId);
public List<VehiclePo> selectVehicleByMotorcadeId(Long motorcadeId);
public com.mhd.common.core.domain.po.VehiclePo selectVehiclePoByVehicleId(Long vehicleId);
/**
* 查询车辆管理列表
*
* @param vehiclePo 车辆管理
* @return 车辆管理集合
*/
public List<VehiclePo> selectVehicleList(VehiclePo vehiclePo);
/**
* 配载页面查询车辆管理列表
*
* @param vehiclePo 车辆管理
* @return 车辆管理集合
*/
public List<VehiclePo> selectStowageVehiclelist(VehiclePo vehiclePo);
/**
* 新增车辆管理
*
* @param vehicle 车辆管理
* @return 结果
*/
public int insertVehicle(Vehicle vehicle);
/**
* 修改车辆管理
*
* @param vehicle 车辆管理
* @return 结果
*/
public int updateVehicle(Vehicle vehicle);
/**
* 批量修改车辆管理
*
* @param list
* @return
*/
public int batchUpdateVehicle(List<Vehicle> list);
/**
* 批量删除车辆管理
*
* @param vehicleIds 需要删除的车辆管理主键集合
* @return 结果
*/
public int deleteVehicleByVehicleIds(Long[] vehicleIds);
/**
* 删除车辆管理信息
*
* @param vehicleId 车辆管理主键
* @return 结果
*/
public int deleteVehicleByVehicleId(Long vehicleId);
List<Vehicle> getVehicleByIds(List<Long> vehicleIdList);
/**
* 根据车辆id,以及车牌号查询
* @param vehicleDto
* @return
*/
List<VehiclePo> selectVehicleByVehicleIdAndPlan(VehicleDto vehicleDto);
VehicleAppPo selectVehicleAppById(Long vehicleId);
List<DriverVehicleBindPo> ownerBindCarList(DriverVehicleBindDto driverVehicleBindDto);
List<DriverVehicleBindPo> driverBindMyCarList(DriverVehicleBindDto driverVehicleBindDto);
VehiclePo findVehicleByPlateNumber(String plateNumber);
}
@@ -0,0 +1,125 @@
package com.linke.transport.domain.vehicle.repository.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.linke.transport.domain.vehicle.entity.Vehicle;
import com.linke.transport.domain.vehicle.repository.po.DriverVehicleBindPo;
import com.linke.transport.domain.vehicle.repository.po.VehicleAppPo;
import com.linke.transport.domain.vehicle.repository.po.VehiclePo;
import com.linke.transport.interfaces.dto.vehicle.VehicleDto;
import com.mhd.common.core.domain.dto.DriverVehicleBindDto;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* 车辆 数据层
*
* 2022-12-9
*
* @author 王子豪
*/
public interface VehicleMapper extends BaseMapper<Vehicle>
{
/**
* 查询车辆管理
*
* @param vehicleId 车辆管理主键
* @return 车辆管理
*/
public VehiclePo selectVehicleByVehicleId(Long vehicleId);
@Select("select * from vehicle where del_flag=1 and motorcade_id=#{motorcadeId} ")
public List<VehiclePo> selectVehicleByMotorcadeId(Long motorcadeId);
public com.mhd.common.core.domain.po.VehiclePo selectVehiclePoByVehicleId(Long vehicleId);
/**
* 查询车辆管理列表
*
* @param vehiclePo 车辆管理
* @return 车辆管理集合
*/
public List<VehiclePo> selectVehicleList(VehiclePo vehiclePo);
/**
* 配载页面查询车辆管理列表
*
* @param vehiclePo 车辆管理
* @return 车辆管理集合
*/
public List<VehiclePo> selectStowageVehiclelist(VehiclePo vehiclePo);
/**
* 新增车辆管理
*
* @param vehicle 车辆管理
* @return 结果
*/
public int insertVehicle(Vehicle vehicle);
/**
* 修改车辆管理
*
* @param vehicle 车辆管理
* @return 结果
*/
public int updateVehicle(Vehicle vehicle);
/**
* 批量修改车辆管理
*
* @param vehicleList
* @return
*/
public int batchUpdateVehicle(@Param("vehicleList") List<Vehicle> vehicleList);
/**
* 删除车辆管理
*
* @param vehicleId 车辆管理主键
* @return 结果
*/
public int deleteVehicleByVehicleId(Long vehicleId);
/**
* 批量删除车辆管理
*
* @param vehicleIds 需要删除的数据主键集合
* @return 结果
*/
public int deleteVehicleByVehicleIds(Long[] vehicleIds);
/**
* 根据车辆ids查询车辆信息
* @param vehicleIdList
* @return
*/
List<Vehicle> getVehicleByIds(@Param("vehicleIdList") List<Long> vehicleIdList);
/**
* 根据车辆id,以及车牌号查询
* @param vehicleDto
* @return
*/
List<VehiclePo> selectVehicleByVehicleIdAndPlan(@Param("vehicleDto") VehicleDto vehicleDto);
VehiclePo findVehicleByPlateNumber(@Param("plateNumber") String plateNumber);
/**
* 根据id查询车辆信息 APP
* @param vehicleId 车辆id
* @return
*/
VehicleAppPo selectVehicleAppById(@Param("vehicleId") Long vehicleId);
/**
* APP我是车主列表查询
*/
List<DriverVehicleBindPo> ownerBindCarList(@Param("driverVehicleBindDto") DriverVehicleBindDto driverVehicleBindDto);
/**
* APP绑定车辆我的车辆列表查询
*/
List<DriverVehicleBindPo> driverBindMyCarList(@Param("driverVehicleBindDto") DriverVehicleBindDto driverVehicleBindDto);
}
@@ -0,0 +1,202 @@
package com.linke.transport.domain.vehicle.repository.persistence;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linke.transport.domain.vehicle.repository.mapper.VehicleMapper;
import com.linke.transport.domain.vehicle.entity.Vehicle;
import com.linke.transport.domain.vehicle.repository.facade.VehicleServiceRepositoryInterface;
import com.linke.transport.domain.vehicle.repository.po.DriverVehicleBindPo;
import com.linke.transport.domain.vehicle.repository.po.VehicleAppPo;
import com.linke.transport.domain.vehicle.repository.po.VehiclePo;
import com.linke.transport.interfaces.dto.vehicle.VehicleDto;
import com.mhd.common.core.domain.dto.DriverVehicleBindDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 车辆 业务实现层
*
* 本层为核心业务层,不可掺杂其他业务
*
* 2022-12-9
*
* @author 王子豪
*/
@Service
public class VehicleRepositoryImpl extends ServiceImpl<VehicleMapper, Vehicle> implements VehicleServiceRepositoryInterface
{
@Autowired
private VehicleMapper vehicleMapper;
/**
* 查询车辆管理
*
* @param vehicleId 车辆管理主键
* @return 车辆管理
*/
@Override
public VehiclePo selectVehicleByVehicleId(Long vehicleId)
{
return vehicleMapper.selectVehicleByVehicleId(vehicleId);
}
@Override
public List<VehiclePo> selectVehicleByMotorcadeId(Long motorcadeId) {
return vehicleMapper.selectVehicleByMotorcadeId(motorcadeId);
}
@Override
public com.mhd.common.core.domain.po.VehiclePo selectVehiclePoByVehicleId(Long vehicleId)
{
return vehicleMapper.selectVehiclePoByVehicleId(vehicleId);
}
/**
* 查询车辆管理列表
*
* @param vehiclePo 车辆管理
* @return 车辆管理
*/
@Override
public List<VehiclePo> selectVehicleList(VehiclePo vehiclePo)
{
return vehicleMapper.selectVehicleList(vehiclePo);
}
/**
* 配载页面查询车辆管理列表
*
* @param vehiclePo 车辆管理
* @return 车辆管理集合
*/
@Override
public List<VehiclePo> selectStowageVehiclelist(VehiclePo vehiclePo){
return vehicleMapper.selectStowageVehiclelist(vehiclePo);
}
/**
* 新增车辆管理
*
* @param vehicle 车辆管理
* @return 结果
*/
@Override
public int insertVehicle(Vehicle vehicle)
{
return vehicleMapper.insert(vehicle);
}
/**
* 修改车辆管理
*
* @param vehicle 车辆管理
* @return 结果
*/
@Override
public int updateVehicle(Vehicle vehicle)
{
return vehicleMapper.updateById(vehicle);
}
/**
* 批量修改车辆管理
*
* @param list
* @return
*/
@Override
public int batchUpdateVehicle(List<Vehicle> list){
return vehicleMapper.batchUpdateVehicle(list);
}
/**
* 批量删除车辆管理
*
* @param vehicleIds 需要删除的车辆管理主键
* @return 结果
*/
@Override
public int deleteVehicleByVehicleIds(Long[] vehicleIds)
{
return vehicleMapper.deleteVehicleByVehicleIds(vehicleIds);
}
/**
* 删除车辆管理信息
*
* @param vehicleId 车辆管理主键
* @return 结果
*/
@Override
public int deleteVehicleByVehicleId(Long vehicleId)
{
return vehicleMapper.deleteVehicleByVehicleId(vehicleId);
}
/**
* 根据车辆ids查询车辆信息
* @param vehicleIdList
* @return
*/
@Override
public List<Vehicle> getVehicleByIds(List<Long> vehicleIdList) {
return vehicleMapper.getVehicleByIds(vehicleIdList);
}
/**
* 根据车辆id,以及车牌号查询
* @param vehicleDto
* @return
*/
@Override
public List<VehiclePo> selectVehicleByVehicleIdAndPlan(VehicleDto vehicleDto) {
return vehicleMapper.selectVehicleByVehicleIdAndPlan(vehicleDto);
}
/**
* 根据id查询车辆信息 APP
* @param vehicleId
* @return
*/
@Override
public VehicleAppPo selectVehicleAppById(Long vehicleId) {
return vehicleMapper.selectVehicleAppById(vehicleId);
}
@Override
public List<DriverVehicleBindPo> ownerBindCarList(DriverVehicleBindDto driverVehicleBindDto) {
return vehicleMapper.ownerBindCarList(driverVehicleBindDto);
}
/**
* APP绑定车辆我的车辆列表查询
*/
@Override
public List<DriverVehicleBindPo> driverBindMyCarList(DriverVehicleBindDto driverVehicleBindDto) {
return vehicleMapper.driverBindMyCarList(driverVehicleBindDto);
}
@Override
public VehiclePo findVehicleByPlateNumber(String plateNumber) {
return vehicleMapper.findVehicleByPlateNumber(plateNumber);
}
/**
* 根据用户id查询车辆信息
* @param userId
* @return
*/
public Vehicle selectVehicleByUserId(Long userId) {
return vehicleMapper.selectOne(new QueryWrapper<Vehicle>().lambda()
.eq(Vehicle::getUserId,userId).eq(Vehicle::getDelFlag,1));
}
public List<Vehicle> selectVehiclesByUserId(Long userId) {
return vehicleMapper.selectList(new QueryWrapper<Vehicle>().lambda()
.eq(Vehicle::getUserId,userId).eq(Vehicle::getDelFlag,1));
}
}
@@ -0,0 +1,78 @@
package com.linke.transport.domain.vehicle.repository.po;
import com.mhd.common.core.web.domain.BaseVOEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* app我的车辆列表查询实体
*
* @author ???
* @date 2023-05-18
*/
@Data
public class DriverVehicleBindPo extends BaseVOEntity{
private static final long serialVersionUID = 1L;
/** 司机车辆绑定表id */
@ApiModelProperty("司机车辆绑定表id")
private Long driverVehicleBindId;
/** 用户主表ID */
@ApiModelProperty("用户主表ID")
private Long userId;
/** 车辆id */
@ApiModelProperty("车辆id")
private Long vehicleId;
/** 车辆关联司机userid */
@ApiModelProperty("车辆关联司机userid")
private Long driverBindId;
/** 绑定司机姓名 */
@ApiModelProperty("绑定司机姓名")
private String bindDriverName;
/** 绑定司机手机号 */
@ApiModelProperty("绑定司机手机号")
private String bindDriverPhone;
/** 一级组织表ID */
@ApiModelProperty("一级组织表ID")
private Long topOrganizationId;
/** 归属组织id */
@ApiModelProperty("归属组织id")
private Long organizationId;
/** 默认状态(1-是,2-否) */
@ApiModelProperty("默认状态(1-是,2-否)")
private Integer defaultFlag;
@ApiModelProperty("车牌号")
private String vehicleLicensePlateNumber;
@ApiModelProperty(name = "车辆类型(数据字典name)")
private String vehicleTypeName;
@ApiModelProperty(name = "核定载质量")
private BigDecimal vehicleApprovedLoadQuantity;
@ApiModelProperty(name = "车辆总认证状态(0-无状态,1-未认证,2-正在审核,3-认证成功,4-认证失败,5-认证失效)")
private Integer authenticationStatus ;
@ApiModelProperty(name = "驳回原因")
private String rejectReason;
@ApiModelProperty(name = "其他车辆车头照片")
private String otherHeadstockImage;
@ApiModelProperty(name = "其他车辆车牌颜色(1-蓝色,2-黄色,2-绿色)")
private String otherLicensePlateColorId;
@ApiModelProperty(name = "其他车辆车牌颜色")
private String otherLicensePlateColorName;
@ApiModelProperty(name = "车辆类型(数据字典id)")
private String vehicleTypeId;
}
@@ -0,0 +1,260 @@
package com.linke.transport.domain.vehicle.repository.po;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mhd.common.core.web.domain.BaseVOEntity;
import com.mhd.common.core.annotation.fieldsetvalue.NeedSetValue;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 车辆管理App po
*
* 2022-12-9
*
* @author 王子豪
*/
@Data
public class VehicleAppPo extends BaseVOEntity implements Serializable
{
@ApiModelProperty(name = "车辆id")
private Long vehicleId = 0L;
@ApiModelProperty(name = "车牌号")
private String vehicleLicensePlateNumber = "";
@ApiModelProperty(name = "车辆类型(数据字典id)")
private String vehicleTypeId = "";
@ApiModelProperty(name = "车辆类型(数据字典name)")
private String vehicleTypeName = "";
@ApiModelProperty(name = "车辆来源(数据字典id)")
private String vehicleSourceId = "";
@ApiModelProperty(name = "车辆来源(数据字典name)")
private String vehicleSourceName = "";
@ApiModelProperty(name = "使用人")
private String vehicleUsePerson = "";
@ApiModelProperty(name = "住址")
private String vehicleAddress = "";
@ApiModelProperty(name = "使用性质")
private String vehicleUseNature = "";
@ApiModelProperty(name = "品牌类型")
private String vehicleBrandType = "";
@ApiModelProperty(name = "车辆识别代号")
private String vehicleIdentificationNumber = "";
@ApiModelProperty(name = "发动机号码")
private String vehicleEngineNumber = "";
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "注册日期")
private Date vehicleRegistrationDate;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "发证日期")
private Date vehicleIssueDate;
@ApiModelProperty(name = "发证机关")
private String vehicleLicenceIssuingAuthority = "";
@ApiModelProperty(name = "档案编号")
private String vehicleFileNumber = "";
@ApiModelProperty(name = "总质量")
private BigDecimal vehicleTotalMass = BigDecimal.ZERO;
@ApiModelProperty(name = "核定载质量")
private BigDecimal vehicleApprovedLoadQuantity = BigDecimal.ZERO;
@ApiModelProperty(name = "外廓尺寸(长)")
private Integer vehicleGabariteOne = 0;
@ApiModelProperty(name = "外廓尺寸(宽)")
private Integer vehicleGabariteTwo = 0;
@ApiModelProperty(name = "外廓尺寸(高)")
private Integer vehicleGabariteThree = 0;
@ApiModelProperty(name = "能源类型(字典id")
private String vehicleEnergyTypeId = "";
@ApiModelProperty(name = "能源类型(字典name")
private String vehicleEnergyTypeName = "";
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "检验有效期")
private Date vehicleCheckoutPeriodValidity;
@ApiModelProperty(name = "备注")
private String vehicleRemark = "";
@NeedSetValue
@ApiModelProperty(name = "行驶证主页")
private String vehicleDrivingLicenseMain = "";
@NeedSetValue
@ApiModelProperty(name = "行驶证副页")
private String vehicleDrivingLicenseDeputy = "";
@NeedSetValue
@ApiModelProperty(name = "行驶证副页反面")
private String vehicleDrivingLicenseDeputyAgainst = "";
@ApiModelProperty(name = "是否挂车(0-无状态,1-挂车,2-不挂车)")
private Integer trailerStatus = 0;
@ApiModelProperty(name = "其他车辆车牌颜色(数据字典id)")
private String otherLicensePlateColorId = "";
@ApiModelProperty(name = "其他车辆车牌颜色(数据字典name)")
private String otherLicensePlateColorName = "";
@ApiModelProperty(name = "其他车辆能源类型(字典id")
private String otherEnergyTypeId = "";
@ApiModelProperty(name = "其他车辆能源类型(字典name")
private String otherEnergyTypeName = "";
@ApiModelProperty(name = "其他车辆车轴轴数(字典id")
private String otherAxlesNumberId = "";
@ApiModelProperty(name = "其他车辆车轴轴数(字典name")
private String otherAxlesNumberName = "";
@ApiModelProperty(name = "其他车辆车辆长度(字典id")
private String otherCarLengthId = "";
@ApiModelProperty(name = "其他车辆车辆长度(字典name")
private String otherCarLengthName = "";
@ApiModelProperty(name = "其他车辆车辆容积(字典id")
private String otherVehicleVolumeId = "";
@ApiModelProperty(name = "其他车辆车辆容积(字典name")
private String otherVehicleVolumeName = "";
@NeedSetValue
@ApiModelProperty(name = "其他车辆车头照片")
private String otherHeadstockImage = "";
@NeedSetValue
@ApiModelProperty(name = "其他车辆车身照片")
private String otherBodyworkImage = "";
@NeedSetValue
@ApiModelProperty(name = "其他车辆人车合影照片")
private String otherPersonCarImage = "";
@ApiModelProperty(name = "道路运输证号")
private String roadTransportCertificateNo = "";
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "道路运输证有效期")
private Date roadTransportCertificateExpireDate;
@ApiModelProperty(name = "道路运输证是否长期(0-无状态,1-长期,2-不长期)")
private Integer roadTransportCertificateLongStatus = 0;
@NeedSetValue
@ApiModelProperty(name = "道路运输证照片")
private String roadTransportCertificateImage = "";
@ApiModelProperty(name = "经营许可证号")
private String businessLicenseNumber = "";
@ApiModelProperty(name = "业户名称")
private String specializedHouseholdsName = "";
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "经营许可证件有效期(开始)")
private Date businessLicenseExpireStartDate;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "经营许可证件有效期(结束)")
private Date businessLicenseExpireEndDate;
@ApiModelProperty(name = "经营许可证件是否长期(0-无状态,1-长期,2-不长期)")
private Integer businessLicenseLongStatus = 0;
@NeedSetValue
@ApiModelProperty(name = "经营许可证件照片")
private String businessLicenseImage = "";
@ApiModelProperty(name = "车辆审核状态(0-无状态,1-未认证,2-等待审核,3-已通过,4-已驳回)")
private Integer authenticationStatus = 0;
@ApiModelProperty(name = "车辆认证状态名称")
private String authenticationStatusName = "";
@ApiModelProperty(name = "驳回原因")
private String rejectReason = "";
@ApiModelProperty(name = "承运人id")
private Long userId = 0L;
@ApiModelProperty(name = "承运人姓名")
private String userName = "";
@ApiModelProperty(name = "承运人手机号")
private String userPhone = "";
@ApiModelProperty(name = "车队id")
private Long motorcadeId = 0L;
@ApiModelProperty(name = "车队名称")
private String motorcadeName = "";
@ApiModelProperty(name = "运载状态(0-无状态,1-空载,2-负载)")
private Integer carryStatus = 0;
@ApiModelProperty(name = "道路运输证校验状态(0-无状态,1-未核验,2-核验通过,3-核验失败)")
private Integer roadTransportCertificateCheckoutStatus = 0;
@ApiModelProperty(name = "经营许可证件校验状态(0-无状态,1-未核验,2-核验通过,3-核验失败)")
private Integer businessLicenseCheckoutStatus = 0;
@ApiModelProperty(name = "入网核验状态(0-无状态,1-未核验,2-已入网,3-未入网)")
private Integer netInStatus = 0;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "入网查询时间")
private Date netInDate;
@ApiModelProperty(name = "使用状态(0-无状态,1-正常,2-黑名单)")
private Integer useStatus = 0;
@ApiModelProperty(name = "最高组织id")
private Long topOrganizationId;
@ApiModelProperty(name = "归属组织id")
private Long organizationId;
@ApiModelProperty(name = "归属组织name")
private String organizationName = "";
@ApiModelProperty(name = "审核人员id")
private Long checkoutPersonId;
@ApiModelProperty(name = "审核人员name")
private String checkoutPersonName = "";
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "审核时间")
private Date checkoutDate;
@ApiModelProperty(name = "行驶证认证状态(0-无状态,1-未认证,2-已认证)")
private Integer vehicleDrivingLicenseAuthStatus = 0;
@ApiModelProperty(name = "车辆认证状态(0-无状态,1-未认证,2-已认证)")
private Integer vehicleAuthStatus = 0;
@ApiModelProperty(name = "挂车认证状态(0-无状态,1-未认证,2-已认证)")
private Integer trailerLicensePlateAuthStatus = 0;
@ApiModelProperty(name = "道路运输证认证状态(0-无状态,1-未认证,2-已认证)")
private Integer roadTransportCertificateAuthStatus = 0;
@ApiModelProperty(name = "经营许可证认证状态(0-无状态,1-未认证,2-已认证)")
private Integer businessLicenseExpireAuthStatus = 0;
@ApiModelProperty(name = "车辆总认证状态(0-无状态,1-未认证,2-已认证)")
private Integer authStatus = 0;
@ApiModelProperty(name = "道路运输证审核状态(0-无状态,1-未认证,2-等待审核,3-已通过,4-已驳回)")
private Integer roadTransportCertificateCheckStatus = 0;
@ApiModelProperty(name = "经营许可证审核状态(0-无状态,1-未认证,2-等待审核,3-已通过,4-已驳回)")
private Integer businessLicenseExpireCheckStatus = 0;
@ApiModelProperty(name = "黑名单状态(0-无状态,1-不是,2-是)")
private Integer blacklistStatus = 0;
@ApiModelProperty(name = "黑名单备注")
private String blacklistRemark = "";
@ApiModelProperty(value = "承运商编码(TMS)用于区别是哪个承运商下的车辆")
private String driverEnterpriseCode;
@ApiModelProperty(value = "数据来源(1-数字物流 2-TMS)")
private Integer dataSources;
@ApiModelProperty(value = "车辆类别:1-个人车辆 2-企业车辆")
private Integer vehicleCategory;
@ApiModelProperty(name = "挂车车牌号")
private String trailerLicensePlateNumber = "";
@ApiModelProperty(name = "挂车车辆类型(数据字典id)")
private String trailerVehicleTypeId = "";
@ApiModelProperty(name = "挂车车辆类型(数据字典name)")
private String trailerVehicleTypeName = "";
@ApiModelProperty(name = "挂车车牌颜色(数据字典id)")
private String trailerLicensePlateColorId = "";
@ApiModelProperty(name = "挂车车牌颜色(数据字典name)")
private String trailerLicensePlateColorName = "";
@ApiModelProperty(name = "挂车总质量")
private BigDecimal trailerTotalMass = BigDecimal.ZERO;
@ApiModelProperty(name = "挂车核定载质量")
private BigDecimal trailerApprovedLoadQuantity = BigDecimal.ZERO;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "挂车行驶证到期时间")
private Date trailerDrivingLicenseExpireDate;
@ApiModelProperty(name = "挂车行驶证是否长期(0-无状态,1-长期,2-不长期)")
private Integer trailerDrivingLicenseLongStatus;
@ApiModelProperty(name = "挂车道路运输证号")
private String trailerRoadTransportCertificateNo = "";
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "挂车道路运输证有效期")
private Date trailerRoadTransportCertificateExpireDate;
@ApiModelProperty(name = "挂车道路运输证是否长期(0-无状态,1-长期,2-不长期)")
private Integer trailerRoadTransportCertificateLongStatus;
@NeedSetValue
@ApiModelProperty(name = "挂车行驶证主页")
private String trailerDrivingLicenseMain = "";
@NeedSetValue
@ApiModelProperty(name = "挂车行驶证副页")
private String trailerDrivingLicenseDeputy = "";
@NeedSetValue
@ApiModelProperty(name = "挂车道路运输证照片")
private String trailerRoadTransportCertificateImage = "";
}
@@ -0,0 +1,428 @@
package com.linke.transport.domain.vehicle.repository.po;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mhd.common.core.web.domain.BaseVOEntity;
import com.mhd.common.core.annotation.fieldsetvalue.NeedSetValue;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 车辆管理 po
*
* 2022-12-9
*
* @author 王子豪
*/
@Data
public class VehiclePo extends BaseVOEntity implements Serializable
{
@ApiModelProperty(name = "车辆id")
private Long vehicleId;
@ApiModelProperty(name = "车牌号")
private String vehicleLicensePlateNumber;
@ApiModelProperty(name = "车辆类别:1-个人车辆 2-企业车辆")
private Integer vehicleCategory;
@ApiModelProperty(name = "车辆类型(数据字典id)")
private String vehicleTypeId;
@ApiModelProperty(name = "车辆类型(数据字典name)")
private String vehicleTypeName;
@ApiModelProperty(name = "车辆来源(数据字典id)")
private String vehicleSourceId;
@ApiModelProperty(name = "车辆来源(数据字典name)")
private String vehicleSourceName;
@ApiModelProperty(name = "使用人")
private String vehicleUsePerson;
@ApiModelProperty(name = "住址")
private String vehicleAddress;
@ApiModelProperty(name = "使用性质")
private String vehicleUseNature;
@ApiModelProperty(name = "品牌类型")
private String vehicleBrandType;
@ApiModelProperty(name = "车辆识别代号")
private String vehicleIdentificationNumber;
@ApiModelProperty(name = "发动机号码")
private String vehicleEngineNumber;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "注册日期")
private Date vehicleRegistrationDate;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "发证日期")
private Date vehicleIssueDate;
@ApiModelProperty(name = "发证机关")
private String vehicleLicenceIssuingAuthority;
@ApiModelProperty(name = "档案编号")
private String vehicleFileNumber;
@ApiModelProperty(name = "总质量")
private BigDecimal vehicleTotalMass;
@ApiModelProperty(name = "核定载质量")
private BigDecimal vehicleApprovedLoadQuantity;
@ApiModelProperty(name = "外廓尺寸(长)")
private Integer vehicleGabariteOne;
@ApiModelProperty(name = "外廓尺寸(宽)")
private Integer vehicleGabariteTwo;
@ApiModelProperty(name = "外廓尺寸(高)")
private Integer vehicleGabariteThree;
@ApiModelProperty(name = "能源类型(字典id")
private String vehicleEnergyTypeId;
@ApiModelProperty(name = "能源类型(字典name")
private String vehicleEnergyTypeName;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "检验有效期")
private Date vehicleCheckoutPeriodValidity;
@ApiModelProperty(name = "备注")
private String vehicleRemark;
@NeedSetValue
@ApiModelProperty(name = "行驶证主页")
private String vehicleDrivingLicenseMain;
@NeedSetValue
@ApiModelProperty(name = "行驶证副页")
private String vehicleDrivingLicenseDeputy;
@NeedSetValue
@ApiModelProperty(name = "行驶证副页反面")
private String vehicleDrivingLicenseDeputyAgainst;
@ApiModelProperty(name = "是否挂车(0-无状态,1-挂车,2-不挂车)")
private Integer trailerStatus;
@ApiModelProperty(name = "挂车车牌号")
private String trailerLicensePlateNumber;
@ApiModelProperty(name = "挂车车辆类型(数据字典id)")
private String trailerVehicleTypeId;
@ApiModelProperty(name = "挂车车辆类型(数据字典name)")
private String trailerVehicleTypeName;
@ApiModelProperty(name = "挂车车牌颜色(数据字典id)")
private String trailerLicensePlateColorId;
@ApiModelProperty(name = "挂车车牌颜色(数据字典name)")
private String trailerLicensePlateColorName;
@ApiModelProperty(name = "挂车总质量")
private BigDecimal trailerTotalMass;
@ApiModelProperty(name = "挂车核定载质量")
private BigDecimal trailerApprovedLoadQuantity;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "挂车行驶证到期时间")
private Date trailerDrivingLicenseExpireDate;
@ApiModelProperty(name = "挂车行驶证是否长期(0-无状态,1-长期,2-不长期)")
private Integer trailerDrivingLicenseLongStatus;
@ApiModelProperty(name = "挂车道路运输证号")
private String trailerRoadTransportCertificateNo;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "挂车道路运输证有效期")
private Date trailerRoadTransportCertificateExpireDate;
@ApiModelProperty(name = "挂车道路运输证是否长期(0-无状态,1-长期,2-不长期)")
private Integer trailerRoadTransportCertificateLongStatus;
@NeedSetValue
@ApiModelProperty(name = "挂车行驶证主页")
private String trailerDrivingLicenseMain;
@NeedSetValue
@ApiModelProperty(name = "挂车行驶证副页")
private String trailerDrivingLicenseDeputy;
@NeedSetValue
@ApiModelProperty(name = "挂车道路运输证照片")
private String trailerRoadTransportCertificateImage;
@ApiModelProperty(name = "其他车辆车牌颜色(数据字典id)")
private String otherLicensePlateColorId;
@ApiModelProperty(name = "其他车辆车牌颜色(数据字典name)")
private String otherLicensePlateColorName;
@ApiModelProperty(name = "其他车辆能源类型(字典id")
private String otherEnergyTypeId;
@ApiModelProperty(name = "其他车辆能源类型(字典name")
private String otherEnergyTypeName;
@ApiModelProperty(name = "其他车辆车轴轴数(字典id")
private String otherAxlesNumberId;
@ApiModelProperty(name = "其他车辆车轴轴数(字典name")
private String otherAxlesNumberName;
@ApiModelProperty(name = "其他车辆车辆长度(字典id")
private String otherCarLengthId;
@ApiModelProperty(name = "其他车辆车辆长度(字典name")
private String otherCarLengthName;
@ApiModelProperty(name = "其他车辆车辆容积(字典id")
private String otherVehicleVolumeId;
@ApiModelProperty(name = "其他车辆车辆容积(字典name")
private String otherVehicleVolumeName;
@NeedSetValue
@ApiModelProperty(name = "其他车辆车头照片")
private String otherHeadstockImage;
@NeedSetValue
@ApiModelProperty(name = "其他车辆车身照片")
private String otherBodyworkImage;
@NeedSetValue
@ApiModelProperty(name = "其他车辆人车合影照片")
private String otherPersonCarImage;
@ApiModelProperty(name = "道路运输证号")
private String roadTransportCertificateNo;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "道路运输证有效期")
private Date roadTransportCertificateExpireDate;
@ApiModelProperty(name = "道路运输证是否长期(0-无状态,1-长期,2-不长期)")
private Integer roadTransportCertificateLongStatus;
@NeedSetValue
@ApiModelProperty(name = "道路运输证照片")
private String roadTransportCertificateImage;
@ApiModelProperty(name = "经营许可证号")
private String businessLicenseNumber;
@ApiModelProperty(name = "业户名称")
private String specializedHouseholdsName;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "经营许可证件有效期(开始)")
private Date businessLicenseExpireStartDate;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "经营许可证件有效期(结束)")
private Date businessLicenseExpireEndDate;
@ApiModelProperty(name = "经营许可证件是否长期(0-无状态,1-长期,2-不长期)")
private Integer businessLicenseLongStatus;
@NeedSetValue
@ApiModelProperty(name = "经营许可证件照片")
private String businessLicenseImage;
@ApiModelProperty(name = "车辆审核状态(0-无状态,1-未认证,2-等待审核,3-已通过,4-已驳回)")
private Integer authenticationStatus;
@ApiModelProperty(name = "车辆认证状态名称")
private String authenticationStatusName = "";
@ApiModelProperty(name = "驳回原因")
private String rejectReason;
@ApiModelProperty(name = "承运人id")
private Long userId;
@ApiModelProperty(name = "承运人姓名")
private String userName;
@ApiModelProperty(name = "承运人手机号")
private String userPhone;
@ApiModelProperty(name = "车队id")
private Long motorcadeId;
@ApiModelProperty(name = "车队名称")
private String motorcadeName;
@ApiModelProperty(name = "运载状态(0-无状态,1-空载,2-负载)")
private Integer carryStatus;
@ApiModelProperty(name = "道路运输证校验状态(0-无状态,1-未核验,2-核验通过,3-核验失败)")
private Integer roadTransportCertificateCheckoutStatus;
@ApiModelProperty(name = "经营许可证件校验状态(0-无状态,1-未核验,2-核验通过,3-核验失败)")
private Integer businessLicenseCheckoutStatus;
@ApiModelProperty(name = "入网核验状态(0-无状态,1-未核验,2-已入网,3-未入网)")
private Integer netInStatus;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "入网查询时间")
private Date netInDate;
@ApiModelProperty(name = "使用状态(0-无状态,1-正常,2-黑名单)")
private Integer useStatus;
@ApiModelProperty(name = "最高组织id")
private Long topOrganizationId;
@ApiModelProperty(name = "归属组织id")
private Long organizationId;
@ApiModelProperty(name = "归属组织name")
private String organizationName;
@ApiModelProperty(name = "审核人员id")
private Long checkoutPersonId;
@ApiModelProperty(name = "审核人员name")
private String checkoutPersonName;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "审核时间")
private Date checkoutDate;
@ApiModelProperty(name = "行驶证认证状态(0-无状态,1-未认证,2-已认证)")
private Integer vehicleDrivingLicenseAuthStatus;
@ApiModelProperty(name = "车辆认证状态(0-无状态,1-未认证,2-已认证)")
private Integer vehicleAuthStatus;
@ApiModelProperty(name = "挂车认证状态(0-无状态,1-未认证,2-已认证)")
private Integer trailerLicensePlateAuthStatus;
@ApiModelProperty(name = "道路运输证认证状态(0-无状态,1-未认证,2-已认证)")
private Integer roadTransportCertificateAuthStatus;
@ApiModelProperty(name = "经营许可证认证状态(0-无状态,1-未认证,2-已认证)")
private Integer businessLicenseExpireAuthStatus;
@ApiModelProperty(name = "车辆总认证状态(0-无状态,1-未认证,2-已认证)")
private Integer authStatus;
@ApiModelProperty(name = "道路运输证审核状态(0-无状态,1-未认证,2-等待审核,3-已通过,4-已驳回)")
private Integer roadTransportCertificateCheckStatus;
@ApiModelProperty(name = "经营许可证审核状态(0-无状态,1-未认证,2-等待审核,3-已通过,4-已驳回)")
private Integer businessLicenseExpireCheckStatus;
@ApiModelProperty(name = "黑名单状态(0-无状态,1-不是,2-是)")
private Integer blacklistStatus;
@ApiModelProperty(name = "黑名单备注")
private String blacklistRemark;
@ApiModelProperty(name = "总质量起始")
private BigDecimal vehicleTotalMassStart;
@ApiModelProperty(name = "总质量结束")
private BigDecimal vehicleTotalMassEnd;
@ApiModelProperty(name = "核定载质量起始")
private BigDecimal vehicleApprovedLoadQuantityStart;
@ApiModelProperty(name = "核定载质量结束")
private BigDecimal vehicleApprovedLoadQuantityEnd;
@ApiModelProperty(name = "其他车辆车轴轴数起始")
private Integer otherAxlesNumberNameStart;
@ApiModelProperty(name = "其他车辆车轴轴数结束")
private Integer otherAxlesNumberNameEnd;
@ApiModelProperty(name = "其他车辆车辆长度起始")
private Integer otherCarLengthNameStart;
@ApiModelProperty(name = "其他车辆车辆长度结束")
private Integer otherCarLengthNameEnd;
@ApiModelProperty(name = "其他车辆车辆容积起始")
private Integer otherVehicleVolumeNameStart;
@ApiModelProperty(name = "其他车辆车辆容积结束")
private Integer otherVehicleVolumeNameEnd;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "检验有效期开始")
private Date vehicleCheckoutPeriodValidityStart;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "检验有效期结束")
private Date vehicleCheckoutPeriodValidityEnd;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "道路运输证有效期")
private Date roadTransportCertificateExpireDateStart;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "道路运输证有效期")
private Date roadTransportCertificateExpireDateEnd;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "经营许可证件有效期(结束)起始")
private Date businessLicenseExpireEndDateStart;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "经营许可证件有效期(结束)结束")
private Date businessLicenseExpireEndDateEnd;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "入网查询时间起始")
private Date netInDateStart;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "入网查询时间结束")
private Date netInDateEnd;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "审核时间起始")
private Date checkoutDateStart;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "审核时间结束")
private Date checkoutDateEnd;
@ApiModelProperty(value = "添加时间起始")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date createTimeStart;
@ApiModelProperty(value = "添加时间结束")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date createTimeEnd;
@ApiModelProperty(name = "组织ID集合")
private List<Long> organizationIdList;
@ApiModelProperty(name = "权限菜单ID")
private Long permissionMenuId;
@ApiModelProperty(name = "标签")
private String label;
@ApiModelProperty(name = "车辆id集合")
private List<Long> vehicleIdList;
private List<Long> vehicleBindIdList;
@ApiModelProperty(name = "绑定用户信息")
private Map<String,String> userMap;
/**
* 司机名称
*/
@ApiModelProperty(name = "司机名称")
private List<String> driverNames;
/**
* 司机数量
*/
@ApiModelProperty(name = "司机数量")
private Integer driverNum;
@ApiModelProperty(value = "校验记录")
private java.lang.String checkRecord;
@ApiModelProperty(value = "查询车辆是否入网时间(是平台查询时间,不是入网时间)")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date checkTruckExistDate;
@ApiModelProperty(value = "查询车辆是否入网人员手机")
private String checkTruckExistUser;
@ApiModelProperty(value = "道路运输证字")
private String roadTransportCertificateWord;
@ApiModelProperty(value = "车辆道路运输证核验时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date checkRtcNoTime;
@ApiModelProperty(value = "企业道路运输经营许可证校验V3:0-未核验,1-已核验通过,2-核验失败(证件号错误/所有人错误),3-已过期,4-经营状态异常")
private Integer checkEnterpriseRoadLicense;
@ApiModelProperty(value = "企业道路运输经营许可证校验时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date checkEnterpriseRoadLicenseTime;
@ApiModelProperty(value = "实际承运人统一社会信用代码或证件号码")
private String actualcarrierid;
@ApiModelProperty(value = "道路运输许可证副页图片地址")
private String transportPermitBackImgUrl;
@ApiModelProperty(value = "车辆入网确认时间(最新定位时间)")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date checkTruckConfirmDate;
@ApiModelProperty(value = "标记状态id")
private String markerStateId;
@ApiModelProperty(value = "标记状态名称")
private String markerStateName;
@ApiModelProperty(value = "行驶证号")
private String drivingPermitNumber;
/**黑名单操作人*/
@ApiModelProperty(value = "黑名单操作人")
private java.lang.String blacklistBy;
@ApiModelProperty(value = "黑名单操作时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private java.util.Date blacklistDate;
@ApiModelProperty(value = "承运商编码(TMS)用于区别是哪个承运商下的车辆")
private String driverEnterpriseCode;
@ApiModelProperty(value = "数据来源(1-数字物流 2-TMS)")
private Integer dataSources;
@ApiModelProperty(name = "用户账号类型:0.无状态1.普通账号2.组织账号3.一级账号4.平台员工5.企业员工,6.合作商")
private Integer userAccountType;
@ApiModelProperty(name = "tms推送状态: 1-未推送 2- 已推送")
private Integer tmsPushStatus;
@ApiModelProperty(value = "添加时间起始")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date createTimeFrom;
@ApiModelProperty(value = "添加时间结束")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date createTimeTo;
@ApiModelProperty(value = "车辆来源 0-自由车辆 1-社会车辆")
private Integer vehicleSource;
@ApiModelProperty(name = "部门Id")
private String departmentId;
@ApiModelProperty(name = "部门名称")
private String departmentName;
@ApiModelProperty(value = "年检有效期")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date annualValidityPeriod;
@ApiModelProperty(value = "保险有效期")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date insuranceValidityPeriod;
}
@@ -0,0 +1,291 @@
package com.linke.transport.domain.vehicle.service;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.linke.transport.domain.vehicle.entity.Vehicle;
import com.linke.transport.domain.vehicle.repository.persistence.VehicleRepositoryImpl;
import com.linke.transport.domain.vehicle.repository.po.DriverVehicleBindPo;
import com.linke.transport.domain.vehicle.repository.po.VehicleAppPo;
import com.linke.transport.domain.vehicle.repository.po.VehiclePo;
import com.linke.transport.interfaces.dto.vehicle.VehicleDto;
import com.mhd.common.core.domain.dto.DriverVehicleBindDto;
import com.mhd.common.core.domain.dto.open.OpenVehicleDto;
import com.mhd.common.core.domain.todo.StatisticalMattersDo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 车辆 防腐层
*
* 本层为防腐层,业务逻辑可在本层完成
*
* 2022-12-9
*
* @author 王子豪
*/
@Service
public class VehicleDomainService
{
@Autowired
private VehicleRepositoryImpl vehicleRepositoryImpl;
/**
* 查询车辆管理
*
* @param vehicleId 车辆管理主键
* @return 车辆管理
*/
public VehiclePo selectVehicleByVehicleId(Long vehicleId)
{
return vehicleRepositoryImpl.selectVehicleByVehicleId(vehicleId);
}
public List<VehiclePo> selectVehicleByMotorcadeId(Long motorcadeId)
{
return vehicleRepositoryImpl.selectVehicleByMotorcadeId(motorcadeId);
}
public com.mhd.common.core.domain.po.VehiclePo selectVehiclePoByVehicleId(Long vehicleId)
{
return vehicleRepositoryImpl.selectVehiclePoByVehicleId(vehicleId);
}
/**
* 查询车辆管理列表
*
* @param vehiclePo 车辆管理
* @return 车辆管理
*/
public List<VehiclePo> selectVehicleList(VehiclePo vehiclePo)
{
return vehicleRepositoryImpl.selectVehicleList(vehiclePo);
}
/**
* 配载页面查询车辆管理列表
*
* @param vehiclePo 车辆管理
* @return 车辆管理集合
*/
// @DataPermissions(cacheName = "master")
public List<VehiclePo> selectStowageVehiclelist(VehiclePo vehiclePo){
return vehicleRepositoryImpl.selectStowageVehiclelist(vehiclePo);
}
/**
* 新增车辆管理
*
* @param vehicle 车辆管理
* @return 结果
*/
public Long insertVehicle(Vehicle vehicle)
{
vehicleRepositoryImpl.insertVehicle(vehicle);
return vehicle.getVehicleId();
}
/**
* 新增车辆管理
*
* @param vehicle 车辆管理
* @return 结果
*/
public boolean saveVehicle(Vehicle vehicle) {
return vehicleRepositoryImpl.save(vehicle);
}
/**
* 修改车辆管理
*
* @param vehicle 车辆管理
* @return 结果
*/
public int updateVehicle(Vehicle vehicle)
{
return vehicleRepositoryImpl.updateVehicle(vehicle);
}
/**
* 修改车辆管理
*
* @param vehicle 车辆管理
* @return 结果
*/
public boolean updateById(Vehicle vehicle) {
return vehicleRepositoryImpl.updateById(vehicle);
}
/**
* 批量修改车辆管理
*
* @param list
* @return
*/
public int batchUpdateVehicle(List<Vehicle> list){
return vehicleRepositoryImpl.batchUpdateVehicle(list);
}
/**
* 批量删除车辆管理
*
* @param vehicleIds 需要删除的车辆管理主键
* @return 结果
*/
public Boolean deleteVehicleByVehicleIds(Long[] vehicleIds)
{
List<Vehicle> list = new ArrayList<>();
for (Long id : vehicleIds) {
Vehicle vehicle = new Vehicle();
vehicle.setVehicleId(id);
vehicle.setDelFlag(2);
list.add(vehicle);
}
return vehicleRepositoryImpl.updateBatchById(list);
}
/**
* 删除车辆管理信息
*
* @param vehicleId 车辆管理主键
* @return 结果
*/
public Boolean deleteVehicleByVehicleId(Long vehicleId)
{
Vehicle vehicle = new Vehicle();
vehicle.setVehicleId(vehicleId);
vehicle.setDelFlag(2);
return vehicleRepositoryImpl.updateById(vehicle);
}
/**
* 根据用户id查询车辆信息
* @param userId
* @return
*/
public Vehicle selectVehicleByUserId(Long userId) {
return vehicleRepositoryImpl.selectVehicleByUserId(userId);
}
public List<Vehicle> selectVehiclesByUserId(Long userId) {
return vehicleRepositoryImpl.selectVehiclesByUserId(userId);
}
/**
* 根据车辆ids查询车辆信息
* @param vehicleIdList
* @return
*/
public List<Vehicle> getVehicleByIds(List<Long> vehicleIdList) {
return vehicleRepositoryImpl.getVehicleByIds(vehicleIdList);
}
/**
* 根据车辆id,以及车牌号查询
* @param vehicleDto
* @return
*/
public List<VehiclePo> selectVehicleByVehicleIdAndPlan(VehicleDto vehicleDto) {
return vehicleRepositoryImpl.selectVehicleByVehicleIdAndPlan(vehicleDto);
}
/**
* 根据id查询车辆信息
* @param vehicleId
* @return
*/
public VehicleAppPo selectVehicleAppById(Long vehicleId) {
return vehicleRepositoryImpl.selectVehicleAppById(vehicleId);
}
/**
* APP我是车主列表查询
* @param driverVehicleBindDto
* @return
*/
public List<DriverVehicleBindPo> ownerBindCarList(DriverVehicleBindDto driverVehicleBindDto) {
return vehicleRepositoryImpl.ownerBindCarList(driverVehicleBindDto);
}
/**
* APP绑定车辆我的车辆列表查询
* @param driverVehicleBindDto
* @return
*/
public List<DriverVehicleBindPo> driverBindMyCarList(DriverVehicleBindDto driverVehicleBindDto) {
return vehicleRepositoryImpl.driverBindMyCarList(driverVehicleBindDto);
}
public VehiclePo findVehicleByPlateNumber(String plateNumber){
return vehicleRepositoryImpl.findVehicleByPlateNumber(plateNumber);
}
/**
* 根据lambda表达式更新
* @param updateWrapper
*/
public Boolean updateByLambda(LambdaUpdateWrapper<Vehicle> updateWrapper) {
return vehicleRepositoryImpl.update(updateWrapper);
}
public Integer vehicleCountByMatter(StatisticalMattersDo statisticalMattersDo) {
return vehicleRepositoryImpl
.lambdaQuery()
.eq(Vehicle::getOrganizationId, statisticalMattersDo.getOrganizationId())
.eq(Vehicle::getDelFlag, 1)
.eq(Vehicle::getAuthenticationStatus, 2)
.count();
}
public boolean batchSaveVehicle(List<Vehicle> list) {
return vehicleRepositoryImpl.saveBatch(list);
}
/**
* 根据车牌号查询
*
* @param plateNumber 车牌号
* @return
*/
public Vehicle selectVehicleByPlateNumber(String plateNumber) {
return vehicleRepositoryImpl
.lambdaQuery()
.eq(Vehicle::getVehicleLicensePlateNumber, plateNumber)
.eq(Vehicle::getDelFlag, 1)
.one();
}
public Vehicle getInfoByOpen(String vehicleLicence, String driverEnterpriseCode) {
return vehicleRepositoryImpl
.lambdaQuery()
.eq(StrUtil.isNotEmpty(driverEnterpriseCode), Vehicle::getDriverEnterpriseCode, driverEnterpriseCode)
.eq(Vehicle::getVehicleLicensePlateNumber, vehicleLicence)
.eq(Vehicle::getDelFlag, 1)
.one();
}
public void updateDateLong(Vehicle vehicle) {
boolean a = vehicle.getTrailerDrivingLicenseLongStatus() != null && vehicle.getTrailerDrivingLicenseLongStatus() == 1;
boolean b = vehicle.getTrailerRoadTransportCertificateLongStatus() != null && vehicle.getTrailerRoadTransportCertificateLongStatus() == 1;
boolean c = vehicle.getRoadTransportCertificateLongStatus() != null && vehicle.getRoadTransportCertificateLongStatus() == 1;
boolean d = vehicle.getBusinessLicenseLongStatus() != null && vehicle.getBusinessLicenseLongStatus() == 1;
if (a || b || c || d){
vehicleRepositoryImpl.lambdaUpdate()
.set(a, Vehicle::getTrailerDrivingLicenseExpireDate, null)
.set(b, Vehicle::getTrailerRoadTransportCertificateExpireDate, null)
.set(c, Vehicle::getRoadTransportCertificateExpireDate, null)
.set(d, Vehicle::getBusinessLicenseExpireStartDate, null)
.set(d, Vehicle::getBusinessLicenseExpireEndDate, null)
.eq(Vehicle::getVehicleId, vehicle.getVehicleId())
.update();
}
}
}
@@ -0,0 +1,346 @@
package com.linke.transport.domain.vehicle.service;
import cn.hutool.core.util.ObjectUtil;
import com.linke.transport.domain.vehicle.entity.Vehicle;
import com.linke.transport.infrastructure.feign.ProductServiceFeign;
import com.mhd.common.core.domain.dto.open.OpenVehicleDto;
import com.mhd.common.core.constant.CacheConstants;
import com.mhd.common.core.domain.dto.wlhy.TmsTrailerInfoDTO;
import com.mhd.common.core.domain.dto.wlhy.TmsVehicleDTO;
import com.mhd.common.core.domain.entity.OrgProductConfig;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.domain.po.SysTenantsPo;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException;
import com.mhd.common.core.exception.digitalLogisticsException.UserError;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.redis.service.RedisService;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.WlhyServiceFeign;
import com.mhd.system.api.domain.WlhyLoginUser;
import com.mhd.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 网络货运车辆domain
*
*/
@Slf4j
@Service
public class VehicleWlhyDomainService
{
@Resource
private WlhyServiceFeign wlhyServiceFeign;
@Resource
private RedisService redisService;
@Resource
private ProductServiceFeign productServiceFeign;
/**
* 校验是否配置网货产品
* @return true-开启,false-关闭
*/
private boolean checkSwitch() {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
String key = CacheConstants.ORG_PRODUCT_KEY + loginUser.getUserPo().getTopOrganizationId();
OrgProductConfig orgProductConfig = redisService.getCacheObject(key);
if(null == orgProductConfig) {
return false;
}
//配置网货
return orgProductConfig.getWlhyFlag() == 1;
}
/**
* 校验是否配置网货产品
*
* @return true-开启,false-关闭
*/
private boolean checkSwitch(Long organizationId) {
if (ObjectUtil.isNull(organizationId)) {
throw new ServiceException("组织ID不能为空");
}
String key = CacheConstants.ORG_PRODUCT_KEY + organizationId;
OrgProductConfig orgProductConfig = redisService.getCacheObject(key);
if (null == orgProductConfig) {
return false;
}
//配置网货
return orgProductConfig.getWlhyFlag() == 1;
}
/**
* 新增网货系统车辆信息
* @param vehicle
* @param bindType 1-绑定,2-不绑定
* @return
*/
public boolean addVehicleInfo(Vehicle vehicle, Integer bindType) {
if(null == vehicle){
throw new ServiceException("同步数据不能为空");
}
//检查是否开启网货
boolean flag = checkSwitch();
if(!flag){
//如果未配置网货产品,返回跳过
return true;
}
//传输实体转换
TmsVehicleDTO tmsVehicleDTO = vehicleEntityConvert(vehicle);
tmsVehicleDTO.setBindType(bindType);
AjaxResult ajaxResult = wlhyServiceFeign.szwlAddVehicle(tmsVehicleDTO);
if(null != ajaxResult && "200".equals(String.valueOf(ajaxResult.get("code")))){
return true;
}else if(null != ajaxResult && !"200".equals(String.valueOf(ajaxResult.get("code")))){
throw new ServiceException("同步网货信息失败:" + ajaxResult.get("msg"));
}else {
throw new ServiceException("同步网货信息失败");
}
}
public boolean updateVehicleInfo(Vehicle vehicle) {
if(null == vehicle){
throw new ServiceException("同步数据不能为空");
}
//检查是否开启网货
boolean flag = checkSwitch();
if(!flag){
//如果未配置网货产品,返回跳过
return true;
}
//传输实体转换
TmsVehicleDTO tmsVehicleDTO = vehicleEntityConvert(vehicle);
AjaxResult ajaxResult = wlhyServiceFeign.szwlUpdateVehicle(tmsVehicleDTO);
if(null != ajaxResult && "200".equals(String.valueOf(ajaxResult.get("code")))){
return true;
}else if(null != ajaxResult && !"200".equals(String.valueOf(ajaxResult.get("code")))){
throw new ServiceException("同步网货信息失败:" + ajaxResult.get("msg"));
}else {
throw new ServiceException("同步网货信息失败");
}
}
/**
* 新增网货系统车辆信息 - 开放接口
*
* @param openVehicleDto
* @return
*/
public void openSynchronizeVehicle(OpenVehicleDto openVehicleDto) {
if (ObjectUtil.isNull(openVehicleDto)) {
throw new ServiceException("同步数据不能为空");
}
//检查是否开启网货
boolean flag = checkSwitch(openVehicleDto.getTopOrganizationId());
//如果配置网货产品,则进行网货同步
if (flag) {
//传输实体转换
AjaxResult ajaxResult = wlhyServiceFeign.openSzwlSynchronizeVehicle(openVehicleDto);
if (null != ajaxResult && !"200".equals(String.valueOf(ajaxResult.get("code")))) {
log.error("同步网货信息失败:" + ajaxResult.get("msg"));
throw new ServiceException("同步网货信息失败:" + ajaxResult.get("msg"));
}
}
}
/**
* 删除网货系统车辆信息 - 开放接口
* @param openVehicleDto
*/
public void openDelVehicle(OpenVehicleDto openVehicleDto) {
if (ObjectUtil.isNull(openVehicleDto)) {
throw new ServiceException("同步数据不能为空");
}
//获取配置的组织ID
R<SysTenantsPo> sysTenantsPoR = productServiceFeign.getTenantsInfoByOpen();
if (R.SUCCESS != sysTenantsPoR.getCode()) {
throw new ServiceException("未获取到组织配置信息");
}
SysTenantsPo sysTenantsPo = sysTenantsPoR.getData();
//检查是否开启网货
boolean flag = checkSwitch(sysTenantsPo.getTopOrganizationId());
//如果配置网货产品,则进行网货同步
if (flag) {
//传输实体转换
AjaxResult ajaxResult = wlhyServiceFeign.openDelVehicle(openVehicleDto);
if (null != ajaxResult && !"200".equals(String.valueOf(ajaxResult.get("code")))) {
log.error("删除网货信息失败:" + ajaxResult.get("msg"));
throw new ServiceException("删除网货信息失败:" + ajaxResult.get("msg"));
}
}
}
/**
* 数字物流网货车辆实体转换
* @param vehicle
* @return
*/
public TmsVehicleDTO vehicleEntityConvert(Vehicle vehicle) {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
WlhyLoginUser wlhyLoginUser = loginUser.getWlhyLoginUser();
TmsVehicleDTO tmsVehicleDTO = new TmsVehicleDTO();
tmsVehicleDTO.setUserId(vehicle.getUserId());
tmsVehicleDTO.setSzwlUserId(vehicle.getUserId());
tmsVehicleDTO.setVehicleLicenseNumber(vehicle.getVehicleLicensePlateNumber());
if (vehicle.getDelFlag() != null && vehicle.getDelFlag() == 2){
tmsVehicleDTO.setIsDelete(1);
return tmsVehicleDTO;
}
tmsVehicleDTO.setMotorcadeId(vehicle.getMotorcadeId()==null ? "":vehicle.getMotorcadeId().toString());
tmsVehicleDTO.setMotorcadeCaptainId(vehicle.getOtherCarLengthId());
tmsVehicleDTO.setMotorcadeCaptainName(vehicle.getOtherCarLengthName());
tmsVehicleDTO.setVehicleTypeId(vehicle.getVehicleTypeId());
tmsVehicleDTO.setVehicleTypeName(vehicle.getVehicleTypeName());
tmsVehicleDTO.setCarryStatus(vehicle.getCarryStatus() != null && vehicle.getCarryStatus() == 2 ? 1:0);
if(vehicle.getAuthenticationStatus()==3){
tmsVehicleDTO.setAuditStatus(1);
}else if(vehicle.getAuthenticationStatus()==4){
tmsVehicleDTO.setAuditStatus(2);
}else {
tmsVehicleDTO.setAuditStatus(0);
}
tmsVehicleDTO.setNuclearLoadWeight(vehicle.getVehicleApprovedLoadQuantity());
tmsVehicleDTO.setVolumeId(vehicle.getOtherVehicleVolumeId());
tmsVehicleDTO.setVolume(vehicle.getOtherVehicleVolumeName());
tmsVehicleDTO.setVehicleTotalWeight(vehicle.getVehicleTotalMass());
tmsVehicleDTO.setVehicleTotalWeightKg(vehicle.getVehicleTotalMass());
tmsVehicleDTO.setVehicleOwner(vehicle.getVehicleUsePerson());
tmsVehicleDTO.setAddress(vehicle.getVehicleAddress());
tmsVehicleDTO.setVehicleIdentificationCode(vehicle.getVehicleIdentificationNumber());
tmsVehicleDTO.setCertifyingAuthority(vehicle.getVehicleLicenceIssuingAuthority());
tmsVehicleDTO.setRegDate(vehicle.getVehicleRegistrationDate());
tmsVehicleDTO.setCertifyingDate(vehicle.getVehicleIssueDate());
tmsVehicleDTO.setVehicleLicenseColorId(vehicle.getOtherLicensePlateColorId());
tmsVehicleDTO.setVehicleLicenseColor(vehicle.getOtherLicensePlateColorName());
tmsVehicleDTO.setVehicleUseNature(vehicle.getVehicleUseNature());
tmsVehicleDTO.setVehicleEnergyTypeId(vehicle.getVehicleEnergyTypeId());
tmsVehicleDTO.setVehicleEnergyType(vehicle.getVehicleEnergyTypeName());
tmsVehicleDTO.setAuditTime(vehicle.getCheckoutDate());
tmsVehicleDTO.setAuditorId(vehicle.getCheckoutPersonId()==null ? "" : vehicle.getCheckoutPersonId().toString());
tmsVehicleDTO.setAuditorName(vehicle.getCheckoutPersonName());
tmsVehicleDTO.setDrivingPermitImgUrl(vehicle.getVehicleDrivingLicenseMain());
tmsVehicleDTO.setTransportPermitImgUrl(vehicle.getRoadTransportCertificateImage());
tmsVehicleDTO.setWorkCertificateImgUrl(vehicle.getBusinessLicenseImage());
tmsVehicleDTO.setDrivingPermitExpDate(vehicle.getVehicleCheckoutPeriodValidity());
tmsVehicleDTO.setDrivingPermitNumber(vehicle.getVehicleFileNumber());
tmsVehicleDTO.setTransportPermitNumber(vehicle.getRoadTransportCertificateNo());
tmsVehicleDTO.setOrganizationId(loginUser.getUserPo().getOrganizationId());
tmsVehicleDTO.setOrganizationName(loginUser.getUserPo().getOrganizationName());
tmsVehicleDTO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
if (vehicle.getUseStatus() == 2){
tmsVehicleDTO.setBlacklistStatus(1);
}else {
tmsVehicleDTO.setBlacklistStatus(0);
}
tmsVehicleDTO.setBlacklistBy(vehicle.getBlacklistBy());
tmsVehicleDTO.setBlacklistDate(vehicle.getBlacklistDate());
tmsVehicleDTO.setBrandModel(vehicle.getVehicleBrandType());
tmsVehicleDTO.setEngineNumber(vehicle.getVehicleEngineNumber());
if(vehicle.getVehicleGabariteOne() != null && vehicle.getVehicleGabariteTwo() != null && vehicle.getVehicleGabariteThree()!=null){
String externalDimensions = vehicle.getVehicleGabariteOne().toString()+ "X" + vehicle.getVehicleGabariteTwo().toString()+"X" + vehicle.getVehicleGabariteThree().toString()+"mm";
tmsVehicleDTO.setExternalDimensions(externalDimensions);
}
tmsVehicleDTO.setCheckRecord(vehicle.getCheckRecord());
tmsVehicleDTO.setTrailerLicenseNumber(vehicle.getTrailerLicensePlateNumber());
tmsVehicleDTO.setRemarks(vehicle.getVehicleRemark());
tmsVehicleDTO.setDrivingPermitBackImgUrl(vehicle.getVehicleDrivingLicenseMain());
tmsVehicleDTO.setAxlenum(vehicle.getOtherAxlesNumberId());
tmsVehicleDTO.setAxlenumName(vehicle.getOtherAxlesNumberName());
tmsVehicleDTO.setDrivingFrontImgUrl(vehicle.getVehicleDrivingLicenseDeputy());
tmsVehicleDTO.setRoadTransportBusinessLicenseNo(vehicle.getRoadTransportCertificateNo());
tmsVehicleDTO.setCheckTruckExist(vehicle.getNetInStatus());
tmsVehicleDTO.setCheckTruckExistDate(vehicle.getCheckTruckExistDate());
tmsVehicleDTO.setCheckTruckExistUser(vehicle.getCheckTruckExistUser());
tmsVehicleDTO.setDrivingOtherImgUrl(vehicle.getVehicleDrivingLicenseDeputyAgainst());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateString = "9999-12-31";
Date date = null;
try {
date = sdf.parse(dateString);
} catch (ParseException e) {
throw new RuntimeException(e);
}
if (vehicle.getBusinessLicenseLongStatus() != null && vehicle.getBusinessLicenseLongStatus() == 1){
tmsVehicleDTO.setBusinessLicenseExpDate(date);
}else {
tmsVehicleDTO.setBusinessLicenseExpDate(vehicle.getBusinessLicenseExpireEndDate());
}
tmsVehicleDTO.setRoadTransportCertificateWord(vehicle.getRoadTransportCertificateWord());
switch (vehicle.getRoadTransportCertificateCheckoutStatus()){
case 1:
tmsVehicleDTO.setCheckRtcNo(0);
break;
case 2:
tmsVehicleDTO.setCheckRtcNo(1);
break;
default:
tmsVehicleDTO.setCheckRtcNo(2);
break;
}
if (vehicle.getRoadTransportCertificateLongStatus() != null && vehicle.getRoadTransportCertificateLongStatus() == 1){
tmsVehicleDTO.setCheckRtcNoTime(date);
}else {
tmsVehicleDTO.setCheckRtcNoTime(vehicle.getCheckRtcNoTime());
}
tmsVehicleDTO.setCheckEnterpriseRoadLicense(vehicle.getCheckEnterpriseRoadLicense());
tmsVehicleDTO.setActualcarrierid(vehicle.getActualcarrierid());
tmsVehicleDTO.setAuditRemark(vehicle.getRejectReason());
tmsVehicleDTO.setTransportPermitBackImgUrl(vehicle.getTransportPermitBackImgUrl());
tmsVehicleDTO.setCheckTruckConfirmDate(vehicle.getCheckTruckConfirmDate());
if(vehicle.getVehicleDrivingLicenseAuthStatus()==2){
tmsVehicleDTO.setDrivingLicenseAuthentication(1);
}else {
tmsVehicleDTO.setDrivingLicenseAuthentication(0);
}
if(vehicle.getRoadTransportCertificateAuthStatus()==2){
tmsVehicleDTO.setRoadTransportPermitAuthentication(1);
}else {
tmsVehicleDTO.setRoadTransportPermitAuthentication(0);
}
tmsVehicleDTO.setMarkerStateId(vehicle.getMarkerStateId());
tmsVehicleDTO.setMarkerStateName(vehicle.getMarkerStateName());
tmsVehicleDTO.setVehicleSource(vehicle.getVehicleSource());
//挂车信息
TmsTrailerInfoDTO tmsTrailerInfoDTO = new TmsTrailerInfoDTO();
tmsTrailerInfoDTO.setVehicleLicenseNumber(vehicle.getTrailerLicensePlateNumber());
tmsTrailerInfoDTO.setVehicleOwner(vehicle.getVehicleUsePerson());
tmsTrailerInfoDTO.setVehicleTypeId(vehicle.getTrailerVehicleTypeId());
tmsTrailerInfoDTO.setVehicleTypeName(vehicle.getTrailerVehicleTypeName());
tmsTrailerInfoDTO.setNuclearLoadWeight(vehicle.getTrailerApprovedLoadQuantity());
tmsTrailerInfoDTO.setVehicleTotalWeight(vehicle.getTrailerTotalMass());
tmsTrailerInfoDTO.setVehicleTotalWeightKg(vehicle.getTrailerTotalMass());
tmsTrailerInfoDTO.setDrivingPermitExpDate(vehicle.getVehicleCheckoutPeriodValidity());
tmsTrailerInfoDTO.setVehicleLicenseColorId(vehicle.getTrailerLicensePlateColorId());
tmsTrailerInfoDTO.setVehicleLicenseColor(vehicle.getTrailerLicensePlateColorName());
tmsTrailerInfoDTO.setDrivingPermitImgUrl(vehicle.getTrailerDrivingLicenseMain());
tmsTrailerInfoDTO.setDrivingFrontImgUrl(vehicle.getTrailerDrivingLicenseDeputy());
tmsTrailerInfoDTO.setTransportPermitNumber(vehicle.getTrailerRoadTransportCertificateNo());
tmsTrailerInfoDTO.setTransportPermitExpDate(vehicle.getTrailerRoadTransportCertificateExpireDate());
tmsTrailerInfoDTO.setTransportPermitImgUrl(vehicle.getTrailerRoadTransportCertificateImage());
tmsVehicleDTO.setTmsTrailerInfo(tmsTrailerInfoDTO);
tmsVehicleDTO.setDepartmentId(vehicle.getDepartmentId());
tmsVehicleDTO.setDepartmentName(vehicle.getDepartmentName());
tmsVehicleDTO.setAnnualValidityPeriod(vehicle.getAnnualValidityPeriod());
tmsVehicleDTO.setInsuranceValidityPeriod(vehicle.getInsuranceValidityPeriod());
return tmsVehicleDTO;
}
}
@@ -0,0 +1,22 @@
package com.linke.transport.domain.warehouse.inboundOrder.event.pojo;
import com.linke.transport.domain.warehouse.inboundOrder.model.InboundOrder;
import com.linke.transport.domain.warehouse.inboundOrder.model.InboundOrderDetail;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 入库完成事件
*/
@Getter
@AllArgsConstructor
public class InboundCompletedEvent {
private final String tmsOrderNo;
private final InboundOrder inboundOrder;
private final List<InboundOrderDetail> details;
}
@@ -0,0 +1,75 @@
package com.linke.transport.domain.warehouse.inboundOrder.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 入库单主表
* </p>
*
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("inbound_order")
@ApiModel(value="InboundOrder对象", description="入库单主表")
public class InboundOrder implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "入库单号 (例如 RKyymmddxxxx)")
@TableField("inbound_order_no")
private String inboundOrderNo;
@ApiModelProperty(value = "货主名称")
@TableField("owner_name")
private String ownerName;
@ApiModelProperty(value = "货主ID", required = true)
private Long ownerId;
@ApiModelProperty(value = "入库时间")
@TableField("inbound_time")
private Date inboundTime;
@ApiModelProperty(value = "备注")
@TableField("remarks")
private String remarks;
@ApiModelProperty(value = "创建时间")
@TableField(value = "created_at")
private Date createdAt;
@ApiModelProperty(value = "更新时间")
@TableField(value = "updated_at")
private Date updatedAt;
@ApiModelProperty(value = "创建人 (例如 用户名)")
@TableField(value = "created_by")
private String createdBy;
@ApiModelProperty(value = "更新人")
@TableField(value = "updated_by")
private String updatedBy;
@ApiModelProperty(value = "逻辑删除标志 (0:未删除, 1:已删除)")
@TableField("is_deleted")
@TableLogic
private Boolean deleted; // 使用Boolean类型,MyBatis-Plus默认处理 0 和 1
}
@@ -0,0 +1,72 @@
package com.linke.transport.domain.warehouse.inboundOrder.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 入库单明细表
* </p>
*
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("inbound_order_detail")
@ApiModel(value="InboundOrderDetail对象", description="入库单明细表")
public class InboundOrderDetail implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "关联入库单主表ID")
@TableField("inbound_order_id")
private Long inboundOrderId;
@ApiModelProperty(value = "关联物料ID")
@TableField("material_id")
private Long materialId;
@ApiModelProperty(value = "入库数量")
@TableField("quantity")
private BigDecimal quantity;
@ApiModelProperty(value = "整机编号 (当物料需要编号管理时填写)")
@TableField("machine_serial_no")
private String machineSerialNo;
@ApiModelProperty(value = "创建时间")
@TableField(value = "created_at")
private Date createdAt;
@ApiModelProperty(value = "更新时间")
@TableField(value = "updated_at")
private Date updatedAt;
@ApiModelProperty(value = "创建人")
@TableField(value = "created_by")
private String createdBy;
@ApiModelProperty(value = "更新人")
@TableField(value = "updated_by")
private String updatedBy;
@ApiModelProperty(value = "逻辑删除标志 (0:未删除, 1:已删除)")
@TableField("is_deleted")
@TableLogic
private Boolean deleted;
}
@@ -0,0 +1,342 @@
package com.linke.transport.domain.warehouse.inventory.event;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.linke.transport.domain.warehouse.inboundOrder.event.pojo.InboundCompletedEvent;
import com.linke.transport.domain.warehouse.inboundOrder.model.InboundOrder;
import com.linke.transport.domain.warehouse.inboundOrder.model.InboundOrderDetail;
import com.linke.transport.domain.warehouse.inventory.event.pojo.InventoryAdjustedEvent;
import com.linke.transport.domain.warehouse.inventory.model.Inventory;
import com.linke.transport.domain.warehouse.inventoryLedger.model.InventoryLedger;
import com.linke.transport.domain.warehouse.material.model.Material;
import com.linke.transport.domain.warehouse.material.repository.MaterialRepository;
import com.linke.transport.domain.warehouse.outboundOrder.evnet.pojo.OutboundCompletedEvent;
import com.linke.transport.domain.warehouse.outboundOrder.model.OutboundOrder;
import com.linke.transport.domain.warehouse.outboundOrder.model.OutboundOrderDetail;
import com.linke.transport.infrastructure.warehouse.inventory.persistence.InventoryMapper;
import com.linke.transport.infrastructure.warehouse.inventoryLedger.persistence.InventoryLedgerMapper;
import com.mhd.common.core.utils.OrderSequence;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
* 库存事件监听器,处理入库完成后的库存更新和流水记录
*/
@Slf4j
@Component
@RequiredArgsConstructor // 使用 Lombok 自动注入 final 字段
public class InventoryEventListener {
private final InventoryMapper inventoryMapper;
private final InventoryLedgerMapper inventoryLedgerMapper;
private final MaterialRepository materialRepository; // 注入物料仓库
/**
* 处理入库完成事件
*
* @param event 入库完成事件
*/
// @Async
@EventListener // 监听 InboundCompletedEvent 事件
@Transactional(propagation = Propagation.REQUIRES_NEW) // 在新事务中执行,与主流程事务隔离
public void handleInboundCompleted(InboundCompletedEvent event) {
InboundOrder order = event.getInboundOrder();
List<InboundOrderDetail> details = event.getDetails();
log.info("接收到入库完成事件,开始处理库存和流水, 入库单号: {}", order.getInboundOrderNo());
for (InboundOrderDetail detail : details) {
try {
// 1. 查询物料信息 (需要从物料服务获取)
Optional<Material> materialOpt = materialRepository.findById(detail.getMaterialId());
if (!materialOpt.isPresent()) {
log.error("处理入库事件失败: 物料ID {} 不存在, 入库单明细ID: {}", detail.getMaterialId(),
detail.getId());
// 异常处理策略:可以记录失败,或者抛出异常让事务回滚(取决于业务需求)
// 这里选择记录日志并继续处理其他明细
continue;
}
Material material = materialOpt.get();
// 2. 更新库存 (查找或创建库存记录)
Inventory currentInventory = findOrCreateInventory(
order.getOwnerId(),
order.getOwnerName(),
detail.getMaterialId(),
order.getId(),
detail.getMachineSerialNo(),
order.getOwnerName()); // 传递创建者
BigDecimal quantityBeforeChange = currentInventory.getQuantity();
BigDecimal changeQuantity = detail.getQuantity();
BigDecimal quantityAfterChange = quantityBeforeChange.add(changeQuantity);
// 使用 Mapper 中的方法原子更新库存(只有物料不是整机编号的才可以更新数量)
int updatedRows = inventoryMapper.increaseQuantity(currentInventory.getId(),
changeQuantity,
order.getUpdatedBy()); // 传递更新者
// 更新库存编号用于订单接口查询
LambdaUpdateWrapper<Inventory> set = Wrappers.<Inventory>lambdaUpdate()
.eq(Inventory::getId, currentInventory.getId())
.set(Inventory::getInBoundOrderId, order.getId());
inventoryMapper.update(null, set);
if (updatedRows > 0) {
log.info("库存更新成功: 货主[{}], 物料ID[{}], 序列号[{}], 增加数量[{}], 更新后数量[{}]",
order.getOwnerName(), detail.getMaterialId(), detail.getMachineSerialNo(),
changeQuantity, quantityAfterChange); // 使用计算后的值记录日志
// 3. 记录库存流水
InventoryLedger ledger = new InventoryLedger();
ledger.setEventTime(order.getInboundTime()); // 使用入库时间作为事件时间
ledger.setType("INBOUND");
ledger.setOrderNo(order.getInboundOrderNo());
ledger.setOrderDetailId(detail.getId());
ledger.setOwnerId(order.getOwnerId());
ledger.setOwnerName(order.getOwnerName());
ledger.setMaterialId(detail.getMaterialId());
// 冗余物料信息
ledger.setMaterialCode(material.getMaterialCode());
ledger.setMaterialName(material.getName());
ledger.setMaterialCategory(material.getCategory());
ledger.setMaterialModel(material.getModel());
ledger.setUnit(material.getUnit());
// 变动信息
ledger.setChangeType("INCREASE");
ledger.setChangeQuantity(changeQuantity);
ledger.setQuantityBeforeChange(quantityBeforeChange);
ledger.setQuantityAfterChange(quantityAfterChange); // 使用更新后的实际库存
ledger.setMachineSerialNo(detail.getMachineSerialNo());
// tmsOrderNo 在入库时通常为空
ledger.setTmsOrderNo(event.getTmsOrderNo());
ledger.setRemarks(event.getInboundOrder().getRemarks());
// createdBy 和 createdAt 会自动填充 (如果配置了 MetaObjectHandler)
ledger.setCreatedBy(order.getCreatedBy()); // 由 MetaObjectHandler 填充
inventoryLedgerMapper.insert(ledger);
log.info("库存流水记录成功, 流水ID: {}", ledger.getId());
} else {
// 更新失败,可能并发导致记录不存在或已被逻辑删除,或者increaseQuantity实现问题
log.error("库存更新失败(影响行数为0): 货主[{}], 物料ID[{}], 序列号[{}]",
order.getOwnerName(), detail.getMaterialId(), detail.getMachineSerialNo());
// 需要根据业务决定是否重试或发出警报
// 这里可能需要抛出异常来回滚当前监听器事务
throw new RuntimeException("库存更新失败,影响行数为0");
}
} catch (Exception e) {
log.error("处理入库单明细 {} 时发生异常: {}", detail.getId(), e.getMessage(), e);
// 异常处理:可以选择继续处理下一条,或者抛出异常回滚整个监听器事务
throw new RuntimeException("处理入库事件明细时发生异常", e); // 抛出异常以回滚
}
}
log.info("入库单 {} 的库存和流水处理完成", order.getInboundOrderNo());
}
/**
* 处理库存调整事件,记录流水
*
* @param event 库存调整事件
*/
@EventListener
@Transactional(propagation = Propagation.REQUIRES_NEW) // 独立事务
@Async // 异步处理
public void handleInventoryAdjusted(InventoryAdjustedEvent event) {
log.info("接收到库存调整事件,开始记录流水, 库存ID: {}", event.getInventoryId());
try {
Material material = event.getMaterial(); // 直接从事件获取物料信息
InventoryLedger ledger = new InventoryLedger();
ledger.setEventTime(new Date()); // 使用当前时间作为调整发生时间
ledger.setType("ADJUSTMENT"); // 类型为调整
// orderNo 和 orderDetailId 在调整时通常为空
ledger.setOwnerId(event.getOwnerId());
ledger.setOwnerName(event.getOwnerName());
ledger.setMaterialId(event.getMaterialId());
// 冗余物料信息
ledger.setMaterialCode(material.getMaterialCode());
ledger.setMaterialName(material.getName());
ledger.setMaterialCategory(material.getCategory());
ledger.setMaterialModel(material.getModel());
ledger.setUnit(material.getUnit());
// 变动信息
ledger.setChangeType(event.getChangeType()); // "INCREASE" or "DECREASE"
ledger.setChangeQuantity(event.getChangeQuantity());
ledger.setQuantityBeforeChange(event.getQuantityBeforeChange());
ledger.setQuantityAfterChange(event.getQuantityAfterChange());
ledger.setMachineSerialNo(event.getMachineSerialNo()); // 通常为 null
// tmsOrderNo 为空
ledger.setRemarks(event.getReason()); // 记录调整原因
ledger.setCreatedBy(event.getOperator()); // 记录操作人
inventoryLedgerMapper.insert(ledger);
log.info("库存调整流水记录成功, 流水ID: {}", ledger.getId());
} catch (Exception e) {
log.error("记录库存调整流水时发生异常, 库存ID: {}, 错误: {}", event.getInventoryId(),
e.getMessage(), e);
// 考虑添加重试机制或告警
// 抛出异常会导致异步任务失败,但不会回滚主事务
throw new RuntimeException("记录库存调整流水失败", e);
}
}
/**
* 处理出库完成事件,记录流水
*
* @param event 出库完成事件
*/
@Async // 异步处理
@EventListener // 监听 OutboundCompletedEvent 事件
@Transactional(propagation = Propagation.REQUIRES_NEW) // 在新事务中执行,与主流程事务隔离
public void handleOutboundCompleted(OutboundCompletedEvent event) {
OutboundOrder order = event.getOutboundOrder();
List<OutboundOrderDetail> details = event.getDetails();
Map<Long, BigDecimal> quantityBeforeDecreaseMap = event.getQuantityBeforeDecreaseMap(); // 获取扣减前数量
log.info("接收到出库完成事件,开始处理流水, 出库单号: {}", order.getOutboundOrderNo());
// 批量获取物料信息,避免循环查询
Map<Long, Material> materialMap = getMaterialMapForOutboundDetails(details);
for (OutboundOrderDetail detail : details) {
try {
Material material = materialMap.get(detail.getMaterialId());
if (material == null) {
log.error("处理出库事件失败: 物料ID {} 未找到, 出库单明细ID: {}", detail.getMaterialId(),
detail.getId());
continue; // 继续处理其他明细
}
// 获取扣减前的数量
BigDecimal quantityBeforeChange = quantityBeforeDecreaseMap.get(detail.getId());
if (quantityBeforeChange == null) {
log.error("处理出库事件失败: 未能在事件中找到明细ID {} 的扣减前数量", detail.getId());
continue;
}
BigDecimal changeQuantity = detail.getQuantity();
BigDecimal quantityAfterChange = quantityBeforeChange.subtract(changeQuantity);
// 记录库存流水
InventoryLedger ledger = new InventoryLedger();
ledger.setEventTime(order.getOutboundTime()); // 使用出库时间
ledger.setType(event.getType()); // 类型
if (event.getType().equals("TMS_USAGE")) {
ledger.setTmsOrderNo(event.getTmsOrderNo());
}
ledger.setOrderNo(order.getOutboundOrderNo());
ledger.setOrderDetailId(detail.getId());
ledger.setOwnerId(order.getOwnerId());
ledger.setOwnerName(order.getOwnerName());
ledger.setMaterialId(detail.getMaterialId());
// 冗余物料信息
ledger.setMaterialCode(material.getMaterialCode()); // 假设 Material 有 getMaterialCode()
ledger.setMaterialName(material.getName());
ledger.setMaterialCategory(material.getCategory());
ledger.setMaterialModel(material.getModel());
ledger.setUnit(material.getUnit());
// 变动信息
ledger.setChangeType("DECREASE"); // 变化类型为减少
ledger.setChangeQuantity(changeQuantity);
ledger.setQuantityBeforeChange(quantityBeforeChange);
ledger.setQuantityAfterChange(quantityAfterChange); // 使用扣减后的理论值
ledger.setMachineSerialNo(detail.getMachineSerialNo());
ledger.setRemarks(event.getOutboundOrder().getRemarks());
ledger.setCreatedBy(order.getCreatedBy()); // 操作人
inventoryLedgerMapper.insert(ledger);
log.info("出库流水记录成功, 流水ID: {}", ledger.getId());
} catch (Exception e) {
log.error("处理出库单明细 {} 流水时发生异常: {}", detail.getId(), e.getMessage(), e);
// 异常处理:可以选择继续处理下一条,或者抛出异常标记异步任务失败
// 注意:这里抛出异常不会回滚主事务(createOutboundOrder)
throw new RuntimeException("处理出库事件流水时发生异常", e);
}
}
log.info("出库单 {} 的流水处理完成", order.getOutboundOrderNo());
}
/**
* 辅助方法:为出库明细批量获取物料信息
*/
private Map<Long, Material> getMaterialMapForOutboundDetails(List<OutboundOrderDetail> details) {
if (CollectionUtils.isEmpty(details)) {
return Collections.emptyMap();
}
List<Long> materialIds = details.stream()
.map(OutboundOrderDetail::getMaterialId)
.distinct()
.collect(Collectors.toList());
return materialRepository.findByIdIn(materialIds)
.map(
list -> list.stream().collect(Collectors.toMap(Material::getId, Function.identity())))
.orElseGet(HashMap::new);
}
/**
* 查找或创建库存记录
*
* @param ownerName 货主
* @param materialId 物料ID
* @param inBoundOrderId 物料主键ID
* @param machineSerialNo 整机编号 (可能为null)
* @param creator 创建人
* @return 找到的或新创建的库存对象 (quantity 可能为 0)
*/
private Inventory findOrCreateInventory(Long ownerId, String ownerName, Long materialId, Long inBoundOrderId,
String machineSerialNo,
String creator) {
LambdaQueryWrapper<Inventory> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
.eq(Inventory::getOwnerId, ownerId)
.eq(Inventory::getMaterialId, materialId);
if (StringUtils.hasText(machineSerialNo)) {
queryWrapper.eq(Inventory::getMachineSerialNo, machineSerialNo);
} else {
queryWrapper.isNull(Inventory::getMachineSerialNo);
}
Inventory inventory = inventoryMapper.selectOne(queryWrapper);
if (inventory == null) {
log.info("未找到库存记录,为 货主ID[{}], 货主[{}], 物料ID[{}], 序列号[{}] 创建新记录", ownerId, ownerName,
materialId, machineSerialNo);
inventory = new Inventory();
inventory.setOwnerId(ownerId);
inventory.setOwnerName(ownerName);
inventory.setMaterialId(materialId);
inventory.setMachineSerialNo(machineSerialNo);
inventory.setQuantity(BigDecimal.ZERO); // 初始数量为0
// createdBy, createdAt, updatedBy, updatedAt 将由 MetaObjectHandler 填充
inventory.setCreatedBy(creator);
inventory.setUpdatedBy(creator);
inventory.setInBoundOrderId(inBoundOrderId);
inventory.setInventoryOrderNo(OrderSequence.getOrderCode("KC"));
// inventory.setCreatedAt(new Date());
inventoryMapper.insert(inventory);
}
return inventory;
}
}
@@ -0,0 +1,43 @@
package com.linke.transport.domain.warehouse.inventory.event.pojo;
import com.linke.transport.domain.warehouse.material.model.Material;
import java.math.BigDecimal;
import lombok.Getter;
/**
* 库存调整完成事件
*/
@Getter
public class InventoryAdjustedEvent {
private final Long inventoryId;
private final Long ownerId;
private final String ownerName;
private final Long materialId;
private final String machineSerialNo;
private final Material material; // 传递物料信息
private final String changeType; // "INCREASE" or "DECREASE"
private final BigDecimal changeQuantity;
private final BigDecimal quantityBeforeChange;
private final BigDecimal quantityAfterChange;
private final String reason;
private final String operator;
public InventoryAdjustedEvent(Long inventoryId, Long ownerId, String ownerName, Long materialId,
String machineSerialNo, Material material, String changeType, BigDecimal changeQuantity,
BigDecimal quantityBeforeChange, BigDecimal quantityAfterChange,
String reason, String operator) {
this.inventoryId = inventoryId;
this.ownerId = ownerId;
this.ownerName = ownerName;
this.materialId = materialId;
this.machineSerialNo = machineSerialNo;
this.material = material;
this.changeType = changeType;
this.changeQuantity = changeQuantity;
this.quantityBeforeChange = quantityBeforeChange;
this.quantityAfterChange = quantityAfterChange;
this.reason = reason;
this.operator = operator;
}
}
@@ -0,0 +1,87 @@
package com.linke.transport.domain.warehouse.inventory.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 库存信息表
* </p>
*
* @author YourName
* @since YYYY-MM-DD
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("inventory")
@ApiModel(value = "Inventory对象", description = "库存信息表")
public class Inventory implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "入库单表主键ID")
@TableField("inbound_order_id")
private Long inBoundOrderId;
@ApiModelProperty("库存单号")
@TableField("inventory_order_no")
private String inventoryOrderNo;
@ApiModelProperty(value = "货主ID", required = true)
@TableField("owner_id")
private Long ownerId;
@ApiModelProperty(value = "货主名称")
@TableField("owner_name")
private String ownerName;
@ApiModelProperty(value = "关联物料ID")
@TableField("material_id")
private Long materialId;
@ApiModelProperty(value = "当前库存数量")
@TableField("quantity")
private BigDecimal quantity;
@ApiModelProperty(value = "整机编号 (当物料需要编号管理时存储,否则为NULL)")
@TableField("machine_serial_no")
private String machineSerialNo;
@ApiModelProperty(value = "创建时间")
@TableField(value = "created_at")
private Date createdAt;
@ApiModelProperty(value = "最后更新时间")
@TableField(value = "updated_at")
private Date updatedAt;
@ApiModelProperty(value = "创建人")
@TableField(value = "created_by")
private String createdBy;
@ApiModelProperty(value = "更新人")
@TableField(value = "updated_by")
private String updatedBy;
@ApiModelProperty(value = "逻辑删除标志 (0:未删除, 1:已删除)")
@TableField("is_deleted")
@TableLogic
private Boolean deleted;
}
@@ -0,0 +1,119 @@
package com.linke.transport.domain.warehouse.inventoryLedger.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.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 库存流水记录表
* </p>
*
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("inventory_ledger")
@ApiModel(value = "InventoryLedger对象", description = "库存流水记录表")
public class InventoryLedger implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "发生时间")
@TableField("event_time")
private Date eventTime;
@ApiModelProperty(value = "流水类型 (INBOUND:入库, OUTBOUND:出库, ADJUSTMENT:库存调整, TMS_USAGE:订单出库)")
@TableField("type")
private String type; // 考虑后续使用枚举类型
@ApiModelProperty(value = "关联单号 (入库/出库单号)")
@TableField("order_no")
private String orderNo;
@ApiModelProperty(value = "关联单据明细ID (入库/出库明细ID)")
@TableField("order_detail_id")
private Long orderDetailId;
@ApiModelProperty(value = "货主ID")
@TableField("owner_id")
private Long ownerId;
@ApiModelProperty(value = "货主名称")
@TableField("owner_name")
private String ownerName;
@ApiModelProperty(value = "关联物料ID")
@TableField("material_id")
private Long materialId;
@ApiModelProperty(value = "物料编码 (冗余)")
@TableField("material_code")
private String materialCode;
@ApiModelProperty(value = "物料名称 (冗余)")
@TableField("material_name")
private String materialName;
@ApiModelProperty(value = "物料分类 (冗余)")
@TableField("material_category")
private String materialCategory;
@ApiModelProperty(value = "物料型号 (冗余)")
@TableField("material_model")
private String materialModel;
@ApiModelProperty(value = "库存单位 (冗余)")
@TableField("unit")
private String unit;
@ApiModelProperty(value = "库存增减类型 (INCREASE:增加, DECREASE:减少)")
@TableField("change_type")
private String changeType; // 考虑后续使用枚举类型
@ApiModelProperty(value = "本次变动数量 (正数)")
@TableField("change_quantity")
private BigDecimal changeQuantity;
@ApiModelProperty(value = "变动前库存数量")
@TableField("quantity_before_change")
private BigDecimal quantityBeforeChange;
@ApiModelProperty(value = "变动后库存数量")
@TableField("quantity_after_change")
private BigDecimal quantityAfterChange;
@ApiModelProperty(value = "整机编号 (如果涉及)")
@TableField("machine_serial_no")
private String machineSerialNo;
@ApiModelProperty(value = "关联的TMS运输订单号 (当type为TMS_USAGE时)")
@TableField("tms_order_no")
private String tmsOrderNo;
@ApiModelProperty(value = "备注 (例如 调整原因)")
@TableField("remarks")
private String remarks;
@ApiModelProperty(value = "记录创建时间")
@TableField(value = "created_at") // 注意:流水表一般只有创建,没有更新
private Date createdAt;
@ApiModelProperty(value = "操作人")
@TableField(value = "created_by")
private String createdBy;
}
@@ -0,0 +1,5 @@
package com.linke.transport.domain.warehouse.material;
public interface MaterialCodeGenerator {
String generate();
}
@@ -0,0 +1,14 @@
package com.linke.transport.domain.warehouse.material.exception;
/**
* 领域异常基类
*/
public class MaterialDomainException extends RuntimeException {
public MaterialDomainException(String message) {
super(message);
}
public MaterialDomainException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,123 @@
package com.linke.transport.domain.warehouse.material.model;
import com.linke.transport.domain.warehouse.material.MaterialCodeGenerator;
import com.linke.transport.domain.warehouse.material.exception.MaterialDomainException;
import com.mhd.common.core.utils.StringUtils;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 物料聚合根(领域核心)
*/
@Data
@NoArgsConstructor
public class Material {
private Long id; // 数据库生成ID
private String materialCode; // 使用生成器生成
private String shipper;
private Long ownerId;
private String category;
private String name;
private String model;
private String unit;
private BigDecimal value;
private boolean codeManaged;
private String remark;
private BigDecimal weight;
private LocalDateTime createTime;
private LocalDateTime updateTime;
// 私有构造方法
private Material(Long ownerId,
String shipper,
String category,
String name,
String model,
String unit,
BigDecimal value,
boolean codeManaged,
BigDecimal weight,
String remark) {
validateRequiredFields( category, name, unit);
this.ownerId = ownerId;
this.shipper = shipper;
this.category = category;
this.name = name;
this.model = model;
this.unit = unit;
this.value = validateValue(value);
this.codeManaged = codeManaged;
this.remark = remark;
this.weight = weight;
this.createTime = LocalDateTime.now();
this.updateTime = LocalDateTime.now();
}
// 工厂方法
public static Material create(Long ownerId,
String shipper,
String category,
String name,
String model,
String unit,
BigDecimal value,
boolean codeManaged,
BigDecimal weight,
String remark,
MaterialCodeGenerator codeGenerator) {
Material material = new Material(ownerId, shipper, category, name, model,
unit, value, codeManaged, weight,remark
);
material.materialCode = codeGenerator.generate();
return material;
}
// 更新方法
public void update(Long ownerId,String shipper,String category,
String name,
String model,
String unit,
BigDecimal value,
boolean codeManaged,
BigDecimal weight,
String remark) {
this.ownerId = ownerId;
this.shipper = shipper;
this.category = category;
this.name = name;
this.model = model;
this.unit = unit;
this.weight = weight;
this.value = validateValue(value);
this.codeManaged = codeManaged;
this.remark = remark;
this.updateTime = LocalDateTime.now();
}
// 保留的核心校验
private void validateRequiredFields(
String category,
String name,
String unit) {
if (StringUtils.isBlank(category)) {
throw new MaterialDomainException("分类不能为空");
}
if (StringUtils.isBlank(name)) {
throw new MaterialDomainException("名称不能为空");
}
if (StringUtils.isBlank(unit)) {
throw new MaterialDomainException("单位不能为空");
}
}
private BigDecimal validateValue(BigDecimal value) {
if (value != null && value.compareTo(BigDecimal.ZERO) < 0) {
throw new MaterialDomainException("物料价值不能为负数");
}
return value;
}
}
@@ -0,0 +1,78 @@
package com.linke.transport.domain.warehouse.material.repository;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.linke.transport.domain.warehouse.material.model.Material;
import java.util.List;
import java.util.Optional;
public interface MaterialRepository {
/**
* 保存物料信息,包括创建新物料和更新已有物料。
*
* @param material 物料对象
* @return 已保存的物料对象
*/
Material save(Material material);
/**
* 更新物料信息。
*
* @param material 包含更新数据的物料对象
*/
void update(Material material);
/**
* 根据ID查找物料。
*
* @param id 物料唯一标识
* @return 如果找到则返回对应的物料对象,否则返回空Optional
*/
Optional<Material> findById(Long id);
/**
* 根据多个ID批量查找物料。
*
* @param ids 物料唯一标识集合
* @return 如果找到则返回对应的物料对象集合,否则返回空Optional
*/
Optional<List<Material>> findByIdIn(List<Long> ids);
/**
* 根据ID删除物料。
*
* @param id 要删除的物料唯一标识
*/
void deleteById(Long id);
/**
* 分页搜索物料。
*
* @param shipper 物料所属者
* @param category 物料分类
* @param name 物料名称
* @param model 物料型号
* @param current 当前页码
* @param size 每页大小
* @return 分页的物料数据
*/
IPage<Material> search(String shipper, String category, String name,String model,String materialCode,Boolean codeManaged,String remark,
Long current, Long size);
/**
* 获取所有物料。
*
* @param ownerId 物料所属者ID
* @return 物料对象列表
*/
List<Material> findAllMaterials(Long ownerId);
/**
* 根据所属者ID更新所属者名称。
*
* @param ownerId 要更新的所属者ID
* @param ownerName 新的所属者名称
* @return 受影响的记录数
*/
int updateOwnerNameByOwnerId(Long ownerId, String ownerName);
}
@@ -0,0 +1,46 @@
package com.linke.transport.domain.warehouse.outboundOrder.evnet.pojo;
import com.linke.transport.domain.warehouse.outboundOrder.model.OutboundOrder;
import com.linke.transport.domain.warehouse.outboundOrder.model.OutboundOrderDetail;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import lombok.Getter;
/**
* 出库完成事件
*/
@Getter
public class OutboundCompletedEvent {
private final OutboundOrder outboundOrder;
private final List<OutboundOrderDetail> details;
private final String type;
private final String tmsOrderNo;
/**
* 库存扣减前的数量 (Key: OutboundOrderDetail ID, Value: Quantity Before Decrease) 用于流水记录
*/
private final Map<Long, BigDecimal> quantityBeforeDecreaseMap;
/**
* Create a new event
*
* @param outboundOrder 完成的出库单
* @param details 出库单明细列表
* @param quantityBeforeDecreaseMap 扣减前数量映射
* @param type 出库类型 (从 DTO 传入)
* @param tmsOrderNo TMS订单号 (从 DTO 传入, 可能为 null)
*/
public OutboundCompletedEvent(OutboundOrder outboundOrder,
List<OutboundOrderDetail> details,
Map<Long, BigDecimal> quantityBeforeDecreaseMap,
String type, // 新增参数
String tmsOrderNo) { // 新增参数
this.outboundOrder = outboundOrder;
this.details = details;
this.quantityBeforeDecreaseMap = quantityBeforeDecreaseMap;
this.type = type; // 保存类型
this.tmsOrderNo = tmsOrderNo; // 保存TMS订单号
}
}
@@ -0,0 +1,76 @@
package com.linke.transport.domain.warehouse.outboundOrder.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 出库单主表
* </p>
*
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("outbound_order")
@ApiModel(value = "OutboundOrder对象", description = "出库单主表")
public class OutboundOrder implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "出库单号 (例如 CKyymmddxxxx)")
@TableField("outbound_order_no")
private String outboundOrderNo;
@ApiModelProperty(value = "货主ID", required = true)
@TableField("owner_id")
private Long ownerId;
@ApiModelProperty(value = "货主名称")
@TableField("owner_name")
private String ownerName;
@ApiModelProperty(value = "出库时间")
@TableField("outbound_time")
private Date outboundTime;
@ApiModelProperty(value = "备注")
@TableField("remarks")
private String remarks;
@ApiModelProperty(value = "创建时间")
@TableField(value = "created_at")
private Date createdAt;
@ApiModelProperty(value = "更新时间")
@TableField(value = "updated_at")
private Date updatedAt;
@ApiModelProperty(value = "创建人")
@TableField(value = "created_by")
private String createdBy;
@ApiModelProperty(value = "更新人")
@TableField(value = "updated_by")
private String updatedBy;
@ApiModelProperty(value = "逻辑删除标志 (0:未删除, 1:已删除)")
@TableField("is_deleted")
@TableLogic
private Boolean deleted;
}
@@ -0,0 +1,75 @@
package com.linke.transport.domain.warehouse.outboundOrder.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 出库单明细表
* </p>
*
* @author YourName
* @since YYYY-MM-DD
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("outbound_order_detail")
@ApiModel(value="OutboundOrderDetail对象", description="出库单明细表")
public class OutboundOrderDetail implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键ID")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "关联出库单主表ID")
@TableField("outbound_order_id")
private Long outboundOrderId;
@ApiModelProperty(value = "关联物料ID")
@TableField("material_id")
private Long materialId;
@ApiModelProperty(value = "出库数量")
@TableField("quantity")
private BigDecimal quantity;
@ApiModelProperty(value = "整机编号 (当物料需要编号管理时选择)")
@TableField("machine_serial_no")
private String machineSerialNo;
@ApiModelProperty(value = "创建时间")
@TableField(value = "created_at")
private Date createdAt;
@ApiModelProperty(value = "更新时间")
@TableField(value = "updated_at")
private Date updatedAt;
@ApiModelProperty(value = "创建人")
@TableField(value = "created_by")
private String createdBy;
@ApiModelProperty(value = "更新人")
@TableField(value = "updated_by")
private String updatedBy;
@ApiModelProperty(value = "逻辑删除标志 (0:未删除, 1:已删除)")
@TableField("is_deleted")
@TableLogic
private Boolean deleted;
}
@@ -0,0 +1,14 @@
package com.linke.transport.infrastructure.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
@@ -0,0 +1,57 @@
package com.linke.transport.infrastructure.dict;
/**
* 隐藏状态枚举类
*
* 2022-11-18
*
* @author 王子豪
*/
public enum VisibleEnum {
SHOW("显示", "0"),
HIDDEN("隐藏","1");
private String name;
private String code;
private VisibleEnum(String name,String code)
{
this.name = name;
this.code=code;
}
public String getName() {
return name;
}
public String getCode() {
return code;
}
public void setName(String name) {
this.name = name;
}
public void setCode(String code) {
this.code = code;
}
public static String getName(String code){
for (VisibleEnum visibleEnum:VisibleEnum.values()){
if(visibleEnum.getCode() == code){
return visibleEnum.getName();
}
}
return null;
}
public static String getCode(String name){
for (VisibleEnum visibleEnum:VisibleEnum.values()){
if(visibleEnum.getName() == name){
return visibleEnum.getCode();
}
}
return null;
}
}
@@ -0,0 +1,9 @@
package com.linke.transport.infrastructure.feign;
//@FeignClient("mhd-basicCenter-service")
//public interface BasicServiceFeign {
//
//
//
//
//}
@@ -0,0 +1,54 @@
package com.linke.transport.infrastructure.feign;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.domain.po.SysTenantsPo;
import com.mhd.common.core.web.domain.AjaxResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@FeignClient("mhd-product-service")
public interface ProductServiceFeign {
/**
* @Description 获取一级组织
*/
@GetMapping("/organization/selectTopId/{id}")
public AjaxResult selectTopId(@PathVariable("id") Long id);
/**
* 查询当前组织所有的组织id
*/
@GetMapping(value = "/organization/getOrganizationIdsByOrganizationId/{organizationId}")
public AjaxResult getOrganizationIdsByOrganizationId(@PathVariable("organizationId") Long organizationId);
/**
* 查询所有的组织id
*/
@GetMapping(value = "/organization/selectAllOrganizationId")
public AjaxResult selectAllOrganizationId();
/**
* 根据applicationName查询定时任务集合
*/
@GetMapping(value = "/elasticJob/elasticJobList/{applicationName}")
public AjaxResult elasticJobList(@PathVariable("applicationName") String applicationName);
/**
* 开放接口-获取配置的组织信息
*
* @return
*/
@GetMapping(value = "/tenants/getTenantsInfoByOpen")
public R<SysTenantsPo> getTenantsInfoByOpen();
/**
* oss上传文件
* @param file
* @return
*/
@PostMapping(value = "/menu/uploadFeign",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public AjaxResult uploadFeign(@RequestPart("file") MultipartFile file);
}
@@ -0,0 +1,72 @@
package com.linke.transport.infrastructure.feign;
import com.mhd.common.core.domain.dto.NoticeMessageLoggingDto;
import com.mhd.common.core.domain.dto.SysProvinceCityCountyDTO;
import com.mhd.common.core.domain.dto.UserFormConfigDto;
import com.mhd.common.core.domain.dto.WebSocketDTO;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.system.api.domain.SysDictData;
import com.mhd.system.api.feign.FeignAutoConfiguration;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
@FeignClient(value = "mhd-system", configuration = FeignAutoConfiguration.class)
public interface SystemServiceFeign {
@GetMapping("/dict/data/{dictCode}")
public AjaxResult getTopOrganization(@PathVariable("dictCode") Long dictCode);
@PostMapping("/dict/data/findDatalist")
public AjaxResult findDatalist(@RequestBody SysDictData sysDictData);
@PostMapping("/basicApi/findAreaInfo")
public AjaxResult findAreaInfo(@RequestBody SysProvinceCityCountyDTO sysProvinceCityCountyDTO);
@PostMapping("/basicApi/findAreaInfoByProvince")
public AjaxResult findAreaInfoByProvince(@RequestBody SysProvinceCityCountyDTO sysProvinceCityCountyDTO);
/**
* 获取用户所在组织的开关配置信息
* @return
*/
@GetMapping("/userConfigSwitchApi/getUserConfigSwitchInfo")
public AjaxResult getUserConfigSwitchInfo();
/**
* 群发消息
*/
@PostMapping("/webSocketApi/bulkSend")
public AjaxResult bulkSend(@RequestBody WebSocketDTO webSocketDTO);
/**
* 单个消息
*/
@PostMapping("/webSocketApi/oneSend")
public AjaxResult oneSend(@RequestBody WebSocketDTO webSocketDTO);
/**
* PC获取租户自定义单配置
*/
@ApiOperation("PC获取租户自定义单配置")
@PostMapping(value = "/userFormConfigApi/getPcUserFromConfigByFeign")
public AjaxResult getPcUserFromConfigByFeign(@RequestBody UserFormConfigDto userFormConfigDto);
@PostMapping("/messageManageApi/addMessageLogging")
public AjaxResult addMessageLogging(@RequestBody NoticeMessageLoggingDto noticeMessageLoggingDto);
/**
* 根据条件查询分类字典数据列表
* @param
* @return
*/
@PostMapping("/dict/data/getDictDataList")
public R<List<SysDictData>> getDictDataList(@RequestBody SysDictData sysDictData);
}
@@ -0,0 +1,207 @@
package com.linke.transport.infrastructure.feign;
import com.mhd.common.core.constant.ServiceNameConstants;
import com.mhd.common.core.domain.dto.DriverVehicleBindDto;
import com.mhd.common.core.domain.dto.UserDataPermissionQueryDTO;
import com.mhd.common.core.domain.dto.UserDriverDTO;
import com.mhd.common.core.domain.entity.DriverVehicleBind;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.domain.po.UserPo;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.system.api.domain.UserDTO;
import com.mhd.system.api.feign.FeignAutoConfiguration;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@FeignClient(value = ServiceNameConstants.USER_CENTER,configuration = FeignAutoConfiguration.class)
public interface UserServiceFeign {
/**
* @Description 绑定车辆
* @Author Alex
* @Date 2023/1/5 21:24
*/
@PostMapping("/userDriverApi/bindVehicle")
public AjaxResult bindVehicle(@RequestBody UserDriverDTO userDriverDTO);
/**
* @Description 绑定车辆
* @Author Alex
* @Date 2023/1/5 21:24
*/
@PostMapping("/userDriverApi/bindVehicle1")
public AjaxResult bindVehicle1(@RequestBody UserDriverDTO userDriverDTO);
@PostMapping("/userDriverApi/bindVehicleForTransportApp")
AjaxResult<?> bindVehicleForTransportApp(@RequestBody UserDriverDTO userDriverDTO);
/**
* 查询用户数据权限-单条
* @param userDataPermissionQueryDTO
* @return
*/
@PostMapping("/userApi/findUserDataPermission")
public AjaxResult findUserDataPermission(@RequestBody UserDataPermissionQueryDTO userDataPermissionQueryDTO);
/**
* 保存司机车辆绑定信息
* @param driverVehicleBindDto
* @return
*/
@PostMapping("/userDriverApi/saveBindVehicle")
public AjaxResult saveBindVehicle(@RequestBody DriverVehicleBindDto driverVehicleBindDto);
/**
* 根据用户id查询司机信息
* @param userId
* @return
*/
@GetMapping("/userDriverApi/getDriverInfoByUserId/{userId}")
public AjaxResult getDriverInfoByUserId(@PathVariable("userId") Long userId);
/**
* 根据司机id查询绑定车辆的用户信息
* @param vehicleId
* @return
*/
@GetMapping("/userDriverApi/selectUserBindByVehicleId/{vehicleId}")
public Map<String,String> selectUserBindByVehicleId(Long vehicleId);
/**
* 根据车辆ids查询司机
*/
@ApiOperation("根据车辆id查询司机")
@PostMapping("/driverVehicleBindApi/getInfoByVid")
public AjaxResult getInfoByVid(@RequestBody List<Long> ids);
/**
* 根据车辆ids查询司机
*/
@ApiOperation("根据车辆id查询司机")
@PostMapping("/driverVehicleBindApi/getListByVid")
public R<List<DriverVehicleBind>> getListByVid(@RequestBody List<Long> ids);
/**
* 根据用户ID查询用户详细信息
*/
@ApiOperation("根据用户ID查询用户详细信息")
@GetMapping("/userApi/getInfo/{userId}")
public AjaxResult getInfo(@PathVariable("userId") Long userId);
@ApiOperation("查询承运人详情及所属企业")
@GetMapping("/userDriverApi/getDriverDataByUserId/{userId}")
public AjaxResult getDriverDataByUserId(@PathVariable("userId") Long userId);
/**
* 查询车辆绑定的承运人列表
*/
@ApiOperation("查询车辆绑定的承运人列表")
@GetMapping("/userAppApi/bindDriverShipList")
public AjaxResult bindDriverShipList(@RequestParam("vehicleId") Long vehicleId);
@ApiOperation("变更车主绑定关系")
@PostMapping("/driverVehicleBindApi/changeVehicleUserId")
public AjaxResult changeVehicleUserId(@RequestBody DriverVehicleBindDto driverVehicleBindDto);
/**
* 查询用户数据权限-包含组织和创建人
* @param userDataPermissionQueryDTO
* @return
*/
@PostMapping("/userApi/findDataPermission")
public AjaxResult findDataPermission(@RequestBody UserDataPermissionQueryDTO userDataPermissionQueryDTO);
/**
* 修改车辆信息时同步修改绑定表信息
*/
@PostMapping("/driverVehicleBindApi/informationSynchronization")
public AjaxResult informationSynchronization(@RequestBody DriverVehicleBindDto driverVehicleBindDto);
/**
* 车辆导入-承运人查询
*
* @return
*/
@ApiOperation("车辆导入-承运人查询")
@GetMapping("/userDriverApi/userDriverImportList")
public AjaxResult userDriverImportList();
/**
* 根据承运商编码获取企业信息
*/
@GetMapping("/openApi/getInfoByEnterpriseCode")
public AjaxResult<?> getInfoByEnterpriseCode(@RequestParam("enterpriseCode") String enterpriseCode);
/**
* 根据车辆ids查询司机
*/
@ApiOperation("根据车辆id查询司机")
@GetMapping("/driverVehicleBindApi/getBindListByVid")
public AjaxResult<?> getBindListByVid(@RequestParam("id") Long id);
/**
* 根据车辆ids查询司机
*/
@ApiOperation("根据车辆id查询司机")
@GetMapping("/driverVehicleBindApi/getBindListByUserId")
public R<List<Long>> getBindListByUserId(@RequestParam("id") Long id);
/**
* 获取全部已经被绑定的车辆
*/
@ApiOperation("获取全部已经被绑定的车辆")
@GetMapping("/driverVehicleBindApi/getAllBindList")
public R<List<Long>> getAllBindList();
/**
* 认证成功查询绑定关系并同步网货
* @param vehicleId
* @return
*/
@GetMapping("/userDriverApi/bindVehicleForWlhy")
public AjaxResult bindVehicleForWlhy(@RequestParam("vehicleId") Long vehicleId);
/**
* 根据用户id查询车队信息
*/
@GetMapping("/userDriverApi/getCaptainInfoByUserId")
public AjaxResult getCaptainInfoByUserId(@RequestParam("userId") Long userId);
/**
* 根据用户id查询企业信息
*/
@GetMapping("/userDriverApi/getEnterpriseByUserId")
public AjaxResult getEnterpriseByUserId(@RequestParam("userId") Long userId);
/**
* 通过用户名查询用户信息
*
* @return 结果
*/
@PostMapping("/userApi/getUserPoByOrganizationAndUserAccount")
public R<UserPo> getUserPoByOrganizationAndUserAccount(@RequestBody UserDTO userDTO);
@ApiOperation("根据用户ID查询角色列表")
@GetMapping("/roleApi/getRoleListByUserId/{userId}")
public AjaxResult getRoleListByUserId(@PathVariable("userId") Long userId);
/**
* 根据获取userId货主公司名称
*
* @return 货主公司名称
*/
@GetMapping("/userApi/userName/{userId}")
R<String> finShipperEnterpriseNamedByUserId(@PathVariable("userId") Long userId);
@GetMapping("/driverVehicleBindApi/isVehicleBinding/{vehicleLicensePlateNumber}")
R<Boolean> isVehicleBinding(
@PathVariable("vehicleLicensePlateNumber") String vehicleLicensePlateNumber);
}
@@ -0,0 +1,44 @@
package com.linke.transport.infrastructure.mq.listener;
import com.linke.transport.application.service.warehouse.WarehouseApplicationService;
import com.mhd.system.api.event.object.ShipperNameChangedEvent;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.context.annotation.Bean;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;
import java.util.function.Consumer;
@Component
@Log4j2
@AllArgsConstructor
public class ShipperNameChangedEventListener {
private final WarehouseApplicationService warehouseApplicationService;
/**
* 创建一个消费者Bean来处理货主名称变更事件。
* Spring Cloud Stream 会将此Bean绑定到 'shipperNameChanged-in-0' 输入通道。
*
* @return 一个处理事件的 Consumer
*/
@Bean
public Consumer<Message<ShipperNameChangedEvent>> shipperNameChanged() {
return message -> {
// 从 Message 对象中获取真正的 payload
ShipperNameChangedEvent event = message.getPayload();
log.info("基础设施层接收到货主名称变更事件: {}", event);
// 打印消息头,有助于调试
log.debug("收到的消息头: {}", message.getHeaders());
try {
// 将事件处理委托给应用层更新货主
warehouseApplicationService.processShipperNameUpdate(event.getUserId(), event.getNewShipperName());
} catch (RuntimeException e) {
log.error("调用应用层处理事件失败, 将抛出异常以触发重试机制. Event: {}", event, e);
// 向上抛出异常,Spring Cloud Stream的重试/死信队列机制会接管
throw e;
}
};
}
}
@@ -0,0 +1,368 @@
package com.linke.transport.infrastructure.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.XML;
import com.linke.transport.infrastructure.feign.ProductServiceFeign;
import com.mhd.common.core.feign.ThirdPartyServiceFeign;
import com.mhd.common.core.utils.SpringUtils;
import com.mhd.common.core.utils.poi.WpsImg;
import com.mhd.common.core.web.domain.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* wps图片工具类
*/
@Slf4j
public class WpsImgUtil {
/**
* 获取wps中的图片
* 包括嵌入形式图片和浮动形式图片
* <p>
* 嵌入形式图片返回方式:
* 以map方式返回
* 键为行列格式 =DISPIMG("ID",1) 字符串
* <p>
* 浮动形式图片返回方式:
* 以map方式返回
* 键为行列格式 x-y 字符串
*
* @param dispStrList
* @param simpleFile
* @return
* @throws IOException
*/
public static Map<String, WpsImg> getWpsImgs(List<String> dispStrList, MultipartFile simpleFile) throws IOException {
List<WpsImg> wpsImgList = new ArrayList<>();
for (String dispStr : dispStrList) {
if (Objects.nonNull(dispStr) && dispStr.startsWith("=DISPIMG")) {
int start = dispStr.indexOf("\"");
int end = dispStr.lastIndexOf("\"");
if (start != -1 && end != -1) {
String imgId = dispStr.substring(start + 1, end);
WpsImg wpsImg = new WpsImg();
wpsImg.setType(0);
wpsImg.setImgId(imgId);
wpsImg.setCellStr(dispStr);
wpsImgList.add(wpsImg);
}
}
}
ZipInputStream zis = new ZipInputStream(simpleFile.getInputStream());
try {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
try {
final String fileName = entry.getName();
if (Objects.equals(fileName, "xl/cellimages.xml")) {
String content = IOUtils.toString(zis, CharsetUtil.UTF_8);
JSONObject js = XML.toJSONObject(content);
if (Objects.isNull(js)) {
continue;
}
JSONObject cellImages = js.getJSONObject("etc:cellImages");
if (Objects.isNull(cellImages)) {
continue;
}
JSONArray cellImage = null;
try {
cellImage = cellImages.getJSONArray("etc:cellImage");
} catch (Exception e) {
}
if (Objects.isNull(cellImage)) {
JSONObject cellImageObj = null;
try {
cellImageObj = cellImages.getJSONObject("etc:cellImage");
} catch (Exception e) {
}
if (Objects.nonNull(cellImageObj)) {
cellImage = new JSONArray();
cellImage.add(cellImageObj);
}
}
if (Objects.isNull(cellImage)) {
continue;
}
for (int i = 0; i < cellImage.size(); i++) {
JSONObject imageItem = cellImage.getJSONObject(i);
if (Objects.isNull(imageItem)) {
continue;
}
JSONObject pic = imageItem.getJSONObject("xdr:pic");
if (Objects.isNull(pic)) {
continue;
}
JSONObject nvPicPr = pic.getJSONObject("xdr:nvPicPr");
if (Objects.isNull(nvPicPr)) {
continue;
}
JSONObject cNvPr = nvPicPr.getJSONObject("xdr:cNvPr");
if (Objects.isNull(cNvPr)) {
continue;
}
String name = cNvPr.getStr("name");
if (StringUtils.isNotEmpty(name)) {
List<WpsImg> wpsImgs = wpsImgList.stream().filter(item -> Objects.equals(item.getImgId(), name)).collect(Collectors.toList());
if (!wpsImgs.isEmpty()) {
JSONObject blipFill = pic.getJSONObject("xdr:blipFill");
if (Objects.isNull(blipFill)) {
continue;
}
JSONObject blip = blipFill.getJSONObject("a:blip");
if (Objects.isNull(blip)) {
continue;
}
String embed = blip.getStr("r:embed");
wpsImgs.forEach(x -> x.setRId(embed));
}
}
}
}
} finally {
zis.closeEntry();
}
}
} finally {
zis.close();
}
ZipInputStream fzis = new ZipInputStream(simpleFile.getInputStream());
try {
ZipEntry entry;
while ((entry = fzis.getNextEntry()) != null) {
try {
final String fileName = entry.getName();
if (Objects.equals(fileName, "xl/_rels/cellimages.xml.rels")) {
String content = IOUtils.toString(fzis, CharsetUtil.UTF_8);
JSONObject js = XML.toJSONObject(content);
JSONObject relationships = js.getJSONObject("Relationships");
if (Objects.isNull(relationships)) {
continue;
}
JSONArray relationship = null;
try {
relationship = relationships.getJSONArray("Relationship");
} catch (Exception e) {
}
if (Objects.isNull(relationship)) {
try {
JSONObject relationshipObj = relationships.getJSONObject("Relationship");
if (Objects.nonNull(relationshipObj)) {
relationship = new JSONArray();
relationship.add(relationshipObj);
}
} catch (Exception e) {
}
}
if (Objects.isNull(relationship)) {
continue;
}
for (int i = 0; i < relationship.size(); i++) {
JSONObject relaItem = relationship.getJSONObject(i);
if (Objects.isNull(relaItem)) {
continue;
}
String id = relaItem.getStr("Id");
String target = "/xl/" + relaItem.getStr("Target");
if (StringUtils.isNotEmpty(id)) {
//wps 重复图片会保存为一个,所以这个处理下,相同rid 指向同一个图片
List<WpsImg> wpsImgs = wpsImgList.stream().filter(item -> Objects.equals(item.getRId(), id)).collect(Collectors.toList());
if (CollUtil.isNotEmpty(wpsImgs)) {
wpsImgs.forEach(x -> x.setImgName(target));
}
}
}
}
} finally {
fzis.closeEntry();
}
}
} finally {
fzis.close();
}
Workbook workbook = WorkbookFactory.create(simpleFile.getInputStream());
List<XSSFPictureData> allPictures = (List<XSSFPictureData>) workbook.getAllPictures();
for (XSSFPictureData pictureData : allPictures) {
PackagePartName partName = pictureData.getPackagePart().getPartName();
URI uri = partName.getURI();
//wps 重复图片会保存为一个,所以这个处理下,相同rid 指向同一个图片
List<WpsImg> wpsImgs = wpsImgList.stream().filter(item -> Objects.equals(item.getImgName(), uri.toString())).collect(Collectors.toList());
if (CollUtil.isNotEmpty(wpsImgs)) {
wpsImgs.forEach(x -> x.setPictureData(pictureData));
}
}
Map<String, WpsImg> result = new HashMap<>();
for (WpsImg wpsImg : wpsImgList) {
result.put(wpsImg.getCellStr(), wpsImg);
}
XSSFSheet sheet = (XSSFSheet) workbook.getSheetAt(0);
Map<String, WpsImg> flotPictures = WpsImgUtil.getFlotPictures(sheet);
result.putAll(flotPictures);
return result;
}
/**
* 获取浮动形式的图片
* 以map方式返回
* 键为行列格式 x-y
*
* @param xssfSheet
* @return
*/
public static Map<String, WpsImg> getFlotPictures(XSSFSheet xssfSheet) {
Map<String, WpsImg> map = new HashMap<>();
XSSFDrawing drawingPatriarch = xssfSheet.getDrawingPatriarch();
if (Objects.isNull(drawingPatriarch)) {
return map;
}
List<XSSFShape> list = drawingPatriarch.getShapes();
for (XSSFShape shape : list) {
XSSFPicture picture = (XSSFPicture) shape;
XSSFClientAnchor xssfClientAnchor = (XSSFClientAnchor) picture.getAnchor();
XSSFPictureData pdata = picture.getPictureData();
// 行号-列号
String key = xssfClientAnchor.getRow1() + "-" + xssfClientAnchor.getCol1();
WpsImg wpsImg = new WpsImg();
wpsImg.setPictureData(pdata);
wpsImg.setType(1);
map.put(key, wpsImg);
}
return map;
}
/**
* 获取图片属性ID
*/
public static <T> List<String> getDispimgList(List<T> list) {
List<String> pictureIds = new ArrayList<>();
try {
for (T object : list) {
// 获取对象的类
Class<?> objClass = object.getClass();
// 获取类中所有声明的字段(包括私有字段)
Field[] fields = objClass.getDeclaredFields();
// 遍历字段并获取其值
for (Field field : fields) {
// 设置字段可访问(如果是私有字段)
field.setAccessible(true);
// 获取字段值
Object value = field.get(object);
if (value instanceof String) {
if (StrUtil.contains(value.toString(), "=DISPIMG")) {
pictureIds.add(value.toString());
}
}
}
}
} catch (Exception e) {
log.error("获取图片属性ID异常", e);
}
return pictureIds;
}
/**
* 获取图片属性ID
*/
public static <T> void setDispimgUrl(List<T> list, Map<String, WpsImg> wpsImgs) {
try {
ProductServiceFeign productServiceFeign = SpringUtils.getBean(ProductServiceFeign.class);
for (T object : list) {
// 获取对象的类
Class<?> objClass = object.getClass();
// 获取类中所有声明的字段(包括私有字段)
Field[] fields = objClass.getDeclaredFields();
// 遍历字段并获取其值
for (Field field : fields) {
// 设置字段可访问(如果是私有字段)
field.setAccessible(true);
// 获取字段值
Object value = field.get(object);
if (value instanceof String) {
String s = value.toString();
if (wpsImgs.containsKey(s)) {
WpsImg wpsImg = wpsImgs.get(s);
PictureData pictureData = wpsImg.getPictureData();
byte[] data = pictureData.getData();
// OutputStream os = Files.newOutputStream(Paths.get("/images/" + wpsImg.getImgId() + ".jpeg"));
try (OutputStream os = Files.newOutputStream(Paths.get("E:\\images" + wpsImg.getImgId() + ".jpeg"))) {
os.write(data);
}
// File file = new File("/images/" + wpsImg.getImgId() + ".jpeg");
File file = new File("E:\\images" + wpsImg.getImgId() + ".jpeg");
MultipartFile cMultiFile = getMultipartFile(file);
AjaxResult ajaxResult = productServiceFeign.uploadFeign(cMultiFile);
if ("200".equals(String.valueOf(ajaxResult.get("code")))) {
String imgUrl = ajaxResult.get(AjaxResult.MSG_TAG).toString();
field.set(object, imgUrl);
}
file.delete();
}
}
}
}
} catch (Exception e) {
log.error("添加图片地址异常", e);
}
}
/**
* file转multiPartFile
*
* @param file
* @return
*/
public static MultipartFile getMultipartFile(File file) {
DiskFileItem item = new DiskFileItem("file"
, MediaType.MULTIPART_FORM_DATA_VALUE
, true
, file.getName()
, (int) file.length()
, file.getParentFile());
try {
OutputStream os = item.getOutputStream();
os.write(FileUtils.readFileToByteArray(file));
} catch (IOException e) {
e.printStackTrace();
}
return new CommonsMultipartFile(item);
}
}
@@ -0,0 +1,15 @@
package com.linke.transport.infrastructure.util.annotation;
import java.lang.annotation.*;
/**
* 数据权限注解
* @author zg
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataPermissions {
String cacheName();//缓存逻辑名称
}
@@ -0,0 +1,103 @@
package com.linke.transport.infrastructure.util.annotation;
import com.alibaba.fastjson2.JSONObject;
import com.linke.transport.infrastructure.feign.UserServiceFeign;
import com.mhd.common.core.domain.dto.UserDataPermissionQueryDTO;
import com.mhd.common.core.domain.po.UserDataPermissionPO;
import com.mhd.common.core.enums.RoleEnum;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
@Component
@Aspect
public class SetDataPermissions {
@Resource
private UserServiceFeign userServiceFeign;
@Before("@annotation(dst)")
public void dosetFeildValue(JoinPoint pjp, DataPermissions dst) throws Throwable {
Object[] args = pjp.getArgs(); //获取目标对象方法参数
//获取当前登陆人
LoginUser loginUser = SecurityUtils.getLoginUser();
String s = dst.cacheName();
Long permissionmenuId = getFieldValue(args, "permissionMenuId");
//主要权限
if ("master".equals(s)) {
if (loginUser != null) {
//判断当前用户是否是超级管理员/租户管理员还是普通用户,如果是超级管理员则返回全部组织,租户管理员则返回租户所属组织的全部组织,普通用户需要判断数据权限
if (RoleEnum.SUPER_ADMIN.getCode().equals(loginUser.getUserPo().getRoleCode())) {
//全部不加限制条件
} else if (loginUser.getUserPo().getRoleCode().contains(RoleEnum.PLAT_ADMIN.getCode())) {
objectSetValue(args, "organizationIdList", loginUser.getOrganizationPo().getOrganizationIdList());
} else {
if (permissionmenuId != null) {
//获取当前用户数据权限
UserDataPermissionQueryDTO userDataPermissionQueryDTO = new UserDataPermissionQueryDTO();
userDataPermissionQueryDTO.setMenuId(permissionmenuId);
userDataPermissionQueryDTO.setOrganizationId(loginUser.getUserPo().getOrganizationId());
userDataPermissionQueryDTO.setUserId(loginUser.getUserPo().getUserId());
AjaxResult info = userServiceFeign.findDataPermission(userDataPermissionQueryDTO);
if ("200".equals(String.valueOf(info.get("code")))) {
UserDataPermissionPO userDataPermissionPO = JSONObject.parseObject(JSONObject.toJSONString(info.get("data")), UserDataPermissionPO.class);
List<Long> organizationIdList = userDataPermissionPO.getOrganizationIdList();
if (userDataPermissionPO.getUserDataPersonalStatus() != null && userDataPermissionPO.getUserDataPersonalStatus() == 1) {
objectSetValue(args, "organizationId", loginUser.getUserPo().getOrganizationId());
objectSetValue(args, "createBy", loginUser.getUserPo().getUserId());
}
if (userDataPermissionPO.getUserDataOrganizationStatus() != null && userDataPermissionPO.getUserDataOrganizationStatus() == 1) {
if (organizationIdList == null) {
organizationIdList = new ArrayList<>();
}
organizationIdList.add(loginUser.getUserPo().getOrganizationId());
}
if (organizationIdList != null) {
objectSetValue(args, "organizationIdList", organizationIdList);
}
}
} else {
objectSetValue(args, "createBy", loginUser.getUserPo().getUserId());
}
}
}
}
}
public void objectSetValue(Object[] args, String fieldName, Object value) {
for (Object arg : args) {
Field field = ReflectionUtils.findField(arg.getClass(), fieldName);
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, arg, value);
}
}
public Long getFieldValue(Object[] args, String field) {
Long a = null;
for (Object arg : args) {
try {
Field fieldName = arg.getClass().getDeclaredField(field);
if (fieldName != null) {
fieldName.setAccessible(true);
Object o = fieldName.get(arg);
if (o != null) {
a = Long.valueOf(o.toString());
return a;
}
}
} catch (Exception e) {
}
}
return a;
}
}
@@ -0,0 +1,8 @@
package com.linke.transport.infrastructure.warehouse.inboundOrder.persistence;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.linke.transport.domain.warehouse.inboundOrder.model.InboundOrderDetail;
public interface InboundOrderDetailMapper extends BaseMapper<InboundOrderDetail> {
}
@@ -0,0 +1,8 @@
package com.linke.transport.infrastructure.warehouse.inboundOrder.persistence;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.linke.transport.domain.warehouse.inboundOrder.model.InboundOrder;
public interface InboundOrderMapper extends BaseMapper<InboundOrder> {
}
@@ -0,0 +1,48 @@
package com.linke.transport.infrastructure.warehouse.inventory.persistence;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.linke.transport.application.service.warehouse.inventory.vo.InventoryVO;
import com.linke.transport.domain.warehouse.inventory.model.Inventory;
import com.linke.transport.interfaces.dto.warehouse.inventory.InventoryDTO;
import java.math.BigDecimal;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface InventoryMapper extends BaseMapper<Inventory> {
/**
* 增加库存(线程安全,使用数据库原子操作)
*
* @param inventoryId 物料ID
* @param quantity 增加的数量
* @param userName 操作用户ID
* @return 更新的行数
*/
int increaseQuantity(@Param("inventoryId") Long inventoryId,
@Param("quantity") BigDecimal quantity,
@Param("userName") String userName);
/**
* 减少库存(原子操作,带乐观锁或版本号校验更佳,此处简化)
*
* @param inventoryId 库存记录ID
* @param quantity 减少的数量 (正数)
* @param userName 操作用户
* @return 更新的行数 (应该为 1 表示成功)
*/
int decreaseQuantity(@Param("inventoryId") Long inventoryId,
@Param("quantity") BigDecimal quantity,
@Param("userName") String userName);
/**
* 分页查询库存列表 (使用 JOIN 获取物料信息)
*
* @param page 分页参数
* @param query 查询条件 DTO
* @return 分页结果,包含物料信息
*/
Page<InventoryVO> findInventoryList(@Param("page") Page<InventoryVO> page, @Param("query") InventoryDTO.Query query);
List<InventoryVO> findAllInventoryList(@Param("ownerId") Long ownerId,@Param("machineSerialNo")String machineSerialNo);
}
@@ -0,0 +1,16 @@
package com.linke.transport.infrastructure.warehouse.inventoryLedger.persistence;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.linke.transport.domain.warehouse.inventoryLedger.model.InventoryLedger;
/**
* <p>
* 库存流水记录表 Mapper 接口
* </p>
*
* @author chenxianfu
* @since 2025-04-29
*/
public interface InventoryLedgerMapper extends BaseMapper<InventoryLedger> {
}
@@ -0,0 +1,20 @@
package com.linke.transport.infrastructure.warehouse.material;
import com.linke.transport.domain.warehouse.material.MaterialCodeGenerator;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ThreadLocalRandom;
import org.springframework.stereotype.Component;
@Component
public class DefaultMaterialCodeGenerator implements MaterialCodeGenerator {
private static final DateTimeFormatter FORMATTER =
DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
@Override
public String generate() {
String timestamp = LocalDateTime.now().format(FORMATTER);
int random = ThreadLocalRandom.current().nextInt(10000);
return "WL" + timestamp + String.format("%04d", random);
}
}
@@ -0,0 +1,41 @@
package com.linke.transport.infrastructure.warehouse.material.converter;
import com.linke.transport.application.service.warehouse.material.vo.MaterialVO;
import com.linke.transport.domain.warehouse.material.exception.MaterialDomainException;
import com.linke.transport.domain.warehouse.material.model.Material;
import com.linke.transport.infrastructure.warehouse.material.persistence.MaterialDO;
import org.springframework.beans.BeanUtils;
public class MaterialConverter {
public static MaterialDO convert(Material source) {
try {
MaterialDO target = new MaterialDO();
BeanUtils.copyProperties(source, target);
return target;
} catch (Exception e) {
throw new MaterialDomainException("对象转换失败", e);
}
}
public static Material convert(MaterialDO source) {
if (source == null) {
return null;
}
try {
Material target = new Material();
BeanUtils.copyProperties(source, target);
return target;
} catch (Exception e) {
throw new MaterialDomainException("对象转换失败", e);
}
}
public static MaterialVO convertToVO(Material source) {
try {
MaterialVO target = new MaterialVO();
BeanUtils.copyProperties(source, target);
return target;
} catch (Exception e) {
throw new MaterialDomainException("对象转换失败", e);
}
}
}
@@ -0,0 +1,35 @@
package com.linke.transport.infrastructure.warehouse.material.persistence;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Data;
@Data
@TableName("material")
public class MaterialDO {
@TableId(type = IdType.AUTO)
private Long id;
private String materialCode;
private String shipper;
private Long ownerId;
private String category;
private String name;
private String model;
private String unit;
private BigDecimal value;
private BigDecimal weight;
private Boolean codeManaged;
private String remark;
private LocalDateTime createTime;
private LocalDateTime updateTime;
@TableLogic
@TableField("is_deleted")
private Boolean deleted;
}
@@ -0,0 +1,9 @@
package com.linke.transport.infrastructure.warehouse.material.persistence;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface MaterialMapper extends BaseMapper<MaterialDO> {
}
@@ -0,0 +1,105 @@
package com.linke.transport.infrastructure.warehouse.material.repository;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.linke.transport.domain.warehouse.material.model.Material;
import com.linke.transport.domain.warehouse.material.repository.MaterialRepository;
import com.linke.transport.infrastructure.warehouse.material.converter.MaterialConverter;
import com.linke.transport.infrastructure.warehouse.material.persistence.MaterialDO;
import com.linke.transport.infrastructure.warehouse.material.persistence.MaterialMapper;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import java.time.LocalDateTime;
@Repository
@RequiredArgsConstructor
public class MaterialRepositoryImpl implements MaterialRepository {
private final MaterialMapper materialMapper;
@Override
public Material save(Material material) {
MaterialDO materialDO = MaterialConverter.convert(material);
materialMapper.insert(materialDO);
BeanUtils.copyProperties(materialDO, material);
return material;
}
@Override
public void update(Material material) {
MaterialDO materialDO = MaterialConverter.convert(material);
materialMapper.updateById(materialDO);
}
@Override
public Optional<Material> findById(Long id) {
return Optional.ofNullable(MaterialConverter.convert(materialMapper.selectById(id)));
}
@Override
public void deleteById(Long id) {
try {
materialMapper.deleteById(id);
} catch (Exception e) {
throw new RuntimeException("删除失败");
}
}
@Override
public IPage<Material> search(String shipper, String category, String name, String model,String materialCode,Boolean codeManaged,String remark,
Long current, Long size) {
LambdaQueryWrapper<MaterialDO> wrapper = Wrappers.<MaterialDO>lambdaQuery()
.eq(StringUtils.isNotBlank(shipper), MaterialDO :: getShipper, shipper)
.eq(StringUtils.isNotBlank(category), MaterialDO :: getCategory, category)
.like(StringUtils.isNotBlank(name), MaterialDO :: getName, name)
.like(StringUtils.isNotBlank(model), MaterialDO :: getModel, model)
.like(StringUtils.isNotBlank(materialCode), MaterialDO :: getMaterialCode, materialCode)
.eq(null!=codeManaged, MaterialDO :: getCodeManaged, codeManaged)
.like(StringUtils.isNotBlank(remark), MaterialDO :: getRemark, remark)
.orderByDesc(MaterialDO :: getCreateTime);
return materialMapper.selectPage(new Page<>(current, size), wrapper)
.convert(MaterialConverter :: convert);
}
@Override
public Optional<List<Material>> findByIdIn(List<Long> ids) {
return Optional.of(materialMapper
.selectBatchIds(ids)
.stream()
.map(MaterialConverter :: convert)
.collect(Collectors.toList())
);
}
@Override
public List<Material> findAllMaterials(Long ownerId) {
return materialMapper
.selectList(Wrappers.<MaterialDO>lambdaQuery().eq(Objects.nonNull(ownerId),MaterialDO :: getOwnerId, ownerId))
.stream()
.map(MaterialConverter :: convert)
.collect(Collectors.toList());
}
@Override
public int updateOwnerNameByOwnerId(Long ownerId, String ownerName) {
LambdaUpdateWrapper<MaterialDO> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(MaterialDO::getOwnerId, ownerId)
.set(MaterialDO::getShipper, ownerName)
.set(MaterialDO::getUpdateTime, LocalDateTime.now());
return materialMapper.update(null, updateWrapper);
}
}
@@ -0,0 +1,8 @@
package com.linke.transport.infrastructure.warehouse.outboundOrder.persistence;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.linke.transport.domain.warehouse.outboundOrder.model.OutboundOrderDetail;
public interface OutboundOrderDetailMapper extends BaseMapper<OutboundOrderDetail> {
}
@@ -0,0 +1,8 @@
package com.linke.transport.infrastructure.warehouse.outboundOrder.persistence;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.linke.transport.domain.warehouse.outboundOrder.model.OutboundOrder;
public interface OutboundOrderMapper extends BaseMapper<OutboundOrder> {
}
@@ -0,0 +1,94 @@
package com.linke.transport.interfaces.assemble.vehicle;
import cn.hutool.core.util.ObjectUtil;
import com.linke.transport.domain.vehicle.entity.Vehicle;
import com.linke.transport.interfaces.dto.vehicle.VehicleDto;
import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException;
import com.mhd.common.core.exception.digitalLogisticsException.UserError;
import com.mhd.common.core.utils.IgnoreNullUtil;
import com.mhd.common.core.utils.bean.BeanUtils;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import java.util.Date;
/**
* entity dto 转换
*
* 2022-12-9
*
* @author 王子豪
*/
public class VehicleAssembler {
/**
* 转换实体
*
* @param vehicleDto dto
* @return entity
*/
public Vehicle toDo(VehicleDto vehicleDto) {
Vehicle vehicle = new Vehicle();
// 拷贝vehicleDto到vehicle中
BeanUtils.copyProperties(vehicleDto, vehicle, IgnoreNullUtil.getNullPropertyNames(vehicleDto));
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new DigitalLogisticsException(UserError.TIMEOUT);
}
String userName = loginUser.getUsername();
// 获取登录人id
Long userId = loginUser.getUserid();
if(vehicleDto.getVehicleId() != null){
if(userId != null){
vehicle.setUpdateBy(userId);
}else {
vehicle.setUpdateBy(new Long("0"));
}
vehicle.setUpdateByName(userName);
vehicle.setUpdateTime(new Date());
if (vehicleDto.getAuthenticationStatus() != null){
vehicle.setCheckoutDate(new Date());
vehicle.setCheckoutPersonId(userId);
vehicle.setCheckoutPersonName(userName);
}
}else {
if(userId != null){
vehicle.setCreateBy(userId);
vehicle.setUpdateBy(userId);
}else {
vehicle.setCreateBy(new Long("0"));
vehicle.setUpdateBy(new Long("0"));
}
vehicle.setCreateByName(userName);
vehicle.setUpdateByName(userName);
vehicle.setCreateTime(new Date());
vehicle.setUpdateTime(new Date());
vehicle.setDelFlag(1);
}
return vehicle;
}
/**
* 转换实体(包含当前审核人)
*
* @param vehicleDto dto
* @return entity
*/
public Vehicle toCheck(VehicleDto vehicleDto) {
Vehicle vehicle = new Vehicle();
// 拷贝vehicleDto到vehicle中
BeanUtils.copyProperties(vehicleDto, vehicle);
//获取登录人
String userName= SecurityUtils.getLoginUser().getUsername();
// 获取登录人id
Long userId = SecurityUtils.getLoginUser().getUserid();
if(userId != null){
vehicle.setCheckoutPersonId(userId);
}else {
vehicle.setCheckoutPersonId(new Long("0"));
}
vehicle.setCheckoutPersonName(userName);
vehicle.setCheckoutDate(new Date());
return vehicle;
}
}
@@ -0,0 +1,416 @@
package com.linke.transport.interfaces.dto.vehicle;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mhd.common.core.web.domain.BaseVOEntity;
import com.mhd.common.core.annotation.fieldsetvalue.NeedSetValue;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 车辆管理 dto
*
* 2022-12-9
*
* @author 王子豪
*/
@Data
public class VehicleDto extends BaseVOEntity implements Serializable
{
@ApiModelProperty(name = "车辆id")
private Long vehicleId;
@ApiModelProperty(name = "车牌号")
private String vehicleLicensePlateNumber;
@ApiModelProperty(name = "车辆类别:1-个人车辆 2-企业车辆")
private Integer vehicleCategory;
@ApiModelProperty(name = "车辆类型(数据字典id)")
private String vehicleTypeId;
@ApiModelProperty(name = "车辆类型(数据字典name)")
private String vehicleTypeName;
@ApiModelProperty(name = "车辆来源(数据字典id)")
private String vehicleSourceId;
@ApiModelProperty(name = "车辆来源(数据字典name)")
private String vehicleSourceName;
@ApiModelProperty(name = "使用人")
private String vehicleUsePerson;
@ApiModelProperty(name = "住址")
private String vehicleAddress;
@ApiModelProperty(name = "使用性质")
private String vehicleUseNature;
@ApiModelProperty(name = "品牌类型")
private String vehicleBrandType;
@ApiModelProperty(name = "车辆识别代号")
private String vehicleIdentificationNumber;
@ApiModelProperty(name = "发动机号码")
private String vehicleEngineNumber;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "注册日期")
private Date vehicleRegistrationDate;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "发证日期")
private Date vehicleIssueDate;
@ApiModelProperty(name = "发证机关")
private String vehicleLicenceIssuingAuthority;
@ApiModelProperty(name = "档案编号")
private String vehicleFileNumber;
@ApiModelProperty(name = "总质量")
private BigDecimal vehicleTotalMass;
@ApiModelProperty(name = "核定载质量")
private BigDecimal vehicleApprovedLoadQuantity;
@ApiModelProperty(name = "外廓尺寸(长)")
private Integer vehicleGabariteOne;
@ApiModelProperty(name = "外廓尺寸(宽)")
private Integer vehicleGabariteTwo;
@ApiModelProperty(name = "外廓尺寸(高)")
private Integer vehicleGabariteThree;
@ApiModelProperty(name = "能源类型(字典id")
private String vehicleEnergyTypeId;
@ApiModelProperty(name = "能源类型(字典name")
private String vehicleEnergyTypeName;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "检验有效期")
private Date vehicleCheckoutPeriodValidity;
@ApiModelProperty(name = "备注")
private String vehicleRemark;
@NeedSetValue
@ApiModelProperty(name = "行驶证主页")
private String vehicleDrivingLicenseMain;
@NeedSetValue
@ApiModelProperty(name = "行驶证副页")
private String vehicleDrivingLicenseDeputy;
@NeedSetValue
@ApiModelProperty(name = "行驶证副页反面")
private String vehicleDrivingLicenseDeputyAgainst;
@ApiModelProperty(name = "是否挂车(0-无状态,1-挂车,2-不挂车)")
private Integer trailerStatus;
@ApiModelProperty(name = "挂车车牌号")
private String trailerLicensePlateNumber;
@ApiModelProperty(name = "挂车车辆类型(数据字典id)")
private String trailerVehicleTypeId;
@ApiModelProperty(name = "挂车车辆类型(数据字典name)")
private String trailerVehicleTypeName;
@ApiModelProperty(name = "挂车车牌颜色(数据字典id)")
private String trailerLicensePlateColorId;
@ApiModelProperty(name = "挂车车牌颜色(数据字典name)")
private String trailerLicensePlateColorName;
@ApiModelProperty(name = "挂车总质量")
private BigDecimal trailerTotalMass;
@ApiModelProperty(name = "挂车核定载质量")
private BigDecimal trailerApprovedLoadQuantity;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "挂车行驶证到期时间")
private Date trailerDrivingLicenseExpireDate;
@ApiModelProperty(name = "挂车行驶证是否长期(0-无状态,1-长期,2-不长期)")
private Integer trailerDrivingLicenseLongStatus;
@ApiModelProperty(name = "挂车道路运输证号")
private String trailerRoadTransportCertificateNo;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "挂车道路运输证有效期")
private Date trailerRoadTransportCertificateExpireDate;
@ApiModelProperty(name = "挂车道路运输证是否长期(0-无状态,1-长期,2-不长期)")
private Integer trailerRoadTransportCertificateLongStatus;
@NeedSetValue
@ApiModelProperty(name = "挂车行驶证主页")
private String trailerDrivingLicenseMain;
@NeedSetValue
@ApiModelProperty(name = "挂车行驶证副页")
private String trailerDrivingLicenseDeputy;
@NeedSetValue
@ApiModelProperty(name = "挂车道路运输证照片")
private String trailerRoadTransportCertificateImage;
@ApiModelProperty(name = "其他车辆车牌颜色(数据字典id)")
private String otherLicensePlateColorId;
@ApiModelProperty(name = "其他车辆车牌颜色(数据字典name)")
private String otherLicensePlateColorName;
@ApiModelProperty(name = "其他车辆能源类型(字典id")
private String otherEnergyTypeId;
@ApiModelProperty(name = "其他车辆能源类型(字典name")
private String otherEnergyTypeName;
@ApiModelProperty(name = "其他车辆车轴轴数(字典id")
private String otherAxlesNumberId;
@ApiModelProperty(name = "其他车辆车轴轴数(字典name")
private String otherAxlesNumberName;
@ApiModelProperty(name = "其他车辆车辆长度(字典id")
private String otherCarLengthId;
@ApiModelProperty(name = "其他车辆车辆长度(字典name")
private String otherCarLengthName;
@ApiModelProperty(name = "其他车辆车辆容积(字典id")
private String otherVehicleVolumeId;
@ApiModelProperty(name = "其他车辆车辆容积(字典name")
private String otherVehicleVolumeName;
@NeedSetValue
@ApiModelProperty(name = "其他车辆车头照片")
private String otherHeadstockImage;
@ApiModelProperty(name = "其他车辆车身照片")
@NeedSetValue
private String otherBodyworkImage;
@NeedSetValue
@ApiModelProperty(name = "其他车辆人车合影照片")
private String otherPersonCarImage;
@ApiModelProperty(name = "道路运输证号")
private String roadTransportCertificateNo;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "道路运输证有效期")
private Date roadTransportCertificateExpireDate;
@ApiModelProperty(name = "道路运输证是否长期(0-无状态,1-长期,2-不长期)")
private Integer roadTransportCertificateLongStatus;
@NeedSetValue
@ApiModelProperty(name = "道路运输证照片")
private String roadTransportCertificateImage;
@ApiModelProperty(name = "经营许可证号")
private String businessLicenseNumber;
@ApiModelProperty(name = "业户名称")
private String specializedHouseholdsName;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "经营许可证件有效期(开始)")
private Date businessLicenseExpireStartDate;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "经营许可证件有效期(结束)")
private Date businessLicenseExpireEndDate;
@ApiModelProperty(name = "经营许可证件是否长期(0-无状态,1-长期,2-不长期)")
private Integer businessLicenseLongStatus;
@NeedSetValue
@ApiModelProperty(name = "经营许可证件照片")
private String businessLicenseImage;
@ApiModelProperty(name = "车辆审核状态(0-无状态,1-未认证,2-等待审核,3-已通过,4-已驳回)")
private Integer authenticationStatus;
@ApiModelProperty(name = "驳回原因")
private String rejectReason;
@ApiModelProperty(name = "承运人用户表id")
private Long userId;
@ApiModelProperty(name = "承运人用户表姓名")
private String userName;
@ApiModelProperty(name = "承运人手机号")
private String userPhone;
@ApiModelProperty(name = "承运人账号")
private String userAccount;
@ApiModelProperty(name = "车队id")
private Long motorcadeId;
@ApiModelProperty(name = "车队名称")
private String motorcadeName;
@ApiModelProperty(name = "运载状态(0-无状态,1-空载,2-负载)")
private Integer carryStatus;
@ApiModelProperty(name = "道路运输证校验状态(0-无状态,1-未核验,2-核验通过,3-核验失败)")
private Integer roadTransportCertificateCheckoutStatus;
@ApiModelProperty(name = "经营许可证件校验状态(0-无状态,1-未核验,2-核验通过,3-核验失败)")
private Integer businessLicenseCheckoutStatus;
@ApiModelProperty(name = "入网核验状态(0-无状态,1-未核验,2-已入网,3-未入网)")
private Integer netInStatus;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "入网查询时间")
private Date netInDate;
@ApiModelProperty(name = "使用状态(0-无状态,1-正常,2-黑名单)")
private Integer useStatus;
@ApiModelProperty(name = "最高组织id")
private Long topOrganizationId;
@ApiModelProperty(name = "归属组织id")
private Long organizationId;
@ApiModelProperty(name = "归属组织name")
private String organizationName;
@ApiModelProperty(name = "审核人员id")
private Long checkoutPersonId;
@ApiModelProperty(name = "审核人员name")
private String checkoutPersonName;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "审核时间")
private Date checkoutDate;
@ApiModelProperty(name = "行驶证认证状态(0-无状态,1-未认证,2-已认证)")
private Integer vehicleDrivingLicenseAuthStatus;
@ApiModelProperty(name = "车辆认证状态(0-无状态,1-未认证,2-已认证)")
private Integer vehicleAuthStatus;
@ApiModelProperty(name = "挂车认证状态(0-无状态,1-未认证,2-已认证)")
private Integer trailerLicensePlateAuthStatus;
@ApiModelProperty(name = "道路运输证认证状态(0-无状态,1-未认证,2-已认证)")
private Integer roadTransportCertificateAuthStatus;
@ApiModelProperty(name = "经营许可证认证状态(0-无状态,1-未认证,2-已认证)")
private Integer businessLicenseExpireAuthStatus;
@ApiModelProperty(name = "车辆总认证状态(0-无状态,1-未认证,2-已认证)")
private Integer authStatus;
@ApiModelProperty(name = "道路运输证审核状态(0-无状态,1-未认证,2-等待审核,3-已通过,4-已驳回)")
private Integer roadTransportCertificateCheckStatus;
@ApiModelProperty(name = "经营许可证审核状态(0-无状态,1-未认证,2-等待审核,3-已通过,4-已驳回)")
private Integer businessLicenseExpireCheckStatus;
@ApiModelProperty(name = "黑名单状态(0-无状态,1-不是,2-是)")
private Integer blacklistStatus;
@ApiModelProperty(name = "黑名单备注")
private String blacklistRemark;
@ApiModelProperty(name = "总质量起始")
private BigDecimal vehicleTotalMassStart;
@ApiModelProperty(name = "总质量结束")
private BigDecimal vehicleTotalMassEnd;
@ApiModelProperty(name = "核定载质量起始")
private BigDecimal vehicleApprovedLoadQuantityStart;
@ApiModelProperty(name = "核定载质量结束")
private BigDecimal vehicleApprovedLoadQuantityEnd;
@ApiModelProperty(name = "其他车辆车轴轴数起始")
private Integer otherAxlesNumberNameStart;
@ApiModelProperty(name = "其他车辆车轴轴数结束")
private Integer otherAxlesNumberNameEnd;
@ApiModelProperty(name = "其他车辆车辆长度起始")
private Integer otherCarLengthNameStart;
@ApiModelProperty(name = "其他车辆车辆长度结束")
private Integer otherCarLengthNameEnd;
@ApiModelProperty(name = "其他车辆车辆容积起始")
private Integer otherVehicleVolumeNameStart;
@ApiModelProperty(name = "其他车辆车辆容积结束")
private Integer otherVehicleVolumeNameEnd;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "检验有效期开始")
private Date vehicleCheckoutPeriodValidityStart;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "检验有效期结束")
private Date vehicleCheckoutPeriodValidityEnd;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "道路运输证有效期")
private Date roadTransportCertificateExpireDateStart;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "道路运输证有效期")
private Date roadTransportCertificateExpireDateEnd;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "经营许可证件有效期(结束)起始")
private Date businessLicenseExpireEndDateStart;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "经营许可证件有效期(结束)结束")
private Date businessLicenseExpireEndDateEnd;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "入网查询时间起始")
private Date netInDateStart;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "入网查询时间结束")
private Date netInDateEnd;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "审核时间起始")
private Date checkoutDateStart;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(name = "审核时间结束")
private Date checkoutDateEnd;
@ApiModelProperty(name = "添加人员")
private String createByName;
@ApiModelProperty(value = "添加时间起始")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date createTimeStart;
@ApiModelProperty(value = "添加时间结束")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date createTimeEnd;
@ApiModelProperty(name = "车辆id集合")
private List<Long> vehicleIdList;
@ApiModelProperty(name = "组织ID集合")
private List<Long> organizationIdList;
@ApiModelProperty(name = "权限菜单ID")
private Long permissionMenuId;
@ApiModelProperty(name = "认证进度(1.(行驶证,添加车辆)2.(车辆信息)3.提交认证(道路运输证)4.无道路运输证,提交认证)")
private Integer authSchdule;
/**
* PC车队认证步骤(0.行驶证 1.车辆信息 2.提交认证(道路运输证)3.提交认证(无道路运输证))
*/
@ApiModelProperty(name = "PC车队认证步骤(0.行驶证 1.车辆信息 2.提交认证(道路运输证)3.提交认证(无道路运输证))")
private Integer stepFlag;
@ApiModelProperty(value = "校验记录")
private java.lang.String checkRecord;
@ApiModelProperty(value = "查询车辆是否入网时间(是平台查询时间,不是入网时间)")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date checkTruckExistDate;
@ApiModelProperty(value = "查询车辆是否入网人员手机")
private String checkTruckExistUser;
@ApiModelProperty(value = "道路运输证字")
private String roadTransportCertificateWord;
@ApiModelProperty(value = "车辆道路运输证核验时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date checkRtcNoTime;
@ApiModelProperty(value = "企业道路运输经营许可证校验V3:0-未核验,1-已核验通过,2-核验失败(证件号错误/所有人错误),3-已过期,4-经营状态异常")
private Integer checkEnterpriseRoadLicense;
@ApiModelProperty(value = "企业道路运输经营许可证校验时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date checkEnterpriseRoadLicenseTime;
@ApiModelProperty(value = "实际承运人统一社会信用代码或证件号码")
private String actualcarrierid;
@ApiModelProperty(value = "道路运输许可证副页图片地址")
private String transportPermitBackImgUrl;
@ApiModelProperty(value = "车辆入网确认时间(最新定位时间)")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date checkTruckConfirmDate;
@ApiModelProperty(value = "标记状态id")
private String markerStateId;
@ApiModelProperty(value = "标记状态名称")
private String markerStateName;
@ApiModelProperty(value = "行驶证号")
private String drivingPermitNumber;
/**黑名单操作人*/
@ApiModelProperty(value = "黑名单操作人")
private java.lang.String blacklistBy;
@ApiModelProperty(value = "黑名单操作时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private java.util.Date blacklistDate;
@ApiModelProperty(value = "承运商编码(TMS)用于区别是哪个承运商下的车辆")
private String driverEnterpriseCode;
@ApiModelProperty(value = "数据来源(1-数字物流 2-TMS)")
private Integer dataSources;
@ApiModelProperty(name = "tms推送状态: 1-未推送 2- 已推送")
private Integer tmsPushStatus;
@ApiModelProperty(value = "添加时间起始")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date createTimeFrom;
@ApiModelProperty(value = "添加时间结束")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date createTimeTo;
@ApiModelProperty(value = "车辆来源 0-自由车辆 1-社会车辆")
private Integer vehicleSource;
@ApiModelProperty(name = "部门Id")
private String departmentId;
@ApiModelProperty(name = "部门名称")
private String departmentName;
@ApiModelProperty(value = "年检有效期")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date annualValidityPeriod;
@ApiModelProperty(value = "保险有效期")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date insuranceValidityPeriod;
}
@@ -0,0 +1,112 @@
package com.linke.transport.interfaces.dto.warehouse.inBoundOrder;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import lombok.Data;
public class InboundOrderDTO {
@Data
@ApiModel(value = "InboundOrderCreateDTO", description = "入库单创建请求体")
public static class Create {
@ApiModelProperty(value = "货主ID", required = true, example = "1001")
@NotNull(message = "货主ID不能为空")
private Long ownerId;
@ApiModelProperty(value = "备注", example = "首批入库")
private String remarks;
@ApiModelProperty(value = "关联的TMS运输订单号")
private String tmsOrderNo;
@ApiModelProperty(value = "入库物料明细列表", required = true)
@NotEmpty(message = "入库物料明细不能为空")
@NotNull
@Valid
private List<Detail> details;
}
@Data
@ApiModel(value = "InboundOrderDetailCreateDTO", description = "入库单物料明细")
public static class Detail {
@ApiModelProperty(value = "物料ID", required = true, example = "101")
@NotNull(message = "物料ID不能为空")
private Long materialId;
@ApiModelProperty(value = "入库数量", required = true, example = "20")
@NotNull(message = "入库数量不能为空")
@DecimalMin(value = "0.01", message = "入库数量必须大于0") // 或者根据业务调整精度和最小值
private BigDecimal quantity;
@ApiModelProperty(value = "整机编号 (当物料需要编号管理时必填)", example = "ZJ0000000001")
// 注意:这里的校验比较复杂,需要在Service层结合物料信息判断是否必填
private String machineSerialNo;
}
@Data
@ApiModel(value = "InboundOrderUpdateDTO", description = "入库单更新请求体 (仅允许更新货主和备注)")
public static class Update {
@ApiModelProperty(value = "要更新的入库单ID", required = true, example = "1")
@NotNull(message = "入库单ID不能为空")
private Long id;
@ApiModelProperty(value = "货主ID", required = true, example = "1001")
@NotNull(message = "货主ID不能为空")
private Long ownerId;
@ApiModelProperty(value = "货主名称", required = true, example = "山东临工")
@NotBlank(message = "货主名称不能为空")
private String ownerName;
@ApiModelProperty(value = "备注", example = "更新备注信息")
private String remarks;
// 注意:根据之前的讨论,编辑操作不涉及明细的修改。如果需要修改明细,
// 通常建议作废原单据,创建新单据。
}
@Data
@ApiModel(value = "InboundOrderQueryDTO", description = "入库单查询条件")
public static class Query { // 继承分页参数
@ApiModelProperty(value = "入库单号", example = "RK2501010001")
private String inboundOrderNo;
@ApiModelProperty(value = "货主ID", example = "1001")
private Long ownerId;
@ApiModelProperty(value = "货主名称", example = "山东临工")
private String ownerName;
@ApiModelProperty(value = "备注", example = "更新备注信息")
private String remarks;
@ApiModelProperty(value = "入库时间", example = "2025-01-01")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") // 控制日期格式
private Date inboundTimeStart;
@ApiModelProperty(value = "入库时间", example = "2025-01-01")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") // 控制日期格式
private Date inboundTimeEnd;
@ApiModelProperty(value = "页码,从1开始", required = true, example = "1")
@NotNull(message = "页码不能为空")
@Min(value = 1, message = "页码最小为1")
private Integer pageNo = 1; // 提供默认值
@ApiModelProperty(value = "每页大小", required = true, example = "10")
@NotNull(message = "每页大小不能为空")
@Min(value = 1, message = "每页大小最小为1")
private Integer pageSize = 10; // 提供默认值
}
}
@@ -0,0 +1,88 @@
package com.linke.transport.interfaces.dto.warehouse.inventory;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.Min;
import javax.validation.constraints.Pattern;
import lombok.Data;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Date;
public class InventoryDTO {
@Data
@ApiModel(value = "InventoryQueryDTO", description = "库存查询条件")
public static class Query { // 继承通用分页DTO
@ApiModelProperty(value = "货主ID", example = "1001")
private Long ownerId;
@ApiModelProperty(value = "货主名称", example = "山东临工")
private String ownerName;
@ApiModelProperty(value = "物料编码", example = "WL001")
private String materialCode;
@ApiModelProperty(value = "物料名称", example = "装载机")
private String materialName;
@ApiModelProperty(value = "物料分类", example = "整机")
private String materialCategory;
@ApiModelProperty(value = "整机编号", example = "ZZJJ00213213211DS")
private String machineCode;
@ApiModelProperty("库存单号")
private String inventoryOrderNo;
@ApiModelProperty(value = "物料型号", example = "LX001")
private String materialModel;
@ApiModelProperty(value = "是否按编号管理", example = "false")
private Boolean codeManaged;
@ApiModelProperty(value = "创建时间")
private Date createdAtStart;
@ApiModelProperty(value = "创建时间")
private Date createdAtEnd;
@ApiModelProperty(value = "页码,从1开始", required = true, example = "1")
@NotNull(message = "页码不能为空")
@Min(value = 1, message = "页码最小为1")
private Integer pageNo = 1; // 提供默认值
@ApiModelProperty(value = "每页大小", required = true, example = "10")
@NotNull(message = "每页大小不能为空")
@Min(value = 1, message = "每页大小最小为1")
private Integer pageSize = 10; // 提供默认值
}
@Data
@ApiModel(value = "InventoryAdjustDTO", description = "库存调整请求体")
public static class Adjust {
@ApiModelProperty(value = "要调整的库存记录ID", required = true, example = "5")
@NotNull(message = "库存记录ID不能为空")
private Long inventoryId;
@ApiModelProperty(value = "调整方向 (INCREASE:增加, DECREASE:减少)", required = true, example = "DECREASE")
@NotBlank(message = "调整方向不能为空")
@Pattern(regexp = "^(INCREASE|DECREASE)$", message = "调整方向类型无效")
private String direction; // 建议后续改为枚举类型
@ApiModelProperty(value = "调整数量 (必须为正数)", required = true, example = "2")
@NotNull(message = "调整数量不能为空")
@DecimalMin(value = "0.01", message = "调整数量必须大于0")
private BigDecimal quantity;
@ApiModelProperty(value = "调整原因/备注", example = "盘点差异调整")
private String reason;
}
}
@@ -0,0 +1,65 @@
package com.linke.transport.interfaces.dto.warehouse.inventoryLedger;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import lombok.Data;
import java.util.Date;
public class InventoryLedgerDTO {
@Data
@ApiModel(value = "InventoryLedgerDTO", description = "库存流水查询条件")
public static class Query { // 继承分页参数
@ApiModelProperty(value = "流水类型 (INBOUND:入库, OUTBOUND:出库, ADJUSTMENT:库存调整, TMS_USAGE:订单出库)")
private String type;
@ApiModelProperty(value = "货主名称", example = "山东临工")
private String ownerName;
@ApiModelProperty(value = "关联单号 (入库/出库单号)")
private String orderNo;
@ApiModelProperty(value = "物料编码 (冗余)")
private String materialCode;
@ApiModelProperty(value = "物料名称 (冗余)")
private String materialName;
@ApiModelProperty(value = "物料分类 (冗余)")
private String materialCategory;
@ApiModelProperty(value = "物料型号 (冗余)")
private String materialModel;
@ApiModelProperty(value = "发生时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
private Date eventTimeStart;
@ApiModelProperty(value = "发生时间")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
private Date eventTimeEnd;
@ApiModelProperty(value = "库存增减类型 (INCREASE:增加, DECREASE:减少)")
private String changeType; // 考虑后续使用枚举类型
@ApiModelProperty(value = "关联的TMS运输订单号 (当type为TMS_USAGE时)")
private String tmsOrderNo;
@ApiModelProperty(value = "备注 (例如 调整原因)")
private String remarks;
@ApiModelProperty(value = "页码,从1开始", required = true, example = "1")
@NotNull(message = "页码不能为空")
@Min(value = 1, message = "页码最小为1")
private Integer pageNo = 1; // 提供默认值
@ApiModelProperty(value = "每页大小", required = true, example = "10")
@NotNull(message = "每页大小不能为空")
@Min(value = 1, message = "每页大小最小为1")
private Integer pageSize = 10; // 提供默认值
}
}
@@ -0,0 +1,105 @@
package com.linke.transport.interfaces.dto.warehouse.outBoundOrder;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
public class OutboundOrderDTO {
@Data
@ApiModel(value = "OutboundOrderCreateDTO", description = "出库单创建请求体")
public static class Create {
@ApiModelProperty(value = "货主ID", required = true, example = "1001")
@NotNull(message = "货主ID不能为空")
private Long ownerId;
@ApiModelProperty(value = "备注", example = "项目领料")
private String remarks;
@ApiModelProperty(value = "流水类型 (OUTBOUND:出库,TMS_USAGE:订单使用)")
@Pattern(regexp = "^(OUTBOUND|TMS_USAGE)$", message = "出库类型无效")
private String type;
@ApiModelProperty(value = "关联的TMS运输订单号 (当type为TMS_USAGE时)")
private String tmsOrderNo;
@ApiModelProperty(value = "出库物料明细列表", required = true)
@NotEmpty(message = "出库物料明细不能为空")
@Valid // 嵌套校验
private List<Detail> details;
}
@Data
@ApiModel(value = "OutboundOrderDetailCreateDTO", description = "出库单物料明细")
public static class Detail {
@ApiModelProperty(value = "要出库的库存记录ID", required = true, example = "5")
@NotNull(message = "库存记录ID不能为空")
private Long inventoryId;
@ApiModelProperty(value = "出库数量", required = true, example = "5")
@NotNull(message = "出库数量不能为空")
@DecimalMin(value = "0.01", message = "出库数量必须大于0")
private BigDecimal quantity;
}
@Data
@ApiModel(value = "OutboundOrderUpdateDTO", description = "出库单更新请求体 (仅允许更新货主和备注)")
public static class Update {
@ApiModelProperty(value = "要更新的出库单ID", required = true, example = "1")
@NotNull(message = "出库单ID不能为空")
private Long id;
@ApiModelProperty(value = "货主ID", required = true, example = "1001")
@NotNull(message = "货主ID不能为空")
private Long ownerId;
@ApiModelProperty(value = "货主名称", required = true, example = "山东临工")
@NotBlank(message = "货主名称不能为空")
private String ownerName;
@ApiModelProperty(value = "备注", example = "更新备注信息")
private String remarks;
}
@Data
@ApiModel(value = "OutboundOrderQueryDTO", description = "出库单查询条件")
public static class Query {
@ApiModelProperty(value = "出库单号", example = "CK2501010001")
private String outboundOrderNo;
@ApiModelProperty(value = "货主ID", example = "1001")
private Long ownerId;
@ApiModelProperty(value = "货主名称", example = "山东临工")
private String ownerName;
@ApiModelProperty(value = "备注", example = "项目领料")
private String remarks;
@ApiModelProperty(value = "出库时间", example = "2025-01-01")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date outboundTimeStart;
@ApiModelProperty(value = "出库时间", example = "2025-01-01")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date outboundTimeEnd;
@ApiModelProperty(value = "页码,从1开始", required = true, example = "1")
@NotNull(message = "页码不能为空")
@Min(value = 1, message = "页码最小为1")
private Integer pageNo = 1;
@ApiModelProperty(value = "每页大小", required = true, example = "10")
@NotNull(message = "每页大小不能为空")
@Min(value = 1, message = "每页大小最小为1")
private Integer pageSize = 10;
}
}
@@ -0,0 +1,53 @@
package com.linke.transport.interfaces.facade.openApi;
import com.linke.transport.application.service.vehicle.OpenVehicleApplicationService;
import com.linke.transport.domain.security.annotation.Encrypt;
import com.linke.transport.domain.security.annotation.OpenApiLog;
import com.mhd.common.core.domain.dto.open.OpenVehicleDto;
import com.mhd.common.core.utils.validate.AddGroup;
import com.mhd.common.core.utils.validate.DelGroup;
import com.mhd.common.core.utils.validate.EditGroup;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.log.annotation.Log;
import com.mhd.common.log.enums.BusinessType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 对外开放Api - 车辆
*/
@Slf4j
@RestController
@RequestMapping("/openApi")
public class OpenApi {
@Autowired
private OpenVehicleApplicationService openVehicleApplicationService;
/**
* 新增/修改车辆
*/
@Encrypt
@OpenApiLog
@PostMapping("/vehicleAuth")
public AjaxResult<?> vehicleAuth(@Validated({AddGroup.class, EditGroup.class}) @RequestBody OpenVehicleDto openVehicleDto) {
openVehicleApplicationService.vehicleAuth(openVehicleDto);
return AjaxResult.success();
}
/**
* 删除车辆
*/
@Encrypt
@OpenApiLog
@PostMapping("/deleteVehicle")
public AjaxResult<?> deleteVehicle(@Validated({DelGroup.class}) @RequestBody OpenVehicleDto openVehicleDto) {
openVehicleApplicationService.deleteVehicle(openVehicleDto);
return AjaxResult.success();
}
}
@@ -0,0 +1,409 @@
package com.linke.transport.interfaces.facade.vehicle;
import com.linke.transport.application.service.common.CommonApplicationService;
import com.linke.transport.application.service.vehicle.VehicleApplicationService;
import com.linke.transport.domain.common.entity.DataPermission;
import com.linke.transport.domain.vehicle.entity.Vehicle;
import com.linke.transport.domain.vehicle.entity.VehicleExcel;
import com.linke.transport.domain.vehicle.repository.po.VehiclePo;
import com.linke.transport.interfaces.assemble.vehicle.VehicleAssembler;
import com.mhd.common.core.domain.dto.SyncTmsVehicleDTO;
import com.linke.transport.interfaces.dto.vehicle.VehicleDto;
import com.mhd.common.core.domain.dto.StatisticalMattersDTO;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.domain.todo.StatisticalMattersDo;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException;
import com.mhd.common.core.utils.IgnoreNullUtil;
import com.mhd.common.core.utils.bean.BeanUtils;
import com.mhd.common.core.web.controller.BaseController;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.core.web.page.TableDataInfo;
import com.mhd.common.log.annotation.Log;
import com.mhd.common.log.enums.BusinessType;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* 车辆接口层
*
* 2022-12-9
*
* @author 王子豪
*/
@Slf4j
@RestController
@RequestMapping("/vehicle")
@CrossOrigin
public class VehicleApi extends BaseController
{
@Autowired
private VehicleApplicationService vehicleApplicationService;
@Autowired
private CommonApplicationService commonApplicationService;
/**
* 查询车辆管理列表
*/
@Log(title = "车辆管理-查询", description = "查询车辆管理列表", businessType = BusinessType.INQUIRE)
@GetMapping("/list")
public TableDataInfo list(VehicleDto vehicleDto)
{
VehiclePo vehiclePo = new VehiclePo();
//转换实体
BeanUtils.copyProperties(vehicleDto, vehiclePo);
//判断当前登录人数据权限
DataPermission dataPermission = commonApplicationService.dataPermission(vehiclePo.getPermissionMenuId());
startPage();
List<VehiclePo> list = vehicleApplicationService.selectVehicleList(vehiclePo, dataPermission);
return getDataTable(list);
}
/**
* 查询未绑定车辆列表
*/
@Log(title = "车辆管理-查询未绑定车辆列表", description = "查询未绑定车辆列表", businessType = BusinessType.INQUIRE)
@GetMapping("/getUnBindList")
public TableDataInfo getUnBindList(VehicleDto vehicleDto)
{
VehiclePo vehiclePo = new VehiclePo();
//转换实体
BeanUtils.copyProperties(vehicleDto, vehiclePo);
//判断当前登录人数据权限
DataPermission dataPermission = commonApplicationService.dataPermission(vehiclePo.getPermissionMenuId());
startPage();
List<VehiclePo> list = vehicleApplicationService.getUnBindList(vehiclePo, dataPermission);
return getDataTable(list);
}
/**
* 查询绑定车辆管理列表
*/
@Log(title = "车辆管理-查询", description = "查询绑定车辆管理列表", businessType = BusinessType.INQUIRE)
@GetMapping("/selectBindVehicleList")
public TableDataInfo selectBindVehicleList(VehicleDto vehicleDto)
{
VehiclePo vehiclePo = new VehiclePo();
//转换实体
BeanUtils.copyProperties(vehicleDto, vehiclePo);
//判断当前登录人数据权限
DataPermission dataPermission = commonApplicationService.dataBindPermission();
startPage();
List<VehiclePo> list = vehicleApplicationService.selectBindVehicleList(vehiclePo, dataPermission);
return getDataTable(list);
}
/**
* 查询车辆管理列表
*/
@Log(title = "车辆管理-查询", description = "查询车辆管理列表", businessType = BusinessType.INQUIRE)
@PostMapping("/listTwo")
public TableDataInfo listTwo(VehicleDto vehicleDto)
{
VehiclePo vehiclePo = new VehiclePo();
//转换实体
BeanUtils.copyProperties(vehicleDto, vehiclePo);
//判断当前登录人数据权限
DataPermission dataPermission = commonApplicationService.dataPermission(vehiclePo.getPermissionMenuId());
startPage();
List<VehiclePo> list = vehicleApplicationService.selectVehicleList(vehiclePo, dataPermission);
return getDataTable(list);
}
/**
* 配载页面查询车辆管理列表
*/
@Log(title = "车辆管理-查询", description = "配载页面查询车辆管理列表", businessType = BusinessType.INQUIRE)
@GetMapping("/getStowageVehiclelist")
public AjaxResult getStowageVehiclelist(VehicleDto vehicleDto)
{
VehiclePo vehiclePo = new VehiclePo();
//转换实体
BeanUtils.copyProperties(vehicleDto, vehiclePo);
//判断当前登录人数据权限
// DataPermission dataPermission = commonApplicationService.dataPermission(vehiclePo.getPermissionMenuId());
List<VehiclePo> list = vehicleApplicationService.selectStowageVehiclelist(vehiclePo);
return AjaxResult.success(list);
}
/**
* 根据用户id查询车辆信息
* @param userId
* @return
*/
@Log(title = "车辆管理-查询", description = "根据用户id查询车辆信息", businessType = BusinessType.INQUIRE)
@GetMapping("/selectVehicleByUserId/{userId}")
public AjaxResult selectVehicleByUserId(@PathVariable("userId")Long userId)
{
return AjaxResult.success(vehicleApplicationService.selectVehicleByUserId(userId));
}
/**
* 根据用户id查询车辆信息
* @param userId
* @return
*/
@Log(title = "车辆管理-查询", description = "根据用户id查询车辆信息", businessType = BusinessType.INQUIRE)
@GetMapping("/selectVehiclesByUserId/{userId}")
public R<List<VehiclePo>> selectVehiclesByUserId(@PathVariable("userId")Long userId)
{
return R.ok(vehicleApplicationService.selectVehiclesByUserId(userId));
}
/**
* 获取车辆管理详细信息
*/
@Log(title = "车辆管理-查询", description = "获取车辆管理详细信息", businessType = BusinessType.INQUIRE)
@GetMapping(value = "/getInfo/{vehicleId}")
public AjaxResult getInfo(@PathVariable("vehicleId") Long vehicleId)
{
return AjaxResult.success(vehicleApplicationService.selectVehicleByVehicleId(vehicleId));
}
@GetMapping(value = "/getVehiclePo/{vehicleId}")
public AjaxResult getVehiclePo(@PathVariable("vehicleId") Long vehicleId)
{
return AjaxResult.success(vehicleApplicationService.selectVehiclePoByVehicleId(vehicleId));
}
/**
* 审核车辆管理
*/
@Log(title = "车辆管理-审核", description = "审核车辆管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
public AjaxResult edit(@RequestBody VehicleDto vehicleDto)
{
Vehicle vehicle = new VehicleAssembler().toCheck(vehicleDto);
if(vehicleDto.getVehicleId() != null){
return AjaxResult.success(vehicleApplicationService.updateVehicle(vehicle));
}else {
return AjaxResult.success(vehicleApplicationService.insertVehicle(vehicle));
}
}
/**
* 编辑车辆管理
*/
@Log(title = "车辆管理-编辑", description = "编辑车辆管理", businessType = BusinessType.UPDATE)
@PostMapping("/editVehicle")
public AjaxResult editVehicle(@RequestBody VehicleDto vehicleDto)
{
Vehicle vehicle = new VehicleAssembler().toDo(vehicleDto);
if(vehicleDto.getVehicleId() != null){
return AjaxResult.success(vehicleApplicationService.updateVehicle(vehicle));
}else {
return AjaxResult.success(vehicleApplicationService.insertVehicle(vehicle));
}
}
/**
* 新增车辆管理
*/
@Log(title = "车辆管理-新增", description = "新增车辆管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
public AjaxResult<?> add(@RequestBody VehicleDto vehicleDto)
{
Vehicle vehicle = new VehicleAssembler().toDo(vehicleDto);
return AjaxResult.success(vehicleApplicationService.insertVehicle(vehicle));
}
/**
* 车辆管理-新增-内部调用前台请勿调用!
* @param vehicleDto 新增参数
* @return
*/
@Log(title = "车辆管理-新增-内部调用", description = "新增车辆管理", businessType = BusinessType.INSERT)
@PostMapping("/addForUserApp")
public AjaxResult<?> addForUserApp(@RequestBody VehicleDto vehicleDto)
{
Vehicle vehicle = new VehicleAssembler().toDo(vehicleDto);
return AjaxResult.success(vehicleApplicationService.addForUserApp(vehicle));
}
/**
* 修改车辆管理
*/
@Log(title = "车辆管理-修改", description = "修改车辆管理", businessType = BusinessType.UPDATE)
@PutMapping("/update")
public AjaxResult update(@RequestBody VehicleDto vehicleDto)
{
Vehicle vehicle = new VehicleAssembler().toDo(vehicleDto);
return AjaxResult.success(vehicleApplicationService.updateVehicle(vehicle));
}
/**
* 批量修改车辆管理
*/
@Log(title = "车辆管理-批量修改", description = "批量修改车辆管理", businessType = BusinessType.UPDATE)
@PutMapping("/batchUpdateVehicle")
public AjaxResult batchUpdateVehicle(@RequestBody VehicleDto vehicleDto)
{
return toAjax(vehicleApplicationService.batchUpdateVehicle(vehicleDto));
}
/**
* 批量删除车辆管理
*/
@Log(title = "车辆管理-批量删除", description = "批量删除车辆管理", businessType = BusinessType.DELETE)
@DeleteMapping("/removeByIds/{vehicleIds}")
public AjaxResult remove(@PathVariable Long[] vehicleIds)
{
return toAjax(vehicleApplicationService.deleteVehicleByVehicleIds(vehicleIds));
}
/**
* 删除车辆管理
*/
@Log(title = "车辆管理-删除", description = "删除车辆管理", businessType = BusinessType.DELETE)
@DeleteMapping("/removeById/{vehicleIds}")
public AjaxResult removeById(@PathVariable Long vehicleIds)
{
return toAjax(vehicleApplicationService.deleteVehicleByVehicleId(vehicleIds));
}
/**
* 根据车辆ids获取车辆信息
* @param vehicleDto
* @return
*/
@PostMapping("/getVehicleByIds")
public AjaxResult getVehicleByIds(@RequestBody VehicleDto vehicleDto)
{
return AjaxResult.success(vehicleApplicationService.getVehicleByIds(vehicleDto));
}
/**
* 根据车牌号查询车辆信息
* @param vehicleDto
* @return
*/
@Log(title = "车辆管理-查询", description = "根据车牌号查询车辆信息", businessType = BusinessType.INQUIRE)
@ApiOperation("查询车辆信息")
@PostMapping("/getVehicleInfoByLicensePlate")
public AjaxResult getVehicleInfoByLicensePlate(@RequestBody VehicleDto vehicleDto) {
return AjaxResult.success(vehicleApplicationService.getVehicleInfoByLicensePlate(vehicleDto));
}
/**
* 根据车牌号查询车辆信息 - 开放接口
* @param vehicleLicence
* @param driverEnterpriseCode
* @return
*/
@ApiOperation("查询车辆信息")
@GetMapping("/getVehicleInfoByOpen")
public AjaxResult<?> getVehicleInfoByOpen(@RequestParam("vehicleLicence") String vehicleLicence, @RequestParam(value = "driverEnterpriseCode", required = false) String driverEnterpriseCode) {
return AjaxResult.success(vehicleApplicationService.getVehicleInfoByOpen(vehicleLicence,driverEnterpriseCode));
}
/**
* PC车辆认证
* @param vehicleDto
* @return
*/
@Log(title = "车辆管理-车辆认证", description = "PC车辆认证", businessType = BusinessType.UPDATE)
@ApiOperation("PC车辆认证")
@PostMapping("/vehicleAuth")
public AjaxResult vehicleAuth(@RequestBody VehicleDto vehicleDto) {
return AjaxResult.success(vehicleApplicationService.vehicleAuth(vehicleDto));
}
/**
* PC车辆认证审核
* @param vehicleDto
* @return
*/
@Log(title = "车辆管理-审核", description = "PC车辆认证审核", businessType = BusinessType.UPDATE)
@ApiOperation("PC车辆认证审核")
@PostMapping("/authVehicle")
public AjaxResult authVehicle(@RequestBody VehicleDto vehicleDto) {
// Vehicle vehicle = new VehicleAssembler().toDo(vehicleDto);
Vehicle vehicle = new Vehicle();
BeanUtils.copyProperties(vehicleDto,vehicle);
return toAjax(vehicleApplicationService.authVehicle(vehicle));
}
/**
* 根据车队id更新车队名称
* @param vehicleDto
* @return
*/
@Log(title = "车辆管理-根据车队id更新车队名称", description = "根据车队id更新车队名称", businessType = BusinessType.UPDATE)
@ApiOperation("根据车队id更新车队名称")
@PostMapping("/updateMotorcadeNameByMotorcadeId")
public AjaxResult updateMotorcadeNameByMotorcadeId(@RequestBody VehicleDto vehicleDto) {
// Vehicle vehicle = new VehicleAssembler().toDo(vehicleDto);
/* Vehicle vehicle = new Vehicle();
BeanUtils.copyProperties(vehicleDto,vehicle);*/
return toAjax(vehicleApplicationService.updateMotorcadeNameByMotorcadeId(vehicleDto));
}
/**
* 获取车辆统计数据
*/
@Log(title = "车辆管理-统计", description = "获取车辆统计数据", businessType = BusinessType.INQUIRE)
@ApiOperation("获取车辆统计数据")
@PostMapping("/vehicleCountByMatter")
public AjaxResult vehicleCountByMatter(@RequestBody StatisticalMattersDTO statisticalMattersDTO) {
StatisticalMattersDo statisticalMattersDo = new StatisticalMattersDo();
BeanUtils.copyProperties(statisticalMattersDTO, statisticalMattersDo, IgnoreNullUtil.getNullPropertyNames(statisticalMattersDTO));
return AjaxResult.success(vehicleApplicationService.vehicleCountByMatter(statisticalMattersDo));
}
/**
* 车辆导入解析数据
* @param multipartFile
* @return
*/
@Log(title = "车辆管理-导入", description = "车辆导入解析数据", businessType = BusinessType.INSERT)
@ApiModelProperty("解析excel数据")
@PostMapping("/parseExcelData")
public R<List<VehicleExcel>> parseExcelData(MultipartFile multipartFile){
return R.ok(vehicleApplicationService.parseExcelData(multipartFile));
}
/**
* 车辆导入
* @param vehicleDtoList
* @return
*/
@Log(title = "车辆管理-导入", description = "车辆导入", businessType = BusinessType.INSERT)
@ApiOperation("车辆导入")
@PostMapping("/importVehicle")
public R<?> importVehicle(@RequestBody List<VehicleDto> vehicleDtoList)
{
try {
vehicleApplicationService.importVehicle(vehicleDtoList);
return R.ok("导入成功");
} catch (ServiceException | DigitalLogisticsException ser) {
log.error("导入失败 TicketEnterpriseApi importEnterprise ServiceException ",ser);
return R.fail(ser.getMessage());
} catch (Exception e) {
log.error("导入失败 TicketEnterpriseApi importEnterprise Exception ",e);
return R.fail("导入失败,未知异常:" + e.getMessage());
}
}
/**
* 同步tms车辆
* @param syncTmsVehicleDTO
* @return
*/
@ApiOperation("同步tms车辆")
@PostMapping("/syncTmsVehicle")
public AjaxResult syncTmsVehicle(@RequestBody SyncTmsVehicleDTO syncTmsVehicleDTO) {
vehicleApplicationService.syncTmsVehicle(syncTmsVehicleDTO);
return AjaxResult.success();
}
@Log(title = "根据车牌号查询车辆信息", description = "根据车牌号查询车辆信息", businessType = BusinessType.UPDATE)
@ApiOperation("根据车牌号查询车辆信息")
@GetMapping("/{plateNumber}")
public R<VehiclePo> findVehicleByPlateNumber(@PathVariable("plateNumber") String plateNumber){
return R.ok(vehicleApplicationService.findVehicleByPlateNumber(plateNumber));
}
}
@@ -0,0 +1,114 @@
package com.linke.transport.interfaces.facadeApi;
import com.linke.transport.application.service.common.CommonApplicationService;
import com.linke.transport.application.service.vehicle.VehicleApplicationService;
import com.linke.transport.domain.vehicle.repository.po.DriverVehicleBindPo;
import com.linke.transport.domain.vehicle.repository.po.VehicleAppPo;
import com.linke.transport.domain.vehicle.repository.po.VehiclePo;
import com.linke.transport.interfaces.dto.vehicle.VehicleDto;
import com.mhd.common.core.domain.dto.DriverVehicleBindDto;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.core.web.controller.BaseController;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.core.web.page.TableDataInfoApi;
import com.mhd.common.log.annotation.Log;
import com.mhd.common.log.enums.BusinessType;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 车辆接口层
*
* 2022-12-9
*
* @author 王子豪
*/
@RestController
@RequestMapping("/vehicleApi")
@CrossOrigin
public class VehicleAppApi extends BaseController
{
@Autowired
private VehicleApplicationService vehicleApplicationService;
@Autowired
private CommonApplicationService commonApplicationService;
@Log(title = "车辆管理(App)", description = "App车辆认证", businessType = BusinessType.UPDATE)
@ApiOperation("App车辆认证")
@PostMapping("/appVehicleAuth")
public AjaxResult appVehicleAuth(@RequestBody VehicleDto vehicleDto) {
return AjaxResult.success(vehicleApplicationService.appVehicleAuth(vehicleDto));
}
/**
* 根据id查询车辆认证状态
* @param vehicleDto
* @return
*/
@Log(title = "车辆管理(App)-查询", description = "根据id查询车辆认证状态", businessType = BusinessType.INQUIRE)
@ApiOperation("根据id查询车辆认证状态")
@GetMapping(value = "/getAuthInfo")
public AjaxResult getAuthInfo(VehicleDto vehicleDto)
{
return AjaxResult.success(vehicleApplicationService.getAuthInfo(vehicleDto));
}
@Log(title = "车辆管理(App)-查询", description = "查询车辆详情", businessType = BusinessType.INQUIRE)
@ApiOperation("查询车辆详情")
@GetMapping(value = "/getVehicleInfoById")
public AjaxResult getVehicleInfoById(@RequestParam(value = "vehicleId" ,required = true) Long vehicleId)
{
VehicleAppPo vehicleAppPo = vehicleApplicationService.getVehicleInfoById(vehicleId);
return AjaxResult.success(vehicleAppPo == null ? new VehicleAppPo():vehicleAppPo);
}
@Log(title = "车辆管理(App)-查询", description = "我是车主列表查询", businessType = BusinessType.INQUIRE)
@ApiOperation("APP我是车主列表查询")
@GetMapping("/ownerBindCarList")
public TableDataInfoApi ownerBindCarList(DriverVehicleBindDto driverVehicleBindDto) {
//转换实体
startPage();
List<DriverVehicleBindPo> list = vehicleApplicationService.ownerBindCarList(driverVehicleBindDto);
return getDataTableApi(list);
}
@Log(title = "车辆管理(App)-查询", description = "APP绑定车辆我的车辆列表查询", businessType = BusinessType.INQUIRE)
@ApiOperation("APP绑定车辆我的车辆列表查询")
@GetMapping("/driverBindMyCarList")
public TableDataInfoApi driverBindMyCarList(DriverVehicleBindDto driverVehicleBindDto) {
//转换实体
startPage();
List<DriverVehicleBindPo> list = vehicleApplicationService.driverBindMyCarList(driverVehicleBindDto);
return getDataTableApi(list);
}
/**
* APP车辆详情删除车辆
* @param vehicleDto
* @return
*/
@Log(title = "车辆管理(App)-删除", description = "APP车辆详情删除车辆", businessType = BusinessType.DELETE)
@ApiOperation("APP车辆详情删除车辆")
@PostMapping("/deleteVehicle")
public AjaxResult deleteVehicle(@RequestBody VehicleDto vehicleDto) {
return toAjax(vehicleApplicationService.deleteVehicle(vehicleDto));
}
@Log(title = "车辆管理(App)-编辑", description = "车辆变更车主", businessType = BusinessType.UPDATE)
@ApiOperation("车辆变更车主")
@PostMapping("/changeVehicleOwner")
public AjaxResult changeVehicleOwner(@RequestBody VehicleDto vehicleDto) {
return toAjax(vehicleApplicationService.changeVehicleOwner(vehicleDto));
}
}
@@ -0,0 +1,64 @@
package com.linke.transport.interfaces.facadeApi.warehouse;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.linke.transport.application.service.warehouse.inBoundOrder.InboundOrderService;
import com.linke.transport.application.service.warehouse.inBoundOrder.vo.InboundOrderVO.Detail;
import com.linke.transport.application.service.warehouse.inBoundOrder.vo.InboundOrderVO.ListSummary;
import com.linke.transport.interfaces.dto.warehouse.inBoundOrder.InboundOrderDTO;
import com.mhd.common.core.domain.entity.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.util.List;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "入库管理")
@RestController
@RequestMapping("/inboundOrders")
@RequiredArgsConstructor
@Slf4j
@Validated
public class InboundOrderController {
private final InboundOrderService inboundOrderService;
@GetMapping("/list")
@ApiOperation("分页查询入库单列表")
public R<IPage<ListSummary>> listInboundOrders(
@ApiParam(value = "查询条件") @Valid InboundOrderDTO.Query queryDTO) {
log.info("接收到分页查询入库单列表请求: {}", queryDTO);
IPage<ListSummary> pageResult = inboundOrderService.listInboundOrders(queryDTO);
log.info("查询入库单列表成功, 当前页 {}, 每页大小 {}, 总记录数 {}, 总页数 {}",
pageResult.getCurrent(), pageResult.getSize(), pageResult.getTotal(),
pageResult.getPages());
return R.ok(pageResult);
}
@GetMapping("/getDetail/{id}")
@ApiOperation("根据Id获取入库单详情")
public R<List<Detail>> getDetailsByInBoundOrderId(
@ApiParam(value = "入库单ID") @PathVariable Long id) {
log.info("接收到获取入库单详情请求: {}", id);
return R.ok(inboundOrderService.getDetailsByInBoundOrderId(id));
}
@PostMapping
@ApiOperation("创建入库单")
public R<Long> createInboundOrder(
@ApiParam(value = "入库单信息") @Valid @RequestBody InboundOrderDTO.Create createDTO) {
log.info("接收到创建入库单请求: {}", createDTO);
Long id = inboundOrderService.createInboundOrder(createDTO);
log.info("创建入库单成功, 入库单ID: {}", id);
return R.ok(id);
}
}
@@ -0,0 +1,65 @@
package com.linke.transport.interfaces.facadeApi.warehouse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.linke.transport.application.service.warehouse.inventory.InventoryService;
import com.linke.transport.application.service.warehouse.inventory.vo.InventoryVO;
import com.linke.transport.domain.warehouse.inventory.model.Inventory;
import com.linke.transport.interfaces.dto.warehouse.inventory.InventoryDTO;
import com.mhd.common.core.domain.entity.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.util.List;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Api(tags = "库存管理")
@RestController
@RequestMapping("inventory")
@RequiredArgsConstructor
@Slf4j
@Validated
public class InventoryController {
private final InventoryService inventoryService;
@GetMapping("/list")
@ApiOperation("分页查询库存列表")
public R<Page<InventoryVO>> listInventory(
@ApiParam(value = "查询条件")
@Valid InventoryDTO.Query queryDTO) { // DTO 中包含分页参数
log.info("接收到分页查询库存列表请求: {}", queryDTO);
Page<InventoryVO> pageResult = inventoryService.listInventory(queryDTO);
log.info("查询库存列表成功, 返回 {} 条记录, 总计 {}", pageResult.getRecords().size(),
pageResult.getTotal());
return R.ok(pageResult);
}
@GetMapping
@ApiOperation("查询所有库存")
public R<List<InventoryVO>> listAllInventory(@RequestParam(name = "ownerId",required = false)Long ownerId,
@RequestParam(name = "machineSerialNo",required = false)String machineSerialNo) {
List<InventoryVO> pageResult = inventoryService.listAllInventory(ownerId,machineSerialNo);
return R.ok(pageResult);
}
@PostMapping("/adjust")
@ApiOperation("调整库存数量 (仅非编号管理物料)")
public R<Void> adjustInventory(
@ApiParam(value = "库存调整信息", required = true)
@Valid @RequestBody InventoryDTO.Adjust adjustDTO) {
log.info("接收到库存调整请求: {}", adjustDTO);
inventoryService.adjustInventory(adjustDTO);
log.info("库存调整成功, 库存ID: {}", adjustDTO.getInventoryId());
return R.ok(); // 返回 200 OK,无内容体
}
@GetMapping("/getInventoryByInboundOrderId/{inboundOrderId}")
@ApiOperation("根据入库ID获取对应的库存详情列表ID(后端远程调用此接口!)")
public R<List<Inventory>> getInventoryItemByInboundOrderId(@PathVariable Long inboundOrderId){
return R.ok(inventoryService.getInventoryItemByInboundOrderId(inboundOrderId));
}
}
@@ -0,0 +1,40 @@
package com.linke.transport.interfaces.facadeApi.warehouse;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.linke.transport.application.service.warehouse.inventoryLedger.InventoryLedgerService;
import com.linke.transport.application.service.warehouse.inventoryLedger.vo.InventoryLedgerVO;
import com.linke.transport.interfaces.dto.warehouse.inventoryLedger.InventoryLedgerDTO;
import com.mhd.common.core.domain.entity.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "库存流水")
@RestController
@RequestMapping("inventoryLedger")
@RequiredArgsConstructor
@Slf4j
@Validated
public class InventoryLedgerController {
private final InventoryLedgerService inventoryLedgerService;
@GetMapping("/list")
@ApiOperation("分页查询库存列表")
public R<IPage<InventoryLedgerVO>> listInventory(
@ApiParam(value = "查询条件")
@Valid InventoryLedgerDTO.Query queryDTO) { // DTO 中包含分页参数
log.info("接收到分页查询库存流水列表请求: {}", queryDTO);
IPage<InventoryLedgerVO> pageResult = inventoryLedgerService.listInventoryLedger(queryDTO);
log.info("查询库存流水列表成功, 返回 {} 条记录, 总计 {}", pageResult.getRecords().size(),
pageResult.getTotal());
return R.ok(pageResult);
}
}
@@ -0,0 +1,105 @@
package com.linke.transport.interfaces.facadeApi.warehouse;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.linke.transport.application.service.warehouse.material.command.CreateMaterialCommand;
import com.linke.transport.application.service.warehouse.material.command.MaterialCommandService;
import com.linke.transport.application.service.warehouse.material.command.UpdateMaterialCommand;
import com.linke.transport.application.service.warehouse.material.query.MaterialQueryCommand;
import com.linke.transport.application.service.warehouse.material.query.MaterialQueryService;
import com.linke.transport.application.service.warehouse.material.vo.MaterialVO;
import com.mhd.common.core.domain.entity.R;
import com.mhd.common.log.annotation.Log;
import com.mhd.common.log.enums.BusinessType;
import io.swagger.annotations.Api;
import java.util.List;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
* 运输管理系统-物料管理接口
*/
@RestController
@Api(tags = "物料管理")
@RequestMapping("/materials")
@RequiredArgsConstructor
public class MaterialApi {
private final MaterialCommandService commandService;
private final MaterialQueryService queryService;
/**
* 创建一条物料数据
*
* @param command 创建参数
* @return 创建数据的ID
*/
@PostMapping
@Log(title = "物料管理(PC)", description = "TMS-创建物料", businessType = BusinessType.INSERT)
public R<Long> createMaterial(@Valid @RequestBody CreateMaterialCommand command) {
return R.ok(commandService.handle(command));
}
/**
* 更新一条物料数据
*
* @param command 更新参数
* @return void
*/
@PutMapping
@Log(title = "物料管理(PC)", description = "TMS-更新物料", businessType = BusinessType.UPDATE)
public R<Void> updateMaterial(@Valid @RequestBody UpdateMaterialCommand command) {
commandService.handle(command);
return R.ok(null);
}
/**
* 根据id删除一条物料数据
*
* @param id 主键id
* @return void
*/
@DeleteMapping("/{id}")
@Log(title = "物料管理(PC)", description = "TMS-删除物料", businessType = BusinessType.DELETE)
public R<Void> deleteMaterial(@PathVariable Long id) {
commandService.deleteMaterial(id);
return R.ok(null);
}
/**
* 分页查询物料
*
* @param param 查询参数
* @return 分页查询结果
*/
@GetMapping("/list")
@Log(title = "物料管理(PC)", description = "TMS-分页查询物料", businessType = BusinessType.OTHER)
public R<IPage<MaterialVO>> queryMaterials(MaterialQueryCommand param) {
return R.ok(queryService.queryMaterials(param));
}
/**
* 获取全部物料数据
*
* @return 全部物料数据
*/
@GetMapping
@Log(title = "物料管理(PC)", description = "TMS-查询物料所有", businessType = BusinessType.OTHER)
public R<List<MaterialVO>> getAllMaterials(@RequestParam(name = "ownerId",required = false) Long ownerId) {
return R.ok(queryService.getAllMaterials(ownerId));
}
/**
* 获取物料详情
*
* @param id 主键id
* @return id对应的物料信息
*/
@GetMapping("/{id}")
@Log(title = "物料管理(PC)", description = "TMS-获取物料详情", businessType = BusinessType.OTHER)
public R<MaterialVO> getMaterial(@PathVariable Long id) {
return R.ok(queryService.getMaterialDetail(id));
}
}
@@ -0,0 +1,68 @@
package com.linke.transport.interfaces.facadeApi.warehouse;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.linke.transport.application.service.warehouse.outBoundOrder.OutboundOrderService;
import com.linke.transport.application.service.warehouse.outBoundOrder.OutboundOrderVO;
import com.linke.transport.interfaces.dto.warehouse.outBoundOrder.OutboundOrderDTO;
import com.mhd.common.core.domain.entity.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.util.List;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "出库管理")
@RestController
@RequestMapping("outboundOrders")
@RequiredArgsConstructor
@Slf4j
@Validated
public class OutboundOrderController {
private final OutboundOrderService outboundOrderService;
@PostMapping
@ApiOperation("创建出库单")
public R<Long> createOutboundOrder(
@ApiParam(value = "出库单创建信息", required = true)
@Valid @RequestBody OutboundOrderDTO.Create createDTO) {
log.info("接收到创建出库单请求: {}", createDTO);
Long id = outboundOrderService.createOutboundOrder(createDTO);
log.info("出库单创建成功, ID: {}", id);
return R.ok(id);
}
@GetMapping("/list")
@ApiOperation("分页查询出库单列表")
public R<IPage<OutboundOrderVO.ListSummary>> listOutboundOrders(
@ApiParam(value = "查询条件")
@Valid OutboundOrderDTO.Query queryDTO) {
log.info("接收到分页查询出库单列表请求: {}", queryDTO);
IPage<OutboundOrderVO.ListSummary> pageResult = outboundOrderService.listOutboundOrders(
queryDTO);
log.info("查询出库单列表成功, 返回 {} 条记录, 总计 {}", pageResult.getRecords().size(),
pageResult.getTotal());
return R.ok(pageResult);
}
@GetMapping("/getDetail/{id}")
@ApiOperation("根据Id获取出库单详情")
public R<List<OutboundOrderVO.Detail>> getDetailsByOutBoundOrderId(
@ApiParam(value = "出库单ID", required = true)
@PathVariable Long id) {
log.info("接收到获取出库单详情请求, ID: {}", id);
List<OutboundOrderVO.Detail> details = outboundOrderService.getDetailsByOutBoundOrderId(id);
return R.ok(details);
}
}
@@ -0,0 +1,36 @@
server:
port: 8006
management:
metrics:
web:
server:
request:
autotime:
enabled: false
spring:
application:
name: mhd-transport-service
profiles:
active: dev
main:
allow-circular-references: true
# nacos配置
cloud:
nacos:
discovery:
#server-addr: 192.168.0.69:8848
server-addr: 127.0.0.1:8848
#server-addr: 116.204.23.92:8848
namespace: 4dd3256a-22c0-42db-9af1-de513a05c6a9
config:
# 配置中心地址
#server-addr: 192.168.0.69:8848
server-addr: 127.0.0.1:8848
#server-addr: 116.204.23.92:8848
# 锁定server端的配置文件(读取它的配置项)
namespace: 4dd3256a-22c0-42db-9af1-de513a05c6a9
group: DEFAULT_GROUP # 默认分组就是DEFAULT_GROUP,如果使用默认分组可以不配置
file-extension: yml #默认properties
@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.linke.transport.infrastructure.warehouse.inventory.persistence.InventoryMapper">
<!-- 原子性增加库存 -->
<update id="increaseQuantity">
UPDATE inventory
SET quantity = quantity + #{quantity},
updated_by = #{userName}
WHERE id = #{inventoryId}
AND is_deleted = 0
</update>
<!-- 原子性扣减库存 -->
<update id="decreaseQuantity">
UPDATE inventory
SET quantity = quantity - #{quantity},
updated_by = #{userName}
WHERE id = #{inventoryId}
AND quantity >= #{quantity} -- 确保库存足够扣减
AND is_deleted = 0 -- 确保记录有效
</update>
<!-- 分页查询库存列表 (JOIN 物料表) -->
<!-- 注意: 请确保你有一个名为 material 的表,并且字段名匹配 -->
<select id="findInventoryList" resultType="com.linke.transport.application.service.warehouse.inventory.vo.InventoryVO">
SELECT
i.id,
i.inventory_order_no,
i.owner_id,
i.owner_name,
i.material_id,
m.category AS material_category,
m.name AS material_name,
m.model AS material_model,
i.quantity,
m.unit,
m.weight,
m.code_managed,
m.value,
i.machine_serial_no,
i.created_at
FROM
inventory i
LEFT JOIN
material m ON i.material_id = m.id AND m.is_deleted = 0
WHERE
i.is_deleted = 0
<if test="query.ownerId != null">
AND i.owner_id = #{query.ownerId}
</if>
<if test="query.ownerName != null and query.ownerName != ''">
AND i.owner_name LIKE CONCAT('%', #{query.ownerName}, '%')
</if>
<if test="query.materialCode != null and query.materialCode != ''">
AND m.code LIKE CONCAT('%', #{query.materialCode}, '%')
</if>
<if test="query.materialName != null and query.materialName != ''">
AND m.name LIKE CONCAT('%', #{query.materialName}, '%')
</if>
<if test="query.materialCategory != null and query.materialCategory != ''">
AND m.category LIKE CONCAT('%', #{query.materialCategory}, '%')
</if>
<if test="query.machineCode != null and query.machineCode != ''">
AND i.machine_serial_no LIKE CONCAT('%', #{query.machineCode}, '%')
</if>
<if test="query.inventoryOrderNo != null and query.inventoryOrderNo != ''">
AND i.inventory_order_no LIKE CONCAT('%', #{query.inventoryOrderNo}, '%')
</if>
<if test="query.materialModel != null and query.materialModel != ''">
AND m.material_model LIKE CONCAT('%', #{query.materialModel}, '%')
</if>
<if test="query.codeManaged != null and query.codeManaged != ''">
AND m.code_managed = #{query.codeManaged}
</if>
<if test="query.createdAtStart != null and query.createdAtEnd != null and @org.jeecg.common.util.oConvertUtils@isNotEmpty(query.createdAtStart) and @org.jeecg.common.util.oConvertUtils@isNotEmpty(query.createdAtEnd)">
and DATE_FORMAT(i.created_at,'%Y-%m-%d') <![CDATA[>=]]> DATE_FORMAT(#{query.createdAtStart},'%Y-%m-%d')
and DATE_FORMAT(i.created_at,'%Y-%m-%d') <![CDATA[<=]]> DATE_FORMAT(#{query.createdAtEnd},'%Y-%m-%d')
</if>
ORDER BY
i.updated_at DESC
</select>
<select id="findAllInventoryList" resultType="com.linke.transport.application.service.warehouse.inventory.vo.InventoryVO">
SELECT i.id,
i.inventory_order_no,
i.owner_id,
i.owner_name,
i.material_id,
m.category AS material_category,
m.name AS material_name,
m.model AS material_model,
i.quantity,
m.unit,
m.weight,
m.code_managed,
i.machine_serial_no
FROM inventory i
LEFT JOIN
material m ON i.material_id = m.id AND m.is_deleted = 0
WHERE i.is_deleted = 0
<if test="ownerId != null">
AND i.owner_id = #{ownerId}
</if>
<if test="machineSerialNo != null and machineSerialNo !=''">
AND i.machine_serial_no LIKE CONCAT('%', #{machineSerialNo}, '%')
</if>
ORDER BY i.updated_at DESC
</select>
</mapper>
@@ -0,0 +1,782 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.linke.transport.domain.vehicle.repository.mapper.VehicleMapper">
<resultMap type="com.linke.transport.domain.vehicle.repository.po.VehiclePo" id="VehicleResult">
<result property="vehicleId" column="vehicle_id" />
<result property="vehicleLicensePlateNumber" column="vehicle_license_plate_number" />
<result property="vehicleTypeId" column="vehicle_type_id" />
<result property="vehicleTypeName" column="vehicle_type_name" />
<result property="vehicleSourceId" column="vehicle_source_id" />
<result property="vehicleSourceName" column="vehicle_source_name" />
<result property="vehicleUsePerson" column="vehicle_use_person" />
<result property="vehicleAddress" column="vehicle_address" />
<result property="vehicleUseNature" column="vehicle_use_nature" />
<result property="vehicleBrandType" column="vehicle_brand_type" />
<result property="vehicleIdentificationNumber" column="vehicle_identification_number" />
<result property="vehicleEngineNumber" column="vehicle_engine_number" />
<result property="vehicleRegistrationDate" column="vehicle_registration_date" />
<result property="vehicleIssueDate" column="vehicle_issue_date" />
<result property="vehicleLicenceIssuingAuthority" column="vehicle_licence_issuing_authority" />
<result property="vehicleFileNumber" column="vehicle_file_number" />
<result property="vehicleTotalMass" column="vehicle_total_mass" />
<result property="vehicleApprovedLoadQuantity" column="vehicle_approved_load_quantity" />
<result property="vehicleGabariteOne" column="vehicle_gabarite_one" />
<result property="vehicleGabariteTwo" column="vehicle_gabarite_two" />
<result property="vehicleGabariteThree" column="vehicle_gabarite_three" />
<result property="vehicleEnergyTypeId" column="vehicle_energy_type_id" />
<result property="vehicleEnergyTypeName" column="vehicle_energy_type_name" />
<result property="vehicleCheckoutPeriodValidity" column="vehicle_checkout_period_validity" />
<result property="vehicleRemark" column="vehicle_remark" />
<result property="vehicleDrivingLicenseMain" column="vehicle_driving_license_main" />
<result property="vehicleDrivingLicenseDeputy" column="vehicle_driving_license_deputy" />
<result property="vehicleDrivingLicenseDeputyAgainst" column="vehicle_driving_license_deputy_against" />
<result property="trailerStatus" column="trailer_status" />
<result property="trailerLicensePlateNumber" column="trailer_license_plate_number" />
<result property="trailerVehicleTypeId" column="trailer_vehicle_type_id" />
<result property="trailerVehicleTypeName" column="trailer_vehicle_type_name" />
<result property="trailerLicensePlateColorId" column="trailer_license_plate_color_id" />
<result property="trailerLicensePlateColorName" column="trailer_license_plate_color_name" />
<result property="trailerTotalMass" column="trailer_total_mass" />
<result property="trailerApprovedLoadQuantity" column="trailer_approved_load_quantity" />
<result property="trailerDrivingLicenseExpireDate" column="trailer_driving_license_expire_date" />
<result property="trailerDrivingLicenseLongStatus" column="trailer_driving_license_long_status" />
<result property="trailerRoadTransportCertificateNo" column="trailer_road_transport_certificate_no" />
<result property="trailerRoadTransportCertificateExpireDate" column="trailer_road_transport_certificate_expire_date" />
<result property="trailerRoadTransportCertificateLongStatus" column="trailer_road_transport_certificate_long_status" />
<result property="trailerDrivingLicenseMain" column="trailer_driving_license_main" />
<result property="trailerDrivingLicenseDeputy" column="trailer_driving_license_deputy" />
<result property="trailerRoadTransportCertificateImage" column="trailer_road_transport_certificate_image" />
<result property="otherLicensePlateColorId" column="other_license_plate_color_id" />
<result property="otherLicensePlateColorName" column="other_license_plate_color_name" />
<result property="otherEnergyTypeId" column="other_energy_type_id" />
<result property="otherEnergyTypeName" column="other_energy_type_name" />
<result property="otherAxlesNumberId" column="other_axles_number_id" />
<result property="otherAxlesNumberName" column="other_axles_number_name" />
<result property="otherCarLengthId" column="other_car_length_id" />
<result property="otherCarLengthName" column="other_car_length_name" />
<result property="otherVehicleVolumeId" column="other_vehicle_volume_id" />
<result property="otherVehicleVolumeName" column="other_vehicle_volume_name" />
<result property="otherHeadstockImage" column="other_headstock_image" />
<result property="otherBodyworkImage" column="other_bodywork_image" />
<result property="otherPersonCarImage" column="other_person_car_image" />
<result property="roadTransportCertificateNo" column="road_transport_certificate_no" />
<result property="roadTransportCertificateExpireDate" column="road_transport_certificate_expire_date" />
<result property="roadTransportCertificateLongStatus" column="road_transport_certificate_long_status" />
<result property="roadTransportCertificateImage" column="road_transport_certificate_image" />
<result property="businessLicenseNumber" column="business_license_number" />
<result property="specializedHouseholdsName" column="specialized_households_name" />
<result property="businessLicenseExpireStartDate" column="business_license_expire_start_date" />
<result property="businessLicenseExpireEndDate" column="business_license_expire_end_date" />
<result property="businessLicenseLongStatus" column="business_license_long_status" />
<result property="businessLicenseImage" column="business_license_image" />
<result property="authenticationStatus" column="authentication_status" />
<result property="rejectReason" column="reject_reason" />
<result property="userId" column="user_id" />
<result property="userName" column="user_name" />
<result property="userPhone" column="user_phone" />
<result property="motorcadeId" column="motorcade_id" />
<result property="motorcadeName" column="motorcade_name" />
<result property="carryStatus" column="carry_status" />
<result property="roadTransportCertificateCheckoutStatus" column="road_transport_certificate_checkout_status" />
<result property="businessLicenseCheckoutStatus" column="business_license_checkout_status" />
<result property="netInStatus" column="net_in_status" />
<result property="netInDate" column="net_in_date" />
<result property="useStatus" column="use_status" />
<result property="organizationId" column="organization_id" />
<result property="organizationName" column="organization_name" />
<result property="checkoutPersonId" column="checkout_person_id" />
<result property="checkoutPersonName" column="checkout_person_name" />
<result property="checkoutDate" column="checkout_date" />
<result property="vehicleDrivingLicenseAuthStatus" column="vehicle_driving_license_auth_status" />
<result property="vehicleAuthStatus" column="vehicle_auth_status" />
<result property="trailerLicensePlateAuthStatus" column="trailer_license_plate_auth_status" />
<result property="roadTransportCertificateAuthStatus" column="road_transport_certificate_auth_status" />
<result property="businessLicenseExpireAuthStatus" column="business_license_expire_auth_status" />
<result property="authStatus" column="auth_status" />
<result property="roadTransportCertificateCheckStatus" column="road_transport_certificate_check_status" />
<result property="businessLicenseExpireCheckStatus" column="business_license_expire_check_status" />
<result property="blacklistStatus" column="blacklist_status" />
<result property="blacklistRemark" column="blacklist_remark" />
<result property="createTime" column="create_time" />
<result property="createBy" column="create_by" />
<result property="createByName" column="create_by_name" />
<result property="updateTime" column="update_time" />
<result property="updateBy" column="update_by" />
<result property="updateByName" column="update_by_name" />
<result property="delFlag" column="del_flag" />
<result property="userName" column="user_name" />
<result property="userPhone" column="user_phone" />
</resultMap>
<sql id="selectVehicleVo">
SELECT
*
FROM
vehicle
</sql>
<select id="selectVehicleList" parameterType="com.linke.transport.domain.vehicle.repository.po.VehiclePo" resultMap="VehicleResult">
<include refid="selectVehicleVo"/>
<where>
del_flag = 1
<if test="vehicleLicensePlateNumber != null and vehicleLicensePlateNumber != ''"> and vehicle_license_plate_number like concat('%', #{vehicleLicensePlateNumber}, '%')</if>
<if test="vehicleTypeId != null and vehicleTypeId != ''"> and vehicle_type_id = #{vehicleTypeId}</if>
<if test="vehicleSourceId != null and vehicleTypeId != ''"> and vehicle_source_id = #{vehicleSourceId}</if>
<if test="vehicleSource != null"> and vehicle_source = #{vehicleSource}</if>
<if test="trailerLicensePlateNumber != null and trailerLicensePlateNumber != ''"> and trailer_license_plate_number like concat('%', #{trailerLicensePlateNumber}, '%')</if>
<if test="authenticationStatus != null "> and authentication_status = #{authenticationStatus}</if>
<if test="userName != null and userName != ''"> and user_name like concat('%', #{userName}, '%')</if>
<if test="motorcadeName != null and motorcadeName != ''"> and motorcade_name like concat('%', #{motorcadeName}, '%')</if>
<if test="carryStatus != null "> and carry_status = #{carryStatus}</if>
<if test="vehicleUseNature != null and vehicleUseNature != ''"> and vehicle_use_nature like concat('%', #{vehicleUseNature}, '%')</if>
<if test="vehicleTotalMassStart != null">
AND IFNULL(vehicle_total_mass,0) >= #{vehicleTotalMassStart}
</if>
<if test="vehicleTotalMassEnd != null">
AND IFNULL(vehicle_total_mass,0) <![CDATA[<=]]> #{vehicleTotalMassEnd}
</if>
<if test="vehicleApprovedLoadQuantityStart != null">
AND IFNULL(vehicle_approved_load_quantity,0) >= #{vehicleApprovedLoadQuantityStart}
</if>
<if test="vehicleApprovedLoadQuantityEnd != null">
AND IFNULL(vehicle_approved_load_quantity,0) <![CDATA[<=]]> #{vehicleApprovedLoadQuantityEnd}
</if>
<if test="otherAxlesNumberNameStart != null">
AND IFNULL(other_axles_number_name,0) >= #{otherAxlesNumberNameStart}
</if>
<if test="otherAxlesNumberNameEnd != null">
AND IFNULL(other_axles_number_name,0) <![CDATA[<=]]> #{otherAxlesNumberNameEnd}
</if>
<if test="otherCarLengthNameStart != null">
AND IFNULL(other_car_length_name,0) >= #{otherCarLengthNameStart}
</if>
<if test="otherCarLengthNameEnd != null">
AND IFNULL(other_car_length_name,0) <![CDATA[<=]]> #{otherCarLengthNameEnd}
</if>
<if test="otherVehicleVolumeNameStart != null">
AND IFNULL(other_vehicle_volume_name,0) >= #{otherVehicleVolumeNameStart}
</if>
<if test="otherVehicleVolumeNameEnd != null">
AND IFNULL(other_vehicle_volume_name,0) <![CDATA[<=]]> #{otherVehicleVolumeNameEnd}
</if>
<if test="otherLicensePlateColorId != null and otherLicensePlateColorId != ''"> and other_license_plate_color_id = #{otherLicensePlateColorId}</if>
<if test="vehicleCheckoutPeriodValidityStart != null">
AND vehicle_checkout_period_validity >= #{vehicleCheckoutPeriodValidityStart}
</if>
<if test="vehicleCheckoutPeriodValidityEnd != null">
AND vehicle_checkout_period_validity <![CDATA[<=]]> #{vehicleCheckoutPeriodValidityEnd}
</if>
<if test="trailerRoadTransportCertificateNo != null and trailerRoadTransportCertificateNo != ''"> and trailer_road_transport_certificate_no = #{trailerRoadTransportCertificateNo}</if>
<if test="roadTransportCertificateExpireDateStart != null">
AND trailer_road_transport_certificate_expire_date >= #{roadTransportCertificateExpireDateStart}
</if>
<if test="roadTransportCertificateExpireDateEnd != null">
AND trailer_road_transport_certificate_expire_date <![CDATA[<=]]> #{roadTransportCertificateExpireDateEnd}
</if>
<if test="roadTransportCertificateCheckoutStatus != null "> and road_transport_certificate_checkout_status = #{roadTransportCertificateCheckoutStatus}</if>
<if test="businessLicenseNumber != null and businessLicenseNumber != ''"> and business_license_number = #{businessLicenseNumber}</if>
<if test="businessLicenseExpireEndDateStart != null">
AND business_license_expire_end_date >= #{businessLicenseExpireEndDateStart}
</if>
<if test="businessLicenseExpireEndDateStart != null">
AND business_license_expire_end_date <![CDATA[<=]]> #{businessLicenseExpireEndDateStart}
</if>
<if test="businessLicenseCheckoutStatus != null "> and business_license_checkout_status = #{businessLicenseCheckoutStatus}</if>
<if test="netInStatus != null "> and net_in_status = #{netInStatus}</if>
<if test="netInDateStart != null">
AND net_in_date >= #{netInDateStart}
</if>
<if test="netInDateEnd != null">
AND net_in_date <![CDATA[<=]]> #{netInDateEnd}
</if>
<if test="useStatus != null "> and use_status = #{useStatus}</if>
<if test="organizationId != null "> and organization_id = #{organizationId}</if>
<if test="organizationName != null "> and organization_id like concat('%', #{organizationName}, '%')</if>
<if test="checkoutPersonName != null and checkoutPersonName != ''"> and checkout_person_name like concat('%', #{checkoutPersonName}, '%')</if>
<if test="checkoutDateStart != null">
AND checkout_date >= #{checkoutDateStart}
</if>
<if test="checkoutDateEnd != null">
AND checkout_date <![CDATA[<=]]> #{checkoutDateEnd}
</if>
<if test="createByName != null and createByName != ''"> and create_by_name like concat('%', #{createByName}, '%')</if>
<if test="createTimeStart != null">
AND date_format(create_time,'%Y-%m-%d') >= date_format(#{createTimeStart},'%Y-%m-%d')
</if>
<if test="createTimeEnd != null">
AND date_format(create_time,'%Y-%m-%d') <![CDATA[<=]]> date_format(#{createTimeEnd},'%Y-%m-%d')
</if>
<if test="createTimeFrom != null">
AND date_format(create_time,'%Y-%m-%d') >= date_format(#{createTimeFrom},'%Y-%m-%d')
</if>
<if test="createTimeTo != null">
AND date_format(create_time,'%Y-%m-%d') <![CDATA[<=]]> date_format(#{createTimeTo},'%Y-%m-%d')
</if>
<if test="createBy != null"> and create_by = #{createBy}</if>
<if test="organizationIdList != null ">
AND organization_id in
<foreach item="id" collection="organizationIdList" open="(" separator="," close=")">
#{id}
</foreach>
</if>
<if test="vehicleIdList != null ">
AND vehicle_id in
<foreach item="id" collection="vehicleIdList" open="(" separator="," close=")">
#{id}
</foreach>
</if>
<if test="vehicleBindIdList != null and vehicleBindIdList.size > 0">
AND vehicle_id not in
<foreach item="id" collection="vehicleBindIdList" open="(" separator="," close=")">
#{id}
</foreach>
</if>
</where>
order by create_time DESC
</select>
<select id="selectStowageVehiclelist" parameterType="com.linke.transport.domain.vehicle.repository.po.VehiclePo" resultMap="VehicleResult">
SELECT
v.vehicle_id,
v.vehicle_license_plate_number,
v.vehicle_type_id,
v.vehicle_type_name,
v.vehicle_approved_load_quantity,
v.vehicle_source_id,
v.vehicle_source_name,
v.user_id,
v.user_name,
v.user_phone,
COALESCE(CONCAT( v.vehicle_license_plate_number, ' ', v.vehicle_type_name, ' ', v.vehicle_approved_load_quantity, 'kg', ' ', v.vehicle_source_name )
,v.vehicle_license_plate_number, ' ', v.vehicle_type_name, ' ', v.vehicle_approved_load_quantity, 'kg', ' ', v.vehicle_source_name) AS label
FROM
vehicle v
<where>
v.del_flag = 1 and v.authentication_status = 3
<choose>
<when test="userAccountType != null and userAccountType == 3 and topOrganizationId != null">
and v.top_organization_id = #{topOrganizationId}
</when>
<otherwise>
and (v.organization_id = #{organizationId} or v.organization_id = #{topOrganizationId})
</otherwise>
</choose>
<!-- <if test="createBy != null"> and v.create_by = #{createBy}</if>-->
<!-- <if test="createBy != null and organizationIdList == null">-->
<!-- and v.create_by = #{createBy}</if>-->
<!-- <if test="organizationIdList != null and createBy == null">-->
<!-- and v.organization_id in-->
<!-- <foreach item="id" collection="organizationIdList" open="(" separator="," close=")">-->
<!-- #{id}-->
<!-- </foreach>-->
<!-- </if>-->
<!-- <if test="organizationIdList != null and createBy != null">-->
<!-- and (v.organization_id in-->
<!-- <foreach item="id" collection="organizationIdList" open="(" separator="," close=")">-->
<!-- #{id}-->
<!-- </foreach>-->
<!-- or v.create_by = #{createBy})-->
<!-- </if>-->
</where>
</select>
<select id="selectVehicleByVehicleId" parameterType="java.lang.Long" resultMap="VehicleResult">
<include refid="selectVehicleVo"/>
where vehicle_id = #{vehicleId} and del_flag = 1
</select>
<select id="selectVehiclePoByVehicleId" parameterType="java.lang.Long" resultType="com.mhd.common.core.domain.po.VehiclePo">
<include refid="selectVehicleVo"/>
where vehicle_id = #{vehicleId} and del_flag = 1
</select>
<insert id="insertVehicle" parameterType="com.linke.transport.domain.vehicle.entity.Vehicle" useGeneratedKeys = "true" keyProperty = "vehicleId">
insert into vehicle
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="vehicleLicensePlateNumber != null">vehicle_license_plate_number,</if>
<if test="vehicleTypeId != null">vehicle_type_id,</if>
<if test="vehicleTypeName != null">vehicle_type_name,</if>
<if test="vehicleSourceId != null">vehicle_source_id,</if>
<if test="vehicleSourceName != null">vehicle_source_name,</if>
<if test="vehicleUsePerson != null">vehicle_use_person,</if>
<if test="vehicleAddress != null">vehicle_address,</if>
<if test="vehicleUseNature != null">vehicle_use_nature,</if>
<if test="vehicleBrandType != null">vehicle_brand_type,</if>
<if test="vehicleIdentificationNumber != null">vehicle_identification_number,</if>
<if test="vehicleEngineNumber != null">vehicle_engine_number,</if>
<if test="vehicleRegistrationDate != null">vehicle_registration_date,</if>
<if test="vehicleIssueDate != null">vehicle_issue_date,</if>
<if test="vehicleLicenceIssuingAuthority != null">vehicle_licence_issuing_authority,</if>
<if test="vehicleFileNumber != null">vehicle_file_number,</if>
<if test="vehicleTotalMass != null">vehicle_total_mass,</if>
<if test="vehicleApprovedLoadQuantity != null">vehicle_approved_load_quantity,</if>
<if test="vehicleGabariteOne != null">vehicle_gabarite_one,</if>
<if test="vehicleGabariteTwo != null">vehicle_gabarite_two,</if>
<if test="vehicleGabariteThree != null">vehicle_gabarite_three,</if>
<if test="vehicleEnergyTypeId != null">vehicle_energy_type_id,</if>
<if test="vehicleEnergyTypeName != null">vehicle_energy_type_name,</if>
<if test="vehicleCheckoutPeriodValidity != null">vehicle_checkout_period_validity,</if>
<if test="vehicleRemark != null">vehicle_remark,</if>
<if test="vehicleDrivingLicenseMain != null">vehicle_driving_license_main,</if>
<if test="vehicleDrivingLicenseDeputy != null">vehicle_driving_license_deputy,</if>
<if test="vehicleDrivingLicenseDeputyAgainst != null">vehicle_driving_license_deputy_against,</if>
<if test="trailerStatus != null">trailer_status,</if>
<if test="trailerLicensePlateNumber != null">trailer_license_plate_number,</if>
<if test="trailerVehicleTypeId != null">trailer_vehicle_type_id,</if>
<if test="trailerVehicleTypeName != null">trailer_vehicle_type_name,</if>
<if test="trailerLicensePlateColorId != null">trailer_license_plate_color_id,</if>
<if test="trailerLicensePlateColorName != null">trailer_license_plate_color_name,</if>
<if test="trailerTotalMass != null">trailer_total_mass,</if>
<if test="trailerApprovedLoadQuantity != null">trailer_approved_load_quantity,</if>
<if test="trailerDrivingLicenseExpireDate != null">trailer_driving_license_expire_date,</if>
<if test="trailerDrivingLicenseLongStatus != null">trailer_driving_license_long_status,</if>
<if test="trailerRoadTransportCertificateNo != null">trailer_road_transport_certificate_no,</if>
<if test="trailerRoadTransportCertificateExpireDate != null">trailer_road_transport_certificate_expire_date,</if>
<if test="trailerRoadTransportCertificateLongStatus != null">trailer_road_transport_certificate_long_status,</if>
<if test="trailerDrivingLicenseMain != null">trailer_driving_license_main,</if>
<if test="trailerDrivingLicenseDeputy != null">trailer_driving_license_deputy,</if>
<if test="trailerRoadTransportCertificateImage != null">trailer_road_transport_certificate_image,</if>
<if test="otherLicensePlateColorId != null">other_license_plate_color_id,</if>
<if test="otherLicensePlateColorName != null">other_license_plate_color_name,</if>
<if test="otherEnergyTypeId != null">other_energy_type_id,</if>
<if test="otherEnergyTypeName != null">other_energy_type_name,</if>
<if test="otherAxlesNumberId != null">other_axles_number_id,</if>
<if test="otherAxlesNumberName != null">other_axles_number_name,</if>
<if test="otherCarLengthId != null">other_car_length_id,</if>
<if test="otherCarLengthName != null">other_car_length_name,</if>
<if test="otherVehicleVolumeId != null">other_vehicle_volume_id,</if>
<if test="otherVehicleVolumeName != null">other_vehicle_volume_name,</if>
<if test="otherHeadstockImage != null">other_headstock_image,</if>
<if test="otherBodyworkImage != null">other_bodywork_image,</if>
<if test="otherPersonCarImage != null">other_person_car_image,</if>
<if test="roadTransportCertificateNo != null">road_transport_certificate_no,</if>
<if test="roadTransportCertificateExpireDate != null">road_transport_certificate_expire_date,</if>
<if test="roadTransportCertificateLongStatus != null">road_transport_certificate_long_status,</if>
<if test="roadTransportCertificateImage != null">road_transport_certificate_image,</if>
<if test="businessLicenseNumber != null">business_license_number,</if>
<if test="specializedHouseholdsName != null">specialized_households_name,</if>
<if test="businessLicenseExpireStartDate != null">business_license_expire_start_date,</if>
<if test="businessLicenseExpireEndDate != null">business_license_expire_end_date,</if>
<if test="businessLicenseLongStatus != null">business_license_long_status,</if>
<if test="businessLicenseImage != null">business_license_image,</if>
<if test="authenticationStatus != null">authentication_status,</if>
<if test="rejectReason != null">reject_reason,</if>
<if test="userId != null">user_id,</if>
<if test="userName != null">user_name,</if>
<if test="userPhone != null">user_phone,</if>
<if test="motorcadeId != null">motorcade_id,</if>
<if test="motorcadeName != null">motorcade_name,</if>
<if test="carryStatus != null">carry_status,</if>
<if test="roadTransportCertificateCheckoutStatus != null">road_transport_certificate_checkout_status,</if>
<if test="businessLicenseCheckoutStatus != null">business_license_checkout_status,</if>
<if test="netInStatus != null">net_in_status,</if>
<if test="netInDate != null">net_in_date,</if>
<if test="useStatus != null">use_status,</if>
<if test="organizationId != null">organization_id,</if>
<if test="organizationName != null">organization_name,</if>
<if test="checkoutPersonId != null">checkout_person_id,</if>
<if test="checkoutPersonName != null">checkout_person_name,</if>
<if test="checkoutDate != null">checkout_date,</if>
<if test="vehicleDrivingLicenseAuthStatus != null">vehicle_driving_license_auth_status,</if>
<if test="vehicleAuthStatus != null">vehicle_auth_status,</if>
<if test="trailerLicensePlateAuthStatus != null">trailer_license_plate_auth_status,</if>
<if test="roadTransportCertificateAuthStatus != null">road_transport_certificate_auth_status,</if>
<if test="businessLicenseExpireAuthStatus != null">business_license_expire_auth_status,</if>
<if test="authStatus != null">auth_status,</if>
<if test="roadTransportCertificateCheckStatus != null">road_transport_certificate_check_status,</if>
<if test="businessLicenseExpireCheckStatus != null">business_license_expire_check_status,</if>
<if test="blacklistStatus != null">blacklist_status,</if>
<if test="blacklistRemark != null">blacklist_remark,</if>
<if test="createTime != null">create_time,</if>
<if test="createBy != null">create_by,</if>
<if test="createByName != null">create_by_name,</if>
<if test="updateTime != null">update_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateByName != null">update_by_name,</if>
<if test="delFlag != null">del_flag,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="vehicleLicensePlateNumber != null">#{vehicleLicensePlateNumber},</if>
<if test="vehicleTypeId != null">#{vehicleTypeId},</if>
<if test="vehicleTypeName != null">#{vehicleTypeName},</if>
<if test="vehicleSourceId != null">#{vehicleSourceId},</if>
<if test="vehicleSourceName != null">#{vehicleSourceName},</if>
<if test="vehicleUsePerson != null">#{vehicleUsePerson},</if>
<if test="vehicleAddress != null">#{vehicleAddress},</if>
<if test="vehicleUseNature != null">#{vehicleUseNature},</if>
<if test="vehicleBrandType != null">#{vehicleBrandType},</if>
<if test="vehicleIdentificationNumber != null">#{vehicleIdentificationNumber},</if>
<if test="vehicleEngineNumber != null">#{vehicleEngineNumber},</if>
<if test="vehicleRegistrationDate != null">#{vehicleRegistrationDate},</if>
<if test="vehicleIssueDate != null">#{vehicleIssueDate},</if>
<if test="vehicleLicenceIssuingAuthority != null">#{vehicleLicenceIssuingAuthority},</if>
<if test="vehicleFileNumber != null">#{vehicleFileNumber},</if>
<if test="vehicleTotalMass != null">#{vehicleTotalMass},</if>
<if test="vehicleApprovedLoadQuantity != null">#{vehicleApprovedLoadQuantity},</if>
<if test="vehicleGabariteOne != null">#{vehicleGabariteOne},</if>
<if test="vehicleGabariteTwo != null">#{vehicleGabariteTwo},</if>
<if test="vehicleGabariteThree != null">#{vehicleGabariteThree},</if>
<if test="vehicleEnergyTypeId != null">#{vehicleEnergyTypeId},</if>
<if test="vehicleEnergyTypeName != null">#{vehicleEnergyTypeName},</if>
<if test="vehicleCheckoutPeriodValidity != null">#{vehicleCheckoutPeriodValidity},</if>
<if test="vehicleRemark != null">#{vehicleRemark},</if>
<if test="vehicleDrivingLicenseMain != null">#{vehicleDrivingLicenseMain},</if>
<if test="vehicleDrivingLicenseDeputy != null">#{vehicleDrivingLicenseDeputy},</if>
<if test="vehicleDrivingLicenseDeputyAgainst != null">#{vehicleDrivingLicenseDeputyAgainst},</if>
<if test="trailerStatus != null">#{trailerStatus},</if>
<if test="trailerLicensePlateNumber != null">#{trailerLicensePlateNumber},</if>
<if test="trailerVehicleTypeId != null">#{trailerVehicleTypeId},</if>
<if test="trailerVehicleTypeName != null">#{trailerVehicleTypeName},</if>
<if test="trailerLicensePlateColorId != null">#{trailerLicensePlateColorId},</if>
<if test="trailerLicensePlateColorName != null">#{trailerLicensePlateColorName},</if>
<if test="trailerTotalMass != null">#{trailerTotalMass},</if>
<if test="trailerApprovedLoadQuantity != null">#{trailerApprovedLoadQuantity},</if>
<if test="trailerDrivingLicenseExpireDate != null">#{trailerDrivingLicenseExpireDate},</if>
<if test="trailerDrivingLicenseLongStatus != null">#{trailerDrivingLicenseLongStatus},</if>
<if test="trailerRoadTransportCertificateNo != null">#{trailerRoadTransportCertificateNo},</if>
<if test="trailerRoadTransportCertificateExpireDate != null">#{trailerRoadTransportCertificateExpireDate},</if>
<if test="trailerRoadTransportCertificateLongStatus != null">#{trailerRoadTransportCertificateLongStatus},</if>
<if test="trailerDrivingLicenseMain != null">#{trailerDrivingLicenseMain},</if>
<if test="trailerDrivingLicenseDeputy != null">#{trailerDrivingLicenseDeputy},</if>
<if test="trailerRoadTransportCertificateImage != null">#{trailerRoadTransportCertificateImage},</if>
<if test="otherLicensePlateColorId != null">#{otherLicensePlateColorId},</if>
<if test="otherLicensePlateColorName != null">#{otherLicensePlateColorName},</if>
<if test="otherEnergyTypeId != null">#{otherEnergyTypeId},</if>
<if test="otherEnergyTypeName != null">#{otherEnergyTypeName},</if>
<if test="otherAxlesNumberId != null">#{otherAxlesNumberId},</if>
<if test="otherAxlesNumberName != null">#{otherAxlesNumberName},</if>
<if test="otherCarLengthId != null">#{otherCarLengthId},</if>
<if test="otherCarLengthName != null">#{otherCarLengthName},</if>
<if test="otherVehicleVolumeId != null">#{otherVehicleVolumeId},</if>
<if test="otherVehicleVolumeName != null">#{otherVehicleVolumeName},</if>
<if test="otherHeadstockImage != null">#{otherHeadstockImage},</if>
<if test="otherBodyworkImage != null">#{otherBodyworkImage},</if>
<if test="otherPersonCarImage != null">#{otherPersonCarImage},</if>
<if test="roadTransportCertificateNo != null">#{roadTransportCertificateNo},</if>
<if test="roadTransportCertificateExpireDate != null">#{roadTransportCertificateExpireDate},</if>
<if test="roadTransportCertificateLongStatus != null">#{roadTransportCertificateLongStatus},</if>
<if test="roadTransportCertificateImage != null">#{roadTransportCertificateImage},</if>
<if test="businessLicenseNumber != null">#{businessLicenseNumber},</if>
<if test="specializedHouseholdsName != null">#{specializedHouseholdsName},</if>
<if test="businessLicenseExpireStartDate != null">#{businessLicenseExpireStartDate},</if>
<if test="businessLicenseExpireEndDate != null">#{businessLicenseExpireEndDate},</if>
<if test="businessLicenseLongStatus != null">#{businessLicenseLongStatus},</if>
<if test="businessLicenseImage != null">#{businessLicenseImage},</if>
<if test="authenticationStatus != null">#{authenticationStatus},</if>
<if test="rejectReason != null">#{rejectReason},</if>
<if test="userId != null">#{userId},</if>
<if test="userName != null">#{userName},</if>
<if test="userPhone != null">#{userPhone},</if>
<if test="motorcadeId != null">#{motorcadeId},</if>
<if test="motorcadeName != null">#{motorcadeName},</if>
<if test="carryStatus != null">#{carryStatus},</if>
<if test="roadTransportCertificateCheckoutStatus != null">#{roadTransportCertificateCheckoutStatus},</if>
<if test="businessLicenseCheckoutStatus != null">#{businessLicenseCheckoutStatus},</if>
<if test="netInStatus != null">#{netInStatus},</if>
<if test="netInDate != null">#{netInDate},</if>
<if test="useStatus != null">#{useStatus},</if>
<if test="organizationId != null">#{organizationId},</if>
<if test="organizationName != null">#{organizationName},</if>
<if test="checkoutPersonId != null">#{checkoutPersonId},</if>
<if test="checkoutPersonName != null">#{checkoutPersonName},</if>
<if test="checkoutDate != null">#{checkoutDate},</if>
<if test="vehicleDrivingLicenseAuthStatus != null">#{vehicleDrivingLicenseAuthStatus},</if>
<if test="vehicleAuthStatus != null">#{vehicleAuthStatus},</if>
<if test="trailerLicensePlateAuthStatus != null">#{trailerLicensePlateAuthStatus},</if>
<if test="roadTransportCertificateAuthStatus != null">#{roadTransportCertificateAuthStatus},</if>
<if test="businessLicenseExpireAuthStatus != null">#{businessLicenseExpireAuthStatus},</if>
<if test="authStatus != null">#{authStatus},</if>
<if test="roadTransportCertificateCheckStatus != null">#{roadTransportCertificateCheckStatus},</if>
<if test="businessLicenseExpireCheckStatus != null">#{businessLicenseExpireCheckStatus},</if>
<if test="blacklistStatus != null">#{blacklistStatus},</if>
<if test="blacklistRemark != null">#{blacklistRemark},</if>
<if test="createTime != null">#{createTime},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createByName != null">#{createByName},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateByName != null">#{updateByName},</if>
<if test="delFlag != null">#{delFlag},</if>
</trim>
</insert>
<update id="updateVehicle" parameterType="com.linke.transport.domain.vehicle.entity.Vehicle">
update vehicle
<trim prefix="SET" suffixOverrides=",">
<if test="vehicleLicensePlateNumber != null">vehicle_license_plate_number = #{vehicleLicensePlateNumber},</if>
<if test="vehicleTypeId != null">vehicle_type_id = #{vehicleTypeId},</if>
<if test="vehicleTypeName != null">vehicle_type_name = #{vehicleTypeName},</if>
<if test="vehicleSourceId != null">vehicle_source_id = #{vehicleSourceId},</if>
<if test="vehicleSourceName != null">vehicle_source_name = #{vehicleSourceName},</if>
<if test="vehicleUsePerson != null">vehicle_use_person = #{vehicleUsePerson},</if>
<if test="vehicleAddress != null">vehicle_address = #{vehicleAddress},</if>
<if test="vehicleUseNature != null">vehicle_use_nature = #{vehicleUseNature},</if>
<if test="vehicleBrandType != null">vehicle_brand_type = #{vehicleBrandType},</if>
<if test="vehicleIdentificationNumber != null">vehicle_identification_number = #{vehicleIdentificationNumber},</if>
<if test="vehicleEngineNumber != null">vehicle_engine_number = #{vehicleEngineNumber},</if>
<if test="vehicleRegistrationDate != null">vehicle_registration_date = #{vehicleRegistrationDate},</if>
<if test="vehicleIssueDate != null">vehicle_issue_date = #{vehicleIssueDate},</if>
<if test="vehicleLicenceIssuingAuthority != null">vehicle_licence_issuing_authority = #{vehicleLicenceIssuingAuthority},</if>
<if test="vehicleFileNumber != null">vehicle_file_number = #{vehicleFileNumber},</if>
<if test="vehicleTotalMass != null">vehicle_total_mass = #{vehicleTotalMass},</if>
<if test="vehicleApprovedLoadQuantity != null">vehicle_approved_load_quantity = #{vehicleApprovedLoadQuantity},</if>
<if test="vehicleGabariteOne != null">vehicle_gabarite_one = #{vehicleGabariteOne},</if>
<if test="vehicleGabariteTwo != null">vehicle_gabarite_two = #{vehicleGabariteTwo},</if>
<if test="vehicleGabariteThree != null">vehicle_gabarite_three = #{vehicleGabariteThree},</if>
<if test="vehicleEnergyTypeId != null">vehicle_energy_type_id = #{vehicleEnergyTypeId},</if>
<if test="vehicleEnergyTypeName != null">vehicle_energy_type_name = #{vehicleEnergyTypeName},</if>
<if test="vehicleCheckoutPeriodValidity != null">vehicle_checkout_period_validity = #{vehicleCheckoutPeriodValidity},</if>
<if test="vehicleRemark != null">vehicle_remark = #{vehicleRemark},</if>
<if test="vehicleDrivingLicenseMain != null">vehicle_driving_license_main = #{vehicleDrivingLicenseMain},</if>
<if test="vehicleDrivingLicenseDeputy != null">vehicle_driving_license_deputy = #{vehicleDrivingLicenseDeputy},</if>
<if test="vehicleDrivingLicenseDeputyAgainst != null">vehicle_driving_license_deputy_against = #{vehicleDrivingLicenseDeputyAgainst},</if>
<if test="trailerStatus != null">trailer_status = #{trailerStatus},</if>
<if test="trailerLicensePlateNumber != null">trailer_license_plate_number = #{trailerLicensePlateNumber},</if>
<if test="trailerVehicleTypeId != null">trailer_vehicle_type_id = #{trailerVehicleTypeId},</if>
<if test="trailerVehicleTypeName != null">trailer_vehicle_type_name = #{trailerVehicleTypeName},</if>
<if test="trailerLicensePlateColorId != null">trailer_license_plate_color_id = #{trailerLicensePlateColorId},</if>
<if test="trailerLicensePlateColorName != null">trailer_license_plate_color_name = #{trailerLicensePlateColorName},</if>
<if test="trailerTotalMass != null">trailer_total_mass = #{trailerTotalMass},</if>
<if test="trailerApprovedLoadQuantity != null">trailer_approved_load_quantity = #{trailerApprovedLoadQuantity},</if>
<if test="trailerDrivingLicenseExpireDate != null">trailer_driving_license_expire_date = #{trailerDrivingLicenseExpireDate},</if>
<if test="trailerDrivingLicenseLongStatus != null">trailer_driving_license_long_status = #{trailerDrivingLicenseLongStatus},</if>
<if test="trailerRoadTransportCertificateNo != null">trailer_road_transport_certificate_no = #{trailerRoadTransportCertificateNo},</if>
<if test="trailerRoadTransportCertificateExpireDate != null">trailer_road_transport_certificate_expire_date = #{trailerRoadTransportCertificateExpireDate},</if>
<if test="trailerRoadTransportCertificateLongStatus != null">trailer_road_transport_certificate_long_status = #{trailerRoadTransportCertificateLongStatus},</if>
<if test="trailerDrivingLicenseMain != null">trailer_driving_license_main = #{trailerDrivingLicenseMain},</if>
<if test="trailerDrivingLicenseDeputy != null">trailer_driving_license_deputy = #{trailerDrivingLicenseDeputy},</if>
<if test="trailerRoadTransportCertificateImage != null">trailer_road_transport_certificate_image = #{trailerRoadTransportCertificateImage},</if>
<if test="otherLicensePlateColorId != null">other_license_plate_color_id = #{otherLicensePlateColorId},</if>
<if test="otherLicensePlateColorName != null">other_license_plate_color_name = #{otherLicensePlateColorName},</if>
<if test="otherEnergyTypeId != null">other_energy_type_id = #{otherEnergyTypeId},</if>
<if test="otherEnergyTypeName != null">other_energy_type_name = #{otherEnergyTypeName},</if>
<if test="otherAxlesNumberId != null">other_axles_number_id = #{otherAxlesNumberId},</if>
<if test="otherAxlesNumberName != null">other_axles_number_name = #{otherAxlesNumberName},</if>
<if test="otherCarLengthId != null">other_car_length_id = #{otherCarLengthId},</if>
<if test="otherCarLengthName != null">other_car_length_name = #{otherCarLengthName},</if>
<if test="otherVehicleVolumeId != null">other_vehicle_volume_id = #{otherVehicleVolumeId},</if>
<if test="otherVehicleVolumeName != null">other_vehicle_volume_name = #{otherVehicleVolumeName},</if>
<if test="otherHeadstockImage != null">other_headstock_image = #{otherHeadstockImage},</if>
<if test="otherBodyworkImage != null">other_bodywork_image = #{otherBodyworkImage},</if>
<if test="otherPersonCarImage != null">other_person_car_image = #{otherPersonCarImage},</if>
<if test="roadTransportCertificateNo != null">road_transport_certificate_no = #{roadTransportCertificateNo},</if>
<if test="roadTransportCertificateExpireDate != null">road_transport_certificate_expire_date = #{roadTransportCertificateExpireDate},</if>
<if test="roadTransportCertificateLongStatus != null">road_transport_certificate_long_status = #{roadTransportCertificateLongStatus},</if>
<if test="roadTransportCertificateImage != null">road_transport_certificate_image = #{roadTransportCertificateImage},</if>
<if test="businessLicenseNumber != null">business_license_number = #{businessLicenseNumber},</if>
<if test="specializedHouseholdsName != null">specialized_households_name = #{specializedHouseholdsName},</if>
<if test="businessLicenseExpireStartDate != null">business_license_expire_start_date = #{businessLicenseExpireStartDate},</if>
<if test="businessLicenseExpireEndDate != null">business_license_expire_end_date = #{businessLicenseExpireEndDate},</if>
<if test="businessLicenseLongStatus != null">business_license_long_status = #{businessLicenseLongStatus},</if>
<if test="businessLicenseImage != null">business_license_image = #{businessLicenseImage},</if>
<if test="authenticationStatus != null">authentication_status = #{authenticationStatus},</if>
<if test="rejectReason != null">reject_reason = #{rejectReason},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="userName != null">user_name = #{userName},</if>
<if test="userPhone != null">user_phone = #{userPhone},</if>
<if test="motorcadeId != null">motorcade_id = #{motorcadeId},</if>
<if test="motorcadeName != null">motorcade_name = #{motorcadeName},</if>
<if test="carryStatus != null">carry_status = #{carryStatus},</if>
<if test="roadTransportCertificateCheckoutStatus != null">road_transport_certificate_checkout_status = #{roadTransportCertificateCheckoutStatus},</if>
<if test="businessLicenseCheckoutStatus != null">business_license_checkout_status = #{businessLicenseCheckoutStatus},</if>
<if test="netInStatus != null">net_in_status = #{netInStatus},</if>
<if test="netInDate != null">net_in_date = #{netInDate},</if>
<if test="useStatus != null">use_status = #{useStatus},</if>
<if test="organizationId != null">organization_id = #{organizationId},</if>
<if test="organizationName != null">organization_name = #{organizationName},</if>
<if test="checkoutPersonId != null">checkout_person_id = #{checkoutPersonId},</if>
<if test="checkoutPersonName != null">checkout_person_name = #{checkoutPersonName},</if>
<if test="checkoutDate != null">checkout_date = #{checkoutDate},</if>
<if test="vehicleDrivingLicenseAuthStatus != null">vehicle_driving_license_auth_status = #{vehicleDrivingLicenseAuthStatus},</if>
<if test="vehicleAuthStatus != null">vehicle_auth_status = #{vehicleAuthStatus},</if>
<if test="trailerLicensePlateAuthStatus != null">trailer_license_plate_auth_status = #{trailerLicensePlateAuthStatus},</if>
<if test="roadTransportCertificateAuthStatus != null">road_transport_certificate_auth_status = #{roadTransportCertificateAuthStatus},</if>
<if test="businessLicenseExpireAuthStatus != null">business_license_expire_auth_status = #{businessLicenseExpireAuthStatus},</if>
<if test="authStatus != null">auth_status = #{authStatus},</if>
<if test="roadTransportCertificateCheckStatus != null">road_transport_certificate_check_status = #{roadTransportCertificateCheckStatus},</if>
<if test="businessLicenseExpireCheckStatus != null">business_license_expire_check_status = #{businessLicenseExpireCheckStatus},</if>
<if test="blacklistStatus != null">blacklist_status = #{blacklistStatus},</if>
<if test="blacklistRemark != null">blacklist_remark = #{blacklistRemark},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createByName != null">create_by_name = #{createByName},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateByName != null">update_by_name = #{updateByName},</if>
<if test="delFlag != null">del_flag = #{delFlag},</if>
</trim>
where vehicle_id = #{vehicleId}
</update>
<update id="batchUpdateVehicle" parameterType="java.util.List">
<foreach collection="vehicleList" item="item" index="index" separator=";">
update vehicle
<trim prefix="SET" suffixOverrides=",">
<if test="item.organizationId != null">
organization_id = #{item.organizationId},
</if>
<if test="item.organizationName != null">
organization_name = #{item.organizationName},
</if>
<if test="item.blacklistStatus != null">
blacklist_status = #{item.blacklistStatus},
</if>
<if test="item.blacklistRemark != null">
blacklist_remark = #{item.blacklistRemark},
</if>
<if test="item.useStatus != null">
use_status = #{item.useStatus},
</if>
<if test="item.tmsPushStatus != null">
tms_push_status = #{item.tmsPushStatus},
</if>
<if test="item.motorcadeId != null">
motorcade_id = #{item.motorcadeId},
</if>
<if test="item.motorcadeName != null">
motorcade_name = #{item.motorcadeName},
</if>
</trim>
where vehicle_id = #{item.vehicleId}
</foreach>
</update>
<delete id="deleteVehicleByVehicleId" parameterType="Long">
delete from vehicle where vehicle_id = #{vehicleId}
</delete>
<delete id="deleteVehicleByVehicleIds" parameterType="String">
delete from vehicle where vehicle_id in
<foreach item="vehicleId" collection="array" open="(" separator="," close=")">
#{vehicleId}
</foreach>
</delete>
<select id="getVehicleByIds" resultType="com.linke.transport.domain.vehicle.entity.Vehicle" parameterType="java.util.List">
SELECT
*
FROM
vehicle a
WHERE
a.del_flag = 1
<include refid="common_where_two"></include>
</select>
<select id="selectVehicleByVehicleIdAndPlan" resultType="com.linke.transport.domain.vehicle.repository.po.VehiclePo">
SELECT
*
FROM
vehicle a
WHERE
a.del_flag = 1
<include refid="common_where_three"></include>
</select>
<select id="selectVehicleAppById" resultType="com.linke.transport.domain.vehicle.repository.po.VehicleAppPo" parameterType="java.lang.Long">
SELECT
*
FROM
vehicle
WHERE
del_flag = 1
AND vehicle_id = #{vehicleId}
</select>
<select id="ownerBindCarList" resultType="com.linke.transport.domain.vehicle.repository.po.DriverVehicleBindPo" parameterType="com.mhd.common.core.domain.dto.DriverVehicleBindDto">
SELECT
v.vehicle_id,
v.user_id,
v.user_name AS bindDriverName,
v.user_phone AS bindDriverPhone,
v.top_organization_id,
v.organization_id,
v.vehicle_license_plate_number,
v.vehicle_type_name,
v.vehicle_approved_load_quantity,
v.authentication_status,
v.other_headstock_image,
v.other_license_plate_color_id,
v.other_license_plate_color_name,
v.vehicle_type_id,
v.reject_reason
FROM
vehicle v
WHERE
v.del_flag = 1
<include refid="where_two"></include>
ORDER BY v.create_time DESC
</select>
<select id="driverBindMyCarList" resultType="com.linke.transport.domain.vehicle.repository.po.DriverVehicleBindPo" parameterType="com.mhd.common.core.domain.dto.DriverVehicleBindDto">
SELECT
v.vehicle_id,
v.user_id,
v.user_name AS bindDriverName,
v.user_phone AS bindDriverPhone,
v.top_organization_id,
v.organization_id,
v.vehicle_license_plate_number,
v.vehicle_type_name,
v.vehicle_approved_load_quantity,
v.authentication_status,
v.other_headstock_image,
v.other_license_plate_color_id,
v.other_license_plate_color_name,
v.vehicle_type_id,
v.reject_reason
FROM
vehicle v
WHERE
v.del_flag = 1
AND v.authentication_status = 3
<include refid="where_two"></include>
ORDER BY v.create_time DESC
</select>
<select id="findVehicleByPlateNumber"
resultType="com.linke.transport.domain.vehicle.repository.po.VehiclePo">
select *
from vehicle
where del_flag = 1 and vehicle_license_plate_number = #{plateNumber};
</select>
<sql id="where_two">
<if test="driverVehicleBindDto.userId != null">
AND v.user_id = #{driverVehicleBindDto.userId}
</if>
<if test="driverVehicleBindDto.queryInfo !=null and driverVehicleBindDto.queryInfo !=''">
AND (v.user_name like concat('%' , #{driverVehicleBindDto.queryInfo } , '%') OR v.vehicle_license_plate_number like concat('%' , #{driverVehicleBindDto.queryInfo } , '%'))
</if>
<if test="driverVehicleBindDto.vehicleIdList !=null and driverVehicleBindDto.vehicleIdList.size() > 0">
and v.vehicle_id not in
<foreach item="vehicleId" index="index" collection="driverVehicleBindDto.vehicleIdList" open="(" separator=" , " close=")">
#{vehicleId}
</foreach>
</if>
</sql>
<sql id="common_where_three">
<if test="vehicleDto.vehicleLicensePlateNumber != null and vehicleDto.vehicleLicensePlateNumber != ''">
and a.vehicle_license_plate_number = #{vehicleDto.vehicleLicensePlateNumber}
</if>
<if test="vehicleDto.vehicleId != null">
and a.vehicle_id = #{vehicleDto.vehicleId}
</if>
<if test="vehicleDto.topOrganizationId != null">
and a.top_organization_id = #{vehicleDto.topOrganizationId}
</if>
</sql>
<sql id="common_where_two">
<if test="vehicleIdList != null ">
AND a.vehicle_id in
<foreach item="id" collection="vehicleIdList" open="(" separator="," close=")">
#{id}
</foreach>
</if>
</sql>
</mapper>