feat(core): 添加出库申请定时任务和二维码生成功能

- 新增 OutboundApplicationJob 定时任务处理出货单据二维码生成
- 添加 ScmgiplanEntity 和 ScmGiPlanItemEntity 实体类定义
- 创建 ScmgiplanQrEntity 和 ScmgiPlanSyncLogEntity 二维码相关实体
- 实现 ScmgiPlanService 服务接口及 ScmgiPlanServiceImpl 实现类
- 添加 ScmgiPlanItemMapper、ScmgiPlanMapper、ScmgiPlanQrMapper 等数据访问层
- 集成二维码生成工具类 QrCodeUtil 支持数据压缩功能
- 创建 QrOutboundApplicationController 提供出库申请相关接口
- 修改数据库配置将 schema 从 ERPCS 和 ERP 统一为 GSSERVER
This commit is contained in:
Gjm
2026-05-15 16:59:52 +08:00
parent 656b0995f4
commit 5e1bbc3905
17 changed files with 1500 additions and 16 deletions

View File

@@ -0,0 +1,95 @@
package com.lideeyunji.module.biz.controller;
import com.lideeyunji.core.framework.entity.erp.ScmgiplanEntity;
import com.lideeyunji.core.framework.entity.erp.ScmgiplanQrEntity;
import com.lideeyunji.core.framework.service.erp.ScmgiPlanService;
import com.lideeyunji.module.biz.service.QrOutboundApplicationService;
import com.lideeyunji.tool.framework.common.pojo.CommonResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.xml.transform.Result;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.lideeyunji.tool.framework.common.pojo.CommonResult.success;
/**
* @author DX
* @create 2026-03-3 11:59
* @dedescription:
*/
@Tag(name = "出库申请控制器")
@RestController
@Validated
@RequestMapping("/outbound")
public class QrOutboundApplicationController {
@Resource
private QrOutboundApplicationService qrOutboundApplicationService;
@Resource
private ScmgiPlanService scmgiPlanService;
@PostMapping("/list")
@PermitAll
@Operation(tags = "出库申请列表",summary = "出库申请列表")
public CommonResult<List<ScmgiplanQrEntity>> list(@RequestBody ScmgiplanEntity scmgiplanEntity) {
return success(qrOutboundApplicationService.selectList(scmgiplanEntity));
}
@PostMapping("/selectOne")
@PermitAll
@Operation(tags = "查询出库申请",summary = "查询出库申请")
public CommonResult<ScmgiplanEntity> selectOne(@RequestBody ScmgiplanEntity scmgiplanEntity) {
return success(qrOutboundApplicationService.selectByCode(scmgiplanEntity));
}
// 批量查询接口
@GetMapping("/selectBatch")
@PermitAll
public CommonResult<List<ScmgiplanQrEntity>> selectBatch(@RequestParam("ids") String ids) {
List<String> idList = Arrays.asList(ids.split(","));
if (idList.isEmpty()) {
return CommonResult.error(200,"ids参数不能为空");
}
List<ScmgiplanEntity>list= scmgiPlanService.selectPlanForQr(idList);
if (list.isEmpty()) {
return CommonResult.error(200,"没有查询到数据");
}
List<String> planIds = list.stream()
.map(ScmgiplanEntity::getId)
.collect(Collectors.toList());
// 批量查询
List<ScmgiplanQrEntity> dataList = qrOutboundApplicationService.selectBatchByIds(planIds);
// 保持原有顺序
Map<String, ScmgiplanQrEntity> dataMap = dataList.stream()
.collect(Collectors.toMap(ScmgiplanQrEntity::getPlanId, Function.identity()));
List<ScmgiplanQrEntity> sortedList = idList.stream()
.map(dataMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
return success(sortedList);
}
@GetMapping("/getQrCode")
@PermitAll
@Operation(tags = "查询出库申请",summary = "查询出库申请")
public CommonResult<ScmgiplanQrEntity> getQrCode(@RequestParam("id") String id) {
return success(qrOutboundApplicationService.getQrCode(id));
}
}

View File

@@ -0,0 +1,11 @@
package com.lideeyunji.module.biz.mapper;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lideeyunji.core.framework.entity.erp.ScmgiplanQrEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
@DS("erp_dev")
public interface QrOutboundApplicationMapper extends BaseMapper<ScmgiplanQrEntity> {
}

View File

@@ -0,0 +1,16 @@
package com.lideeyunji.module.biz.service;
import com.lideeyunji.core.framework.entity.erp.ScmgiplanEntity;
import com.lideeyunji.core.framework.entity.erp.ScmgiplanQrEntity;
import java.util.List;
public interface QrOutboundApplicationService {
List<ScmgiplanQrEntity> selectList(ScmgiplanEntity scmgiplanEntity);
ScmgiplanEntity selectByCode(ScmgiplanEntity scmgiplanEntity);
ScmgiplanQrEntity getQrCode(String id);
List<ScmgiplanQrEntity> selectBatchByIds(List<String> idList);
}

View File

@@ -0,0 +1,157 @@
package com.lideeyunji.module.biz.service.impl;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lideeyunji.core.framework.entity.erp.ScmGiPlanItemEntity;
import com.lideeyunji.core.framework.entity.erp.ScmgiplanEntity;
import com.lideeyunji.core.framework.entity.erp.ScmgiplanQrEntity;
import com.lideeyunji.core.framework.mapper.erp.ScmgiPlanItemMapper;
import com.lideeyunji.core.framework.mapper.erp.ScmgiPlanMapper;
import com.lideeyunji.module.biz.mapper.QrOutboundApplicationMapper;
import com.lideeyunji.module.biz.service.QrOutboundApplicationService;
import com.lideeyunji.tool.framework.sql.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@Service
@Slf4j
public class QrQrOutboundApplicationServiceImpl extends ServiceImpl<QrOutboundApplicationMapper, ScmgiplanQrEntity> implements QrOutboundApplicationService {
@Resource
private ScmgiPlanMapper scmgiPlanMapper;
@Resource
private ScmgiPlanItemMapper scmgiPlanItemMapper;
@Override
public List<ScmgiplanQrEntity> selectList(ScmgiplanEntity scmgiplanEntity) {
LambdaQueryWrapper<ScmgiplanQrEntity> queryWrapper = new LambdaQueryWrapper<ScmgiplanQrEntity>();
if (StringUtils.isNotBlank(scmgiplanEntity.getPlanCode())) {
queryWrapper.eq(ScmgiplanQrEntity::getPlanCode, scmgiplanEntity.getPlanCode());
}
if (StringUtils.isNotBlank(scmgiplanEntity.getPlanStatus())) {
queryWrapper.eq(ScmgiplanQrEntity::getPlanStatus, scmgiplanEntity.getPlanStatus());
}
return baseMapper.selectList(queryWrapper);
}
@Override
public ScmgiplanEntity selectByCode(ScmgiplanEntity scmgiplanEntity) {
if (scmgiplanEntity == null || StringUtils.isBlank(scmgiplanEntity.getPlanCode())) {
return null;
}
ScmgiplanEntity dbEntity = scmgiPlanMapper.selectOne(new LambdaQueryWrapper<ScmgiplanEntity>()
.eq(ScmgiplanEntity::getPlanCode, scmgiplanEntity.getPlanCode())
.eq(ScmgiplanEntity::getIsStop, "0"));
if (dbEntity == null) {
return null;
}
cn.hutool.core.bean.BeanUtil.copyProperties(scmgiplanEntity, dbEntity,
CopyOptions.create()
.setIgnoreNullValue(true)
.setIgnoreError(true)
.setIgnoreProperties("id"));
scmgiPlanMapper.updateById(dbEntity);
if (CollectionUtils.isNotEmpty(scmgiplanEntity.getScmGiPlanItemEntities())) {
List<ScmGiPlanItemEntity> inputItems = scmgiplanEntity.getScmGiPlanItemEntities();
List<String> inputMaterialCodes = inputItems.stream()
.map(ScmGiPlanItemEntity::getMaterialCode)
.filter(StringUtils::isNotBlank)
.distinct()
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(inputMaterialCodes)) {
return dbEntity;
}
List<ScmGiPlanItemEntity> dbItems = scmgiPlanItemMapper.selectList(
new LambdaQueryWrapper<ScmGiPlanItemEntity>()
.eq(ScmGiPlanItemEntity::getPlanId, dbEntity.getId())
.in(ScmGiPlanItemEntity::getMaterialCode, inputMaterialCodes));
java.util.Map<String, ScmGiPlanItemEntity> dbItemMap = dbItems.stream()
.collect(Collectors.toMap(ScmGiPlanItemEntity::getMaterialCode, item -> item, (k1, k2) -> k1));
List<ScmGiPlanItemEntity> toInsert = new java.util.ArrayList<>();
List<ScmGiPlanItemEntity> toUpdate = new java.util.ArrayList<>();
for (ScmGiPlanItemEntity inputItem : inputItems) {
if (StringUtils.isBlank(inputItem.getMaterialCode())) {
continue;
}
ScmGiPlanItemEntity dbItem = dbItemMap.get(inputItem.getMaterialCode());
if (dbItem == null) {
ScmGiPlanItemEntity newItem = new ScmGiPlanItemEntity();
cn.hutool.core.bean.BeanUtil.copyProperties(inputItem, newItem,
CopyOptions.create()
.setIgnoreProperties("id"));
newItem.setId(UUID.randomUUID().toString());
newItem.setPlanId(dbEntity.getId());
toInsert.add(newItem);
} else {
cn.hutool.core.bean.BeanUtil.copyProperties(inputItem, dbItem,
CopyOptions.create()
.setIgnoreNullValue(true)
.setIgnoreError(true)
.setIgnoreProperties("id"));
toUpdate.add(dbItem);
}
}
List<ScmGiPlanItemEntity> toDelete = dbItems.stream()
.filter(dbItem -> !inputMaterialCodes.contains(dbItem.getMaterialCode()))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(toInsert)) {
toInsert.forEach(item -> scmgiPlanItemMapper.insert(item));
}
if (CollectionUtils.isNotEmpty(toUpdate)) {
toUpdate.forEach(item -> scmgiPlanItemMapper.updateById(item));
}
// if (CollectionUtils.isNotEmpty(toDelete)) {
// List<String> deleteIds = toDelete.stream()
// .map(ScmGiPlanItemEntity::getId)
// .collect(Collectors.toList());
// scmgiPlanItemMapper.deleteBatchIds(deleteIds);
// }
dbEntity.setScmGiPlanItemEntities(inputItems);
}
return dbEntity;
}
@Override
public ScmgiplanQrEntity getQrCode(String id) {
ScmgiplanQrEntity scmgiplanQrEntity = baseMapper.selectOne(new LambdaQueryWrapper<ScmgiplanQrEntity>()
.eq(ScmgiplanQrEntity::getPlanId, id)
);
return scmgiplanQrEntity;
}
@Override
public List<ScmgiplanQrEntity> selectBatchByIds(List<String> idList) {
if (idList == null || idList.isEmpty()) {
return Collections.emptyList();
}
return baseMapper.selectList(new LambdaQueryWrapper<ScmgiplanQrEntity>().in(ScmgiplanQrEntity::getPlanId, idList));
}
}