Merge branch 'develop' into qms/develop
This commit is contained in:
commit
6f231f1a60
|
|
@ -13,6 +13,8 @@ spring:
|
|||
import: nacos:shared.properties?group=${spring.profiles.active}&refreshEnabled=true
|
||||
cloud:
|
||||
nacos:
|
||||
username: wms
|
||||
password: wms
|
||||
config:
|
||||
server-addr: ${nacos.server-addr:192.168.163.83:8848}
|
||||
namespace: wms
|
||||
|
|
@ -21,6 +23,8 @@ spring:
|
|||
server-addr: ${nacos.server-addr:192.168.163.83:8848}
|
||||
namespace: wms
|
||||
group: ${spring.profiles.active}
|
||||
username: wms
|
||||
password: wms
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 200MB
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
logging:
|
||||
loki:
|
||||
url: http://192.168.163.83:3100/loki/api/v1/push
|
||||
url: http://192.168.163.85:3100/loki/api/v1/push
|
||||
level:
|
||||
root: info
|
||||
com:
|
||||
|
|
@ -27,4 +27,14 @@ sa-token:
|
|||
management:
|
||||
otlp:
|
||||
tracing:
|
||||
endpoint: http://192.168.163.83:4318/v1/traces
|
||||
endpoint: http://192.168.163.85:4318/v1/traces
|
||||
spring:
|
||||
datasource:
|
||||
hikari:
|
||||
pool-name: WmsAdminProdPool
|
||||
maximum-pool-size: 20
|
||||
minimum-idle: 20
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
leak-detection-threshold: 60000
|
||||
|
|
@ -13,10 +13,14 @@ spring:
|
|||
import: nacos:shared.properties?group=${spring.profiles.active}&refreshEnabled=true
|
||||
cloud:
|
||||
nacos:
|
||||
username: ${nacos.username:}
|
||||
password: ${nacos.password:}
|
||||
config:
|
||||
server-addr: ${nacos.server-addr:192.168.163.83:8848}
|
||||
namespace: wms
|
||||
group: ${spring.profiles.active}
|
||||
file-extension: properties
|
||||
refresh-enabled: true
|
||||
discovery:
|
||||
server-addr: ${nacos.server-addr:192.168.163.83:8848}
|
||||
namespace: wms
|
||||
|
|
|
|||
|
|
@ -1,10 +1,20 @@
|
|||
logging:
|
||||
loki:
|
||||
url: http://192.168.163.83:3100/loki/api/v1/push
|
||||
url: http://192.168.163.85:3100/loki/api/v1/push
|
||||
level:
|
||||
root: info
|
||||
com:
|
||||
nflg: debug
|
||||
alibaba:
|
||||
cloud:
|
||||
nacos: info
|
||||
nacos: info
|
||||
spring:
|
||||
datasource:
|
||||
hikari:
|
||||
pool-name: WmsAuthProdPool
|
||||
maximum-pool-size: 20
|
||||
minimum-idle: 20
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
leak-detection-threshold: 60000
|
||||
|
|
@ -9,10 +9,14 @@ spring:
|
|||
import: nacos:shared.properties?group=${spring.profiles.active}&refreshEnabled=true
|
||||
cloud:
|
||||
nacos:
|
||||
username: ${nacos.username:}
|
||||
password: ${nacos.password:}
|
||||
config:
|
||||
server-addr: ${nacos.server-addr:192.168.163.83:8848}
|
||||
namespace: wms
|
||||
group: ${spring.profiles.active}
|
||||
file-extension: properties
|
||||
refresh-enabled: true
|
||||
discovery:
|
||||
server-addr: ${nacos.server-addr:192.168.163.83:8848}
|
||||
namespace: wms
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package com.nflg.wms.common.pojo.qo;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 老鼠图PDF导出请求参数
|
||||
*/
|
||||
@Data
|
||||
public class MaterialPdfExportQO {
|
||||
|
||||
/**
|
||||
* 物料明细ID列表
|
||||
*/
|
||||
@NotEmpty(message = "物料ID不能为空")
|
||||
private List<Long> ids;
|
||||
|
||||
/**
|
||||
* 每页老鼠图数量(2/4/6/8/9,默认6)
|
||||
*/
|
||||
@NotNull(message = "每页数量不能为空")
|
||||
private Integer perPage;
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import com.nflg.wms.common.util.NumberUtil;
|
|||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ShipmentMaterialCodeQRVO {
|
||||
|
|
@ -69,4 +70,24 @@ public class ShipmentMaterialCodeQRVO {
|
|||
*/
|
||||
private String customerName;
|
||||
|
||||
/**
|
||||
* 二维码编号列表(用于打印)
|
||||
*/
|
||||
private List<String> qrCodes;
|
||||
|
||||
/**
|
||||
* 物料码主表ID(用于查询客户信息)
|
||||
*/
|
||||
private Long materialCodeId;
|
||||
|
||||
/**
|
||||
* 销售订单号
|
||||
*/
|
||||
private String soNo;
|
||||
|
||||
/**
|
||||
* 下单日期
|
||||
*/
|
||||
private String orderDate;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,20 @@
|
|||
logging:
|
||||
loki:
|
||||
url: http://192.168.163.83:3100/loki/api/v1/push
|
||||
url: http://192.168.163.85:3100/loki/api/v1/push
|
||||
level:
|
||||
root: info
|
||||
com:
|
||||
nflg: debug
|
||||
alibaba:
|
||||
cloud:
|
||||
nacos: info
|
||||
nacos: info
|
||||
spring:
|
||||
datasource:
|
||||
hikari:
|
||||
pool-name: WmsGatewayProdPool
|
||||
maximum-pool-size: 20
|
||||
minimum-idle: 20
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
leak-detection-threshold: 60000
|
||||
|
|
@ -9,10 +9,14 @@ spring:
|
|||
import: nacos:shared.properties?group=${spring.profiles.active}&refreshEnabled=true
|
||||
cloud:
|
||||
nacos:
|
||||
username: ${nacos.username:}
|
||||
password: ${nacos.password:}
|
||||
config:
|
||||
server-addr: ${nacos.server-addr:112.74.186.154:8848}
|
||||
namespace: wms
|
||||
group: ${spring.profiles.active}
|
||||
file-extension: properties
|
||||
refresh-enabled: true
|
||||
discovery:
|
||||
server-addr: ${nacos.server-addr:112.74.186.154:8848}
|
||||
namespace: wms
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
</select>
|
||||
|
||||
<select id="getListVOByCodeIds" 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
|
||||
SELECT qr.id,qr.no,it.material_no,it.material_describe,qr.num,it.unit,qr.status,mc.device_no,mc.customer_name,it.material_code_id
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,10 +1,20 @@
|
|||
logging:
|
||||
loki:
|
||||
url: http://192.168.163.83:3100/loki/api/v1/push
|
||||
url: http://192.168.163.85:3100/loki/api/v1/push
|
||||
level:
|
||||
root: info
|
||||
com:
|
||||
nflg: debug
|
||||
alibaba:
|
||||
cloud:
|
||||
nacos: info
|
||||
nacos: info
|
||||
spring:
|
||||
datasource:
|
||||
hikari:
|
||||
pool-name: WmsScheduledProdPool
|
||||
maximum-pool-size: 20
|
||||
minimum-idle: 20
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
leak-detection-threshold: 60000
|
||||
|
|
@ -9,10 +9,14 @@ spring:
|
|||
import: nacos:shared.properties?group=${spring.profiles.active}&refreshEnabled=true
|
||||
cloud:
|
||||
nacos:
|
||||
username: ${nacos.username:}
|
||||
password: ${nacos.password:}
|
||||
config:
|
||||
server-addr: ${nacos.server-addr:192.168.163.83:8848}
|
||||
namespace: wms
|
||||
group: ${spring.profiles.active}
|
||||
file-extension: properties
|
||||
refresh-enabled: true
|
||||
discovery:
|
||||
server-addr: ${nacos.server-addr:192.168.163.83:8848}
|
||||
namespace: wms
|
||||
|
|
|
|||
|
|
@ -9,13 +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.pojo.vo.ShipmentMaterialCodeQRVO;
|
||||
import com.nflg.wms.common.util.EecExcelUtil;
|
||||
import com.nflg.wms.common.util.NumberUtil;
|
||||
import com.nflg.wms.common.util.UserUtil;
|
||||
|
|
@ -52,8 +50,8 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLEncoder;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
|
@ -139,7 +137,7 @@ public class MaterialCodeController extends BaseController {
|
|||
if (CollectionUtil.isNotEmpty(idsForDelete)) {
|
||||
materialCodeService.removeByIds(idsForDelete);
|
||||
materialCodeForwardService.lambdaUpdate()
|
||||
.in(WmsShipmentMaterialCodeForward::getMaterialCodeId)
|
||||
.in(WmsShipmentMaterialCodeForward::getMaterialCodeId, idsForDelete)
|
||||
.remove();
|
||||
idsForDelete = materialCodeItemService.lambdaQuery()
|
||||
.in(WmsShipmentMaterialCodeItem::getMaterialCodeId, idsForDelete)
|
||||
|
|
@ -402,7 +400,6 @@ public class MaterialCodeController extends BaseController {
|
|||
|
||||
/**
|
||||
* 清单明细-导入
|
||||
*
|
||||
* @param materialCodeId 清单ID
|
||||
* @param cover 导入模式,true:覆盖,false:新增
|
||||
* @param file 文件
|
||||
|
|
@ -561,7 +558,6 @@ public class MaterialCodeController extends BaseController {
|
|||
|
||||
/**
|
||||
* 清单明细-根据二维码唯一号获取物料信息(PDA使用)
|
||||
*
|
||||
* @param code 二维码唯一号
|
||||
*/
|
||||
@GetMapping("getInfoByQRCode")
|
||||
|
|
@ -591,7 +587,6 @@ public class MaterialCodeController extends BaseController {
|
|||
|
||||
/**
|
||||
* 根据清单导出标签图片ZIP(用于直连打印机打印)
|
||||
*
|
||||
* @param ids 清单id列表
|
||||
*/
|
||||
@PostMapping("exportItemImageZip1")
|
||||
|
|
@ -603,7 +598,6 @@ public class MaterialCodeController extends BaseController {
|
|||
|
||||
/**
|
||||
* 根据清单项导出标签图片ZIP(用于直连打印机打印)
|
||||
*
|
||||
* @param ids 清单明细id列表
|
||||
*/
|
||||
@PostMapping("exportItemImageZip")
|
||||
|
|
@ -646,7 +640,6 @@ public class MaterialCodeController extends BaseController {
|
|||
|
||||
/**
|
||||
* 代发物料-导入
|
||||
*
|
||||
* @param id 清单ID
|
||||
*/
|
||||
@PostMapping("importForward")
|
||||
|
|
@ -763,21 +756,36 @@ public class MaterialCodeController extends BaseController {
|
|||
* 导出老鼠图PDF
|
||||
*/
|
||||
@PostMapping("exportPdf")
|
||||
public ApiResult<String> exportPdf(HttpServletResponse response, @RequestBody MaterialPdfQO request) throws Exception {
|
||||
List<WmsShipmentMaterialCodeItem> materialCodeIts =materialCodeItemService.lambdaQuery()
|
||||
.in(WmsShipmentMaterialCodeItem::getId, request.getMaterialIds()).list();
|
||||
//根据前端传入的物料ID查询对应的物料编号再查询物料主数据
|
||||
List<WmsShipmentMaterial> shipmentMaterials = materialService.lambdaQuery()
|
||||
.in(WmsShipmentMaterial::getNo, materialCodeIts
|
||||
.stream()
|
||||
.map(WmsShipmentMaterialCodeItem::getMaterialNo)
|
||||
.toList())
|
||||
.list();
|
||||
//根据前端传入的物料ID查询物料明细
|
||||
public ApiResult<String> exportPdf(HttpServletResponse response, @Valid @RequestBody MaterialPdfExportQO qo) throws Exception {
|
||||
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(qo.getIds())).throwMessage("没有需要导出的数据");
|
||||
|
||||
// 每页数量校验
|
||||
Integer perPage = qo.getPerPage() != null ? qo.getPerPage() : 6;
|
||||
List<Integer> validPerPage = List.of(2, 4, 6, 8, 9);
|
||||
VUtil.trueThrowBusinessError(!validPerPage.contains(perPage)).throwMessage("每页数量只能为2/4/6/8/9");
|
||||
|
||||
// 从 list 中提取物料ID(明细ID)
|
||||
List<Long> materialIds = qo.getIds().stream()
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
VUtil.trueThrowBusinessError(materialIds.isEmpty()).throwMessage("物料ID不能为空");
|
||||
|
||||
// 根据前端传入的物料ID查询对应的物料编号再查询物料主数据
|
||||
List<WmsShipmentMaterialCodeItem> materialCodeItems = materialCodeItemService.lambdaQuery()
|
||||
.in(WmsShipmentMaterialCodeItem::getId, request.getMaterialIds()).list();
|
||||
//将主数据转换成PDF需要的DTO列表
|
||||
List<MaterialPdfDTO> items = Convert.toList(MaterialPdfDTO.class, materialCodeIts);
|
||||
.in(WmsShipmentMaterialCodeItem::getId, materialIds)
|
||||
.list();
|
||||
|
||||
List<String> materialNos = materialCodeItems.stream()
|
||||
.map(WmsShipmentMaterialCodeItem::getMaterialNo)
|
||||
.distinct()
|
||||
.toList();
|
||||
|
||||
List<WmsShipmentMaterial> shipmentMaterials = materialService.lambdaQuery()
|
||||
.in(WmsShipmentMaterial::getNo, materialNos)
|
||||
.list();
|
||||
|
||||
// 将主数据转换成PDF需要的DTO列表
|
||||
List<MaterialPdfDTO> items = Convert.toList(MaterialPdfDTO.class, materialCodeItems);
|
||||
Map<String, WmsShipmentMaterial> materialMap = shipmentMaterials.stream()
|
||||
.collect(Collectors.toMap(WmsShipmentMaterial::getNo, m -> m));
|
||||
for (MaterialPdfDTO dto : items) {
|
||||
|
|
@ -788,7 +796,8 @@ public class MaterialCodeController extends BaseController {
|
|||
dto.setDrawingNo(mat.getDrawingNo());
|
||||
}
|
||||
}
|
||||
//计算总重量 = 单个重量 * 数量 累加
|
||||
|
||||
// 计算总重量 = 单个重量 * 数量 累加
|
||||
BigDecimal allWeight = new BigDecimal(0);
|
||||
for (WmsShipmentMaterialCodeItem temp : materialCodeItems) {
|
||||
WmsShipmentMaterial material = shipmentMaterials.stream()
|
||||
|
|
@ -800,16 +809,48 @@ public class MaterialCodeController extends BaseController {
|
|||
BigDecimal num = temp.getActualNum() == null ? BigDecimal.ZERO : temp.getActualNum();
|
||||
allWeight = allWeight.add(weight.multiply(num));
|
||||
}
|
||||
MaterialPdfVO material = Convert.convert(MaterialPdfVO.class, request);
|
||||
material.setWeight(allWeight);
|
||||
material.setQrCode(QRCodeUtil.generateQRCodeBase64(request.getNo(), 100, 100));
|
||||
//制作pdf
|
||||
|
||||
// 从 materialIds 中获取第一条数据
|
||||
WmsShipmentMaterialCodeItem firstItem = materialCodeItems.get(0);
|
||||
|
||||
// 根据物料码主表ID查询清单信息(清单编号、机台编号、销售订单号、客户名称、下单日期)
|
||||
WmsShipmentMaterialCode materialCode = null;
|
||||
if (firstItem.getMaterialCodeId() != null) {
|
||||
materialCode = materialCodeService.lambdaQuery()
|
||||
.select(WmsShipmentMaterialCode::getNo,
|
||||
WmsShipmentMaterialCode::getDeviceNo,
|
||||
WmsShipmentMaterialCode::getSoNo,
|
||||
WmsShipmentMaterialCode::getCustomerName,
|
||||
WmsShipmentMaterialCode::getOrderDate)
|
||||
.eq(WmsShipmentMaterialCode::getId, firstItem.getMaterialCodeId())
|
||||
.one();
|
||||
}
|
||||
|
||||
// 构建表头数据
|
||||
MaterialPdfVO material = new MaterialPdfVO();
|
||||
// 优先使用从数据库查询的清单信息,如果没有则使用前端传入的数据
|
||||
material.setNo(materialCode != null ? materialCode.getNo() : firstItem.getMaterialCodeId().toString()); // 清单编号
|
||||
material.setDeviceNo(materialCode != null ? materialCode.getDeviceNo() : null); // 机台编号
|
||||
material.setMaterialNo(firstItem.getMaterialNo()); // 物料编号
|
||||
material.setSoNo(materialCode != null ? materialCode.getSoNo() : null); // 销售订单号
|
||||
material.setCustomerName(materialCode != null ? materialCode.getCustomerName() : null); // 客户名称
|
||||
material.setOrderDay(materialCode != null ? materialCode.getOrderDate() : null); // 下单日期
|
||||
material.setWeight(allWeight); // 总重量
|
||||
|
||||
// 用清单编号生成二维码
|
||||
String qrCodeNo = materialCode != null ? materialCode.getNo() : "";
|
||||
material.setQrCode(QRCodeUtil.generateQRCodeBase64(qrCodeNo, 100, 100));
|
||||
|
||||
// 制作pdf
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
variables.put("info", material);
|
||||
variables.put("pages", PdfPageDTO.create(items, 9, new MaterialPdfDTO()));
|
||||
variables.put("pages", PdfPageDTO.create(items, perPage, new MaterialPdfDTO()));
|
||||
|
||||
// 根据每页数量选择对应模板
|
||||
String templateName = "物料老鼠图" + perPage;
|
||||
String html = ThymeleafUtil.generator(
|
||||
"/template/",
|
||||
"物料老鼠图",
|
||||
templateName,
|
||||
".html",
|
||||
variables
|
||||
);
|
||||
|
|
@ -825,43 +866,70 @@ public class MaterialCodeController extends BaseController {
|
|||
|
||||
/**
|
||||
* 导出标签图片PDF(打印预览)
|
||||
*
|
||||
* @param response HTTP响应
|
||||
* @param ids 物料主数据id列表(wms_shipment_material.id)
|
||||
* @param list 物料码主表列表
|
||||
*/
|
||||
@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);
|
||||
|
||||
public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<ShipmentMaterialCodeQRVO> list) throws Exception {
|
||||
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(list)).throwMessage("物料数据不存在");
|
||||
|
||||
// 收集所有物料码主表ID
|
||||
List<Long> materialCodeIds = list.stream()
|
||||
.map(ShipmentMaterialCodeQRVO::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
VUtil.trueThrowBusinessError(materialCodeIds.isEmpty()).throwMessage("物料码ID不能为空");
|
||||
|
||||
// 根据物料码主表ID查询物料明细(包含二维码信息和客户名称)
|
||||
List<ShipmentMaterialCodeQRVO> qrDatas = materialCodeItemQrService.getListVOByCodeIds(materialCodeIds);
|
||||
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(qrDatas)).throwMessage("没有需要打印的二维码数据");
|
||||
|
||||
// 构建客户名称Map(从传入的list中获取,key为物料码主表ID)
|
||||
Map<Long, String> customerNameMap = list.stream()
|
||||
.filter(item -> item.getId() != null && StrUtil.isNotBlank(item.getCustomerName()))
|
||||
.collect(Collectors.toMap(
|
||||
ShipmentMaterialCodeQRVO::getId,
|
||||
ShipmentMaterialCodeQRVO::getCustomerName,
|
||||
(v1, v2) -> v1
|
||||
));
|
||||
|
||||
// 根据物料编号查询物料图片
|
||||
Map<String, String> images = materialService.lambdaQuery()
|
||||
.select(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage)
|
||||
.in(WmsShipmentMaterial::getNo, datas.stream().map(ShipmentMaterialCodeQRVO::getMaterialNo).collect(Collectors.toSet()))
|
||||
.in(WmsShipmentMaterial::getNo, qrDatas.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);
|
||||
|
||||
List<Map<String, Object>> printList = new ArrayList<>();
|
||||
|
||||
for (ShipmentMaterialCodeQRVO item : qrDatas) {
|
||||
// 优先使用从list中获取的客户名称,如果没有则使用SQL查询的customerName
|
||||
String customerName = customerNameMap.get(item.getMaterialCodeId());
|
||||
if (StrUtil.isBlank(customerName)) {
|
||||
customerName = item.getCustomerName();
|
||||
}
|
||||
|
||||
Map<String, Object> info = new HashMap<>();
|
||||
info.put("no", item.getNo());
|
||||
info.put("materialNo", item.getMaterialNo());
|
||||
info.put("numText", item.getNumText());
|
||||
info.put("customerName", customerName);
|
||||
|
||||
Map<String, String> ext = new HashMap<>();
|
||||
ext.put("qrCode", QRCodeUtil.generateQRCodeBase64(item.getNo(), 200, 200));
|
||||
ext.put("lst", QRCodeUtil.imageUrlToBase64(images.get(item.getMaterialNo())));
|
||||
|
||||
Map<String, Object> printData = new HashMap<>();
|
||||
printData.put("info", info);
|
||||
printData.put("ext", ext);
|
||||
printList.add(printData);
|
||||
}
|
||||
|
||||
variables.put("list", printList);
|
||||
|
||||
String html = ThymeleafUtil.generator("/template/label/", "material-pdf", ".html", variables);
|
||||
URL baseUrl = new ClassPathResource("template/label/").getURL();
|
||||
PdfGeneratorUtil.generatePdf("物料码标签", html, baseUrl.toString(), response);
|
||||
|
|
@ -869,45 +937,84 @@ public class MaterialCodeController extends BaseController {
|
|||
|
||||
/**
|
||||
* 根据明细ID导出物料明细PDF(打印预览)
|
||||
*
|
||||
* @param response HTTP响应
|
||||
* @param ids 明细id列表(wms_shipment_material_code_item.id)
|
||||
* @param list 物料明细列表(包含qrCodes二维码数组)
|
||||
*/
|
||||
@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);
|
||||
|
||||
public void exportItemToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<ShipmentMaterialCodeQRVO> list) throws Exception {
|
||||
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(list)).throwMessage("没有需要导出的数据");
|
||||
|
||||
// 收集所有二维码编号
|
||||
List<String> allQrCodes = new ArrayList<>();
|
||||
for (ShipmentMaterialCodeQRVO item : list) {
|
||||
if (item.getQrCodes() != null && !item.getQrCodes().isEmpty()) {
|
||||
allQrCodes.addAll(item.getQrCodes());
|
||||
}
|
||||
}
|
||||
VUtil.trueThrowBusinessError(allQrCodes.isEmpty()).throwMessage("没有需要打印的二维码");
|
||||
|
||||
// 根据物料码主表ID查询客户名称
|
||||
Set<Long> materialCodeIds = list.stream()
|
||||
.map(ShipmentMaterialCodeQRVO::getMaterialCodeId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Map<Long, String> customerNameMap = new HashMap<>();
|
||||
if (!materialCodeIds.isEmpty()) {
|
||||
customerNameMap = materialCodeService.lambdaQuery()
|
||||
.select(WmsShipmentMaterialCode::getId, WmsShipmentMaterialCode::getCustomerName)
|
||||
.in(WmsShipmentMaterialCode::getId, materialCodeIds)
|
||||
.list()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(WmsShipmentMaterialCode::getId, WmsShipmentMaterialCode::getCustomerName));
|
||||
}
|
||||
|
||||
// 根据物料编号查询物料图片
|
||||
Map<String, String> images = materialService.lambdaQuery()
|
||||
.select(WmsShipmentMaterial::getNo, WmsShipmentMaterial::getImage)
|
||||
.in(WmsShipmentMaterial::getNo, datas.stream().map(ShipmentMaterialCodeQRVO::getMaterialNo).collect(Collectors.toSet()))
|
||||
.in(WmsShipmentMaterial::getNo, list.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);
|
||||
|
||||
List<Map<String, Object>> printList = new ArrayList<>();
|
||||
|
||||
for (ShipmentMaterialCodeQRVO item : list) {
|
||||
if (item.getQrCodes() == null || item.getQrCodes().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取客户名称
|
||||
String customerName = customerNameMap.get(item.getMaterialCodeId());
|
||||
|
||||
for (String qrCode : item.getQrCodes()) {
|
||||
Map<String, Object> info = new HashMap<>();
|
||||
info.put("no", qrCode);
|
||||
info.put("materialNo", item.getMaterialNo());
|
||||
info.put("numText", item.getNumText());
|
||||
info.put("customerName", customerName);
|
||||
|
||||
Map<String, String> ext = new HashMap<>();
|
||||
ext.put("qrCode", QRCodeUtil.generateQRCodeBase64(qrCode, 200, 200));
|
||||
ext.put("lst", QRCodeUtil.imageUrlToBase64(images.get(item.getMaterialNo())));
|
||||
|
||||
Map<String, Object> printData = new HashMap<>();
|
||||
printData.put("info", info);
|
||||
printData.put("ext", ext);
|
||||
printList.add(printData);
|
||||
}
|
||||
}
|
||||
|
||||
variables.put("list", printList);
|
||||
|
||||
// 生成 PDF
|
||||
String html = ThymeleafUtil.generator("/template/label/", "material-pdf", ".html", variables);
|
||||
URL baseUrl = new ClassPathResource("template/label/").getURL();
|
||||
PdfGeneratorUtil.generatePdf("物料明细标签", html, baseUrl.toString(), response);
|
||||
ClassPathResource resource = new ClassPathResource("template/label/");
|
||||
VUtil.trueThrowBusinessError(!resource.exists()).throwMessage("PDF模板不存在");
|
||||
|
||||
URL baseUrl = resource.getURL();
|
||||
PdfGeneratorUtil.generatePdf("物料标签", html, baseUrl.toString(), response);
|
||||
}
|
||||
}
|
||||
|
|
@ -415,21 +415,34 @@ public class PackagingCodeController extends BaseController {
|
|||
*/
|
||||
@PostMapping("exportToPdf")
|
||||
public void exportToPdf(HttpServletResponse response, @RequestBody @NotEmpty List<ShipmentPackagingCodeVO> list) throws Exception {
|
||||
|
||||
List<Long> ids = list.stream()
|
||||
.map(ShipmentPackagingCodeVO::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
|
||||
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(ids)).throwMessage("ID不能为空");
|
||||
|
||||
// 根据ID列表查询包装码数据
|
||||
List<WmsShipmentPackagingCode> packagingCodes = packagingCodeService.lambdaQuery()
|
||||
.in(WmsShipmentPackagingCode::getId,ids)
|
||||
.list();
|
||||
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(packagingCodes)).throwMessage("包装码数据不存在");
|
||||
|
||||
// 查询包装类型字典
|
||||
List<DictionaryItem> types = dictionaryItemService.getListByDictionaryCode("PackagingType");
|
||||
Map<Long, String> typeMap = types.stream()
|
||||
.collect(Collectors.toMap(DictionaryItem::getId, DictionaryItem::getName));
|
||||
|
||||
// 构建打印数据
|
||||
Map<String, Object> variables = new HashMap<>();
|
||||
variables.put("list", list.stream()
|
||||
.map(data -> {
|
||||
variables.put("list", packagingCodes.stream()
|
||||
.map(code -> {
|
||||
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));
|
||||
vo.setNo(code.getNo());
|
||||
vo.setName(code.getName());
|
||||
vo.setTypeName(typeMap.getOrDefault(code.getType(), ""));
|
||||
vo.setQrCode(QRCodeUtil.generateQRCodeBase64(code.getNo(), 100, 100));
|
||||
return vo;
|
||||
}).toList()
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import com.google.zxing.common.BitMatrix;
|
|||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Base64;
|
||||
import java.util.Hashtable;
|
||||
|
||||
|
|
@ -38,4 +40,22 @@ public class QRCodeUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static String imageUrlToBase64(String imageUrl) {
|
||||
if (imageUrl == null || imageUrl.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
try (InputStream in = new URL(imageUrl).openStream();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
byte[] buf = new byte[4096];
|
||||
int n;
|
||||
while ((n = in.read(buf)) != -1) {
|
||||
baos.write(buf, 0, n);
|
||||
}
|
||||
String ext = imageUrl.toLowerCase().contains(".png") ? "png" : "jpeg";
|
||||
return "data:image/" + ext + ";base64," + Base64.getEncoder().encodeToString(baos.toByteArray());
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
logging:
|
||||
loki:
|
||||
url: http://192.168.163.83:3100/loki/api/v1/push
|
||||
url: http://192.168.163.85:3100/loki/api/v1/push
|
||||
level:
|
||||
root: info
|
||||
com:
|
||||
|
|
@ -27,4 +27,14 @@ sa-token:
|
|||
management:
|
||||
otlp:
|
||||
tracing:
|
||||
endpoint: http://192.168.163.83:4318/v1/traces
|
||||
endpoint: http://192.168.163.83:4318/v1/traces
|
||||
spring:
|
||||
datasource:
|
||||
hikari:
|
||||
pool-name: WmsShipmentProdPool
|
||||
maximum-pool-size: 20
|
||||
minimum-idle: 20
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
leak-detection-threshold: 60000
|
||||
|
|
@ -13,10 +13,14 @@ spring:
|
|||
import: nacos:shared.properties?group=${spring.profiles.active}&refreshEnabled=true
|
||||
cloud:
|
||||
nacos:
|
||||
username: ${nacos.username:}
|
||||
password: ${nacos.password:}
|
||||
config:
|
||||
server-addr: ${nacos.server-addr:192.168.163.83:8848}
|
||||
namespace: wms
|
||||
group: ${spring.profiles.active}
|
||||
file-extension: properties
|
||||
refresh-enabled: true
|
||||
discovery:
|
||||
server-addr: ${nacos.server-addr:192.168.163.83:8848}
|
||||
namespace: wms
|
||||
|
|
|
|||
|
|
@ -6,30 +6,51 @@
|
|||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<style>
|
||||
@page {
|
||||
size: 1200px 800px;
|
||||
size: 1000px 500px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 1200px;
|
||||
height: 800px;
|
||||
font-size: 20pt;
|
||||
font-size: 11pt;
|
||||
font-family: SimSun, Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.label-page {
|
||||
width: 1000px;
|
||||
height: 500px;
|
||||
display: table;
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
.label-page:last-child {
|
||||
page-break-after: auto;
|
||||
}
|
||||
|
||||
.label-center {
|
||||
display: table-cell;
|
||||
width: 1000px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.label-content {
|
||||
display: inline-block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 1200px;
|
||||
height: 800px;
|
||||
width: 900px;
|
||||
border: 3px solid #000;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 3px solid #000;
|
||||
padding: 10px;
|
||||
padding: 4px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
word-wrap: break-word;
|
||||
|
|
@ -37,54 +58,61 @@
|
|||
}
|
||||
|
||||
.qrcode {
|
||||
width: 380px;
|
||||
height: 380px;
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
}
|
||||
.lst{
|
||||
width: 800px;
|
||||
height: auto;
|
||||
max-width: 480px;
|
||||
width: auto;
|
||||
height: 220px;
|
||||
}
|
||||
</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>
|
||||
<div class="label-page" th:each="item, iterStat : ${list}">
|
||||
<div class="label-center">
|
||||
<div class="label-content">
|
||||
<table>
|
||||
<tr>
|
||||
<td style="text-align: center; width: 200px" rowspan="3">
|
||||
<img alt="" class="qrcode" th:src="${item.ext.qrCode}"/>
|
||||
<div style="font-size: 16pt" th:text="${item.info.no}">0PC7B724KV6FM</div>
|
||||
</td>
|
||||
<td style="width: 140px;">
|
||||
机台编号
|
||||
</td>
|
||||
<td style="width: 200px;" th:text="${item.info.no}">
|
||||
26LBZ4000L001
|
||||
</td>
|
||||
<td style="width: 140px;">
|
||||
客户名称
|
||||
</td>
|
||||
<td style="text-align: center" th:text="${item.info.customerName}">
|
||||
北京市京联鑫路用材料有限公司
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
物料编码
|
||||
</td>
|
||||
<td th:text="${item.info.materialNo}">
|
||||
3100006701
|
||||
</td>
|
||||
<td>
|
||||
数量
|
||||
</td>
|
||||
<td th:text="${item.info.numText}">
|
||||
10
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<img alt="" class="lst" th:src="${item.ext.lst}"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>包装码标签-A4打印版</title>
|
||||
<title>包装码标签-打印预览版</title>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<style>
|
||||
@page {
|
||||
|
|
@ -15,31 +15,29 @@
|
|||
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;
|
||||
display: table;
|
||||
page-break-after: always;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.label-page:last-child {
|
||||
page-break-after: auto;
|
||||
}
|
||||
|
||||
.label-center {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.label-content {
|
||||
display: inline-block;
|
||||
width: 600px;
|
||||
height: 400px;
|
||||
transform-origin: center center;
|
||||
transform: scale(calc(210mm / 600px));
|
||||
}
|
||||
|
||||
table {
|
||||
|
|
@ -72,19 +70,21 @@
|
|||
<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 class="label-center">
|
||||
<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>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>物料老鼠图</title>
|
||||
<style>
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: SimSun, serif;
|
||||
font-size: 9pt;
|
||||
padding: 10px;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo img {
|
||||
height: 40px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
td {
|
||||
border: 1px solid #000;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
tr:first-child td {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
td:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
td:last-child {
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.data-item {
|
||||
width: 100%;
|
||||
float: left;
|
||||
border-right: 1px solid #000;
|
||||
border-left: 1px solid #000;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.cell-img {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cell-img img {
|
||||
vertical-align: middle; /* 防止图片底部留空隙 */
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: auto auto;
|
||||
margin-left: 200px;
|
||||
}
|
||||
|
||||
.cell {
|
||||
border-bottom: 1px solid #000;
|
||||
padding: 7px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cell1 {
|
||||
border-bottom: 1px solid #000;
|
||||
padding: 7px;
|
||||
height: 25px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.container {
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
.container:last-child {
|
||||
page-break-after: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" th:each="page,pageStat : ${pages}">
|
||||
<div class="logo"><img alt="" src="../img/logo1.png"/></div>
|
||||
<table>
|
||||
<tr>
|
||||
<td>清单编号:<span th:text="${info.no}">12255665451615</span></td>
|
||||
<td>机台编号:<span th:text="${info.deviceNo}">1111</span></td>
|
||||
<td>物料编号:<span th:text="${info.materialNo}">12255665451615</span></td>
|
||||
<!-- 二维码:右侧固定 + 跨3行 -->
|
||||
<td style="width: 120px; text-align: right; vertical-align: middle;" rowspan="3">
|
||||
<img alt="二维码" style="width: 100px; height: 100px;" th:src="${info.qrCode}" src="../img/logo1.png"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<td>销售订单号:<span th:text="${info.soNo}">1</span></td>
|
||||
<td>客户名称:<span th:text="${info.customerName}">12255665451615</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<td>下单日期:<span th:text="${info.orderDay}">1</span></td>
|
||||
<td>总重:<span th:text="${info.weight}">348.41</span></td>
|
||||
<td>页码:<span th:text="${pageStat.count}">1</span>/<span th:text="${pageStat.size}">2</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="data-item" th:each="item,itemStat : ${page.datas}">
|
||||
<div class="cell" style="height: 300px;">
|
||||
<div class="cell-img">
|
||||
<img style="width: 340px;height: 280px;" alt=""
|
||||
th:src="${!#strings.isEmpty(item.image)} ? ${item.image} : (${#strings.isEmpty(item.materialNo)} ? '' : 'http://192.168.163.83:9090/nflg-wms/template/none.png')"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell">SAP编码:<span th:text="${item.materialNo}">2222222222</span></div>
|
||||
<div class="cell1">图号:<span
|
||||
th:text="${item.drawingNo}">图号图号图号图号图号图号图号图号图号图号图号图号图号图号图号图号</span>
|
||||
</div>
|
||||
<div class="cell1">名称:<span
|
||||
th:text="${item.materialDescribe}">名称名称名称名称名称名称名称名称名称名名称名名称名称名称称名称名称名称称名称名称名称</span>
|
||||
</div>
|
||||
<div class="cell">数量:<span th:text="${item.num}">1</span> 重量:<span
|
||||
th:text="${item.weight}">348.41</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>物料老鼠图</title>
|
||||
<style>
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: SimSun, serif;
|
||||
font-size: 9pt;
|
||||
padding: 10px;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo img {
|
||||
height: 40px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
td {
|
||||
border: 1px solid #000;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
tr:first-child td {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
td:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
td:last-child {
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.data-item {
|
||||
width: 50%;
|
||||
float: left;
|
||||
border-right: 1px solid #000;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.data-item:nth-child(2n+1) {
|
||||
border-left: 1px solid #000;
|
||||
clear: left;
|
||||
}
|
||||
|
||||
.cell-img {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cell-img img {
|
||||
vertical-align: middle; /* 防止图片底部留空隙 */
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.cell {
|
||||
border-bottom: 1px solid #000;
|
||||
padding: 7px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cell1 {
|
||||
border-bottom: 1px solid #000;
|
||||
padding: 7px;
|
||||
height: 25px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.container {
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
.container:last-child {
|
||||
page-break-after: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" th:each="page,pageStat : ${pages}">
|
||||
<div class="logo"><img alt="" src="../img/logo1.png"/></div>
|
||||
<table>
|
||||
<tr>
|
||||
<td>清单编号:<span th:text="${info.no}">12255665451615</span></td>
|
||||
<td>机台编号:<span th:text="${info.deviceNo}">1111</span></td>
|
||||
<td>物料编号:<span th:text="${info.materialNo}">12255665451615</span></td>
|
||||
<!-- 二维码:右侧固定 + 跨3行 -->
|
||||
<td style="width: 120px; text-align: right; vertical-align: middle;" rowspan="3">
|
||||
<img alt="二维码" style="width: 100px; height: 100px;" th:src="${info.qrCode}" src="../img/logo1.png"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<td>销售订单号:<span th:text="${info.soNo}">1</span></td>
|
||||
<td>客户名称:<span th:text="${info.customerName}">12255665451615</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<td>下单日期:<span th:text="${info.orderDay}">1</span></td>
|
||||
<td>总重:<span th:text="${info.weight}">348.41</span></td>
|
||||
<td>页码:<span th:text="${pageStat.count}">1</span>/<span th:text="${pageStat.size}">2</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="data-item" th:each="item,itemStat : ${page.datas}">
|
||||
<div class="cell" style="height: 300px;">
|
||||
<div class="cell-img">
|
||||
<img style="width: 340px;height: 280px;" alt=""
|
||||
th:src="${!#strings.isEmpty(item.image)} ? ${item.image} : (${#strings.isEmpty(item.materialNo)} ? '' : 'http://192.168.163.83:9090/nflg-wms/template/none.png')"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell">SAP编码:<span th:text="${item.materialNo}">2222222222</span></div>
|
||||
<div class="cell1">图号:<span
|
||||
th:text="${item.drawingNo}">图号图号图号图号图号图号图号图号图号图号图号图号图号图号图号图号</span>
|
||||
</div>
|
||||
<div class="cell1">名称:<span
|
||||
th:text="${item.materialDescribe}">名称名称名称名称名称名称名称名称名称名名称名名称名称名称称名称名称名称称名称名称名称</span>
|
||||
</div>
|
||||
<div class="cell">数量:<span th:text="${item.num}">1</span> 重量:<span
|
||||
th:text="${item.weight}">348.41</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>物料老鼠图</title>
|
||||
<style>
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: SimSun, serif;
|
||||
font-size: 9pt;
|
||||
padding: 10px;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo img {
|
||||
height: 40px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
td {
|
||||
border: 1px solid #000;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
tr:first-child td {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
td:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
td:last-child {
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.data-item {
|
||||
width: 33.16207%;
|
||||
float: left;
|
||||
border-right: 1px solid #000;
|
||||
}
|
||||
|
||||
.data-item-row-first {
|
||||
border-left: 1px solid #000;
|
||||
}
|
||||
|
||||
.cell-img {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cell-img img {
|
||||
vertical-align: middle; /* 防止图片底部留空隙 */
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.cell {
|
||||
border-bottom: 1px solid #000;
|
||||
padding: 7px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cell1 {
|
||||
border-bottom: 1px solid #000;
|
||||
padding: 7px;
|
||||
height: 25px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.container {
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
.container:last-child {
|
||||
page-break-after: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" th:each="page,pageStat : ${pages}">
|
||||
<div class="logo"><img alt="" src="../img/logo1.png"/></div>
|
||||
<table>
|
||||
<tr>
|
||||
<td>清单编号:<span th:text="${info.no}">12255665451615</span></td>
|
||||
<td>机台编号:<span th:text="${info.deviceNo}">1111</span></td>
|
||||
<td>物料编号:<span th:text="${info.materialNo}">12255665451615</span></td>
|
||||
<!-- 二维码:右侧固定 + 跨3行 -->
|
||||
<td style="width: 120px; text-align: right; vertical-align: middle;" rowspan="3">
|
||||
<img alt="二维码" style="width: 100px; height: 100px;" th:src="${info.qrCode}" src="../img/logo1.png"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<td>销售订单号:<span th:text="${info.soNo}">1</span></td>
|
||||
<td>客户名称:<span th:text="${info.customerName}">12255665451615</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<td>下单日期:<span th:text="${info.orderDay}">1</span></td>
|
||||
<td>总重:<span th:text="${info.weight}">348.41</span></td>
|
||||
<td>页码:<span th:text="${pageStat.count}">1</span>/<span th:text="${pageStat.size}">2</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="data-item" th:each="item,itemStat : ${page.datas}"
|
||||
th:classappend="${itemStat.index % 3 == 0} ? 'data-item-row-first'">
|
||||
<div class="cell" style="height: 300px;">
|
||||
<div class="cell-img">
|
||||
<img style="width: 200px;height: 280px;" alt=""
|
||||
th:src="${!#strings.isEmpty(item.image)} ? ${item.image} : (${#strings.isEmpty(item.materialNo)} ? '' : 'http://192.168.163.83:9090/nflg-wms/template/none.png')"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell">SAP编码:<span th:text="${item.materialNo}">2222222222</span></div>
|
||||
<div class="cell1">图号:<span
|
||||
th:text="${item.drawingNo}">图号图号图号图号图号图号图号图号图号图号图号图号图号图号图号图号</span>
|
||||
</div>
|
||||
<div class="cell1">名称:<span
|
||||
th:text="${item.materialDescribe}">名称名称名称名称名称名称名称名称名称名名称名名称名称名称称名称名称名称称名称名称名称</span>
|
||||
</div>
|
||||
<div class="cell">数量:<span th:text="${item.num}">1</span> 重量:<span
|
||||
th:text="${item.weight}">348.41</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>物料老鼠图</title>
|
||||
<style>
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: SimSun, serif;
|
||||
font-size: 9pt;
|
||||
padding: 10px;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo img {
|
||||
height: 40px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
td {
|
||||
border: 1px solid #000;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
tr:first-child td {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
td:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
td:last-child {
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.data-item {
|
||||
width: 24.995%;
|
||||
float: left;
|
||||
border-right: 1px solid #000;
|
||||
border-left: 1px solid #000;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.data-item:nth-child(4n) {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.cell-img {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cell-img img {
|
||||
vertical-align: middle; /* 防止图片底部留空隙 */
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.cell {
|
||||
border-bottom: 1px solid #000;
|
||||
padding: 7px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cell1 {
|
||||
border-bottom: 1px solid #000;
|
||||
padding: 7px;
|
||||
height: 25px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.container {
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
.container:last-child {
|
||||
page-break-after: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" th:each="page,pageStat : ${pages}">
|
||||
<div class="logo"><img alt="" src="../img/logo1.png"/></div>
|
||||
<table>
|
||||
<tr>
|
||||
<td>清单编号:<span th:text="${info.no}">12255665451615</span></td>
|
||||
<td>机台编号:<span th:text="${info.deviceNo}">1111</span></td>
|
||||
<td>物料编号:<span th:text="${info.materialNo}">12255665451615</span></td>
|
||||
<!-- 二维码:右侧固定 + 跨3行 -->
|
||||
<td style="width: 120px; text-align: right; vertical-align: middle;" rowspan="3">
|
||||
<img alt="二维码" style="width: 100px; height: 100px;" th:src="${info.qrCode}" src="../img/logo1.png"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<td>销售订单号:<span th:text="${info.soNo}">1</span></td>
|
||||
<td>客户名称:<span th:text="${info.customerName}">12255665451615</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<td>下单日期:<span th:text="${info.orderDay}">1</span></td>
|
||||
<td>总重:<span th:text="${info.weight}">348.41</span></td>
|
||||
<td>页码:<span th:text="${pageStat.count}">1</span>/<span th:text="${pageStat.size}">2</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="data-item" th:each="item,itemStat : ${page.datas}">
|
||||
<div class="cell" style="height: 300px;">
|
||||
<div class="cell-img">
|
||||
<img style="width: 150px;height: 250px;" alt=""
|
||||
th:src="${!#strings.isEmpty(item.image)} ? ${item.image} : (${#strings.isEmpty(item.materialNo)} ? '' : 'http://192.168.163.83:9090/nflg-wms/template/none.png')"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cell">SAP编码:<span th:text="${item.materialNo}">2222222222</span></div>
|
||||
<div class="cell1">图号:<span
|
||||
th:text="${item.drawingNo}">图号图号图号图号图号图号图号图号图号图号图号图号图号图号图号图号</span>
|
||||
</div>
|
||||
<div class="cell1">名称:<span
|
||||
th:text="${item.materialDescribe}">名称名称名称名称名称名称名称名称名称名名称名名称名称名称称名称名称名称称名称名称名称</span>
|
||||
</div>
|
||||
<div class="cell">数量:<span th:text="${item.num}">1</span> 重量:<span
|
||||
th:text="${item.weight}">348.41</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,10 +1,20 @@
|
|||
logging:
|
||||
loki:
|
||||
url: http://192.168.163.83:3100/loki/api/v1/push
|
||||
url: http://192.168.163.85:3100/loki/api/v1/push
|
||||
level:
|
||||
root: info
|
||||
com:
|
||||
nflg: debug
|
||||
alibaba:
|
||||
cloud:
|
||||
nacos: info
|
||||
nacos: info
|
||||
spring:
|
||||
datasource:
|
||||
hikari:
|
||||
pool-name: WmsSrmReceiveProdPool
|
||||
maximum-pool-size: 20
|
||||
minimum-idle: 20
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
leak-detection-threshold: 60000
|
||||
|
|
@ -13,10 +13,14 @@ spring:
|
|||
import: nacos:shared.properties?group=${spring.profiles.active}&refreshEnabled=true
|
||||
cloud:
|
||||
nacos:
|
||||
username: ${nacos.username:}
|
||||
password: ${nacos.password:}
|
||||
config:
|
||||
server-addr: ${nacos.server-addr:192.168.163.83:8848}
|
||||
namespace: wms
|
||||
group: ${spring.profiles.active}
|
||||
file-extension: properties
|
||||
refresh-enabled: true
|
||||
discovery:
|
||||
server-addr: ${nacos.server-addr:192.168.163.83:8848}
|
||||
namespace: wms
|
||||
|
|
|
|||
Loading…
Reference in New Issue