Merge branch 'develop' into qms/develop
This commit is contained in:
commit
e95e500e3c
|
|
@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
|||
import com.nflg.wms.admin.pojo.dto.*;
|
||||
import com.nflg.wms.admin.pojo.request.UnqualifiedWarehousingRequest;
|
||||
import com.nflg.wms.admin.service.NormalQMControllerService;
|
||||
import com.nflg.wms.admin.service.SapService;
|
||||
import com.nflg.wms.common.constant.BarCodeProcessStage;
|
||||
import com.nflg.wms.common.pojo.ApiResult;
|
||||
import com.nflg.wms.common.pojo.PageData;
|
||||
|
|
@ -74,8 +75,11 @@ public class NormalQMController extends BaseController {
|
|||
@Resource
|
||||
private IWmsQrCodeMasterService qrCodeMasterService;
|
||||
|
||||
private SapService sapService;
|
||||
|
||||
/**
|
||||
* 获取SRM推送过来的质检单信息
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -87,6 +91,7 @@ public class NormalQMController extends BaseController {
|
|||
|
||||
/**
|
||||
* 导出质检单
|
||||
*
|
||||
* @param request 查询条件
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -100,6 +105,7 @@ public class NormalQMController extends BaseController {
|
|||
|
||||
/**
|
||||
* 质检物料上架任务(PDA)
|
||||
*
|
||||
* @param orderNo 送货单号或任务单号
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -112,6 +118,7 @@ public class NormalQMController extends BaseController {
|
|||
|
||||
/**
|
||||
* 质检物料上架物料详情
|
||||
*
|
||||
* @param taskId 任务ID
|
||||
**/
|
||||
@GetMapping("PDA/task/item")
|
||||
|
|
@ -123,6 +130,7 @@ public class NormalQMController extends BaseController {
|
|||
|
||||
/**
|
||||
* 质检物料上架任务确认
|
||||
*
|
||||
* @param request
|
||||
**/
|
||||
@Transactional
|
||||
|
|
@ -368,6 +376,7 @@ public class NormalQMController extends BaseController {
|
|||
|
||||
/**
|
||||
* 无码质检任务上架确认
|
||||
*
|
||||
* @param request 任务ID
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -478,7 +487,16 @@ public class NormalQMController extends BaseController {
|
|||
WmsSrmQualityInspection inspection = wmsSrmQualityInspectionService.getById(request.getId());
|
||||
VUtil.trueThrowBusinessError(Objects.isNull(inspection)).throwMessage("无效的质检单");
|
||||
VUtil.trueThrowBusinessError(!inspection.getInspectionResult().equals("不合格")).throwMessage("该质检单不是不合格单");
|
||||
VUtil.trueThrowBusinessError(inspection.getReceiveQty().compareTo(BigDecimal.ZERO) > 0).throwMessage("该质检单已生成上架任务");
|
||||
VUtil.trueThrowBusinessError(inspection.getReceiveQty().compareTo(BigDecimal.ZERO) > 0).throwMessage("该质检单已完成冲销");
|
||||
List<ZWM3A27ItemDTO> itemDTOs = new ArrayList<>();
|
||||
ZWM3A27ItemDTO itemDTO = new ZWM3A27ItemDTO()
|
||||
.setEbeln(inspection.getPoNum())
|
||||
.setEbeln(inspection.getPoNum()).
|
||||
setEbelp(Integer.valueOf(inspection.getPoLineNumber())).
|
||||
setMenge(inspection.getDeliveryQty()).setMatDoc(inspection.getMaterialDoc105())
|
||||
.setDocYear(inspection.getMaterialDocYear105());
|
||||
itemDTOs.add(itemDTO);
|
||||
sapService.zwm3a27(inspection.getMaterialDoc105(), inspection.getMaterialDocYear105(), itemDTOs);
|
||||
inspection.setReceiveQty(request.getReceiveQty());
|
||||
wmsSrmQualityInspectionService.updateById(inspection);
|
||||
return ApiResult.success();
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@ import java.util.zip.ZipOutputStream;
|
|||
|
||||
/**
|
||||
* 装箱管理
|
||||
*
|
||||
* @author: nflg
|
||||
* @date: 2022/3/17
|
||||
* @description:
|
||||
|
|
@ -86,7 +85,6 @@ public class QrCodeMasterController extends BaseController {
|
|||
|
||||
/**
|
||||
* 获取包装箱和箱内物料信息
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -126,7 +124,6 @@ public class QrCodeMasterController extends BaseController {
|
|||
|
||||
/**
|
||||
* 包装箱编码获取包装箱和箱内物料信息
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -161,7 +158,6 @@ public class QrCodeMasterController extends BaseController {
|
|||
|
||||
/**
|
||||
* 箱码Validation
|
||||
*
|
||||
* @param qrCodeMaster
|
||||
* @param smallQrCodeMasters
|
||||
*/
|
||||
|
|
@ -209,7 +205,6 @@ public class QrCodeMasterController extends BaseController {
|
|||
|
||||
/**
|
||||
* 装箱绑码
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -265,7 +260,6 @@ public class QrCodeMasterController extends BaseController {
|
|||
|
||||
/**
|
||||
* 拆箱删除
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -294,7 +288,6 @@ public class QrCodeMasterController extends BaseController {
|
|||
/**
|
||||
* 换箱
|
||||
* 针对库存地点内的物料箱合并,修改物料的箱属性和库存
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -402,7 +395,6 @@ public class QrCodeMasterController extends BaseController {
|
|||
|
||||
/**
|
||||
* 物料出入库统一扫码接口
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
* @author
|
||||
|
|
@ -437,7 +429,6 @@ public class QrCodeMasterController extends BaseController {
|
|||
|
||||
/**
|
||||
* 换箱扫码接口
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
* @author
|
||||
|
|
@ -469,11 +460,12 @@ public class QrCodeMasterController extends BaseController {
|
|||
|
||||
/**
|
||||
* 导出标签图片为ZIP
|
||||
*
|
||||
* @param datas 二维码列表
|
||||
*/
|
||||
@PostMapping(value = "exportToZip", produces = "application/zip")
|
||||
public ResponseEntity<byte[]> exportToZip(@Valid @RequestBody @NotEmpty List<QrCodeItemVO> datas) throws Exception {
|
||||
VUtil.trueThrowBusinessError(datas.stream().map(QrCodeItemVO::getPackagingType).collect(Collectors.toSet()).size() > 1)
|
||||
.throwMessage("只能选择一种包装类型");
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
|
||||
for (QrCodeItemVO it : datas) {
|
||||
|
|
@ -482,7 +474,8 @@ public class QrCodeMasterController extends BaseController {
|
|||
dto.setQrCode(QRCodeUtil.generateQRCodeBase64(generateQRContent(dto), 100, 100));
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
variables.put("list", List.of(dto));
|
||||
String html = ThymeleafUtil.generator("/template/qrcode/", "dp-1-label", ".html", variables);
|
||||
String html = ThymeleafUtil.generator("/template/qrcode/"
|
||||
, datas.get(0).getPackagingType() == 0 ? "dp-1-label" : "medium-box-label", ".html", variables);
|
||||
ZipEntry entry = new ZipEntry(it.getBarcodeCode() + ".png");
|
||||
zos.putNextEntry(entry);
|
||||
byte[] imageBytes = HtmlToImageUtil.convertToPng(html, 600);
|
||||
|
|
@ -499,11 +492,12 @@ public class QrCodeMasterController extends BaseController {
|
|||
|
||||
/**
|
||||
* 导出标签图片为PDF
|
||||
*
|
||||
* @param datas 二维码列表
|
||||
*/
|
||||
@PostMapping("exportToPdf")
|
||||
public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<QrCodeItemVO> datas) throws Exception {
|
||||
VUtil.trueThrowBusinessError(datas.stream().map(QrCodeItemVO::getPackagingType).collect(Collectors.toSet()).size() > 1)
|
||||
.throwMessage("只能选择一种包装类型");
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
variables.put("list", datas.stream().map(data ->
|
||||
{
|
||||
|
|
@ -512,7 +506,8 @@ public class QrCodeMasterController extends BaseController {
|
|||
dto.setQrCode(QRCodeUtil.generateQRCodeBase64(generateQRContent(dto), 100, 100));
|
||||
return dto;
|
||||
}).toList());
|
||||
String html = ThymeleafUtil.generator("/template/qrcode/", "dp-1", ".html", variables);
|
||||
String html = ThymeleafUtil.generator("/template/qrcode/"
|
||||
, datas.get(0).getPackagingType() == 0 ? "dp-1" : "medium-box", ".html", variables);
|
||||
URL baseUrl = new ClassPathResource("template/qrcode/").getURL();
|
||||
PdfGeneratorUtil.generatePdf("箱码标签图片", html, baseUrl.toString(), response);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.nflg.wms.admin.pojo.dto.QCMaterialSyncDTO;
|
|||
import com.nflg.wms.admin.pojo.dto.ZWM3A17DTO;
|
||||
import com.nflg.wms.admin.repository.SrmMaterialReceiptNoScanCodesRepository;
|
||||
import com.nflg.wms.admin.repository.SrmMaterialReceiptScanCodesRepository;
|
||||
import com.nflg.wms.common.constant.BarCodeProcessStage;
|
||||
import com.nflg.wms.common.pojo.document.SrmMaterialReceiptNoScanCodes;
|
||||
import com.nflg.wms.common.pojo.document.SrmMaterialReceiptScanCodes;
|
||||
import com.nflg.wms.common.pojo.dto.*;
|
||||
|
|
@ -619,37 +620,30 @@ public class NormalPGIControllerService {
|
|||
}
|
||||
}
|
||||
|
||||
//编码管理
|
||||
// if (CollectionUtil.isNotEmpty(dto.getQrCodes())) {
|
||||
// //同步箱码信息到物料码中
|
||||
// List<WmsQrCodeMaster> parents = dto.getQrCodes()
|
||||
// .stream()
|
||||
// .filter(qrCode -> qrCode.getPackagingType() == 1)
|
||||
// .toList();
|
||||
// if (CollectionUtil.isNotEmpty(parents)) {
|
||||
// List<WmsQrCodeMaster> children = qrCodeMasterService.lambdaQuery()
|
||||
// .in(WmsQrCodeMaster::getParentBarcodeId, parents
|
||||
// .stream()
|
||||
// .map(WmsQrCodeMaster::getId)
|
||||
// .toList()
|
||||
// )
|
||||
// .list();
|
||||
// parents.forEach(p -> {
|
||||
// children.stream()
|
||||
// .filter(c -> c.getParentBarcodeId().equals(p.getId()))
|
||||
// .forEach(c -> {
|
||||
// c.setProcessStage(p.getProcessStage());
|
||||
// c.setLastScanBy(UserUtil.getUserId());
|
||||
// c.setLastScanByname(UserUtil.getUserName());
|
||||
// c.setLastScanTime(LocalDateTime.now());
|
||||
// c.setFactoryCode(p.getFactoryCode());
|
||||
// c.setStorageLocation(p.getStorageLocation());
|
||||
// c.setBinLocation(p.getBinLocation());
|
||||
// c.setReceiptItemId(p.getReceiptItemId());
|
||||
// });
|
||||
// });
|
||||
// dto.getQrCodes().addAll(children);
|
||||
// }
|
||||
// 这里需要同步一个信息,就是把箱码的状态也要改为收货状态,
|
||||
List<Long> parentIds = dto.getQrCodes().stream()
|
||||
.filter(qrCode -> qrCode.getPackagingType() == 0)
|
||||
.map(WmsQrCodeMaster::getParentBarcodeId)
|
||||
.distinct()
|
||||
.toList();
|
||||
if (CollectionUtil.isNotEmpty(parentIds)) {
|
||||
// 获取所有的父级物料信息
|
||||
List<WmsQrCodeMaster> parents2 = qrCodeMasterService.lambdaQuery()
|
||||
.in(WmsQrCodeMaster::getId, parentIds)
|
||||
.list();
|
||||
for (WmsQrCodeMaster parent : parents2) {
|
||||
boolean exists = dto.getQrCodes().stream().anyMatch(qrCode ->
|
||||
qrCode.getBarcodeCode().equals(parent.getBarcodeCode()));
|
||||
if (!exists) {
|
||||
parent.setProcessStage(BarCodeProcessStage.Received.getState());
|
||||
parent.setLastScanBy(UserUtil.getUserId());
|
||||
parent.setLastScanByname(UserUtil.getUserName());
|
||||
parent.setLastScanTime(LocalDateTime.now());
|
||||
dto.getQrCodes().add(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qrCodeMasterService.updateBarCode(dto.getQrCodes());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,64 @@
|
|||
package com.nflg.wms.common.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 物料码打印DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class MaterialCodePrintDTO {
|
||||
|
||||
/**
|
||||
* 二维码(Base64)
|
||||
*/
|
||||
private String qrCode;
|
||||
|
||||
/**
|
||||
* 唯一码
|
||||
*/
|
||||
private String no;
|
||||
|
||||
/**
|
||||
* 物料编号
|
||||
*/
|
||||
private String materialNo;
|
||||
|
||||
/**
|
||||
* 物料描述
|
||||
*/
|
||||
private String materialDescribe;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
private BigDecimal num;
|
||||
|
||||
/**
|
||||
* 数量文本
|
||||
*/
|
||||
private String numText;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 机台编号
|
||||
*/
|
||||
private String deviceNo;
|
||||
|
||||
/**
|
||||
* 客户名称
|
||||
*/
|
||||
private String customerName;
|
||||
|
||||
/**
|
||||
* 图片(Base64)
|
||||
*/
|
||||
private String lst;
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package com.nflg.wms.common.pojo.vo;
|
||||
|
||||
import com.nflg.wms.common.util.NumberUtil;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 物料明细打印预览VO
|
||||
*/
|
||||
@Data
|
||||
public class MaterialItemPrintVO {
|
||||
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 物料编号
|
||||
*/
|
||||
private String materialNo;
|
||||
|
||||
/**
|
||||
* 物料描述
|
||||
*/
|
||||
private String materialDescribe;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
private BigDecimal num;
|
||||
|
||||
/**
|
||||
* 数量文本
|
||||
*/
|
||||
private String numText;
|
||||
|
||||
public String getNumText() {
|
||||
return NumberUtil.format(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实发数量
|
||||
*/
|
||||
private BigDecimal actualNum;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 项目类型
|
||||
*/
|
||||
private String projectType;
|
||||
|
||||
/**
|
||||
* 生产订单号
|
||||
*/
|
||||
private String productionOrderNumber;
|
||||
|
||||
/**
|
||||
* 箱号
|
||||
*/
|
||||
private String boxNo;
|
||||
|
||||
/**
|
||||
* 机台编号
|
||||
*/
|
||||
private String deviceNo;
|
||||
|
||||
/**
|
||||
* 客户名称
|
||||
*/
|
||||
private String customerName;
|
||||
|
||||
/**
|
||||
* 二维码(Base64)
|
||||
*/
|
||||
private String qrCode;
|
||||
|
||||
/**
|
||||
* 图片(Base64)
|
||||
*/
|
||||
private String image;
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.nflg.wms.repository.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.nflg.wms.common.pojo.vo.MaterialItemPrintVO;
|
||||
import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeItemVO;
|
||||
import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItem;
|
||||
|
||||
|
|
@ -20,4 +21,8 @@ public interface WmsShipmentMaterialCodeItemMapper extends BaseMapper<WmsShipmen
|
|||
List<ShipmentMaterialCodeItemVO> getByCodeId(Long codeId);
|
||||
|
||||
void updatePackingNum(Set<Long> ids);
|
||||
|
||||
List<MaterialItemPrintVO> getListByMaterialNos(Set<String> materialNos);
|
||||
|
||||
List<MaterialItemPrintVO> getListByItemIds(List<Long> ids);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeQRVO;
|
|||
import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItemQr;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
|
@ -21,4 +22,6 @@ public interface WmsShipmentMaterialCodeItemQrMapper extends BaseMapper<WmsShipm
|
|||
List<ShipmentMaterialCodeQRVO> getListVOByItemIds(List<Long> ids);
|
||||
|
||||
List<ShipmentMaterialCodeQRVO> getListVOByCodeIds(List<Long> ids);
|
||||
|
||||
List<ShipmentMaterialCodeQRVO> getListVOByMaterialNos(Set<String> materialNos);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||
import jakarta.validation.constraints.NotEmpty;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
|
@ -22,4 +23,6 @@ public interface IWmsShipmentMaterialCodeItemQrService extends IService<WmsShipm
|
|||
List<ShipmentMaterialCodeQRVO> getListVOByItemIds(List<Long> ids);
|
||||
|
||||
List<ShipmentMaterialCodeQRVO> getListVOByCodeIds(List<Long> ids);
|
||||
|
||||
List<ShipmentMaterialCodeQRVO> getListVOByMaterialNos(Set<String> materialNos);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.nflg.wms.repository.service;
|
||||
|
||||
import com.nflg.wms.common.pojo.vo.MaterialItemPrintVO;
|
||||
import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeItemVO;
|
||||
import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItem;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
|
@ -20,4 +21,8 @@ public interface IWmsShipmentMaterialCodeItemService extends IService<WmsShipmen
|
|||
List<ShipmentMaterialCodeItemVO> getByCodeId(Long codeId);
|
||||
|
||||
void updatePackingNum(Set<Long> ids);
|
||||
|
||||
List<MaterialItemPrintVO> getListByMaterialNos(Set<String> materialNos);
|
||||
|
||||
List<MaterialItemPrintVO> getListByItemIds(List<Long> ids);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
|
@ -34,4 +35,9 @@ public class WmsShipmentMaterialCodeItemQrServiceImpl extends ServiceImpl<WmsShi
|
|||
public List<ShipmentMaterialCodeQRVO> getListVOByCodeIds(List<Long> ids) {
|
||||
return baseMapper.getListVOByCodeIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ShipmentMaterialCodeQRVO> getListVOByMaterialNos(Set<String> materialNos) {
|
||||
return baseMapper.getListVOByMaterialNos(materialNos);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.nflg.wms.repository.service.impl;
|
||||
|
||||
import com.nflg.wms.common.pojo.vo.MaterialItemPrintVO;
|
||||
import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeItemVO;
|
||||
import com.nflg.wms.repository.entity.WmsShipmentMaterialCodeItem;
|
||||
import com.nflg.wms.repository.mapper.WmsShipmentMaterialCodeItemMapper;
|
||||
|
|
@ -30,4 +31,14 @@ public class WmsShipmentMaterialCodeItemServiceImpl extends ServiceImpl<WmsShipm
|
|||
public void updatePackingNum(Set<Long> ids) {
|
||||
baseMapper.updatePackingNum(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MaterialItemPrintVO> getListByMaterialNos(Set<String> materialNos) {
|
||||
return baseMapper.getListByMaterialNos(materialNos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MaterialItemPrintVO> getListByItemIds(List<Long> ids) {
|
||||
return baseMapper.getListByItemIds(ids);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,4 +25,28 @@
|
|||
#{id}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<select id="getListByMaterialNos" resultType="com.nflg.wms.common.pojo.vo.MaterialItemPrintVO">
|
||||
SELECT it.id, it.material_no, it.material_describe, it.num, it.actual_num, it.unit,
|
||||
it.project_type, it.production_order_number, it.box_no,
|
||||
mc.device_no, mc.customer_name
|
||||
FROM wms_shipment_material_code_item it
|
||||
INNER JOIN wms_shipment_material_code mc ON mc."id" = it.material_code_id
|
||||
WHERE it.material_no IN
|
||||
<foreach item="item" collection="materialNos" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<select id="getListByItemIds" resultType="com.nflg.wms.common.pojo.vo.MaterialItemPrintVO">
|
||||
SELECT it.id, it.material_no, it.material_describe, it.num, it.actual_num, it.unit,
|
||||
it.project_type, it.production_order_number, it.box_no,
|
||||
mc.device_no, mc.customer_name
|
||||
FROM wms_shipment_material_code_item it
|
||||
INNER JOIN wms_shipment_material_code mc ON mc."id" = it.material_code_id
|
||||
WHERE it.id IN
|
||||
<foreach item="item" collection="ids" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -31,4 +31,15 @@
|
|||
#{item}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<select id="getListVOByMaterialNos" resultType="com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeQRVO">
|
||||
SELECT qr.id,qr.no,it.material_no,it.material_describe,qr.num,it.unit,qr.status,mc.device_no,mc.customer_name
|
||||
FROM wms_shipment_material_code_item_qr qr
|
||||
INNER JOIN wms_shipment_material_code_item it ON qr.item_id=it."id"
|
||||
INNER JOIN wms_shipment_material_code mc ON mc."id"=it.material_code_id
|
||||
where it.material_no in
|
||||
<foreach item="item" collection="materialNos" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.nflg.wms.common.pojo.ApiResult;
|
||||
import com.nflg.wms.common.pojo.PageData;
|
||||
import com.nflg.wms.common.pojo.dto.MaterialCodePrintDTO;
|
||||
import com.nflg.wms.common.pojo.dto.MaterialPdfDTO;
|
||||
import com.nflg.wms.common.pojo.qo.*;
|
||||
import com.nflg.wms.common.pojo.vo.MaterialPdfVO;
|
||||
import com.nflg.wms.common.pojo.vo.MaterialItemPrintVO;
|
||||
import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeQRVO;
|
||||
import com.nflg.wms.common.pojo.vo.ShipmentMaterialCodeItemVO;
|
||||
import com.nflg.wms.common.util.EecExcelUtil;
|
||||
|
|
@ -51,6 +53,7 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLEncoder;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
|
@ -819,4 +822,92 @@ public class MaterialCodeController extends BaseController {
|
|||
InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
|
||||
return ApiResult.success(fileUploadService.upload("tmp/sp/" + RandomUtil.randomString(10) + "/" + material.getNo() + "老鼠图.pdf", inputStream, MediaType.APPLICATION_PDF_VALUE));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出标签图片PDF(打印预览)
|
||||
*
|
||||
* @param response HTTP响应
|
||||
* @param ids 物料主数据id列表(wms_shipment_material.id)
|
||||
*/
|
||||
@PostMapping("exportToPdf")
|
||||
public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<Long> ids) throws Exception {
|
||||
// 根据清单ID查询二维码数据
|
||||
List<ShipmentMaterialCodeQRVO> datas = materialCodeItemQrService.getListVOByCodeIds(ids);
|
||||
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(datas)).throwMessage("物料数据不存在");
|
||||
|
||||
// 取第一条数据
|
||||
ShipmentMaterialCodeQRVO data = datas.get(0);
|
||||
|
||||
// 根据物料编号查询物料图片
|
||||
Map<String, String> images = materialService.lambdaQuery()
|
||||
.select(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage)
|
||||
.in(WmsShipmentMaterial::getNo, datas.stream().map(ShipmentMaterialCodeQRVO::getMaterialNo).collect(Collectors.toSet()))
|
||||
.list()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage));
|
||||
|
||||
// 构建打印数据
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
|
||||
Map<String, Object> info = new HashMap<>();
|
||||
info.put("no", data.getNo());
|
||||
info.put("materialNo", data.getMaterialNo());
|
||||
info.put("numText", data.getNumText());
|
||||
info.put("customerName", data.getCustomerName());
|
||||
|
||||
Map<String, String> ext = new HashMap<>();
|
||||
ext.put("qrCode", QRCodeUtil.generateQRCodeBase64(data.getNo(), 200, 200));
|
||||
ext.put("lst", images.get(data.getMaterialNo()));
|
||||
|
||||
variables.put("info", info);
|
||||
variables.put("ext", ext);
|
||||
|
||||
String html = ThymeleafUtil.generator("/template/label/", "material-pdf", ".html", variables);
|
||||
URL baseUrl = new ClassPathResource("template/label/").getURL();
|
||||
PdfGeneratorUtil.generatePdf("物料码标签", html, baseUrl.toString(), response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据明细ID导出物料明细PDF(打印预览)
|
||||
*
|
||||
* @param response HTTP响应
|
||||
* @param ids 明细id列表(wms_shipment_material_code_item.id)
|
||||
*/
|
||||
@PostMapping("exportItemToPdf")
|
||||
public void exportItemToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<Long> ids) throws Exception {
|
||||
// 根据明细ID查询数据
|
||||
List<ShipmentMaterialCodeQRVO> datas = materialCodeItemQrService.getListVOByItemIds(ids);
|
||||
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(datas)).throwMessage("没有需要导出的数据");
|
||||
|
||||
// 取第一条数据
|
||||
ShipmentMaterialCodeQRVO data = datas.get(0);
|
||||
|
||||
// 根据物料编号查询物料图片
|
||||
Map<String, String> images = materialService.lambdaQuery()
|
||||
.select(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage)
|
||||
.in(WmsShipmentMaterial::getNo, datas.stream().map(ShipmentMaterialCodeQRVO::getMaterialNo).collect(Collectors.toSet()))
|
||||
.list()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage));
|
||||
|
||||
// 构建打印数据
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
|
||||
Map<String, Object> info = new HashMap<>();
|
||||
info.put("no", data.getNo());
|
||||
info.put("materialNo", data.getMaterialNo());
|
||||
info.put("numText", data.getNumText());
|
||||
info.put("customerName", data.getCustomerName());
|
||||
|
||||
Map<String, String> ext = new HashMap<>();
|
||||
ext.put("qrCode", QRCodeUtil.generateQRCodeBase64(data.getNo(), 200, 200));
|
||||
ext.put("lst", images.get(data.getMaterialNo()));
|
||||
|
||||
variables.put("info", info);
|
||||
variables.put("ext", ext);
|
||||
|
||||
String html = ThymeleafUtil.generator("/template/label/", "material-pdf", ".html", variables);
|
||||
URL baseUrl = new ClassPathResource("template/label/").getURL();
|
||||
PdfGeneratorUtil.generatePdf("物料明细标签", html, baseUrl.toString(), response);
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@ import com.nflg.wms.repository.service.*;
|
|||
import com.nflg.wms.shipment.service.BasdeSerialNumberControllerService;
|
||||
import com.nflg.wms.shipment.util.HtmlToImageUtil;
|
||||
import com.nflg.wms.shipment.util.KeyUtil;
|
||||
import com.nflg.wms.shipment.util.PdfGeneratorUtil;
|
||||
import com.nflg.wms.shipment.util.QRCodeUtil;
|
||||
import com.nflg.wms.shipment.util.ThymeleafUtil;
|
||||
import com.nflg.wms.starter.BaseController;
|
||||
|
|
@ -34,10 +35,12 @@ import org.springframework.http.HttpHeaders;
|
|||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.net.URL;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -406,4 +409,33 @@ public class PackagingCodeController extends BaseController {
|
|||
headers.setContentLength(zipBytes.length);
|
||||
return new ResponseEntity<>(zipBytes, headers, HttpStatus.OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出标签图片PDF(打印预览)
|
||||
*/
|
||||
@PostMapping("exportToPdf")
|
||||
public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<ShipmentPackagingCodeVO> list) throws Exception {
|
||||
List<DictionaryItem> types = dictionaryItemService.getListByDictionaryCode("PackagingType");
|
||||
|
||||
// 构建打印数据
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
variables.put("list", list.stream()
|
||||
.map(data -> {
|
||||
ShipmentPackagingCodeVO vo = new ShipmentPackagingCodeVO();
|
||||
vo.setNo(data.getNo());
|
||||
vo.setName(data.getName());
|
||||
vo.setTypeName(types.stream()
|
||||
.filter(type -> type.getId().equals(data.getType()))
|
||||
.map(DictionaryItem::getName)
|
||||
.findFirst()
|
||||
.orElse(""));
|
||||
vo.setQrCode(QRCodeUtil.generateQRCodeBase64(data.getNo(), 100, 100));
|
||||
return vo;
|
||||
}).toList()
|
||||
);
|
||||
|
||||
String html = ThymeleafUtil.generator("/template/label/", "packaging-pdf", ".html", variables);
|
||||
URL baseUrl = new ClassPathResource("template/label/").getURL();
|
||||
PdfGeneratorUtil.generatePdf("包装码标签", html, baseUrl.toString(), response);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>包装码</title>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<style>
|
||||
@page {
|
||||
size: 1200px 800px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 1200px;
|
||||
height: 800px;
|
||||
font-size: 20pt;
|
||||
font-family: SimSun, Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 1200px;
|
||||
height: 800px;
|
||||
border: 3px solid #000;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 3px solid #000;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
width: 380px;
|
||||
height: 380px;
|
||||
}
|
||||
.lst{
|
||||
width: 800px;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<tr>
|
||||
<td style="text-align: center; width: 400px" rowspan="3">
|
||||
<img alt="" class="qrcode" th:src="${ext.qrCode}"/>
|
||||
<div style="font-size: 16pt" th:text="${info.no}">0PC7B724KV6FM</div>
|
||||
</td>
|
||||
<td style="width: 140px;">
|
||||
机台编号
|
||||
</td>
|
||||
<td style="width: 200px;" th:text="${info.no}">
|
||||
26LBZ4000L001
|
||||
</td>
|
||||
<td style="width: 140px;">
|
||||
客户名称
|
||||
</td>
|
||||
<td style="text-align: left" th:text="${info.customerName}">
|
||||
北京市京联鑫路用材料有限公司
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
物料编码
|
||||
</td>
|
||||
<td th:text="${info.materialNo}">
|
||||
3100006701
|
||||
</td>
|
||||
<td>
|
||||
数量
|
||||
</td>
|
||||
<td th:text="${info.numText}">
|
||||
10
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<img style="width: 750px;" alt="" src="https://img-s.msn.cn/tenant/amp/entityid/AA1VWN3Q.img?w=768&h=333&m=6" class="lst" th:src="${ext.lst}"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>包装码标签-A4打印版</title>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<style>
|
||||
@page {
|
||||
size: A4 portrait;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 10pt;
|
||||
font-family: SimSun, Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.label-page {
|
||||
width: 210mm;
|
||||
height: 297mm;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
page-break-after: always;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.label-page:last-child {
|
||||
page-break-after: auto;
|
||||
}
|
||||
|
||||
.label-content {
|
||||
width: 600px;
|
||||
height: 400px;
|
||||
transform-origin: center center;
|
||||
transform: scale(calc(210mm / 600px));
|
||||
}
|
||||
|
||||
table {
|
||||
width: 600px;
|
||||
height: 400px;
|
||||
border: 3px solid #000;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 3px solid #000;
|
||||
}
|
||||
|
||||
.div-with-border {
|
||||
border-bottom: 3px solid #000;
|
||||
padding: 18px;
|
||||
text-align: left;
|
||||
width: 320px;
|
||||
display: block;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
width: 260px;
|
||||
height: 260px;
|
||||
margin: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="label-page" th:each="item, iterStat : ${list}">
|
||||
<div class="label-content">
|
||||
<table>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<img alt="" class="qrcode" th:src="${item.qrCode}"/>
|
||||
<div style="font-size: 16pt" th:text="${item.no}">NFLG-QZ-002</div>
|
||||
</td>
|
||||
<td style="text-align: left;vertical-align: top">
|
||||
<div class="div-with-border">包装名称: <span th:text="${item.name}">NFLG-QZ-002 测试包装名称</span></div>
|
||||
<div class="div-with-border">包装类型: <span th:text="${item.typeName}">托盘</span></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,210 @@
|
|||
package com.nflg.wms.shipment;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.nflg.wms.repository.entity.WmsShipmentMaterial;
|
||||
import com.nflg.wms.repository.mapper.WmsShipmentMaterialMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 物料图片批量上传测试
|
||||
* 从桌面的Output文件夹读取所有图片并上传,然后更新物料表的image字段
|
||||
*/
|
||||
@Slf4j
|
||||
@SpringBootTest
|
||||
@ContextConfiguration(classes = ShipmentApplication.class)
|
||||
public class MaterialImageUploadTest {
|
||||
|
||||
@Resource
|
||||
private WmsShipmentMaterialMapper materialMapper;
|
||||
|
||||
@Resource
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
// 文件上传接口地址
|
||||
private static final String UPLOAD_URL = "https://pomp.nflg.net/api/admin/file/uploadSingleFile1";
|
||||
|
||||
@Test
|
||||
public void testUploadImagesFromZip() {
|
||||
// 桌面路径
|
||||
String desktopPath = System.getProperty("user.home") + File.separator + "Desktop";
|
||||
String outputDirPath = desktopPath + File.separator + "Output";
|
||||
|
||||
log.info("开始处理Output文件夹: {}", outputDirPath);
|
||||
|
||||
// 检查文件夹是否存在
|
||||
File outputDir = new File(outputDirPath);
|
||||
if (!outputDir.exists()) {
|
||||
log.error("Output文件夹不存在: {}", outputDirPath);
|
||||
throw new RuntimeException("Output文件夹不存在: " + outputDirPath);
|
||||
}
|
||||
|
||||
if (!outputDir.isDirectory()) {
|
||||
log.error("路径不是文件夹: {}", outputDirPath);
|
||||
throw new RuntimeException("路径不是文件夹: " + outputDirPath);
|
||||
}
|
||||
|
||||
// 递归获取所有图片文件
|
||||
java.util.List<File> imageFiles = new java.util.ArrayList<>();
|
||||
collectImageFiles(outputDir, imageFiles);
|
||||
|
||||
if (imageFiles.isEmpty()) {
|
||||
log.warn("Output文件夹中没有找到图片文件");
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("找到 {} 个图片文件", imageFiles.size());
|
||||
|
||||
// 处理每个图片文件
|
||||
int successCount = 0;
|
||||
int notFoundCount = 0;
|
||||
int errorCount = 0;
|
||||
|
||||
for (File imageFile : imageFiles) {
|
||||
try {
|
||||
// 获取文件名(不带后缀)
|
||||
String fileNameWithoutExt = FileUtil.getPrefix(imageFile.getName());
|
||||
log.info("处理文件: {}, 文件名(无后缀): {}", imageFile.getName(), fileNameWithoutExt);
|
||||
|
||||
// 上传文件
|
||||
String url = uploadFile(imageFile);
|
||||
log.info("文件上传成功, url: {}", url);
|
||||
|
||||
// 根据no字段查找物料
|
||||
WmsShipmentMaterial material = materialMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<WmsShipmentMaterial>()
|
||||
.eq(WmsShipmentMaterial::getNo, fileNameWithoutExt)
|
||||
);
|
||||
|
||||
if (material != null) {
|
||||
// 更新image字段
|
||||
LambdaUpdateWrapper<WmsShipmentMaterial> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(WmsShipmentMaterial::getNo, fileNameWithoutExt)
|
||||
.set(WmsShipmentMaterial::getImage, url);
|
||||
|
||||
int updateCount = materialMapper.update(null, updateWrapper);
|
||||
if (updateCount > 0) {
|
||||
imageFile.delete();
|
||||
log.info("成功更新物料 {} 的图片url", fileNameWithoutExt);
|
||||
successCount++;
|
||||
} else {
|
||||
log.error("更新物料 {} 的图片url失败", fileNameWithoutExt);
|
||||
errorCount++;
|
||||
}
|
||||
} else {
|
||||
log.warn("未找到物料编号为 {} 的物料记录", fileNameWithoutExt);
|
||||
notFoundCount++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("处理文件 {} 时发生错误: {}", imageFile.getName(), e.getMessage(), e);
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// 输出统计信息
|
||||
log.info("========================================");
|
||||
log.info("处理完成!");
|
||||
log.info("总文件数: {}", imageFiles.size());
|
||||
log.info("成功更新: {}", successCount);
|
||||
log.info("未找到物料: {}", notFoundCount);
|
||||
log.info("处理错误: {}", errorCount);
|
||||
log.info("========================================");
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件 - 调用HTTP接口
|
||||
*/
|
||||
private String uploadFile(File file) {
|
||||
// 构建multipart请求
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||
headers.add("authorization", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoiM3pCT2dQT203ZmZTVEY5S0gxYldaZ0w0ZmJGVW85TnoiLCJuYW1lIjoi6LaF57qn566h55CG5ZGYIiwiY29kZSI6ImFkbWluIiwicm9sZXMiOlsiU3VwZXJBZG1pbiJdLCJ0eXBlIjoxfQ.Ircp8zNaLX7Wly7IZxEEdQrFo2BVfufXxXDhn7wSdrk");
|
||||
|
||||
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
|
||||
body.add("file", new FileSystemResource(file));
|
||||
|
||||
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
|
||||
|
||||
// 使用String接收响应,避免Jackson反序列化LocalDateTime的问题
|
||||
ResponseEntity<String> responseEntity = restTemplate.postForEntity(UPLOAD_URL, requestEntity, String.class);
|
||||
|
||||
// 检查响应
|
||||
if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody() == null) {
|
||||
throw new RuntimeException("文件上传失败,HTTP状态码: " + responseEntity.getStatusCode());
|
||||
}
|
||||
|
||||
// 手动解析JSON
|
||||
String responseBody = responseEntity.getBody();
|
||||
log.debug("上传响应: {}", responseBody);
|
||||
|
||||
cn.hutool.json.JSONObject jsonObject = cn.hutool.json.JSONUtil.parseObj(responseBody);
|
||||
int code = jsonObject.getInt("code", -1);
|
||||
|
||||
if (code != 200) {
|
||||
String message = jsonObject.getStr("message", "未知错误");
|
||||
throw new RuntimeException("文件上传失败: " + message);
|
||||
}
|
||||
|
||||
// 提取url
|
||||
cn.hutool.json.JSONObject result = jsonObject.getJSONObject("result");
|
||||
if (result == null) {
|
||||
throw new RuntimeException("文件上传失败: 返回结果为空");
|
||||
}
|
||||
|
||||
String url = result.getStr("url");
|
||||
if (url == null || url.isEmpty()) {
|
||||
throw new RuntimeException("文件上传失败: URL为空");
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归收集所有图片文件
|
||||
*/
|
||||
private void collectImageFiles(File dir, java.util.List<File> imageFiles) {
|
||||
File[] files = dir.listFiles();
|
||||
if (files == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
collectImageFiles(file, imageFiles);
|
||||
} else {
|
||||
String lowerName = file.getName().toLowerCase();
|
||||
if (lowerName.endsWith(".jpg") || lowerName.endsWith(".jpeg") ||
|
||||
lowerName.endsWith(".png") || lowerName.endsWith(".gif") ||
|
||||
lowerName.endsWith(".bmp")) {
|
||||
imageFiles.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归删除目录
|
||||
*/
|
||||
private void deleteDirectory(File file) {
|
||||
if (file.isDirectory()) {
|
||||
File[] files = file.listFiles();
|
||||
if (files != null) {
|
||||
for (File f : files) {
|
||||
deleteDirectory(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue