新增机器货道配置表

This commit is contained in:
zhangji committed 2025-09-09 15:27:00 +08:00
1 parent e4ab1124c3
commit 88cbffa5bc
13 files changed
+564

No files matched your search

@@ -56,6 +56,7 @@ public interface ErrorCodeConstants {
// ========== 贩卖机信息 1-008-009-000 ==========
ErrorCode DEVICE_NOT_EXISTS = new ErrorCode(1_008_009_000, "贩卖机信息不存在");
ErrorCode DEVICE_NOT_EXISTS_INFO = new ErrorCode(1_008_009_001, "贩卖机【{}】不存在");
ErrorCode DEVICE_EXISTS = new ErrorCode(1_008_009_001, "贩卖机信息已存在");
// ========== 商品汇总 1-008-010-000 ==========
ErrorCode SUMMARY_NOT_EXISTS = new ErrorCode(1_008_010_000, "商品汇总不存在");
@@ -64,4 +65,9 @@ public interface ErrorCodeConstants {
// ========== 商品库存日志 1-008-011-000 ==========
ErrorCode STOCK_LOG_NOT_EXISTS = new ErrorCode(1_008_011_000, "商品库存日志不存在");
// ========== 货道 1-008-012-000 ==========
ErrorCode CHANNEL_NOT_EXISTS = new ErrorCode(1_008_012_000, "货道不存在");
ErrorCode CHANNEL_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_008_012_001, "导入货道数据不能为空!");
ErrorCode CHANNEL_EXISTS = new ErrorCode(1_008_013_001, "货道已经存在");
}
@@ -0,0 +1,109 @@
package cn.iocoder.yudao.module.product.controller.admin.channel;
import io.swagger.v3.oas.annotations.Parameters;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.product.controller.admin.channel.vo.*;
import cn.iocoder.yudao.module.product.dal.dataobject.channel.ChannelDO;
import cn.iocoder.yudao.module.product.service.channel.ChannelService;
import org.springframework.web.multipart.MultipartFile;
@Tag(name = "管理后台 - 货道")
@RestController
@RequestMapping("/product/channel")
@Validated
public class ChannelController {
@Resource
private ChannelService channelService;
@PostMapping("/create")
@Operation(summary = "创建货道")
@PreAuthorize("@ss.hasPermission('product:channel:create')")
public CommonResult<Long> createChannel(@Valid @RequestBody ChannelSaveReqVO createReqVO) {
return success(channelService.createChannel(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新货道")
@PreAuthorize("@ss.hasPermission('product:channel:update')")
public CommonResult<Boolean> updateChannel(@Valid @RequestBody ChannelSaveReqVO updateReqVO) {
channelService.updateChannel(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除货道")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('product:channel:delete')")
public CommonResult<Boolean> deleteChannel(@RequestParam("id") Long id) {
channelService.deleteChannel(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得货道")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('product:channel:query')")
public CommonResult<ChannelRespVO> getChannel(@RequestParam("id") Long id) {
ChannelDO channel = channelService.getChannel(id);
return success(BeanUtils.toBean(channel, ChannelRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得货道分页")
@PreAuthorize("@ss.hasPermission('product:channel:query')")
public CommonResult<PageResult<ChannelRespVO>> getChannelPage(@Valid ChannelPageReqVO pageReqVO) {
PageResult<ChannelDO> pageResult = channelService.getChannelPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ChannelRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出货道 Excel")
@PreAuthorize("@ss.hasPermission('product:channel:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportChannelExcel(@Valid ChannelPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ChannelDO> list = channelService.getChannelPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "货道.xls", "数据", ChannelRespVO.class,
BeanUtils.toBean(list, ChannelRespVO.class));
}
@PostMapping("/import")
@Operation(summary = "导入货道 Excel")
@Parameters({
@Parameter(name = "file", description = "Excel 文件", required = true),
@Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
})
@PreAuthorize("@ss.hasPermission('product:channel:import')")
public CommonResult<ChannelImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
@RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
List<ChannelImportExcelVO> list = ExcelUtils.read(file, ChannelImportExcelVO.class);
return success(channelService.importChannelList(list, updateSupport));
}
}
@@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.product.controller.admin.channel.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 货道 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ChannelImportExcelVO {
@ExcelProperty("名称")
private String name;
@ExcelProperty("设备IMEI")
private String deviceId;
@ExcelProperty("当前使用的货道或柜门编号")
private String cabinetChannel;
@ExcelProperty("最大货物数")
private Integer maxNum;
@ExcelProperty("货道行号")
private Integer channelLine;
}
@@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.product.controller.admin.channel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Schema(description = "管理后台 - 货道导入 Response VO")
@Data
@Builder
public class ChannelImportRespVO {
@Schema(description = "创建成功的货道名数组", requiredMode = Schema.RequiredMode.REQUIRED)
private List<String> createChannelnames;
@Schema(description = "更新成功的货道名数组", requiredMode = Schema.RequiredMode.REQUIRED)
private List<String> updateChannelnames;
@Schema(description = "导入失败的货道集合,key 为货道名,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED)
private Map<String, String> failureChannelnames;
}
@@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.product.controller.admin.channel.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 货道分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ChannelPageReqVO extends PageParam {
@Schema(description = "名称", example = "芋艿")
private String name;
@Schema(description = "设备IMEI", example = "12439")
private String deviceId;
@Schema(description = "当前使用的货道或柜门编号")
private String cabinetChannel;
@Schema(description = "最大货物数")
private Integer maxNum;
@Schema(description = "货道行号")
private Integer channelLine;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
@@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.product.controller.admin.channel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 货道 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ChannelRespVO {
@Schema(description = "表编号,自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
@ExcelProperty("表编号,自增")
private Long id;
@Schema(description = "名称", example = "芋艿")
@ExcelProperty("名称")
private String name;
@Schema(description = "设备IMEI", requiredMode = Schema.RequiredMode.REQUIRED, example = "12439")
@ExcelProperty("设备IMEI")
private String deviceId;
@Schema(description = "当前使用的货道或柜门编号")
@ExcelProperty("当前使用的货道或柜门编号")
private String cabinetChannel;
@Schema(description = "最大货物数")
@ExcelProperty("最大货物数")
private Integer maxNum;
@Schema(description = "货道行号")
@ExcelProperty("货道行号")
private Integer channelLine;
@Schema(description = "创建时间")
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
@@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.product.controller.admin.channel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 货道新增/修改 Request VO")
@Data
public class ChannelSaveReqVO {
@Schema(description = "表编号,自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
private Long id;
@Schema(description = "名称", example = "芋艿")
private String name;
@Schema(description = "设备IMEI", requiredMode = Schema.RequiredMode.REQUIRED, example = "12439")
@NotEmpty(message = "设备IMEI不能为空")
private String deviceId;
@Schema(description = "当前使用的货道或柜门编号")
private String cabinetChannel;
@Schema(description = "最大货物数")
private Integer maxNum;
@Schema(description = "货道行号")
private Integer channelLine;
}
@@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.product.controller.admin.channel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
@Schema(description = "管理后台 - 货道新增/修改 Request VO")
@Data
public class ChannelTestReqVO {
@Schema(description = "表编号,自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "24906")
private Long id;
@Schema(description = "名称", example = "芋艿")
private String name;
@Schema(description = "设备IMEI", requiredMode = Schema.RequiredMode.REQUIRED, example = "12439")
@NotEmpty(message = "设备IMEI不能为空")
private String deviceId;
@Schema(description = "当前使用的货道或柜门编号")
private String cabinetChannel;
@Schema(description = "最大货物数")
private Integer maxNum;
@Schema(description = "货道行号")
private Integer channelLine;
}
@@ -0,0 +1,51 @@
package cn.iocoder.yudao.module.product.dal.dataobject.channel;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 货道 DO
*
* @author 小如之家
*/
@TableName("product_channel")
@KeySequence("product_channel_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChannelDO extends BaseDO {
/**
* 表编号,自增
*/
@TableId
private Long id;
/**
* 名称
*/
private String name;
/**
* 设备IMEI
*/
private String deviceId;
/**
* 当前使用的货道或柜门编号
*/
private String cabinetChannel;
/**
* 最大货物数
*/
private Integer maxNum;
/**
* 货道行号
*/
private Integer channelLine;
}
@@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.product.dal.mysql.channel;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.product.dal.dataobject.channel.ChannelDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.product.controller.admin.channel.vo.*;
/**
* 货道 Mapper
*
* @author 小如之家
*/
@Mapper
public interface ChannelMapper extends BaseMapperX<ChannelDO> {
default PageResult<ChannelDO> selectPage(ChannelPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ChannelDO>()
.likeIfPresent(ChannelDO::getName, reqVO.getName())
.eqIfPresent(ChannelDO::getDeviceId, reqVO.getDeviceId())
.eqIfPresent(ChannelDO::getCabinetChannel, reqVO.getCabinetChannel())
.eqIfPresent(ChannelDO::getMaxNum, reqVO.getMaxNum())
.eqIfPresent(ChannelDO::getChannelLine, reqVO.getChannelLine())
.betweenIfPresent(ChannelDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ChannelDO::getId));
}
default ChannelDO selectByDeviceIdAndCabinetChannel(String deviceId, String cabinetChannel){
return selectOne(ChannelDO::getDeviceId, deviceId, ChannelDO::getCabinetChannel, cabinetChannel);
}
}
@@ -0,0 +1,56 @@
package cn.iocoder.yudao.module.product.service.channel;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.product.controller.admin.channel.vo.*;
import cn.iocoder.yudao.module.product.dal.dataobject.channel.ChannelDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
/**
* 货道 Service 接口
*
* @author 小如之家
*/
public interface ChannelService {
/**
* 创建货道
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createChannel(@Valid ChannelSaveReqVO createReqVO);
/**
* 更新货道
*
* @param updateReqVO 更新信息
*/
void updateChannel(@Valid ChannelSaveReqVO updateReqVO);
/**
* 删除货道
*
* @param id 编号
*/
void deleteChannel(Long id);
/**
* 获得货道
*
* @param id 编号
* @return 货道
*/
ChannelDO getChannel(Long id);
/**
* 获得货道分页
*
* @param pageReqVO 分页查询
* @return 货道分页
*/
PageResult<ChannelDO> getChannelPage(ChannelPageReqVO pageReqVO);
ChannelImportRespVO importChannelList(List<ChannelImportExcelVO> list, Boolean updateSupport);
}
@@ -0,0 +1,110 @@
package cn.iocoder.yudao.module.product.service.channel;
import cn.hutool.core.collection.CollUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.module.product.controller.admin.channel.vo.*;
import cn.iocoder.yudao.module.product.dal.dataobject.channel.ChannelDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.product.dal.mysql.channel.ChannelMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_IMPORT_LIST_IS_EMPTY;
/**
* 货道 Service 实现类
*
* @author 小如之家
*/
@Service
@Validated
public class ChannelServiceImpl implements ChannelService {
@Resource
private ChannelMapper channelMapper;
@Override
public Long createChannel(ChannelSaveReqVO createReqVO) {
ChannelDO dbChannel = channelMapper.selectByDeviceIdAndCabinetChannel(createReqVO.getDeviceId(),createReqVO.getCabinetChannel());
if (dbChannel != null){
throw exception(CHANNEL_EXISTS);
}
// 插入
ChannelDO channel = BeanUtils.toBean(createReqVO, ChannelDO.class);
channelMapper.insert(channel);
// 返回
return channel.getId();
}
@Override
public void updateChannel(ChannelSaveReqVO updateReqVO) {
// 校验存在
validateChannelExists(updateReqVO.getId());
// 更新
ChannelDO updateObj = BeanUtils.toBean(updateReqVO, ChannelDO.class);
channelMapper.updateById(updateObj);
}
@Override
public void deleteChannel(Long id) {
// 校验存在
validateChannelExists(id);
// 删除
channelMapper.deleteById(id);
}
private void validateChannelExists(Long id) {
if (channelMapper.selectById(id) == null) {
throw exception(CHANNEL_NOT_EXISTS);
}
}
@Override
public ChannelDO getChannel(Long id) {
return channelMapper.selectById(id);
}
@Override
public PageResult<ChannelDO> getChannelPage(ChannelPageReqVO pageReqVO) {
return channelMapper.selectPage(pageReqVO);
}
@Override
public ChannelImportRespVO importChannelList(List<ChannelImportExcelVO> importList, Boolean updateSupport) {
// 1 参数校验
if (CollUtil.isEmpty(importList)) {
throw exception(CHANNEL_IMPORT_LIST_IS_EMPTY);
}
ChannelImportRespVO respVO = ChannelImportRespVO.builder()
.createChannelnames(new ArrayList<>())
.updateChannelnames(new ArrayList<>())
.failureChannelnames(new LinkedHashMap<>())
.build();
importList.forEach(excelVO -> {
ChannelDO dbChannel = channelMapper.selectByDeviceIdAndCabinetChannel(excelVO.getDeviceId(),excelVO.getCabinetChannel());
if (dbChannel == null){
channelMapper.insert(BeanUtils.toBean(excelVO, ChannelDO.class));
respVO.getCreateChannelnames().add(excelVO.getName());
return;
}
if (!updateSupport){
respVO.getFailureChannelnames().put(excelVO.getName(), CHANNEL_EXISTS.getMsg());
return;
}
ChannelDO channel = BeanUtils.toBean(excelVO, ChannelDO.class);
channel.setId(dbChannel.getId());
channelMapper.updateById(channel);
respVO.getUpdateChannelnames().add(excelVO.getName());
});
return respVO;
}
}
@@ -70,6 +70,10 @@ public class DeviceServiceImpl implements DeviceService {
@Override
public Long createDevice(DeviceSaveReqVO createReqVO) {
DeviceDO deviceByDeviceId = deviceMapper.getDeviceByDeviceId(createReqVO.getDeviceId());
if (ObjectUtil.isNotNull(deviceByDeviceId)) {
throw exception(DEVICE_EXISTS);
}
// 插入
DeviceDO device = BeanUtils.toBean(createReqVO, DeviceDO.class);
deviceMapper.insert(device);