Compare commits

...

143 Commits

Author SHA1 Message Date
HuangHuiKang 577b59e982 fix:修改仓库库存,仓库明细相关接口 21 hours ago
liutao 6099084d6b 打印配置新增查询条件 23 hours ago
liutao 04ad97606e 打印配置新增三个字段 24 hours ago
liutao fb868edb63 修改设备维修、点检任务、点检记录 1 day ago
liutao 2870477097 Merge remote-tracking branch 'origin/main' 3 days ago
liutao e45dcb2945 打印机配置update 3 days ago
HuangHuiKang 71cffc2a1e feat:新增模具组字段 4 days ago
HuangHuiKang ab03c51450 feat:新增盘点单相关接口 4 days ago
HuangHuiKang 950df74b83 fix:修改模具组接口 4 days ago
HuangHuiKang 9baafe4755 fix:修改仓库出入库单据审核流程 4 days ago
liutao 3c8384751e 打印机配置 4 days ago
HuangHuiKang f10deea93a fix:修改仓储入库单据相关接口 5 days ago
HuangHuiKang ef7c95bcac fix:添加物料和备件采购单位字段 5 days ago
HuangHuiKang 067d78a51f fix:修改模具出入库后模具组状态及修改审批流程 5 days ago
HuangHuiKang 7f905fa2af fix:添加出入库单据物料分类字段 5 days ago
HuangHuiKang df9899ed09 fix:添加模具组在库状态 6 days ago
HuangHuiKang 5d09204f8f fix:修改出库单据接口 6 days ago
HuangHuiKang 16ebe147af fix:产品添加图片字段 6 days ago
HuangHuiKang 4c60ac4563 fix:添加批量新增压网记录接口 6 days ago
HuangHuiKang a3634e88dd fix:修改入库单据问题 6 days ago
HuangHuiKang 623c14fd99 fix:添加设备台账顶级分类 6 days ago
HuangHuiKang 75889f05cd fix:修复点检保养问题 7 days ago
HuangHuiKang 9907ec6c7c fix:修改添加入库单据相关审批接口 7 days ago
HuangHuiKang d6879bb617 fix:修改模具组维护点检/维护新增接口 7 days ago
HuangHuiKang 7e9b743544 fix:入库单据添加库区id及快照名称 7 days ago
HuangHuiKang 3f0b8e3d31 feat:添加产品相关字段 1 week ago
HuangHuiKang 36fdf46263 feat:添加产品关联包装方案 1 week ago
HuangHuiKang 0688ca49d9 feat:添加包装方案页面 1 week ago
HuangHuiKang a34c5cf60e fix:修复模具组模糊查询 1 week ago
HuangHuiKang b2a9857887 fix:修复模具组相关问题 1 week ago
HuangHuiKang 5f370f6c2f fix:添加产品分类树状列表接口 1 week ago
HuangHuiKang d081c4d0d7 fix:添加产品分类树状列表接口 1 week ago
HuangHuiKang 2a842d54f4 fix:修改模具出库及模具入库接口 1 week ago
liutao 71e1e85bd5 设备台账扫描查询接口修改 1 week ago
liutao 279ec3d5eb 设备台账车间显示产线 1 week ago
HuangHuiKang b96ee62ff9 fix:修改新增子模具压网接口。新增点检保养接口 2 weeks ago
HuangHuiKang 4bca0543fa Merge remote-tracking branch 'origin/main' into main 2 weeks ago
liutao a2d5172d1f Merge remote-tracking branch 'origin/main' 2 weeks ago
liutao 78028d46e6 设备点检任务,记录接口修改 2 weeks ago
HuangHuiKang 7f0a1f8852 fix:添加子模具压网时间 2 weeks ago
HuangHuiKang ce82871a5f fix:1、修改模具出库,模具入库,维修项目,维修单,点检任务模具为模具组。2、添加设备台账及模具组维修单list接口。3、修改上下模相关接口 2 weeks ago
liutao 30c071de31 Merge remote-tracking branch 'origin/main' 2 weeks ago
liutao 08de3331f4 设备维修接口修改 2 weeks ago
HuangHuiKang 9229c9cbad fix:修改模具管理为模具组相关接口 2 weeks ago
HuangHuiKang d50cd0dc94 Merge remote-tracking branch 'origin/main' into main 2 weeks ago
liutao 2ceae37dc9 Merge remote-tracking branch 'origin/main' 2 weeks ago
liutao 273f46b841 设备台账接口修改 2 weeks ago
HuangHuiKang 7b6cc825c0 fix:修改模具维修单 2 weeks ago
HuangHuiKang 167f85e648 fix:产品分类类型问题 2 weeks ago
HuangHuiKang a21f92779c fix:修改产品物料模块 2 weeks ago
liutao a90d9e557f 取消删除校验 2 weeks ago
liutao 5999814527 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/deviceledger/vo/DeviceLedgerSaveReqVO.java
3 weeks ago
liutao 6c47b7a529 设备关键件明细的保存更新删除 3 weeks ago
HuangHuiKang d01f508d1d fix:修改点检记录编码为模糊查询 3 weeks ago
HuangHuiKang 80f4f07c83 fix:添加维修单告警等级,修复菜单权限问题,修复点检保养问题,添加点检记录list接口,添加产品分类字段 3 weeks ago
HuangHuiKang b4c11c8d29 fix:修改设备台账字段、修改维修单相关字段,添加点检任务设备id过滤条件 3 weeks ago
HuangHuiKang cae6e64c65 feat:优化设备台账新增接口,修复关联关键件、备件回显问题 3 weeks ago
HuangHuiKang a5698d1449 feat:添加设备台账产线相关接口及扫码器菜单字段 3 weeks ago
liutao 110ed1e424 Merge remote-tracking branch 'origin/main' 3 weeks ago
liutao b398ba86d8 提交阿里云的dev数据库 3 weeks ago
HuangHuiKang 50fa59507e fix:修复打印模板问题 4 weeks ago
HuangHuiKang 5996a0b532 fix:关闭线上接口文档访问 4 weeks ago
liutao d0752db094 Merge remote-tracking branch 'origin/main' 4 weeks ago
HuangHuiKang 01e1533304 fix:新增报表模板管理模块 4 weeks ago
liutao 06c83b3303 分类增加导入功能 4 weeks ago
HuangHuiKang ed352141e0 fix:菜单权限问题 4 weeks ago
HuangHuiKang 84c6c16278 feat:app端权限管理修改及功能导航模块 4 weeks ago
liutao 3984fbe953 增加昨日的数据对比 1 month ago
liutao ab4d198ee2 能耗实体类 1 month ago
liutao 8546d1e67e 能源概览接口 1 month ago
HuangHuiKang 8fcf74187b feat:新增打印模板相关接口 1 month ago
HuangHuiKang 4b08408511 feat:优化app概况接口 1 month ago
HuangHuiKang 13183a6a2a feat:添加app质量概况接口 1 month ago
HuangHuiKang 1ea54b1f57 fix:修改产能报表 1 month ago
HuangHuiKang a7863b39b5 feat:添加产能报表相关接口 1 month ago
HuangHuiKang dbc47aa249 fix:优化产能时间 1 month ago
liutao 0af3e8757f Merge remote-tracking branch 'origin/main' 1 month ago
liutao 9585c9eb96 优化代码 1 month ago
liutao 719cfb797e 设备运行总览 1 month ago
liutao b85e6e7360 设备运行概览接口 1 month ago
HuangHuiKang 380a4a3bd1 fix:修改prod配置文件 1 month ago
liutao 5c1055b821 Merge remote-tracking branch 'origin/main' 1 month ago
HuangHuiKang 000aa526e8 fix:修改采集设备产能 1 month ago
HuangHuiKang 4dc54fcbc8 fix:添加报工产能回显 1 month ago
HuangHuiKang 5ca9c9112a fix:添加报工数、数据采集的产量排产的算法 1 month ago
HuangHuiKang 999dd4f12e Merge remote-tracking branch 'origin/main' into main
# Conflicts:
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java
#	yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java
2 months ago
liutao c40230913f 设备增加图片字段 2 months ago
必硕 b84682b9f4 Merge pull request '产品物料信息增加编码搜索条件' (#1) from ck into main
Reviewed-on: #1
2 months ago
ck-chenkang 564726280b 产品物料信息增加编码搜索条件 2 months ago
liutao a9a910ed8f 防止key为null的情况 2 months ago
liutao 77320d3da3 历史记录查询接口 2 months ago
HuangHuiKang b67ff2879c fix:优化采集设备分页查询接口 2 months ago
HuangHuiKang fcc3cf46c0 feat:新增库区和库位页面 2 months ago
HuangHuiKang ec455718f1 fix:app扫码查询相关接口添加编码过滤条件 2 months ago
HuangHuiKang c2ec3f0dbf fix:优化app统计报表查询速度 2 months ago
liutao 00f5b71f27 Merge remote-tracking branch 'origin/main' 2 months ago
liutao d85744aba4 增加单设备监控的查询接口 2 months ago
HuangHuiKang 728121dd77 fix:修复已知问题,添加修改计算损耗率。 2 months ago
liutao 15dc437e4e 增加查询采集设备的接口 2 months ago
HuangHuiKang 09a2c8458c fix:修复已知问题,修改添加检验模板关联产品 2 months ago
HuangHuiKang e6197fd60a fix:修复已知问题 2 months ago
HuangHuiKang 92feeb7f84 fix:修改生产整体概况返回 2 months ago
HuangHuiKang a8fb7cd262 feat:完成生产计划报表相关接口 2 months ago
HuangHuiKang ead8061756 feat:完成app统计报表 2 months ago
HuangHuiKang 6923984f8f feat:完成app统计报表 2 months ago
HuangHuiKang 29567d00af fix:修改redis 2 months ago
HuangHuiKang b31e3ede4f fix:产线列表返回采集设备名称 2 months ago
HuangHuiKang a6031a0c30 fix:1、修改生产计划入库时可选仓库。2、修改产线只能选择一对一的采集设备。 2 months ago
HuangHuiKang f804a95f24 fix:添加计划状态 2 months ago
HuangHuiKang 6d651523c3 fix:修改时间返回格式 2 months ago
HuangHuiKang a1db78fd3d fix:添加app-设备概况接口 2 months ago
HuangHuiKang c2bde1b2b9 fix:添加app-生产概况-任务统计 2 months ago
HuangHuiKang 7616b34052 fix:添加app-生产概况-产品时间筛选 2 months ago
HuangHuiKang 6185639d4a Merge remote-tracking branch 'origin/main' into main 2 months ago
liutao 90e5cd0654 去掉多余的规格型号 2 months ago
HuangHuiKang 0e54bd9035 feat:添加甘特图计划状态字段 2 months ago
HuangHuiKang dee985829f feat:报工记录添加勾选导出 2 months ago
HuangHuiKang 6030506c8b feat:添加app-首页报表-生产概况-产品统计 2 months ago
HuangHuiKang 5dd2d7fa59 feat:添加报工记录页面及修改甘特图返回 2 months ago
HuangHuiKang 4935872568 fix:修复任务单状态问题 2 months ago
liutao 75408b486b 增加查询条件 2 months ago
HuangHuiKang 5ab15ccca2 fix:修改任务单相关状态 2 months ago
HuangHuiKang 50a0b97572 fix:添加甘特图返回字段,修改bom物料信息取消合并 2 months ago
HuangHuiKang d4d3ad4f57 fix:修改物料信息单位限制 2 months ago
HuangHuiKang f5be8bc03a feat:生成甘特图添加生产时间安排以及是否跳过节假日条件 2 months ago
HuangHuiKang b19632ab32 fix:修改添加生产计划-已完工状态 2 months ago
HuangHuiKang c465299f08 feat:排产任务单汇总明细列表展示编辑关联设备 2 months ago
liutao 1a389d8df3 Merge remote-tracking branch 'origin/main' 2 months ago
liutao bf213b6da5 修改字段类型 2 months ago
HuangHuiKang 70936e690d feat:新增一件排产及甘特图功能模块 2 months ago
liutao bc85d4e924 导入功能实体 2 months ago
liutao 24f11f4deb Merge remote-tracking branch 'origin/main' 2 months ago
liutao e99d6e36c0 关键件增加图片上传 2 months ago
HuangHuiKang a86d70c0a6 feat:新增数据采集产能 2 months ago
liutao 5b7456c50a 实体类增加字段 2 months ago
HuangHuiKang 977a16e6c9 feat:新增排产功能模块相关字段,修改新增计划接口 2 months ago
liutao bc9159c1ac 大屏查询接口无携带租户编号 3 months ago
liutao 04cc023b4f 查询大屏接口取消拦截 3 months ago
HuangHuiKang 835fa5b271 fix:新增点位添加限制 3 months ago
HuangHuiKang 1b90a076fe feat:修改采集设备点位删除逻辑 3 months ago
liutao 0bbac34d67 Merge branch 'liutao_branch' 3 months ago
HuangHuiKang 9c46da356f feat:prod配置文件 3 months ago
HuangHuiKang 00681c954e feat:新增生成二维码功能 3 months ago

@ -70,10 +70,13 @@
<netty.version>4.1.113.Final</netty.version> <netty.version>4.1.113.Final</netty.version>
<mqtt.version>1.2.5</mqtt.version> <mqtt.version>1.2.5</mqtt.version>
<opc.version>0.6.9</opc.version> <opc.version>0.6.9</opc.version>
<qrcode.version>3.5.3</qrcode.version>
<!-- 三方云服务相关 --> <!-- 三方云服务相关 -->
<commons-io.version>2.17.0</commons-io.version> <commons-io.version>2.17.0</commons-io.version>
<commons-compress.version>1.27.1</commons-compress.version> <commons-compress.version>1.27.1</commons-compress.version>
<aws-java-sdk-s3.version>1.12.777</aws-java-sdk-s3.version> <aws-java-sdk-s3.version>1.12.777</aws-java-sdk-s3.version>
<s3.version>2.41.33</s3.version>
<justauth.version>1.0.8</justauth.version> <justauth.version>1.0.8</justauth.version>
<jimureport.version>1.7.8</jimureport.version> <jimureport.version>1.7.8</jimureport.version>
<weixin-java.version>4.6.0</weixin-java.version> <weixin-java.version>4.6.0</weixin-java.version>
@ -589,6 +592,17 @@
<version>${aws-java-sdk-s3.version}</version> <version>${aws-java-sdk-s3.version}</version>
</dependency> </dependency>
<!-- <dependency>-->
<!-- <groupId>software.amazon.awssdk</groupId>-->
<!-- <artifactId>s3</artifactId>-->
<!-- <version>${s3.version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>software.amazon.awssdk</groupId>-->
<!-- <artifactId>sts</artifactId>-->
<!-- <version>${s3.version}</version>-->
<!-- </dependency>-->
<dependency> <dependency>
<groupId>com.xingyuv</groupId> <groupId>com.xingyuv</groupId>
<artifactId>spring-boot-starter-justauth</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) --> <artifactId>spring-boot-starter-justauth</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
@ -648,6 +662,16 @@
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
<version>${logback.version}</version> <version>${logback.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>${qrcode.version}</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>${qrcode.version}</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>

@ -35,7 +35,7 @@ public interface GlobalErrorCodeConstants {
// ========== 自定义错误段 ========== // ========== 自定义错误段 ==========
ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求 ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求
ErrorCode DEMO_DENY = new ErrorCode(901, "演示模式,禁止写操作"); ErrorCode DEMO_DENY = new ErrorCode(901, "演示模式,禁止写操作");
ErrorCode DEVICE_CONTACT_MODEL_NOT_EXISTS = new ErrorCode(902, "查询不到该设备"); ErrorCode DEVICE_CONTACT_MODEL_NOT_EXISTS = new ErrorCode(902, "查询不到该点位");
ErrorCode UNKNOWN = new ErrorCode(999, "未知错误"); ErrorCode UNKNOWN = new ErrorCode(999, "未知错误");

@ -28,9 +28,12 @@ import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.NoHandlerFoundException; import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException; import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException; import javax.validation.ValidationException;
@ -385,4 +388,90 @@ public class GlobalExceptionHandler {
return null; return null;
} }
/**
*
*/
@ExceptionHandler(MaxUploadSizeExceededException.class)
public CommonResult<String> handleMaxUploadSizeExceededException(
MaxUploadSizeExceededException e,
HttpServletRequest request,
HttpServletResponse response) {
log.error("文件上传大小超出限制: {}", request.getRequestURI(), e);
// 从异常信息中提取实际大小和限制大小
String errorMessage = extractSizeInfo(e);
return CommonResult.error(400,
String.format("文件大小超出限制。%s 请上传小于500MB的文件", errorMessage)
);
}
/**
* Multipart
*/
@ExceptionHandler(MultipartException.class)
public CommonResult<String> handleMultipartException(
MultipartException e,
HttpServletRequest request) {
log.error("文件上传异常: {}", request.getRequestURI(), e);
if (e.getMessage().contains("SizeLimitExceededException")) {
return CommonResult.error(400, "文件大小超出限制请上传小于500MB的文件");
} else if (e.getMessage().contains("FileSizeLimitExceededException")) {
return CommonResult.error(400, "单个文件大小超出限制请上传小于500MB的文件");
} else if (e.getMessage().contains("临时文件夹")) {
return CommonResult.error(400, "临时文件夹不可用,请检查磁盘空间");
}
return CommonResult.error(400, "文件上传失败:" + e.getMessage());
}
/**
*
*/
private String extractSizeInfo(MaxUploadSizeExceededException e) {
String message = e.getMessage();
try {
// 解析异常信息,提取大小数据
if (message.contains("exceeds the configured maximum")) {
// 格式: ... size (367254613) exceeds the configured maximum (104857600)
String sizePart = message.substring(message.indexOf("size (") + 6);
String actualSizeStr = sizePart.substring(0, sizePart.indexOf(")"));
String maxPart = message.substring(message.indexOf("maximum (") + 9);
String maxSizeStr = maxPart.substring(0, maxPart.indexOf(")"));
long actualSize = Long.parseLong(actualSizeStr);
long maxSize = Long.parseLong(maxSizeStr);
return String.format("实际大小: %s, 限制大小: %s",
formatFileSize(actualSize),
formatFileSize(maxSize)
);
}
} catch (Exception ex) {
log.error("解析文件大小信息失败", ex);
}
return "请检查文件大小";
}
/**
*
*/
private String formatFileSize(long size) {
if (size < 1024) {
return size + " B";
} else if (size < 1024 * 1024) {
return String.format("%.2f KB", size / 1024.0);
} else if (size < 1024 * 1024 * 1024) {
return String.format("%.2f MB", size / (1024.0 * 1024.0));
} else {
return String.format("%.2f GB", size / (1024.0 * 1024.0 * 1024.0));
}
}
} }

@ -0,0 +1,16 @@
package cn.iocoder.yudao.module.common.api.mold.enums;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
/**
* ERP
* <p>
* erp 使 1-030-000-000
*/
public interface ErrorCodeConstants {
// ========== 二维码记录表1-030-100-000 ==========
ErrorCode RECORD_NOT_EXISTS = new ErrorCode(1_003_000_000, "通用二维码记录不存在。");
ErrorCode FAILED_TO_REGENERATE = new ErrorCode(1_003_000_001, "重新生成二维码/条形码错误。");
}

@ -16,6 +16,12 @@
<description>common 模块业务实现</description> <description>common 模块业务实现</description>
<dependencies> <dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<!-- 模块自身 --> <!-- 模块自身 -->
<dependency> <dependency>
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
@ -56,6 +62,14 @@
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId> <artifactId>yudao-spring-boot-starter-excel</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

@ -29,6 +29,27 @@ public class MoldBrandPageReqVO extends PageParam {
@Schema(description = "产品ID", example = "2336") @Schema(description = "产品ID", example = "2336")
private Long productId; private Long productId;
@Schema(description = "产品名称", example = "产品A")
private String productName;
@Schema(description = "图片")
private String images;
@Schema(description = "版本", example = "V1.0")
private String version;
@Schema(description = "状态", example = "0")
private Integer status;
@Schema(description = "排除状态", example = "4")
private Integer excludeStatus;
@Schema(description = "当前位置", example = "一号机台")
private String currentPosition;
@Schema(description = "设备名称", example = "注塑机")
private String deviceName;
@Schema(description = "预期寿命(小时)") @Schema(description = "预期寿命(小时)")
private BigDecimal useTime; private BigDecimal useTime;
@ -56,4 +77,7 @@ public class MoldBrandPageReqVO extends PageParam {
@Schema(description = "id集合导出用") @Schema(description = "id集合导出用")
private String ids; private String ids;
@Schema(description = "关键字(匹配编码/名称/产品型号)")
private String keyword;
} }

@ -40,6 +40,7 @@ public class MoldBrandRespVO {
// @ExcelProperty("产品") // @ExcelProperty("产品")
private String productName; private String productName;
@Schema(description = "预期寿命/次") @Schema(description = "预期寿命/次")
@ExcelProperty("预期寿命/次") @ExcelProperty("预期寿命/次")
private BigDecimal useTime; private BigDecimal useTime;

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.common.controller.admin.mold.vo; package cn.iocoder.yudao.module.common.controller.admin.mold.vo;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.common.enums.MoldBrandStatusEnum;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -7,6 +9,7 @@ import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.List;
@Schema(description = "管理后台 - 模具型号新增/修改 Request VO") @Schema(description = "管理后台 - 模具型号新增/修改 Request VO")
@Data @Data
@ -16,7 +19,7 @@ public class MoldBrandSaveReqVO {
private Long id; private Long id;
@Schema(description = "型号编码", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "型号编码", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "型号编码不能为空") // @NotEmpty(message = "型号编码不能为空")
private String code; private String code;
@Schema(description = "型号名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") @Schema(description = "型号名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
@ -24,13 +27,41 @@ public class MoldBrandSaveReqVO {
private String name; private String name;
@Schema(description = "规格", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @Schema(description = "规格", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotEmpty(message = "规格不能为空") // @NotEmpty(message = "规格不能为空")
private String moldType; private String moldType;
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2336") @Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2336")
// @NotNull(message = "产品ID不能为空") // @NotNull(message = "产品ID不能为空")
private Long productId; private Long productId;
@Schema(description = "产品名称", example = "产品A")
private String productName;
@Schema(description = "产品ID列表可多选")
private List<Long> productIds;
@Schema(description = "图片", example = "https://example.com/mold.png")
private String images;
@Schema(description = "图纸", example = "https://example.com/drawing.pdf")
private String drawings;
@Schema(description = "操作手册", example = "https://example.com/manual.pdf")
private String operationManual;
@Schema(description = "操作视频", example = "https://example.com/video.mp4")
private String operationVideo;
@Schema(description = "版本", example = "V1.0")
private String version;
@Schema(description = "状态", example = "0")
@InEnum(MoldBrandStatusEnum.class)
private Integer status;
@Schema(description = "当前位置", example = "一号机台")
private String currentPosition;
@Schema(description = "预期寿命(小时)") @Schema(description = "预期寿命(小时)")
private BigDecimal useTime; private BigDecimal useTime;

@ -23,6 +23,18 @@ public class MoldPageReqVO extends PageParam {
@Schema(description = "模具名称", example = "芋艿") @Schema(description = "模具名称", example = "芋艿")
private String name; private String name;
@Schema(description = "类型")
private String type;
@Schema(description = "安装位置")
private String installLocation;
@Schema(description = "材质")
private String material;
@Schema(description = "数量")
private Integer quantity;
@Schema(description = "单位ID", example = "19527") @Schema(description = "单位ID", example = "19527")
private Long unitId; private Long unitId;

@ -28,6 +28,9 @@ public class MoldProductRespVO {
@ExcelProperty("产品") @ExcelProperty("产品")
private String productName; private String productName;
@Schema(description = "产品名称快照", example = "产品A")
private String productNameSnapshot;
@Schema(description = "备注", example = "你猜") @Schema(description = "备注", example = "你猜")
@ExcelProperty("备注") @ExcelProperty("备注")
private String remark; private String remark;

@ -1,5 +1,10 @@
package cn.iocoder.yudao.module.common.controller.admin.mold.vo; package cn.iocoder.yudao.module.common.controller.admin.mold.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import java.util.*; import java.util.*;
@ -31,6 +36,22 @@ public class MoldRespVO {
@ExcelProperty("模具名称") @ExcelProperty("模具名称")
private String name; private String name;
@Schema(description = "类型")
@ExcelProperty("类型")
private String type;
@Schema(description = "安装位置")
@ExcelProperty("安装位置")
private String installLocation;
@Schema(description = "材质")
@ExcelProperty("材质")
private String material;
@Schema(description = "数量")
@ExcelProperty("数量")
private Integer quantity;
@Schema(description = "单位ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "19527") @Schema(description = "单位ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "19527")
private Long unitId; private Long unitId;
@ -86,4 +107,19 @@ public class MoldRespVO {
@ExcelProperty("附件地址") @ExcelProperty("附件地址")
private String fileUrl; private String fileUrl;
@Schema(description = "压网时间")
@ExcelProperty("压网时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime pressureNetTime;
@Schema(description = "压网天数")
@ExcelProperty("压网天数")
private Long pressureNetDays;
} }

@ -16,13 +16,25 @@ public class MoldSaveReqVO {
private Long id; private Long id;
@Schema(description = "模具编码", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "模具编码", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "模具编码不能为空") // @NotEmpty(message = "模具编码不能为空")
private String code; private String code;
@Schema(description = "模具名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") @Schema(description = "模具名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
@NotEmpty(message = "模具名称不能为空") @NotEmpty(message = "模具名称不能为空")
private String name; private String name;
@Schema(description = "类型")
private String type;
@Schema(description = "安装位置")
private String installLocation;
@Schema(description = "材质")
private String material;
@Schema(description = "数量")
private Integer quantity;
@Schema(description = "单位ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "19527") @Schema(description = "单位ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "19527")
// @NotNull(message = "单位ID不能为空") // @NotNull(message = "单位ID不能为空")
private Long unitId; private Long unitId;

@ -72,6 +72,8 @@ public class MoldRepairPageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime; private LocalDateTime[] createTime;
@Schema(description = "维修结果")
private Integer repairStatus;
@Schema(description = "ids集合导出用") @Schema(description = "ids集合导出用")
private String ids; private String ids;

@ -113,5 +113,49 @@ public class MoldRepairRespVO {
@ExcelProperty("维修状态") @ExcelProperty("维修状态")
private String repairStatusName; private String repairStatusName;
@Schema(description = "故障等级 1-一般 2-严重 3-紧急")
@ExcelProperty("故障等级")
private Integer faultLevel;
@Schema(description = "是否停机")
@ExcelProperty("是否停机")
private Boolean shutdown;
@Schema(description = "故障现象")
@ExcelProperty("故障现象")
private String faultPhenomenon;
@Schema(description = "故障描述")
@ExcelProperty("故障描述")
private String faultDescription;
@Schema(description = "故障图片,多个逗号分隔")
@ExcelProperty("故障图片")
private String faultImages;
@Schema(description = "停机时长")
@ExcelProperty("停机时长")
private String shutdownDuration;
@Schema(description = "故障原因")
@ExcelProperty("故障原因")
private String faultReason;
@Schema(description = "处理措施")
@ExcelProperty("处理措施")
private String treatmentMeasures;
@Schema(description = "更换配件")
@ExcelProperty("更换配件")
private String replacementParts;
@Schema(description = "维修总结/维修内容")
@ExcelProperty("维修总结/维修内容")
private String repairSummary;
@Schema(description = "维修后图片,多个逗号分隔")
@ExcelProperty("维修后图片")
private String repairedImages;
} }

@ -52,9 +52,12 @@ public class MoldRepairSaveReqVO {
@Schema(description = "验收日期") @Schema(description = "验收日期")
private LocalDateTime confirmDate; private LocalDateTime confirmDate;
//
// @Schema(description = "维修结果")
// private String repairResult;
@Schema(description = "维修结果") @Schema(description = "维修结果")
private String repairResult; private String repairStatus;
@Schema(description = "维修人员") @Schema(description = "维修人员")
private String acceptedBy; private String acceptedBy;
@ -80,4 +83,37 @@ public class MoldRepairSaveReqVO {
@Schema(description = "关键件Id") @Schema(description = "关键件Id")
private Long componentId; private Long componentId;
@Schema(description = "故障等级 1-一般 2-严重 3-紧急")
private Integer faultLevel;
@Schema(description = "是否停机")
private Boolean shutdown;
@Schema(description = "故障现象")
private String faultPhenomenon;
@Schema(description = "故障描述")
private String faultDescription;
@Schema(description = "故障图片,多个逗号分隔")
private String faultImages;
@Schema(description = "停机时长")
private String shutdownDuration;
@Schema(description = "故障原因")
private String faultReason;
@Schema(description = "处理措施")
private String treatmentMeasures;
@Schema(description = "更换配件")
private String replacementParts;
@Schema(description = "维修总结/维修内容")
private String repairSummary;
@Schema(description = "维修后图片,多个逗号分隔")
private String repairedImages;
} }

@ -0,0 +1,122 @@
package cn.iocoder.yudao.module.common.controller.admin.qrcoderecord;
import cn.iocoder.yudao.module.common.controller.admin.qrcoderecord.vo.QrcodeRecordPageReqVO;
import cn.iocoder.yudao.module.common.controller.admin.qrcoderecord.vo.QrcodeRecordRespVO;
import cn.iocoder.yudao.module.common.controller.admin.qrcoderecord.vo.QrcodeRecordSaveReqVO;
import cn.iocoder.yudao.module.common.dal.dataobject.qrcoderecord.QrcodeRecordDO;
import cn.iocoder.yudao.module.common.service.qrcordrecord.QrcodeRecordService;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
@Tag(name = "管理后台 - 通用二维码记录")
@RestController
@RequestMapping("/qrcode/record")
@Validated
public class QrcodeRecordController {
@Resource
private QrcodeRecordService qrcodeRecordService;
@PostMapping("/create")
@Operation(summary = "创建通用二维码记录")
@PreAuthorize("@ss.hasPermission('qrcode:record:create')")
public CommonResult<Long> createRecord(@Valid @RequestBody QrcodeRecordSaveReqVO createReqVO) {
return success(qrcodeRecordService.createRecord(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新通用二维码记录")
@PreAuthorize("@ss.hasPermission('qrcode:record:update')")
public CommonResult<Boolean> updateRecord(@Valid @RequestBody QrcodeRecordSaveReqVO updateReqVO) {
qrcodeRecordService.updateRecord(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除通用二维码记录")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('qrcode:record:delete')")
public CommonResult<Boolean> deleteRecord(@RequestParam("id") Long id) {
qrcodeRecordService.deleteRecord(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得通用二维码记录")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('qrcode:record:query')")
public CommonResult<QrcodeRecordRespVO> getRecord(@RequestParam("id") Long id) {
QrcodeRecordDO record = qrcodeRecordService.getRecord(id);
return success(BeanUtils.toBean(record, QrcodeRecordRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得通用二维码记录分页")
@PreAuthorize("@ss.hasPermission('qrcode:record:query')")
public CommonResult<PageResult<QrcodeRecordRespVO>> getRecordPage(@Valid QrcodeRecordPageReqVO pageReqVO) {
PageResult<QrcodeRecordDO> pageResult = qrcodeRecordService.getRecordPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, QrcodeRecordRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出通用二维码记录 Excel")
@PreAuthorize("@ss.hasPermission('qrcode:record:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportRecordExcel(@Valid QrcodeRecordPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<QrcodeRecordDO> list = qrcodeRecordService.getRecordPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "通用二维码记录.xls", "数据", QrcodeRecordRespVO.class,
BeanUtils.toBean(list, QrcodeRecordRespVO.class));
}
//TODO 扫二维码拉起app端,仍需app拉起连接地址。
// @GetMapping(value = "/scan", produces = "text/html;charset=UTF-8")
// @Operation(summary = "扫二维码拉起app端 ")
// @PermitAll
// public void scan(@RequestParam("type") String type,
// @RequestParam("id") Long id,
// @RequestParam(required=false) String code,
// HttpServletResponse response) throws IOException {
// String html = qrcodeRecordService.buildScanTransitHtml(type, id,code);
// response.setContentType("text/html;charset=UTF-8");
// response.getWriter().write(html);
// }
@GetMapping("/scan/resolve-id")
@Operation(summary = "扫二维码返回对应id ")
@PermitAll
public CommonResult<Map<String, Object>> resolveId(@RequestParam String type,
@RequestParam Long id,
@RequestParam String code) {
return success(qrcodeRecordService.resolveScanBizId(type, id, code));
}
}

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.common.controller.admin.qrcoderecord.vo;
import lombok.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 通用二维码记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class QrcodeRecordPageReqVO extends PageParam {
@Schema(description = "业务类型MOLD/PRODUCT/EQUIPMENT/PART/SPARE/WORK_ORDER", example = "2")
private String bizType;
@Schema(description = "业务ID", example = "31277")
private Long bizId;
@Schema(description = "业务编码")
private String bizCode;
@Schema(description = "二维码场景DETAIL/LABEL/TRACE")
private String qrScene;
@Schema(description = "二维码内容(扫码入口地址)")
private String qrContent;
@Schema(description = "二维码文件名", example = "芋艿")
private String fileName;
@Schema(description = "MinIO bucket名称", example = "王五")
private String bucketName;
@Schema(description = "MinIO对象路径", example = "赵六")
private String objectName;
@Schema(description = "二维码图片访问地址", example = "https://www.iocoder.cn")
private String qrcodeFileUrl;
@Schema(description = "文件MIME类型", example = "1")
private String mimeType;
@Schema(description = "文件大小(字节)")
private Long fileSize;
@Schema(description = "状态1-有效 0-失效", example = "1")
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "QR(二维码)/BARCODE(条形码)", example = "")
private String codeType;
}

@ -0,0 +1,73 @@
package cn.iocoder.yudao.module.common.controller.admin.qrcoderecord.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 通用二维码记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class QrcodeRecordRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "28938")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "业务类型MOLD/PRODUCT/EQUIPMENT/PART/SPARE/WORK_ORDER", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("业务类型MOLD/PRODUCT/EQUIPMENT/PART/SPARE/WORK_ORDER")
private String bizType;
@Schema(description = "业务ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "31277")
@ExcelProperty("业务ID")
private Long bizId;
@Schema(description = "业务编码")
@ExcelProperty("业务编码")
private String bizCode;
@Schema(description = "二维码场景DETAIL/LABEL/TRACE", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("二维码场景DETAIL/LABEL/TRACE")
private String qrScene;
@Schema(description = "二维码内容(扫码入口地址)", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("二维码内容(扫码入口地址)")
private String qrContent;
@Schema(description = "二维码文件名", example = "芋艿")
@ExcelProperty("二维码文件名")
private String fileName;
@Schema(description = "MinIO bucket名称", example = "王五")
@ExcelProperty("MinIO bucket名称")
private String bucketName;
@Schema(description = "MinIO对象路径", example = "赵六")
@ExcelProperty("MinIO对象路径")
private String objectName;
@Schema(description = "二维码图片访问地址", example = "https://www.iocoder.cn")
@ExcelProperty("二维码图片访问地址")
private String qrcodeFileUrl;
@Schema(description = "文件MIME类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("文件MIME类型")
private String mimeType;
@Schema(description = "文件大小(字节)")
@ExcelProperty("文件大小(字节)")
private Long fileSize;
@Schema(description = "状态1-有效 0-失效", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("状态1-有效 0-失效")
private Integer status;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "QR(二维码)/BARCODE(条形码)", example = "")
private String codeType;
}

@ -0,0 +1,61 @@
package cn.iocoder.yudao.module.common.controller.admin.qrcoderecord.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 通用二维码记录新增/修改 Request VO")
@Data
public class QrcodeRecordSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "28938")
private Long id;
@Schema(description = "业务类型MOLD/PRODUCT/EQUIPMENT/PART/SPARE/WORK_ORDER", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotEmpty(message = "业务类型MOLD/PRODUCT/EQUIPMENT/PART/SPARE/WORK_ORDER不能为空")
private String bizType;
@Schema(description = "业务ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "31277")
@NotNull(message = "业务ID不能为空")
private Long bizId;
@Schema(description = "业务编码")
private String bizCode;
@Schema(description = "二维码场景DETAIL/LABEL/TRACE", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "二维码场景DETAIL/LABEL/TRACE不能为空")
private String qrScene;
@Schema(description = "二维码内容(扫码入口地址)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "二维码内容(扫码入口地址)不能为空")
private String qrContent;
@Schema(description = "二维码文件名", example = "芋艿")
private String fileName;
@Schema(description = "MinIO bucket名称", example = "王五")
private String bucketName;
@Schema(description = "MinIO对象路径", example = "赵六")
private String objectName;
@Schema(description = "二维码图片访问地址", example = "https://www.iocoder.cn")
private String qrcodeFileUrl;
@Schema(description = "文件MIME类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotEmpty(message = "文件MIME类型不能为空")
private String mimeType;
@Schema(description = "文件大小(字节)")
private Long fileSize;
@Schema(description = "状态1-有效 0-失效", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态1-有效 0-失效不能为空")
private Integer status;
@Schema(description = "QR(二维码)/BARCODE(条形码)", example = "")
private String codeType;
}

@ -47,6 +47,42 @@ public class MoldBrandDO extends BaseDO {
* ID * ID
*/ */
private Long productId; private Long productId;
/**
*
*/
private String productName;
/**
*
*/
private String images;
/**
*
*/
private String drawings;
/**
*
*/
private String operationManual;
/**
*
*/
private String operationVideo;
/**
*
*/
private String version;
/**
*
*/
private Integer status;
/**
*
*/
private String currentPosition;
/** /**
* 寿() * 寿()
*/ */

@ -35,6 +35,10 @@ public class MoldBrandProductDO extends BaseDO {
* ID * ID
*/ */
private Long productId; private Long productId;
/**
*
*/
private String productName;
/** /**
* *
*/ */

@ -40,6 +40,22 @@ public class MoldDO extends BaseDO {
* *
*/ */
private String name; private String name;
/**
*
*/
private String type;
/**
*
*/
private String installLocation;
/**
*
*/
private String material;
/**
*
*/
private Integer quantity;
/** /**
* ID * ID
*/ */
@ -113,4 +129,16 @@ public class MoldDO extends BaseDO {
@TableField(exist = false) @TableField(exist = false)
private String moldType; private String moldType;
/**
*
*/
@TableField(exist = false)
private String qrcodeUrl;
/**
*
*/
@TableField(exist = false)
private String templateJson;
} }

@ -117,4 +117,59 @@ public class MoldRepairDO extends BaseDO {
*/ */
private Integer repairStatus; private Integer repairStatus;
/**
* 1- 2- 3-
*/
private Integer faultLevel;
/**
*
*/
private Boolean shutdown;
/**
*
*/
private String faultPhenomenon;
/**
*
*/
private String faultDescription;
/**
*
*/
private String faultImages;
/**
*
*/
private String shutdownDuration;
/**
*
*/
private String faultReason;
/**
*
*/
private String treatmentMeasures;
/**
*
*/
private String replacementParts;
/**
* /
*/
private String repairSummary;
/**
*
*/
private String repairedImages;
} }

@ -0,0 +1,81 @@
package cn.iocoder.yudao.module.common.dal.dataobject.qrcoderecord;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* DO
*
* @author
*/
@TableName("qrcode_record")
@KeySequence("qrcode_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class QrcodeRecordDO extends BaseDO {
/**
* ID
*/
@TableId
private Long id;
/**
* MOLD/PRODUCT/EQUIPMENT/PART/SPARE/WORK_ORDER
*/
private String bizType;
/**
* ID
*/
private Long bizId;
/**
*
*/
private String bizCode;
/**
* DETAIL/LABEL/TRACE
*/
private String qrScene;
/**
*
*/
private String qrContent;
/**
*
*/
private String fileName;
/**
* MinIO bucket
*/
private String bucketName;
/**
* MinIO
*/
private String objectName;
/**
* 访
*/
private String qrcodeFileUrl;
/**
* MIME
*/
private String mimeType;
/**
*
*/
private Long fileSize;
/**
* 1- 0-
*/
private Integer status;
/**
* QR()/BARCODE()
*/
private String codeType;
}

@ -21,14 +21,34 @@ import java.util.stream.Collectors;
@Mapper @Mapper
public interface MoldBrandMapper extends BaseMapperX<MoldBrandDO> { public interface MoldBrandMapper extends BaseMapperX<MoldBrandDO> {
default PageResult<MoldBrandDO> selectPage(MoldBrandPageReqVO reqVO) { default LambdaQueryWrapperX<MoldBrandDO> buildQueryWrapper(MoldBrandPageReqVO reqVO) {
LambdaQueryWrapperX<MoldBrandDO> queryWrapper = new LambdaQueryWrapperX<>();
if(StringUtils.isNotBlank(reqVO.getCode())&&StringUtils.isNotBlank(reqVO.getName())&&reqVO.getCode().equals(reqVO.getName())){
if(reqVO.getCode().contains("MOLD-")){
queryWrapper.eq(MoldBrandDO::getId, reqVO.getCode().replace("MOLD-",""));
}else{
queryWrapper.and(w -> w
.like(MoldBrandDO::getCode, reqVO.getCode())
.or()
.like(MoldBrandDO::getName, reqVO.getName())
);
}
}else{
queryWrapper.likeIfPresent(MoldBrandDO::getCode, reqVO.getCode())
.likeIfPresent(MoldBrandDO::getName, reqVO.getName());
}
LambdaQueryWrapperX<MoldBrandDO> moldBrandDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>(); queryWrapper
moldBrandDOLambdaQueryWrapperX /* .likeIfPresent(MoldBrandDO::getCode, reqVO.getCode())
.eqIfPresent(MoldBrandDO::getCode, reqVO.getCode()) .likeIfPresent(MoldBrandDO::getName, reqVO.getName())*/
.likeIfPresent(MoldBrandDO::getName, reqVO.getName())
.eqIfPresent(MoldBrandDO::getMoldType, reqVO.getMoldType()) .eqIfPresent(MoldBrandDO::getMoldType, reqVO.getMoldType())
.eqIfPresent(MoldBrandDO::getProductId, reqVO.getProductId()) .eqIfPresent(MoldBrandDO::getProductId, reqVO.getProductId())
.likeIfPresent(MoldBrandDO::getProductName, reqVO.getProductName())
.likeIfPresent(MoldBrandDO::getImages, reqVO.getImages())
.likeIfPresent(MoldBrandDO::getVersion, reqVO.getVersion())
.eqIfPresent(MoldBrandDO::getStatus, reqVO.getStatus())
.neIfPresent(MoldBrandDO::getStatus, reqVO.getExcludeStatus())
.likeIfPresent(MoldBrandDO::getCurrentPosition, reqVO.getCurrentPosition())
.eqIfPresent(MoldBrandDO::getUseTime, reqVO.getUseTime()) .eqIfPresent(MoldBrandDO::getUseTime, reqVO.getUseTime())
.eqIfPresent(MoldBrandDO::getMaintainType, reqVO.getMaintainType()) .eqIfPresent(MoldBrandDO::getMaintainType, reqVO.getMaintainType())
.eqIfPresent(MoldBrandDO::getMaintainTime, reqVO.getMaintainTime()) .eqIfPresent(MoldBrandDO::getMaintainTime, reqVO.getMaintainTime())
@ -39,35 +59,33 @@ public interface MoldBrandMapper extends BaseMapperX<MoldBrandDO> {
.betweenIfPresent(MoldBrandDO::getCreateTime, reqVO.getCreateTime()) .betweenIfPresent(MoldBrandDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MoldBrandDO::getId); .orderByDesc(MoldBrandDO::getId);
// 单独处理 ids 条件 //关键字(匹配编码/名称/产品型号)
if (StringUtils.isNotBlank(reqVO.getKeyword())) {
queryWrapper.and(wrapper ->
wrapper.like(MoldBrandDO::getCode, reqVO.getKeyword())
.or()
.like(MoldBrandDO::getName, reqVO.getKeyword())
.or()
.like(MoldBrandDO::getProductName, reqVO.getKeyword())
);
}
if (StringUtils.isNotBlank(reqVO.getIds())) { if (StringUtils.isNotBlank(reqVO.getIds())) {
List<Long> idList = Arrays.stream(reqVO.getIds().split(",")) List<Long> idList = Arrays.stream(reqVO.getIds().split(","))
.map(String::trim) .map(String::trim)
.map(Long::valueOf) .map(Long::valueOf)
.collect(Collectors.toList()); .collect(Collectors.toList());
moldBrandDOLambdaQueryWrapperX.in(MoldBrandDO::getId, idList); queryWrapper.in(MoldBrandDO::getId, idList);
}
return queryWrapper;
} }
return selectPage(reqVO, moldBrandDOLambdaQueryWrapperX); default PageResult<MoldBrandDO> selectPage(MoldBrandPageReqVO reqVO) {
return selectPage(reqVO, buildQueryWrapper(reqVO));
} }
default List<MoldBrandDO> selectBy(MoldBrandPageReqVO reqVO) { default List<MoldBrandDO> selectBy(MoldBrandPageReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<MoldBrandDO>() return selectList(buildQueryWrapper(reqVO));
.eqIfPresent(MoldBrandDO::getCode, reqVO.getCode())
.likeIfPresent(MoldBrandDO::getName, reqVO.getName())
.eqIfPresent(MoldBrandDO::getMoldType, reqVO.getMoldType())
.eqIfPresent(MoldBrandDO::getProductId, reqVO.getProductId())
.eqIfPresent(MoldBrandDO::getUseTime, reqVO.getUseTime())
.eqIfPresent(MoldBrandDO::getMaintainType, reqVO.getMaintainType())
.eqIfPresent(MoldBrandDO::getMaintainTime, reqVO.getMaintainTime())
.eqIfPresent(MoldBrandDO::getMoldSize, reqVO.getMoldSize())
.eqIfPresent(MoldBrandDO::getRemark, reqVO.getRemark())
.eqIfPresent(MoldBrandDO::getIsEnable, reqVO.getIsEnable())
.eqIfPresent(MoldBrandDO::getOrgType, reqVO.getOrgType())
.betweenIfPresent(MoldBrandDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MoldBrandDO::getId));
} }
} }

@ -32,4 +32,10 @@ public interface MoldBrandProductMapper extends BaseMapperX<MoldBrandProductDO>
.eqIfPresent(MoldBrandProductDO::getBrandId, reqVO.getBrandId()) .eqIfPresent(MoldBrandProductDO::getBrandId, reqVO.getBrandId())
.orderByDesc(MoldBrandProductDO::getId)); .orderByDesc(MoldBrandProductDO::getId));
} }
default List<MoldBrandProductDO> selectListByBrandIds(Collection<Long> brandIds) {
return selectList(new LambdaQueryWrapperX<MoldBrandProductDO>()
.inIfPresent(MoldBrandProductDO::getBrandId, brandIds)
.orderByDesc(MoldBrandProductDO::getId));
}
} }

@ -21,11 +21,15 @@ import java.util.stream.Collectors;
@Mapper @Mapper
public interface MoldMapper extends BaseMapperX<MoldDO> { public interface MoldMapper extends BaseMapperX<MoldDO> {
default PageResult<MoldDO> selectPage(MoldPageReqVO reqVO) { default LambdaQueryWrapperX<MoldDO> buildQueryWrapper(MoldPageReqVO reqVO) {
LambdaQueryWrapperX<MoldDO> wrapper = new LambdaQueryWrapperX<>(); LambdaQueryWrapperX<MoldDO> wrapper = new LambdaQueryWrapperX<>();
wrapper wrapper
.likeIfPresent(MoldDO::getCode, reqVO.getCode()) .likeIfPresent(MoldDO::getCode, reqVO.getCode())
.likeIfPresent(MoldDO::getName, reqVO.getName()) .likeIfPresent(MoldDO::getName, reqVO.getName())
.likeIfPresent(MoldDO::getType, reqVO.getType())
.likeIfPresent(MoldDO::getInstallLocation, reqVO.getInstallLocation())
.likeIfPresent(MoldDO::getMaterial, reqVO.getMaterial())
.eqIfPresent(MoldDO::getQuantity, reqVO.getQuantity())
.eqIfPresent(MoldDO::getUnitId, reqVO.getUnitId()) .eqIfPresent(MoldDO::getUnitId, reqVO.getUnitId())
.eqIfPresent(MoldDO::getMachineId, reqVO.getMachineId()) .eqIfPresent(MoldDO::getMachineId, reqVO.getMachineId())
.likeIfPresent(MoldDO::getMachineName, reqVO.getMachineName()) .likeIfPresent(MoldDO::getMachineName, reqVO.getMachineName())
@ -51,7 +55,15 @@ public interface MoldMapper extends BaseMapperX<MoldDO> {
if (reqVO.getStatuss() != null && !reqVO.getStatuss().isEmpty()) { if (reqVO.getStatuss() != null && !reqVO.getStatuss().isEmpty()) {
wrapper.in(MoldDO::getStatus, reqVO.getStatuss()); wrapper.in(MoldDO::getStatus, reqVO.getStatuss());
} }
return selectPage(reqVO, wrapper); return wrapper;
}
default PageResult<MoldDO> selectPage(MoldPageReqVO reqVO) {
return selectPage(reqVO, buildQueryWrapper(reqVO));
}
default List<MoldDO> selectList(MoldPageReqVO reqVO) {
return selectList(buildQueryWrapper(reqVO));
} }
// 保持原有方法以兼容旧代码 // 保持原有方法以兼容旧代码
@ -69,6 +81,10 @@ public interface MoldMapper extends BaseMapperX<MoldDO> {
return selectList(new LambdaQueryWrapperX<MoldDO>() return selectList(new LambdaQueryWrapperX<MoldDO>()
.eqIfPresent(MoldDO::getCode, reqVO.getCode()) .eqIfPresent(MoldDO::getCode, reqVO.getCode())
.likeIfPresent(MoldDO::getName, reqVO.getName()) .likeIfPresent(MoldDO::getName, reqVO.getName())
.likeIfPresent(MoldDO::getType, reqVO.getType())
.likeIfPresent(MoldDO::getInstallLocation, reqVO.getInstallLocation())
.likeIfPresent(MoldDO::getMaterial, reqVO.getMaterial())
.eqIfPresent(MoldDO::getQuantity, reqVO.getQuantity())
.eqIfPresent(MoldDO::getBrandId, reqVO.getBrandId()) .eqIfPresent(MoldDO::getBrandId, reqVO.getBrandId())
.orderByDesc(MoldDO::getId)); .orderByDesc(MoldDO::getId));
} }
@ -78,4 +94,6 @@ public interface MoldMapper extends BaseMapperX<MoldDO> {
.eq(MoldDO::getBrandId, brandId) .eq(MoldDO::getBrandId, brandId)
.orderByDesc(MoldDO::getId)); .orderByDesc(MoldDO::getId));
} }
String selectPrintTemplate();
} }

@ -27,7 +27,7 @@ public interface MoldRepairMapper extends BaseMapperX<MoldRepairDO> {
LambdaQueryWrapperX<MoldRepairDO> moldRepairDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>(); LambdaQueryWrapperX<MoldRepairDO> moldRepairDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>();
moldRepairDOLambdaQueryWrapperX moldRepairDOLambdaQueryWrapperX
.eqIfPresent(MoldRepairDO::getRepairCode, reqVO.getRepairCode()) .likeIfPresent(MoldRepairDO::getRepairCode, reqVO.getRepairCode())
.likeIfPresent(MoldRepairDO::getRepairName, reqVO.getRepairName()) .likeIfPresent(MoldRepairDO::getRepairName, reqVO.getRepairName())
.eqIfPresent(MoldRepairDO::getMoldId, reqVO.getMoldId()) .eqIfPresent(MoldRepairDO::getMoldId, reqVO.getMoldId())
.eqIfPresent(MoldRepairDO::getMoldCode, reqVO.getMoldCode()) .eqIfPresent(MoldRepairDO::getMoldCode, reqVO.getMoldCode())
@ -38,6 +38,7 @@ public interface MoldRepairMapper extends BaseMapperX<MoldRepairDO> {
.betweenIfPresent(MoldRepairDO::getRequireDate, reqVO.getRequireDate()) .betweenIfPresent(MoldRepairDO::getRequireDate, reqVO.getRequireDate())
.betweenIfPresent(MoldRepairDO::getFinishDate, reqVO.getFinishDate()) .betweenIfPresent(MoldRepairDO::getFinishDate, reqVO.getFinishDate())
.betweenIfPresent(MoldRepairDO::getConfirmDate, reqVO.getConfirmDate()) .betweenIfPresent(MoldRepairDO::getConfirmDate, reqVO.getConfirmDate())
.eqIfPresent(MoldRepairDO::getRepairStatus, reqVO.getRepairStatus())
.eqIfPresent(MoldRepairDO::getRepairResult, reqVO.getRepairResult()) .eqIfPresent(MoldRepairDO::getRepairResult, reqVO.getRepairResult())
.eqIfPresent(MoldRepairDO::getAcceptedBy, reqVO.getAcceptedBy()) .eqIfPresent(MoldRepairDO::getAcceptedBy, reqVO.getAcceptedBy())
.eqIfPresent(MoldRepairDO::getConfirmBy, reqVO.getConfirmBy()) .eqIfPresent(MoldRepairDO::getConfirmBy, reqVO.getConfirmBy())

@ -27,7 +27,7 @@ public interface MoldTicketManagementMapper extends BaseMapperX<MoldTicketManage
ticketManagementDOLambdaQueryWrapperX ticketManagementDOLambdaQueryWrapperX
.eqIfPresent(MoldTicketManagementDO::getTaskId, reqVO.getTaskId()) .eqIfPresent(MoldTicketManagementDO::getTaskId, reqVO.getTaskId())
.eqIfPresent(MoldTicketManagementDO::getPlanId, reqVO.getPlanId()) .eqIfPresent(MoldTicketManagementDO::getPlanId, reqVO.getPlanId())
.eqIfPresent(MoldTicketManagementDO::getPlanNo, reqVO.getPlanNo()) .likeIfPresent(MoldTicketManagementDO::getPlanNo, reqVO.getPlanNo())
.likeIfPresent(MoldTicketManagementDO::getMoldName, reqVO.getMoldName()) .likeIfPresent(MoldTicketManagementDO::getMoldName, reqVO.getMoldName())
.eqIfPresent(MoldTicketManagementDO::getPlanType, reqVO.getPlanType()) .eqIfPresent(MoldTicketManagementDO::getPlanType, reqVO.getPlanType())
.likeIfPresent(MoldTicketManagementDO::getConfigName, reqVO.getConfigName()) .likeIfPresent(MoldTicketManagementDO::getConfigName, reqVO.getConfigName())

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.common.dal.mysql.qrcoderecord;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.common.controller.admin.qrcoderecord.vo.QrcodeRecordPageReqVO;
import cn.iocoder.yudao.module.common.dal.dataobject.qrcoderecord.QrcodeRecordDO;
import org.apache.ibatis.annotations.Mapper;
/**
* Mapper
*
* @author
*/
@Mapper
public interface QrcodeRecordMapper extends BaseMapperX<QrcodeRecordDO> {
default PageResult<QrcodeRecordDO> selectPage(QrcodeRecordPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<QrcodeRecordDO>()
.eqIfPresent(QrcodeRecordDO::getBizType, reqVO.getBizType())
.eqIfPresent(QrcodeRecordDO::getBizId, reqVO.getBizId())
.eqIfPresent(QrcodeRecordDO::getBizCode, reqVO.getBizCode())
.eqIfPresent(QrcodeRecordDO::getQrScene, reqVO.getQrScene())
.eqIfPresent(QrcodeRecordDO::getQrContent, reqVO.getQrContent())
.likeIfPresent(QrcodeRecordDO::getFileName, reqVO.getFileName())
.likeIfPresent(QrcodeRecordDO::getBucketName, reqVO.getBucketName())
.likeIfPresent(QrcodeRecordDO::getObjectName, reqVO.getObjectName())
.eqIfPresent(QrcodeRecordDO::getQrcodeFileUrl, reqVO.getQrcodeFileUrl())
.eqIfPresent(QrcodeRecordDO::getMimeType, reqVO.getMimeType())
.eqIfPresent(QrcodeRecordDO::getFileSize, reqVO.getFileSize())
.eqIfPresent(QrcodeRecordDO::getStatus, reqVO.getStatus())
.betweenIfPresent(QrcodeRecordDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(QrcodeRecordDO::getId));
}
}

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum CodeTypeEnum {
QR("QR", "二维码"),
BARCODE("BARCODE", "条形码");
private final String code;
private final String desc;
public String getCode() {
return code;
}
public String getDesc() {
return desc;
}
public static CodeTypeEnum fromBarcodeType(Integer barcodeType) {
if (barcodeType == null) {
return null;
}
return Integer.valueOf(1).equals(barcodeType) ? BARCODE : QR;
}
}

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.common.enums;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
@Getter
@AllArgsConstructor
public enum MoldBrandStatusEnum implements IntArrayValuable {
ON_MACHINE(0, "在机"),
STANDBY(1, "待用"),
REPAIRING(2, "维修"),
SCRAPPED(3, "报废"),
IN_STOCK(4, "在库");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MoldBrandStatusEnum::getStatus).toArray();
private final Integer status;
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum QrcodeBizTypeEnum {
PRODUCT("PRODUCTMATERIAL", "产品物料"),
EQUIPMENT("EQUIPMENT", "设备"),
DEVICE_LINE("DEVICE_LINE", "设备产线"),
KEY_PART("KEY_PART", "关键件"),
MOLD("MOLD", "模具"),
SPARE("SPARE", "备件");
private final String code;
private final String name;
public static QrcodeBizTypeEnum of(String code) {
for (QrcodeBizTypeEnum item : values()) {
if (item.code.equalsIgnoreCase(code)) {
return item;
}
}
return null;
}
}

@ -0,0 +1,9 @@
package cn.iocoder.yudao.module.common.handler;
public interface QrcodeBizHandler {
String getBizType();
boolean exists(Long id);
String buildDeepLink(Long id);
String buildH5Path(Long id);
}

@ -0,0 +1,86 @@
package cn.iocoder.yudao.module.common.service.qrcordrecord;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.common.controller.admin.qrcoderecord.vo.QrcodeRecordPageReqVO;
import cn.iocoder.yudao.module.common.controller.admin.qrcoderecord.vo.QrcodeRecordSaveReqVO;
import cn.iocoder.yudao.module.common.dal.dataobject.qrcoderecord.QrcodeRecordDO;
import cn.iocoder.yudao.module.common.enums.CodeTypeEnum;
import cn.iocoder.yudao.module.common.enums.QrcodeBizTypeEnum;
import org.springframework.transaction.annotation.Transactional;
import javax.validation.Valid;
import java.util.Collection;
import java.io.UnsupportedEncodingException;
import java.util.Map;
/**
* Service
*
* @author
*/
public interface QrcodeRecordService {
/**
*
*
* @param createReqVO
* @return
*/
Long createRecord(@Valid QrcodeRecordSaveReqVO createReqVO);
/**
*
*
* @param updateReqVO
*/
void updateRecord(@Valid QrcodeRecordSaveReqVO updateReqVO);
/**
*
*
* @param id
*/
void deleteRecord(Long id);
/**
*
*
* @param id
* @return
*/
QrcodeRecordDO getRecord(Long id);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<QrcodeRecordDO> getRecordPage(QrcodeRecordPageReqVO pageReqVO);
void generateOrRefresh(QrcodeBizTypeEnum bizType, Long bizId, String bizCode, String scene) throws UnsupportedEncodingException;
void generateOrRefreshBarcode(QrcodeBizTypeEnum bizType, Long bizId, String bizCode, String scene) throws UnsupportedEncodingException;
String buildScanTransitHtml(String type, Long id,String code);
String selectQrcodeUrlByIdAndCode(String code, Long id, String code1);
Map<Long, String> selectQrcodeUrlMapByBizTypeAndIds(String bizType, Collection<Long> bizIds);
Map<String, Object> resolveScanBizId(String type, Long id, String code);
void deleteByBiz(QrcodeBizTypeEnum bizType, Long bizId);
void regenerateByCodeType(QrcodeBizTypeEnum bizType, Long bizId, String bizCode, String scene, String codeType)
throws UnsupportedEncodingException;
void generateOrRefresh(
QrcodeBizTypeEnum bizType,
Long bizId,
String bizCode,
String scene,
CodeTypeEnum codeType
) throws UnsupportedEncodingException;
}

@ -0,0 +1,627 @@
package cn.iocoder.yudao.module.common.service.qrcordrecord;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.common.controller.admin.qrcoderecord.vo.QrcodeRecordPageReqVO;
import cn.iocoder.yudao.module.common.controller.admin.qrcoderecord.vo.QrcodeRecordSaveReqVO;
import cn.iocoder.yudao.module.common.dal.dataobject.qrcoderecord.QrcodeRecordDO;
import cn.iocoder.yudao.module.common.dal.mysql.qrcoderecord.QrcodeRecordMapper;
import cn.iocoder.yudao.module.common.enums.CodeTypeEnum;
import cn.iocoder.yudao.module.common.enums.QrcodeBizTypeEnum;
import cn.iocoder.yudao.module.common.handler.QrcodeBizHandler;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.common.api.mold.enums.ErrorCodeConstants.RECORD_NOT_EXISTS;
/**
* Service
*
* @author
*/
@Service
@Validated
@Slf4j
public class QrcodeRecordServiceImpl implements QrcodeRecordService {
@Resource
private FileApi fileApi;
@Value("${yudao.qrcode.scan-base-url}")
private String scanBaseUrl;
@Value("${yudao.qrcode.width:300}")
private Integer width;
@Value("${yudao.qrcode.height:300}")
private Integer height;
@Value("${yudao.qrcode.default-bucket:common-qrcode}")
private String defaultBucket;
@Value("${yudao.qrcode.fail-url}")
private String failUrl;
@Value("${yudao.qrcode.scan-base-url}")
private String serverBaseUrl;
@Value("#{${yudao.qrcode.buckets:{}}}")
private Map<String, String> bucketMap = new HashMap<>();
@Resource
private QrcodeRecordMapper qrcodeRecordMapper;
private final Map<String, QrcodeBizHandler> handlerMap;
public QrcodeRecordServiceImpl(List<QrcodeBizHandler> handlers) {
this.handlerMap = handlers.stream()
.collect(Collectors.toMap(h -> h.getBizType().toUpperCase(), h -> h));
}
@Override
public Long createRecord(QrcodeRecordSaveReqVO createReqVO) {
// 插入
QrcodeRecordDO record = BeanUtils.toBean(createReqVO, QrcodeRecordDO.class);
qrcodeRecordMapper.insert(record);
// 返回
return record.getId();
}
@Override
public void updateRecord(QrcodeRecordSaveReqVO updateReqVO) {
// 校验存在
validateRecordExists(updateReqVO.getId());
// 更新
QrcodeRecordDO updateObj = BeanUtils.toBean(updateReqVO, QrcodeRecordDO.class);
qrcodeRecordMapper.updateById(updateObj);
}
@Override
public void deleteRecord(Long id) {
// 校验存在
validateRecordExists(id);
// 删除
qrcodeRecordMapper.deleteById(id);
}
private void validateRecordExists(Long id) {
if (qrcodeRecordMapper.selectById(id) == null) {
throw exception(RECORD_NOT_EXISTS);
}
}
@Override
public QrcodeRecordDO getRecord(Long id) {
return qrcodeRecordMapper.selectById(id);
}
@Override
public PageResult<QrcodeRecordDO> getRecordPage(QrcodeRecordPageReqVO pageReqVO) {
return qrcodeRecordMapper.selectPage(pageReqVO);
}
@Override
public void generateOrRefresh(QrcodeBizTypeEnum bizType, Long bizId, String bizCode, String scene) throws UnsupportedEncodingException {
if (bizType == null || bizId == null) {
throw new IllegalArgumentException("bizType 或 bizId 不能为空");
}
String qrScene = StrUtil.blankToDefault(scene, "DETAIL");
// 1. 幂等查询biz_type + biz_id + scene 唯一)
QrcodeRecordDO existed = qrcodeRecordMapper.selectOne(
new LambdaQueryWrapper<QrcodeRecordDO>()
.eq(QrcodeRecordDO::getBizType, bizType.getCode())
.eq(QrcodeRecordDO::getBizId, bizId)
.eq(QrcodeRecordDO::getBizCode,bizCode)
.eq(QrcodeRecordDO::getCodeType,"QR")
.eq(QrcodeRecordDO::getQrScene, qrScene)
.last("limit 1")
);
// 2. 组装二维码内容(统一扫码入口)
// String qrContent = "{\"type\":\"" + bizType.getCode()
// + "\",\"id\":" + bizId
// + (StrUtil.isNotBlank(bizCode) ? ",\"code\":\"" + bizCode + "\"" : "")
// + "}";
String qrContent = bizType.getCode() + "-" + bizId;
// 3. 生成二维码PNG
byte[] pngBytes = buildQrPng(qrContent, width, height);
// 4. 选择bucket + objectName
String bucket = resolveBucket(bizType); // 例如 yudao.qrcode.buckets.mold
String objectName = bizType.getCode().toLowerCase() + "/qr/" + LocalDate.now() + "/" + bizId + ".png";
String fileName = bizType.getCode().toLowerCase() + "_" + bizCode + ".png";
// 5. 上传文件(按你项目 FileApi 实际签名改)
// 如果支持bucket参数用这个
// FileRespDTO file = fileApi.createFile(bucket, objectName, "image/png", pngBytes);
// 默认上传
Map<String, String> file = fileApi.createFile(fileName, objectName, pngBytes);
String fileUrl = file.get("fileUrl");
// 6. upsert 记录
QrcodeRecordDO record = new QrcodeRecordDO();
record.setBizType(bizType.getCode());
record.setBizId(bizId);
record.setBizCode(bizCode);
record.setQrScene(qrScene);
record.setQrContent(qrContent);
record.setFileName(fileName);
record.setBucketName(bucket);
record.setObjectName(objectName);
record.setQrcodeFileUrl(fileUrl);
record.setMimeType("image/png");
record.setFileSize((long) pngBytes.length);
record.setStatus(1);
if (existed == null) {
qrcodeRecordMapper.insert(record);
} else {
record.setId(existed.getId());
qrcodeRecordMapper.updateById(record);
}
}
@Override
// @Transactional(rollbackFor = Exception.class)
public void generateOrRefreshBarcode(QrcodeBizTypeEnum bizType, Long bizId, String bizCode, String scene) throws UnsupportedEncodingException {
if (bizType == null || bizId == null) {
throw new IllegalArgumentException("bizType 或 bizId 不能为空");
}
String qrScene = StrUtil.blankToDefault(scene, "DETAIL");
QrcodeRecordDO existed = qrcodeRecordMapper.selectOne(
new LambdaQueryWrapper<QrcodeRecordDO>()
.eq(QrcodeRecordDO::getBizType, bizType.getCode())
.eq(QrcodeRecordDO::getBizId, bizId)
.eq(QrcodeRecordDO::getBizCode, bizCode)
.eq(QrcodeRecordDO::getCodeType, "BARCODE")
.eq(QrcodeRecordDO::getQrScene, qrScene)
.last("limit 1")
);
// String barcodeContent = "{\"type\":\"" + bizType.getCode()
// + "\",\"id\":" + bizId
// + (StrUtil.isNotBlank(bizCode) ? ",\"code\":\"" + bizCode + "\"" : "")
// + "}";
String barcodeContent = bizType.getCode() + "-" + bizId;
int barcodeWidth = 600;
int barcodeHeight = 180;
byte[] pngBytes = buildBarcodePng(barcodeContent, barcodeWidth, barcodeHeight);
String bucket = resolveBucket(bizType);
String objectName = bizType.getCode().toLowerCase() + "/barcode/" + LocalDate.now() + "/" + bizId + ".png";
String fileName = bizType.getCode().toLowerCase() + "_" + bizCode + "_barcode.png";
Map<String, String> file = fileApi.createFile(fileName, objectName, pngBytes);
String fileUrl = file.get("fileUrl");
QrcodeRecordDO record = new QrcodeRecordDO();
record.setBizType(bizType.getCode());
record.setBizId(bizId);
record.setBizCode(bizCode);
record.setCodeType("BARCODE");
record.setQrScene(qrScene);
record.setQrContent(barcodeContent);
record.setFileName(fileName);
record.setBucketName(bucket);
record.setObjectName(objectName);
record.setQrcodeFileUrl(fileUrl);
record.setMimeType("image/png");
record.setFileSize((long) pngBytes.length);
record.setStatus(1);
if (existed == null) {
qrcodeRecordMapper.insert(record);
} else {
record.setId(existed.getId());
qrcodeRecordMapper.updateById(record);
}
}
private byte[] buildBarcodePng(String content, int width, int height) {
try {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.MARGIN, 1);
BitMatrix matrix = new MultiFormatWriter().encode(content, BarcodeFormat.CODE_128, width, height, hints);
BufferedImage image = MatrixToImageWriter.toBufferedImage(matrix);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, "png", os);
return os.toByteArray();
} catch (Exception e) {
throw new RuntimeException("生成条形码失败", e);
}
}
@Override
public String buildScanTransitHtml(String type, Long id,String code) {
String fallback = normalizeUrl(StrUtil.blankToDefault(failUrl, "/"));
if (StrUtil.isBlank(type) || id == null) {
return buildRedirectHtml(fallback);
}
if (StrUtil.isBlank(code)) {
return buildRedirectHtml(fallback);
}
QrcodeRecordDO record = qrcodeRecordMapper.selectOne(
new LambdaQueryWrapper<QrcodeRecordDO>()
.eq(QrcodeRecordDO::getBizType, type.trim().toUpperCase())
.eq(QrcodeRecordDO::getBizId, id)
.eq(QrcodeRecordDO::getQrScene, "DETAIL")
.last("limit 1")
);
if (record == null || !StrUtil.equals(record.getBizCode(), code)) {
return buildRedirectHtml(fallback);
}
QrcodeBizHandler handler = handlerMap.get(type.trim().toUpperCase());
if (handler == null) {
return buildRedirectHtml(fallback);
}
try {
if (!handler.exists(id)) {
return buildRedirectHtml(fallback);
}
String target = StrUtil.blankToDefault(handler.buildDeepLink(id), handler.buildH5Path(id));
if (StrUtil.isBlank(target)) {
return buildRedirectHtml(fallback);
}
return buildRedirectHtml(normalizeUrl(target));
} catch (Exception e) {
return buildRedirectHtml(fallback);
}
}
@Override
public String selectQrcodeUrlByIdAndCode(String bizType, Long bizId, String bizCode) {
if (StrUtil.isBlank(bizType) || bizId == null || StrUtil.isBlank(bizCode)) {
return null;
}
QrcodeRecordDO record = qrcodeRecordMapper.selectOne(Wrappers.<QrcodeRecordDO>lambdaQuery()
.eq(QrcodeRecordDO::getBizType, bizType)
.eq(QrcodeRecordDO::getBizId, bizId)
.eq(QrcodeRecordDO::getBizCode, bizCode)
.eq(QrcodeRecordDO::getStatus, 1)
.last("limit 1"));
if (record == null || StrUtil.isBlank(record.getQrcodeFileUrl())) {
return null;
}
return record.getQrcodeFileUrl();
}
@Override
public Map<Long, String> selectQrcodeUrlMapByBizTypeAndIds(String bizType, Collection<Long> bizIds) {
if (StrUtil.isBlank(bizType) || bizIds == null || bizIds.isEmpty()) {
return new HashMap<>();
}
List<QrcodeRecordDO> records = qrcodeRecordMapper.selectList(Wrappers.<QrcodeRecordDO>lambdaQuery()
.eq(QrcodeRecordDO::getBizType, bizType)
.in(QrcodeRecordDO::getBizId, bizIds)
.eq(QrcodeRecordDO::getStatus, 1)
.orderByDesc(QrcodeRecordDO::getId));
return records.stream()
.filter(record -> StrUtil.isNotBlank(record.getQrcodeFileUrl()))
.collect(Collectors.toMap(
QrcodeRecordDO::getBizId,
QrcodeRecordDO::getQrcodeFileUrl,
(first, second) -> first
));
}
@Override
public Map<String, Object> resolveScanBizId(String type, Long id, String code) {
Map<String, Object> result = new HashMap<>();
if (StrUtil.isBlank(type) || id == null || StrUtil.isBlank(code)) {
return null;
}
QrcodeRecordDO record = qrcodeRecordMapper.selectOne(
new LambdaQueryWrapper<QrcodeRecordDO>()
.eq(QrcodeRecordDO::getBizType, type)
.eq(QrcodeRecordDO::getBizId, id)
.eq(QrcodeRecordDO::getBizCode,code)
.eq(QrcodeRecordDO::getQrScene, "DETAIL")
.last("limit 1")
);
if (record == null) {
return null;
}
QrcodeBizHandler handler = handlerMap.get(type.trim().toUpperCase());
if (handler == null) {
return null;
}
result.put("type", type);
result.put("id", id);
return result;
}
private String normalizeUrl(String url) {
if (StrUtil.isBlank(url)) {
return "/";
}
if (StrUtil.startWithAny(url, "http://", "https://", "besure://")) {
return url;
}
String base = StrUtil.blankToDefault(serverBaseUrl, "");
if (StrUtil.isBlank(base)) {
return url.startsWith("/") ? url : "/" + url;
}
return StrUtil.removeSuffix(base, "/") + "/" + StrUtil.removePrefix(url, "/");
}
private String buildRedirectHtml(String targetUrl) {
String safe = escapeHtml(StrUtil.blankToDefault(targetUrl, "/"));
return "<!doctype html><html><head><meta charset=\"UTF-8\">"
+ "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
+ "<meta http-equiv=\"Cache-Control\" content=\"no-store, no-cache, must-revalidate, max-age=0\">"
+ "<meta http-equiv=\"Pragma\" content=\"no-cache\">"
+ "<meta http-equiv=\"Expires\" content=\"0\">"
+ "<title>跳转中...</title></head><body>"
+ "<script>window.location.replace('" + safe + "');</script>"
+ "<noscript><a href=\"" + safe + "\">点击继续</a></noscript>"
+ "</body></html>";
}
private String escapeHtml(String s) {
return s.replace("&", "&amp;")
.replace("<", "&lt;")
.replace(">", "&gt;")
.replace("\"", "&quot;")
.replace("'", "&#39;");
}
private String resolveBucket(QrcodeBizTypeEnum bizType) {
if (bizType == null) {
return defaultBucket;
}
if (bucketMap == null || bucketMap.isEmpty()) {
return defaultBucket;
}
String bucket = bucketMap.get(bizType.getCode().toLowerCase());
return StrUtil.blankToDefault(bucket, defaultBucket);
}
private byte[] buildQrPng(String content, int width, int height) {
try {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.MARGIN, 1);
BitMatrix matrix = new MultiFormatWriter()
.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
BufferedImage image = MatrixToImageWriter.toBufferedImage(matrix);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, "png", os);
return os.toByteArray();
} catch (Exception e) {
throw new RuntimeException("生成二维码失败", e);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteByBiz(QrcodeBizTypeEnum bizType, Long bizId) {
if (bizType == null || bizId == null) {
return;
}
List<QrcodeRecordDO> records = qrcodeRecordMapper.selectList(
Wrappers.<QrcodeRecordDO>lambdaQuery()
.eq(QrcodeRecordDO::getBizType, bizType.getCode())
.eq(QrcodeRecordDO::getBizId, bizId)
);
if (records == null || records.isEmpty()) {
return;
}
for (QrcodeRecordDO record : records) {
try {
String objectName = record.getObjectName();
if (StrUtil.isBlank(objectName)) {
continue;
}
// 通过 path(objectName) 找到 infra_file
Long id = fileApi.getFileByPath(objectName);
if (id == null) {
// 可选log.warn("未找到文件记录, qrcodeId={}, path={}", record.getId(), objectName);
continue;
}
// 用文件主键删除(会删存储+删infra_file记录
fileApi.deleteFile(id);
} catch (Exception e) {
// 你可按策略选择:继续 or 抛异常回滚
// 建议先打日志
log.warn("删除文件失败, qrcodeId={}, path={}", record.getId(), record.getObjectName(), e);
}
}
qrcodeRecordMapper.delete(
Wrappers.<QrcodeRecordDO>lambdaQuery()
.eq(QrcodeRecordDO::getBizType, bizType.getCode())
.eq(QrcodeRecordDO::getBizId, bizId)
);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void regenerateByCodeType(QrcodeBizTypeEnum bizType, Long bizId, String bizCode, String scene, String codeType)
throws UnsupportedEncodingException {
if (bizType == null || bizId == null) {
throw new IllegalArgumentException("bizType 或 bizId 不能为空");
}
String qrScene = StrUtil.blankToDefault(scene, "DETAIL");
String normalizedCodeType = StrUtil.blankToDefault(codeType, "QR").trim().toUpperCase();
if (!StrUtil.equalsAny(normalizedCodeType, "QR", "BARCODE")) {
throw new IllegalArgumentException("codeType 仅支持 QR 或 BARCODE");
}
// 1. 按业务唯一键 + 码类型查询
QrcodeRecordDO existed = qrcodeRecordMapper.selectOne(
new LambdaQueryWrapper<QrcodeRecordDO>()
.eq(QrcodeRecordDO::getBizType, bizType.getCode())
.eq(QrcodeRecordDO::getBizId, bizId)
.eq(QrcodeRecordDO::getBizCode, bizCode)
// .eq(QrcodeRecordDO::getCodeType, normalizedCodeType)
.eq(QrcodeRecordDO::getQrScene, qrScene)
.last("limit 1")
);
// 2. 组装内容
// String content = "{\"type\":\"" + bizType.getCode()
// + "\",\"id\":" + bizId
// + (StrUtil.isNotBlank(bizCode) ? ",\"code\":\"" + bizCode + "\"" : "")
// + "}";
String content = bizType.getCode() + "-" + bizId;
// 3. 生成图片(按类型)
byte[] pngBytes;
String objectDir;
String fileNameSuffix;
if (StrUtil.equals(normalizedCodeType, "BARCODE")) {
pngBytes = buildBarcodePng(content, 600, 180);
objectDir = "barcode";
fileNameSuffix = "_barcode.png";
} else {
pngBytes = buildQrPng(content, width, height);
objectDir = "qr";
fileNameSuffix = ".png";
}
// 4. 组织文件信息
String bucket = resolveBucket(bizType);
String objectName = bizType.getCode().toLowerCase() + "/" + objectDir + "/" + LocalDate.now() + "/" + bizId + ".png";
String fileName = bizType.getCode().toLowerCase() + "_" + StrUtil.blankToDefault(bizCode, String.valueOf(bizId)) + fileNameSuffix;
// 5. 如果已存在先删旧文件MinIO + infra_file
if (existed != null && StrUtil.isNotBlank(existed.getObjectName())) {
try {
Long fileId = fileApi.getFileByPath(existed.getObjectName());
if (fileId != null) {
fileApi.deleteFile(fileId);
}
} catch (Exception e) {
log.warn("删除旧二维码/条形码文件失败, qrcodeId={}, path={}", existed.getId(), existed.getObjectName(), e);
}
}
// 6. 上传新文件
Map<String, String> file = fileApi.createFile(fileName, objectName, pngBytes);
String fileUrl = file.get("fileUrl");
// 7. upsert 记录
QrcodeRecordDO record = new QrcodeRecordDO();
record.setBizType(bizType.getCode());
record.setBizId(bizId);
record.setBizCode(bizCode);
record.setCodeType(normalizedCodeType);
record.setQrScene(qrScene);
record.setQrContent(content);
record.setFileName(fileName);
record.setBucketName(bucket);
record.setObjectName(objectName);
record.setQrcodeFileUrl(fileUrl);
record.setMimeType("image/png");
record.setFileSize((long) pngBytes.length);
record.setStatus(1);
if (existed == null) {
qrcodeRecordMapper.insert(record);
} else {
record.setId(existed.getId());
qrcodeRecordMapper.updateById(record);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void generateOrRefresh(QrcodeBizTypeEnum bizType,
Long bizId,
String bizCode,
String scene,
CodeTypeEnum codeType) throws UnsupportedEncodingException {
if (codeType == null) {
log.info("codeType为空");
return;
}
if (codeType == CodeTypeEnum.BARCODE) {
generateOrRefreshBarcode(bizType, bizId, bizCode, scene);
} else {
generateOrRefresh(bizType, bizId, bizCode, scene);
}
}
}

@ -8,5 +8,12 @@
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/ 文档可见https://www.iocoder.cn/MyBatis/x-plugins/
--> -->
<select id="selectPrintTemplate" resultType="java.lang.String">
select template_json
from mes_print_template
where deleted = 0
and template_type = 4
and template_biz_type = 1
</select>
</mapper> </mapper>

@ -16,9 +16,9 @@
mtm.task_time, mtm.task_time,
CONCAT( '(', su.username, ')', su.nickname) as operator CONCAT( '(', su.username, ')', su.nickname) as operator
from from
besure.mes_mold_ticket_results mtr mes_mold_ticket_results mtr
left join besure.mes_mold_ticket_management mtm on mtm.id = mtr.management_id left join mes_mold_ticket_management mtm on mtm.id = mtr.management_id
left join besure.system_users su on mtm.operator = su.id left join system_users su on mtm.operator = su.id
WHERE 1=1 WHERE 1=1
<!-- ID集合过滤 --> <!-- ID集合过滤 -->
<if test="ids != null and ids != ''"> <if test="ids != null and ids != ''">

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.common.dal.mysql.qrcoderecord.QrcodeRecordMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>

@ -9,5 +9,6 @@ public interface DictTypeConstants {
String AUDIT_STATUS = "erp_audit_status"; // 审核状态 String AUDIT_STATUS = "erp_audit_status"; // 审核状态
String STOCK_RECORD_BIZ_TYPE = "erp_stock_record_biz_type"; // 库存明细的业务类型 String STOCK_RECORD_BIZ_TYPE = "erp_stock_record_biz_type"; // 库存明细的业务类型
String PRODUCT_CATEGORY_TYPE = "erp_product_category_type"; // 产品分类类型
} }

@ -6,36 +6,22 @@ import lombok.RequiredArgsConstructor;
import java.util.Arrays; import java.util.Arrays;
/**
* ERP
*
* TODO 稿==退
*
* @author
*/
@RequiredArgsConstructor @RequiredArgsConstructor
@Getter @Getter
public enum ErpAuditStatus implements IntArrayValuable { public enum ErpAuditStatus implements IntArrayValuable {
DRAFT(0, "草稿"), // 审核中 DRAFT(0, "待提交"),
UN_APPROVE(1, "驳回"), // 审核通过 UN_APPROVE(1, "已驳回"),
PROCESS(10, "审核"), // 审核中 PROCESS(10, "审核中"),
APPROVE(20, "审核"); // 审核通过 APPROVE(20, "审核通过");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpAuditStatus::getStatus).toArray(); public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpAuditStatus::getStatus).toArray();
/**
*
*/
private final Integer status; private final Integer status;
/**
*
*/
private final String name; private final String name;
@Override @Override
public int[] array() { public int[] array() {
return ARRAYS; return ARRAYS;
} }
} }

@ -13,6 +13,11 @@ public interface ErrorCodeConstants {
ErrorCode SUPPLIER_NOT_EXISTS = new ErrorCode(1_030_100_000, "供应商不存在"); ErrorCode SUPPLIER_NOT_EXISTS = new ErrorCode(1_030_100_000, "供应商不存在");
ErrorCode SUPPLIER_NOT_ENABLE = new ErrorCode(1_030_100_000, "供应商({})未启用"); ErrorCode SUPPLIER_NOT_ENABLE = new ErrorCode(1_030_100_000, "供应商({})未启用");
// ========== ERP 包装方案1-030-104-000 ==========
ErrorCode PACKAGING_SCHEME_NOT_EXISTS = new ErrorCode(1_030_104_000, "包装方案不存在");
ErrorCode PACKAGING_SCHEME_CODE_DUPLICATE = new ErrorCode(1_030_104_001, "包装方案编码已存在");
ErrorCode PACKAGING_SCHEME_NAME_DUPLICATE = new ErrorCode(1_030_104_002, "包装方案名称已存在");
// ========== ERP 采购订单1-030-101-000 ========== // ========== ERP 采购订单1-030-101-000 ==========
ErrorCode PURCHASE_ORDER_NOT_EXISTS = new ErrorCode(1_030_101_000, "采购订单不存在"); ErrorCode PURCHASE_ORDER_NOT_EXISTS = new ErrorCode(1_030_101_000, "采购订单不存在");
ErrorCode PURCHASE_ORDER_DELETE_FAIL_APPROVE = new ErrorCode(1_030_101_001, "采购订单({})已审核,无法删除"); ErrorCode PURCHASE_ORDER_DELETE_FAIL_APPROVE = new ErrorCode(1_030_101_001, "采购订单({})已审核,无法删除");
@ -90,6 +95,12 @@ public interface ErrorCodeConstants {
// ========== ERP 仓库 1-030-400-000 ========== // ========== ERP 仓库 1-030-400-000 ==========
ErrorCode WAREHOUSE_NOT_EXISTS = new ErrorCode(1_030_400_000, "仓库不存在"); ErrorCode WAREHOUSE_NOT_EXISTS = new ErrorCode(1_030_400_000, "仓库不存在");
ErrorCode WAREHOUSE_NOT_ENABLE = new ErrorCode(1_030_400_001, "仓库({})未启用"); ErrorCode WAREHOUSE_NOT_ENABLE = new ErrorCode(1_030_400_001, "仓库({})未启用");
ErrorCode WAREHOUSE_AREA_CODE_EXISTS = new ErrorCode(1_030_400_002, "仓库库区编码不存在");
ErrorCode WAREHOUSE_AREA_DELETE_FAIL_EXISTS_LOCATION = new ErrorCode(1_030_400_003, "仓库库区删除失败,请先删除对应库位信息");
ErrorCode WAREHOUSE_AREA_NOT_EXISTS = new ErrorCode(1_030_400_004, "仓库库区不存在");
ErrorCode WAREHOUSE_LOCATION_CODE_EXISTS = new ErrorCode(1_030_400_005, "库位编码不存在");
ErrorCode WAREHOUSE_LOCATION_NOT_EXISTS = new ErrorCode(1_030_400_006, "库位不存在");
ErrorCode WAREHOUSE_LOCATION_WAREHOUSE_AREA_NOT_MATCH = new ErrorCode(1_030_400_007, "暂无匹配库位信息");
// ========== ERP 其它入库单 1-030-401-000 ========== // ========== ERP 其它入库单 1-030-401-000 ==========
ErrorCode STOCK_IN_NOT_EXISTS = new ErrorCode(1_030_401_000, "其它入库单不存在"); ErrorCode STOCK_IN_NOT_EXISTS = new ErrorCode(1_030_401_000, "其它入库单不存在");
@ -98,6 +109,14 @@ public interface ErrorCodeConstants {
ErrorCode STOCK_IN_APPROVE_FAIL = new ErrorCode(1_030_401_003, "审核失败,只有未审核的入库单才能审核"); ErrorCode STOCK_IN_APPROVE_FAIL = new ErrorCode(1_030_401_003, "审核失败,只有未审核的入库单才能审核");
ErrorCode STOCK_IN_NO_EXISTS = new ErrorCode(1_030_401_004, "生成入库单失败,请重新提交"); ErrorCode STOCK_IN_NO_EXISTS = new ErrorCode(1_030_401_004, "生成入库单失败,请重新提交");
ErrorCode STOCK_IN_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_401_005, "其它入库单({})已审核,无法修改"); ErrorCode STOCK_IN_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_401_005, "其它入库单({})已审核,无法修改");
ErrorCode STOCK_IN_UPDATE_FAIL_PROCESS = new ErrorCode(1_030_401_006, "其它入库单({})审核中,无法修改");
ErrorCode STOCK_IN_DELETE_FAIL_PROCESS = new ErrorCode(1_030_401_007, "其它入库单({})审核中,无法删除");
ErrorCode STOCK_IN_SUBMIT_FAIL_STATUS = new ErrorCode(1_030_401_008, "提交审核失败,只有待提交或已驳回的入库单才能提交");
ErrorCode STOCK_IN_SUBMIT_FAIL_USER = new ErrorCode(1_030_401_009, "提交审核失败,只有创建人才能提交审核");
ErrorCode STOCK_IN_SUBMIT_FAIL_AUDIT_USER_EMPTY = new ErrorCode(1_030_401_010, "提交审核失败,请选择审核人");
ErrorCode STOCK_IN_AUDIT_FAIL_STATUS = new ErrorCode(1_030_401_011, "审核失败,只有审核中的入库单才能审核");
ErrorCode STOCK_IN_AUDIT_FAIL_USER = new ErrorCode(1_030_401_012, "审核失败,当前用户不是指定审核人");
ErrorCode STOCK_IN_AUDIT_FAIL_RESULT = new ErrorCode(1_030_401_013, "审核失败,审核结果只支持通过或驳回");
ErrorCode STOCK_ALERADY_IN = new ErrorCode(1_030_401_005, "模具({})已经入库,无法继续操作入库"); ErrorCode STOCK_ALERADY_IN = new ErrorCode(1_030_401_005, "模具({})已经入库,无法继续操作入库");
ErrorCode STOCK_ALERADY_OUT = new ErrorCode(1_030_401_005, "模具({})已经出库,无法继续操作出库"); ErrorCode STOCK_ALERADY_OUT = new ErrorCode(1_030_401_005, "模具({})已经出库,无法继续操作出库");
@ -109,6 +128,14 @@ public interface ErrorCodeConstants {
ErrorCode STOCK_OUT_APPROVE_FAIL = new ErrorCode(1_030_402_003, "审核失败,只有未审核的出库单才能审核"); ErrorCode STOCK_OUT_APPROVE_FAIL = new ErrorCode(1_030_402_003, "审核失败,只有未审核的出库单才能审核");
ErrorCode STOCK_OUT_NO_EXISTS = new ErrorCode(1_030_402_004, "生成出库单失败,请重新提交"); ErrorCode STOCK_OUT_NO_EXISTS = new ErrorCode(1_030_402_004, "生成出库单失败,请重新提交");
ErrorCode STOCK_OUT_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_402_005, "其它出库单({})已审核,无法修改"); ErrorCode STOCK_OUT_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_402_005, "其它出库单({})已审核,无法修改");
ErrorCode STOCK_OUT_UPDATE_FAIL_PROCESS = new ErrorCode(1_030_402_006, "其它出库单({})审核中,无法修改");
ErrorCode STOCK_OUT_DELETE_FAIL_PROCESS = new ErrorCode(1_030_402_007, "其它出库单({})审核中,无法删除");
ErrorCode STOCK_OUT_SUBMIT_FAIL_STATUS = new ErrorCode(1_030_402_008, "提交审核失败,只有待提交或已驳回的出库单才能提交审核");
ErrorCode STOCK_OUT_SUBMIT_FAIL_USER = new ErrorCode(1_030_402_009, "提交审核失败,只有创建人才能提交审核");
ErrorCode STOCK_OUT_SUBMIT_FAIL_AUDIT_USER_EMPTY = new ErrorCode(1_030_402_010, "提交审核失败,请选择审核人");
ErrorCode STOCK_OUT_AUDIT_FAIL_STATUS = new ErrorCode(1_030_402_011, "审核失败,只有审核中的出库单才能审核");
ErrorCode STOCK_OUT_AUDIT_FAIL_USER = new ErrorCode(1_030_402_012, "审核失败,当前用户不是指定审核人");
ErrorCode STOCK_OUT_AUDIT_FAIL_RESULT = new ErrorCode(1_030_402_013, "审核失败,审核结果只支持通过或驳回");
// ========== ERP 库存调拨单 1-030-403-000 ========== // ========== ERP 库存调拨单 1-030-403-000 ==========
ErrorCode STOCK_MOVE_NOT_EXISTS = new ErrorCode(1_030_402_000, "库存调拨单不存在"); ErrorCode STOCK_MOVE_NOT_EXISTS = new ErrorCode(1_030_402_000, "库存调拨单不存在");
@ -125,6 +152,14 @@ public interface ErrorCodeConstants {
ErrorCode STOCK_CHECK_APPROVE_FAIL = new ErrorCode(1_030_403_003, "审核失败,只有未审核的盘点单才能审核"); ErrorCode STOCK_CHECK_APPROVE_FAIL = new ErrorCode(1_030_403_003, "审核失败,只有未审核的盘点单才能审核");
ErrorCode STOCK_CHECK_NO_EXISTS = new ErrorCode(1_030_403_004, "生成盘点号失败,请重新提交"); ErrorCode STOCK_CHECK_NO_EXISTS = new ErrorCode(1_030_403_004, "生成盘点号失败,请重新提交");
ErrorCode STOCK_CHECK_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_403_005, "库存盘点单({})已审核,无法修改"); ErrorCode STOCK_CHECK_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_403_005, "库存盘点单({})已审核,无法修改");
ErrorCode STOCK_CHECK_DELETE_FAIL_PROCESS = new ErrorCode(1_030_403_006, "库存盘点单({})审核中,无法删除");
ErrorCode STOCK_CHECK_UPDATE_FAIL_PROCESS = new ErrorCode(1_030_403_007, "库存盘点单({})审核中,无法修改");
ErrorCode STOCK_CHECK_SUBMIT_FAIL_STATUS = new ErrorCode(1_030_403_008, "提交审核失败,只有待提交或已驳回的盘点单才能提交审核");
ErrorCode STOCK_CHECK_SUBMIT_FAIL_USER = new ErrorCode(1_030_403_009, "提交审核失败,只有创建人才能提交审核");
ErrorCode STOCK_CHECK_SUBMIT_FAIL_AUDIT_USER_EMPTY = new ErrorCode(1_030_403_010, "提交审核失败,请选择审核人");
ErrorCode STOCK_CHECK_AUDIT_FAIL_STATUS = new ErrorCode(1_030_403_011, "审核失败,只有审核中的盘点单才能审核");
ErrorCode STOCK_CHECK_AUDIT_FAIL_USER = new ErrorCode(1_030_403_012, "审核失败,当前用户不是指定审核人");
ErrorCode STOCK_CHECK_AUDIT_FAIL_RESULT = new ErrorCode(1_030_403_013, "审核失败,审核结果只支持通过或驳回");
// ========== ERP 产品库存 1-030-404-000 ========== // ========== ERP 产品库存 1-030-404-000 ==========
ErrorCode STOCK_COUNT_NEGATIVE = new ErrorCode(1_030_404_000, "操作失败,产品({})所在仓库({})的库存:{},小于变更数量:{}"); ErrorCode STOCK_COUNT_NEGATIVE = new ErrorCode(1_030_404_000, "操作失败,产品({})所在仓库({})的库存:{},小于变更数量:{}");
@ -133,6 +168,11 @@ public interface ErrorCodeConstants {
// ========== ERP 产品 1-030-500-000 ========== // ========== ERP 产品 1-030-500-000 ==========
ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_030_500_000, "产品不存在"); ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_030_500_000, "产品不存在");
ErrorCode PRODUCT_NOT_ENABLE = new ErrorCode(1_030_500_001, "产品({})未启用"); ErrorCode PRODUCT_NOT_ENABLE = new ErrorCode(1_030_500_001, "产品({})未启用");
ErrorCode PRODUCT_CODE_EXISTS = new ErrorCode(1_030_500_002, "产品编码已存在");
ErrorCode PRODUCT_NAME_AND_STANDARD_EXISTS = new ErrorCode(1_030_500_003, "名称+规格已存在且不能重复");
ErrorCode PRODUCT_CODE_NOT_EXISTS = new ErrorCode(1_030_500_004, "产品编码不存在");
ErrorCode PRODUCT_DEVICE_REL_NOT_EXISTS = new ErrorCode(1_030_500_005, "产品-设备关联不存在");
ErrorCode PRODUCT_MOLD_REL_NOT_EXISTS = new ErrorCode(1_030_500_006, "产品-模具关联不存在");
// ========== ERP 产品分类 1-030-501-000 ========== // ========== ERP 产品分类 1-030-501-000 ==========
ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_030_501_000, "产品分类不存在"); ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_030_501_000, "产品分类不存在");
@ -147,6 +187,8 @@ public interface ErrorCodeConstants {
ErrorCode PRODUCT_UNIT_NOT_EXISTS = new ErrorCode(1_030_502_000, "产品单位不存在"); ErrorCode PRODUCT_UNIT_NOT_EXISTS = new ErrorCode(1_030_502_000, "产品单位不存在");
ErrorCode PRODUCT_UNIT_NAME_DUPLICATE = new ErrorCode(1_030_502_001, "已存在该名字的产品单位"); ErrorCode PRODUCT_UNIT_NAME_DUPLICATE = new ErrorCode(1_030_502_001, "已存在该名字的产品单位");
ErrorCode PRODUCT_UNIT_EXITS_PRODUCT = new ErrorCode(1_030_502_002, "存在产品使用该单位,无法删除"); ErrorCode PRODUCT_UNIT_EXITS_PRODUCT = new ErrorCode(1_030_502_002, "存在产品使用该单位,无法删除");
ErrorCode PRODUCT_UNIT_CONVERT_SELF_NOT_ALLOWED = new ErrorCode(1_030_502_003, "不能设置自己的单位换算自己的单位");
ErrorCode PRODUCT_PURCHASE_UNIT_CONVERT_QUANTITY_INVALID = new ErrorCode(1_030_502_004, "采购单位换算数量必须大于0");
// ========== ERP 结算账户 1-030-600-000 ========== // ========== ERP 结算账户 1-030-600-000 ==========
ErrorCode ACCOUNT_NOT_EXISTS = new ErrorCode(1_030_600_000, "结算账户不存在"); ErrorCode ACCOUNT_NOT_EXISTS = new ErrorCode(1_030_600_000, "结算账户不存在");
@ -177,15 +219,19 @@ public interface ErrorCodeConstants {
ErrorCode MOLD_CODE_EMPTY = new ErrorCode(1_003_000_005, "模具编码不能为空"); ErrorCode MOLD_CODE_EMPTY = new ErrorCode(1_003_000_005, "模具编码不能为空");
ErrorCode MOLD_BRAND_CODE_DUPLICATE = new ErrorCode(1_003_000_006, "模具品牌编码已存在"); ErrorCode MOLD_BRAND_CODE_DUPLICATE = new ErrorCode(1_003_000_006, "模具品牌编码已存在");
ErrorCode MOLD_BRAND_CODE_EMPTY = new ErrorCode(1_003_000_007, "模具品牌编码不能为空"); ErrorCode MOLD_BRAND_CODE_EMPTY = new ErrorCode(1_003_000_007, "模具品牌编码不能为空");
// ========== 模具组相关 1_112_000 ==========
ErrorCode MOLD_SET_NOT_EXISTS = new ErrorCode(1_112_001, "模具组不存在");
ErrorCode MOLD_PRESSURE_NET_RECORD_NOT_EXISTS = new ErrorCode(1_112_002, "子模具压网记录不存在");
ErrorCode MOLD_SET_CODE_EMPTY = new ErrorCode(1_003_000_005, "模具组编码不能为空");
// ========== 编码规则相关 1_111_000 ==========
ErrorCode AUTOCODE_RECORD_NOT_EXISTS = new ErrorCode(1_111_003, "编码生成记录不存在"); ErrorCode AUTOCODE_RECORD_NOT_EXISTS = new ErrorCode(1_111_003, "编码生成记录不存在");
ErrorCode AUTOCODE_RULE_NOT_EXISTS = new ErrorCode(1_111_004, "编码规则不存在"); ErrorCode AUTOCODE_RULE_NOT_EXISTS = new ErrorCode(1_111_004, "编码规则不存在");
ErrorCode AUTOCODE_PART_NOT_EXISTS = new ErrorCode(1_111_005, "编码规则组成不存在"); ErrorCode AUTOCODE_PART_NOT_EXISTS = new ErrorCode(1_111_005, "编码规则组成不存在");
ErrorCode AUTOCODE_GEN_NOT_UNIQUE = new ErrorCode(1_111_006, "编码已存在"); ErrorCode AUTOCODE_GEN_NOT_UNIQUE = new ErrorCode(1_111_006, "编码已存在");
ErrorCode PRODUCT_REFERENCES_EXIST = new ErrorCode(1_003_000_000, "存在产品已被引用,请先删除引用。"); ErrorCode PRODUCT_REFERENCES_EXIST = new ErrorCode(1_003_000_000, "存在产品已被引用,请先删除引用。");
} }

@ -0,0 +1,16 @@
package cn.iocoder.yudao.module.erp.enums.stock;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public enum ErpStockCheckApproveActionEnum {
SUBMIT("SUBMIT"),
APPROVE("APPROVE"),
REJECT("REJECT");
private final String actionType;
}

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.erp.enums.stock;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public enum ErpStockInApproveActionEnum {
SUBMIT("SUBMIT"),
APPROVE("APPROVE"),
REJECT("REJECT"),
AUTO_APPROVE("AUTO_APPROVE");
private final String actionType;
}

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.erp.enums.stock;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public enum ErpStockOutApproveActionEnum {
SUBMIT("SUBMIT"),
APPROVE("APPROVE"),
REJECT("REJECT"),
AUTO_APPROVE("AUTO_APPROVE");
private final String actionType;
}

@ -25,6 +25,11 @@ public enum ErpStockRecordBizTypeEnum implements IntArrayValuable {
OTHER_OUT(20, "其他出库"), OTHER_OUT(20, "其他出库"),
OTHER_OUT_CANCEL(21, "其他出库(作废)"), OTHER_OUT_CANCEL(21, "其他出库(作废)"),
MATERIAL_IN(25, "物料入库"),
MATERIAL_IN_CANCEL(26, "物料入库(作废)"),
MATERIAL_OUT(27, "物料出库"),
MATERIAL_OUT_CANCEL(28, "物料出库(作废)"),
MOVE_IN(30, "调拨入库"), MOVE_IN(30, "调拨入库"),
MOVE_IN_CANCEL(31, "调拨入库(作废)"), MOVE_IN_CANCEL(31, "调拨入库(作废)"),
MOVE_OUT(32, "调拨出库"), MOVE_OUT(32, "调拨出库"),
@ -47,7 +52,6 @@ public enum ErpStockRecordBizTypeEnum implements IntArrayValuable {
PURCHASE_RETURN(80, "采购退货出库"), PURCHASE_RETURN(80, "采购退货出库"),
PURCHASE_RETURN_CANCEL(81, "采购退货出库(作废)"), PURCHASE_RETURN_CANCEL(81, "采购退货出库(作废)"),
SPARE_PARTS(90, "备件入库"), SPARE_PARTS(90, "备件入库"),
SPARE_PARTS_INVALIDATION(91, "备件入库(作废)"), SPARE_PARTS_INVALIDATION(91, "备件入库(作废)"),
@ -89,7 +93,6 @@ public enum ErpStockRecordBizTypeEnum implements IntArrayValuable {
if (type == null) { if (type == null) {
return null; return null;
} }
// status = 10 表示作废
if (Objects.equals(status, 10)) { if (Objects.equals(status, 10)) {
return type + 1; return type + 1;
} }

@ -27,6 +27,11 @@
<artifactId>yudao-module-erp-api</artifactId> <artifactId>yudao-module-erp-api</artifactId>
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-infra-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 --> <!-- 业务组件 -->

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.erp.controller.admin.autocode; package cn.iocoder.yudao.module.erp.controller.admin.autocode;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.erp.controller.admin.autocode.enums.ErpBarcodeTypeEnum;
import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil; import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil;
import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.Parameters;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -91,6 +93,16 @@ public class AutocodeRuleController {
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<AutocodeRuleDO> list = autocodeRuleService.getAutocodeRulePage(pageReqVO).getList(); List<AutocodeRuleDO> list = autocodeRuleService.getAutocodeRulePage(pageReqVO).getList();
List<AutocodeRuleRespVO> autocodeRuleRespVOS = BeanUtils.toBean(list, AutocodeRuleRespVO.class);
if (CollUtil.isNotEmpty(autocodeRuleRespVOS)) {
for (AutocodeRuleRespVO respVO : autocodeRuleRespVOS) {
if (respVO.getBarcodeType()!=null){
respVO.setBarcodeTypeName(ErpBarcodeTypeEnum.getDescByType(respVO.getBarcodeType()));
}
}
}
// 导出 Excel // 导出 Excel
ExcelUtils.write(response, "编码规则.xls", "数据", AutocodeRuleRespVO.class, ExcelUtils.write(response, "编码规则.xls", "数据", AutocodeRuleRespVO.class,
BeanUtils.toBean(list, AutocodeRuleRespVO.class)); BeanUtils.toBean(list, AutocodeRuleRespVO.class));

@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.erp.controller.admin.autocode.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* /
*/
@Getter
@AllArgsConstructor
public enum ErpBarcodeTypeEnum {
BARCODE(1, "条形码"),
QRCODE(2, "二维码"),
BOTH(3, "条形码+二维码");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpBarcodeTypeEnum::getType).toArray();
private final Integer type;
private final String desc;
/**
*
*/
public static String getDescByType(Integer type) {
if (type == null) {
return "";
}
for (ErpBarcodeTypeEnum value : values()) {
if (value.getType().equals(type)) {
return value.getDesc();
}
}
return "未知";
}
}

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.erp.controller.admin.autocode.util;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.module.common.enums.CodeTypeEnum;
import cn.iocoder.yudao.module.erp.controller.admin.autocode.vo.AutocodeRecordSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.autocode.vo.AutocodeRecordSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.autocode.AutocodePartDO; import cn.iocoder.yudao.module.erp.dal.dataobject.autocode.AutocodePartDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.autocode.AutocodeRecordDO; import cn.iocoder.yudao.module.erp.dal.dataobject.autocode.AutocodeRecordDO;
@ -184,4 +185,14 @@ public class AutoCodeUtil {
return autoCode; return autoCode;
} }
public CodeTypeEnum queryCodeType(String ruleCode) {
AutocodeRuleDO rule = iAutoCodeRuleService.getAutocodeRuleByRuleCode(ruleCode);
if (rule == null) {
return null;
}
return CodeTypeEnum.fromBarcodeType(rule.getBarcodeType());
}
} }

@ -46,4 +46,7 @@ public class AutocodeRulePageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime; private LocalDateTime[] createTime;
@Schema(description = "码类型条形码-1 二维码-2", example = "")
private Integer barcodeType;
} }

@ -27,6 +27,13 @@ public class AutocodeRuleRespVO {
@ExcelProperty("规则名称") @ExcelProperty("规则名称")
private String ruleName; private String ruleName;
@Schema(description = "码类型条形码-1 二维码-2", example = "")
private Integer barcodeType;
@Schema(description = "码类型", example = "")
@ExcelProperty("码类型")
private String barcodeTypeName;
@Schema(description = "描述") @Schema(description = "描述")
@ExcelProperty("描述") @ExcelProperty("描述")
private String ruleDesc; private String ruleDesc;

@ -45,4 +45,8 @@ public class AutocodeRuleSaveReqVO {
@Schema(description = "编码规则组成列表") @Schema(description = "编码规则组成列表")
private List<AutocodePartDO> autocodeParts; private List<AutocodePartDO> autocodeParts;
@Schema(description = "码类型条形码-1 二维码-2", example = "")
private Integer barcodeType;
} }

@ -13,6 +13,8 @@ import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandDO;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandProductDO; import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandProductDO;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO; import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO;
import cn.iocoder.yudao.module.common.dal.dataobject.moldrepair.MoldRepairDO; import cn.iocoder.yudao.module.common.dal.dataobject.moldrepair.MoldRepairDO;
import cn.iocoder.yudao.module.erp.controller.admin.mold.vo.MoldBrandPageRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.mold.vo.MoldBrandRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.mold.vo.MoldBrandTreeRespVO; import cn.iocoder.yudao.module.erp.controller.admin.mold.vo.MoldBrandTreeRespVO;
import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService; import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
@ -27,6 +29,7 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List; import java.util.List;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
@ -44,7 +47,7 @@ public class MoldBrandController {
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建模具型号") @Operation(summary = "创建模具型号")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:create')") @PreAuthorize("@ss.hasPermission('erp:mold-brand:create')")
public CommonResult<Long> createMoldBrand(@Valid @RequestBody MoldBrandSaveReqVO createReqVO) { public CommonResult<Long> createMoldBrand(@Valid @RequestBody MoldBrandSaveReqVO createReqVO) throws UnsupportedEncodingException {
return success(moldBrandService.createMoldBrand(createReqVO)); return success(moldBrandService.createMoldBrand(createReqVO));
} }
@ -70,22 +73,26 @@ public class MoldBrandController {
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:query')") @PreAuthorize("@ss.hasPermission('erp:mold-brand:query')")
public CommonResult<MoldBrandRespVO> getMoldBrand(@RequestParam("id") Long id) { public CommonResult<MoldBrandRespVO> getMoldBrand(@RequestParam("id") Long id) {
MoldBrandDO moldBrand = moldBrandService.getMoldBrand(id); MoldBrandRespVO respVO = moldBrandService.getMoldBrandDetail(id);
return success(BeanUtils.toBean(moldBrand, MoldBrandRespVO.class)); moldBrandService.fillLatestOperateDeviceName(respVO);
return success(respVO);
} }
@GetMapping("/getBrandList") @GetMapping("/getBrandList")
@Operation(summary = "获得模具型号列表") @Operation(summary = "获得模具型号列表")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:query')") @PreAuthorize("@ss.hasPermission('erp:mold-brand:query')")
public CommonResult<List<MoldBrandDO>> getBrandList(MoldBrandPageReqVO pageReqVO) { public CommonResult<List<MoldBrandRespVO>> getBrandList(MoldBrandPageReqVO pageReqVO) {
List<MoldBrandDO> brandDOList = moldBrandService.selectBy(pageReqVO); PageResult<MoldBrandRespVO> pageResult = moldBrandService.getMoldBrandPage(pageReqVO);
return success(brandDOList); return success(pageResult.getList());
} }
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得模具型号分页") @Operation(summary = "获得模具型号分页")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:query')") @PreAuthorize("@ss.hasPermission('erp:mold-brand:query')")
public CommonResult<PageResult<MoldBrandRespVO>> getMoldBrandPage(@Valid MoldBrandPageReqVO pageReqVO) { public CommonResult<MoldBrandPageRespVO> getMoldBrandPage(@Valid MoldBrandPageReqVO pageReqVO) {
PageResult<MoldBrandRespVO> pageResult = moldBrandService.getMoldBrandPage(pageReqVO); MoldBrandPageRespVO respVO = moldBrandService.getMoldBrandPageWithStatistics(pageReqVO);
return success(pageResult); if (respVO != null && respVO.getPageResult() != null) {
moldBrandService.fillLatestOperateDeviceName(respVO.getPageResult().getList());
}
return success(respVO);
} }
@GetMapping("/export-excel") @GetMapping("/export-excel")
@ -135,23 +142,23 @@ public class MoldBrandController {
@GetMapping("/mold/list") @GetMapping("/mold/list")
@Operation(summary = "获得模具列表") @Operation(summary = "获得模具列表")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:query')") @PreAuthorize("@ss.hasPermission('erp:mold-brand:query')")
public CommonResult<List<MoldDO>> getMoldList() { public CommonResult<List<MoldDO>> getMoldList(@Valid MoldPageReqVO pageReqVO) {
List<MoldDO> moldDOList = moldBrandService.getMoldList(); List<MoldDO> moldDOList = moldBrandService.getMoldList(pageReqVO);
return success(moldDOList); return success(moldDOList);
} }
@PostMapping("/mold/create") @PostMapping("/mold/create")
@Operation(summary = "创建模具") @Operation(summary = "创建模具")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:create')") @PreAuthorize("@ss.hasPermission('erp:mold-brand:create')")
public CommonResult<Long> createMold(@Valid @RequestBody MoldSaveReqVO createReqVO) { public CommonResult<Long> createMold(@Valid @RequestBody MoldSaveReqVO createReqVO) throws UnsupportedEncodingException {
return success(moldBrandService.createMold(createReqVO)); return success(moldBrandService.createMold(createReqVO));
} }
@PutMapping("/mold/update") @PutMapping("/mold/update")
@Operation(summary = "更新模具") @Operation(summary = "更新模具")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:update')") @PreAuthorize("@ss.hasPermission('erp:mold-brand:update')")
public CommonResult<Boolean> updateMold(@Valid @RequestBody MoldDO mold) { public CommonResult<Boolean> updateMold(@Valid @RequestBody MoldSaveReqVO updateReqVO) {
moldBrandService.updateMold(mold); moldBrandService.updateMold(updateReqVO);
return success(true); return success(true);
} }
@ -166,10 +173,10 @@ public class MoldBrandController {
@GetMapping("/mold/get") @GetMapping("/mold/get")
@Operation(summary = "获得模具") @Operation(summary = "获得模具")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('erp:mold-brand:query')") @PreAuthorize("@ss.hasPermission('erp:mold-brand:query')")
public CommonResult<MoldDO> getMold(@RequestParam("id") Long id) { public CommonResult<MoldDO> getMold(@RequestParam(value = "id", required = false) Long id,
return success(moldBrandService.getMold(id)); @RequestParam(value = "code", required = false) String code) {
return success(moldBrandService.getMold(id, code));
} }
@GetMapping("/mold/export-excel") @GetMapping("/mold/export-excel")
@ -186,6 +193,15 @@ public class MoldBrandController {
ExcelUtils.write(response, "模具.xls", "数据", MoldRespVO.class, list); ExcelUtils.write(response, "模具.xls", "数据", MoldRespVO.class, list);
} }
@PostMapping("/regenerate-code")
public CommonResult<Boolean> regenerateCode(@RequestParam("id") Long id,
@RequestParam("code") String code) throws UnsupportedEncodingException {
moldBrandService.regenerateCode(id, code);
return success(true);
}
// ==================== 子表(模具产品) ==================== // ==================== 子表(模具产品) ====================
@GetMapping("/mold-brand-product/page") @GetMapping("/mold-brand-product/page")

@ -0,0 +1,106 @@
package cn.iocoder.yudao.module.erp.controller.admin.mold;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.erp.controller.admin.mold.vo.MoldPressureNetRecordPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.mold.vo.MoldPressureNetRecordRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.mold.vo.MoldPressureNetRecordSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.mold.MoldPressureNetRecordDO;
import cn.iocoder.yudao.module.erp.service.mold.MoldPressureNetRecordService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
@Tag(name = "管理后台 - 子模具压网记录")
@RestController
@RequestMapping("/erp/mold-pressure-net-record")
@Validated
public class MoldPressureNetRecordController {
@Resource
private MoldPressureNetRecordService moldPressureNetRecordService;
@PostMapping("/create")
@Operation(summary = "创建子模具压网记录")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:create')")
public CommonResult<Long> createMoldPressureNetRecord(@Valid @RequestBody MoldPressureNetRecordSaveReqVO createReqVO) {
return success(moldPressureNetRecordService.createMoldPressureNetRecord(createReqVO));
}
@PostMapping("/batch-create")
@Operation(summary = "批量创建子模具压网记录")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:create')")
public CommonResult<Boolean> createMoldPressureNetRecordBatch(@Valid @RequestBody List<MoldPressureNetRecordSaveReqVO> createReqVOList) {
moldPressureNetRecordService.createBatchMoldPressureNetRecord(createReqVOList);
return success(true);
}
@PutMapping("/update")
@Operation(summary = "更新子模具压网记录")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:update')")
public CommonResult<Boolean> updateMoldPressureNetRecord(@Valid @RequestBody MoldPressureNetRecordSaveReqVO updateReqVO) {
moldPressureNetRecordService.updateMoldPressureNetRecord(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除子模具压网记录")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('erp:mold-brand:delete')")
public CommonResult<Boolean> deleteMoldPressureNetRecord(@RequestParam("id") Long id) {
moldPressureNetRecordService.deleteMoldPressureNetRecord(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得子模具压网记录")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:query')")
public CommonResult<MoldPressureNetRecordRespVO> getMoldPressureNetRecord(@RequestParam("id") Long id) {
MoldPressureNetRecordDO record = moldPressureNetRecordService.getMoldPressureNetRecord(id);
return success(BeanUtils.toBean(record, MoldPressureNetRecordRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得子模具压网记录分页")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:query')")
public CommonResult<PageResult<MoldPressureNetRecordRespVO>> getMoldPressureNetRecordPage(@Valid MoldPressureNetRecordPageReqVO pageReqVO) {
PageResult<MoldPressureNetRecordDO> pageResult = moldPressureNetRecordService.getMoldPressureNetRecordPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, MoldPressureNetRecordRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出子模具压网记录 Excel")
@PreAuthorize("@ss.hasPermission('erp:mold-brand:query')")
@ApiAccessLog(operateType = EXPORT)
public void exportMoldPressureNetRecordExcel(@Valid MoldPressureNetRecordPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<MoldPressureNetRecordDO> list = moldPressureNetRecordService.getMoldPressureNetRecordPage(pageReqVO).getList();
ExcelUtils.write(response, "子模具压网记录.xls", "数据", MoldPressureNetRecordRespVO.class,
BeanUtils.toBean(list, MoldPressureNetRecordRespVO.class));
}
}

@ -29,6 +29,9 @@ public class MoldBrandPageReqVO extends PageParam {
@Schema(description = "产品ID", example = "2336") @Schema(description = "产品ID", example = "2336")
private Long productId; private Long productId;
@Schema(description = "设备名称", example = "注塑机")
private String deviceName;
@Schema(description = "预期寿命(小时)") @Schema(description = "预期寿命(小时)")
private BigDecimal useTime; private BigDecimal useTime;

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.erp.controller.admin.mold.vo;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 模具型号分页 Response VO")
@Data
public class MoldBrandPageRespVO {
@Schema(description = "分页结果", requiredMode = Schema.RequiredMode.REQUIRED)
private PageResult<MoldBrandRespVO> pageResult;
@Schema(description = "全部数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Long allCount;
@Schema(description = "在机数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
private Long onMachineCount;
@Schema(description = "待用数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
private Long standbyCount;
@Schema(description = "在库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8")
private Long inStockCount;
@Schema(description = "维修数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
private Long repairingCount;
@Schema(description = "报废数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
private Long scrappedCount;
}

@ -11,6 +11,7 @@ import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*; import com.alibaba.excel.annotation.*;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
@Schema(description = "管理后台 - 模具型号 Response VO") @Schema(description = "管理后台 - 模具型号 Response VO")
@ -40,6 +41,50 @@ public class MoldBrandRespVO {
// @ExcelProperty("产品") // @ExcelProperty("产品")
private String productName; private String productName;
@Schema(description = "图片", example = "https://example.com/mold.png")
@ExcelProperty("图片")
private String images;
@Schema(description = "图纸", example = "https://example.com/drawing.pdf")
@ExcelProperty("图纸")
private String drawings;
@Schema(description = "操作手册", example = "https://example.com/manual.pdf")
@ExcelProperty("操作手册")
private String operationManual;
@Schema(description = "操作视频", example = "https://example.com/video.mp4")
@ExcelProperty("操作视频")
private String operationVideo;
@Schema(description = "版本", example = "V1.0")
@ExcelProperty("版本")
private String version;
@Schema(description = "状态", example = "0")
@ExcelProperty("状态")
private Integer status;
@Schema(description = "当前位置", example = "一号机台")
@ExcelProperty("当前位置")
private String currentPosition;
@Schema(description = "设备id", requiredMode = Schema.RequiredMode.REQUIRED, example = "2336")
private Long deviceId;
@Schema(description = "当前设备", example = "")
@ExcelProperty("当前设备")
private String deviceName;
@Schema(description = "子模数", example = "0")
private Long childMoldCount;
@Schema(description = "产品ID列表")
private List<Long> productIds;
@Schema(description = "产品列表")
private List<ErpProductDO> products;
@Schema(description = "预期寿命/次") @Schema(description = "预期寿命/次")
@ExcelProperty("预期寿命/次") @ExcelProperty("预期寿命/次")
private BigDecimal useTime; private BigDecimal useTime;
@ -75,4 +120,11 @@ public class MoldBrandRespVO {
@DictFormat("mes_org_type") @DictFormat("mes_org_type")
private String orgType; private String orgType;
// , converter = OrgTypeConverter.class // , converter = OrgTypeConverter.class
@Schema(description = "二维码", example = "")
private String qrCodeUrl;
@Schema(description = "打印模板", example = "")
private String templateJson;
} }

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.erp.controller.admin.mold.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 模具型号状态统计 Response VO")
@Data
public class MoldBrandStatusStatisticsRespVO {
@Schema(description = "全部数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
private Long allCount;
@Schema(description = "在机数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
private Long onMachineCount;
@Schema(description = "待用数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
private Long standbyCount;
@Schema(description = "在库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8")
private Long inStockCount;
@Schema(description = "维修数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
private Long repairingCount;
@Schema(description = "报废数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
private Long scrappedCount;
}

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.erp.controller.admin.mold.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 子模具压网记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MoldPressureNetRecordPageReqVO extends PageParam {
@Schema(description = "模具组ID", example = "1")
private Long moldBrandId;
@Schema(description = "模具组名称", example = "A组")
private String moldBrandName;
@Schema(description = "子模具ID", example = "1")
private Long moldId;
@Schema(description = "子模具名称", example = "子模具A")
private String moldName;
@Schema(description = "压网时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] pressureNetTime;
@Schema(description = "备注", example = "备注")
private String remark;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,49 @@
package cn.iocoder.yudao.module.erp.controller.admin.mold.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 子模具压网记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class MoldPressureNetRecordRespVO {
@Schema(description = "ID", example = "1")
@ExcelProperty("ID")
private Long id;
@Schema(description = "模具组ID", example = "1")
@ExcelProperty("模具组ID")
private Long moldBrandId;
@Schema(description = "模具组名称", example = "A组")
@ExcelProperty("模具组名称")
private String moldBrandName;
@Schema(description = "子模具ID", example = "1")
@ExcelProperty("子模具ID")
private Long moldId;
@Schema(description = "子模具名称", example = "子模具A")
@ExcelProperty("子模具名称")
private String moldName;
@Schema(description = "压网时间")
@ExcelProperty("压网时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime pressureNetTime;
@Schema(description = "备注", example = "备注")
@ExcelProperty("备注")
private String remark;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.erp.controller.admin.mold.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 子模具压网记录新增/修改 Request VO")
@Data
public class MoldPressureNetRecordSaveReqVO {
@Schema(description = "ID", example = "1")
private Long id;
@Schema(description = "模具组ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "模具组ID不能为空")
private Long moldBrandId;
@Schema(description = "模具组名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "A组")
private String moldBrandName;
@Schema(description = "子模具ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "子模具ID不能为空")
private Long moldId;
@Schema(description = "子模具名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "子模具A")
private String moldName;
@Schema(description = "压网时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "压网时间不能为空")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime pressureNetTime;
@Schema(description = "备注", example = "备注")
private String remark;
}

@ -85,4 +85,13 @@ public class MoldRespVO {
@ExcelProperty("附件地址") @ExcelProperty("附件地址")
private String fileUrl; private String fileUrl;
@Schema(description = "压网时间")
@ExcelProperty("压网时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime pressureNetTime;
@Schema(description = "压网天数", example = "5")
@ExcelProperty("压网天数")
private Long pressureNetDays;
} }

@ -0,0 +1,108 @@
package cn.iocoder.yudao.module.erp.controller.admin.product;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.packagingscheme.ErpPackagingSchemePageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.packagingscheme.ErpPackagingSchemeRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.packagingscheme.ErpPackagingSchemeSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpPackagingSchemeDO;
import cn.iocoder.yudao.module.erp.service.product.ErpPackagingSchemeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@Tag(name = "管理后台 - ERP 包装方案")
@RestController
@RequestMapping("/erp/packaging-scheme")
@Validated
public class ErpPackagingSchemeController {
@Resource
private ErpPackagingSchemeService packagingSchemeService;
@PostMapping("/create")
@Operation(summary = "创建包装方案")
@PreAuthorize("@ss.hasPermission('erp:packaging-scheme:create')")
public CommonResult<Long> createPackagingScheme(@Valid @RequestBody ErpPackagingSchemeSaveReqVO createReqVO) {
return success(packagingSchemeService.createPackagingScheme(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新包装方案")
@PreAuthorize("@ss.hasPermission('erp:packaging-scheme:update')")
public CommonResult<Boolean> updatePackagingScheme(@Valid @RequestBody ErpPackagingSchemeSaveReqVO updateReqVO) {
packagingSchemeService.updatePackagingScheme(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除包装方案")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('erp:packaging-scheme:delete')")
public CommonResult<Boolean> deletePackagingScheme(@RequestParam("id") Long id) {
packagingSchemeService.deletePackagingScheme(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得包装方案")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:packaging-scheme:query')")
public CommonResult<ErpPackagingSchemeRespVO> getPackagingScheme(@RequestParam("id") Long id) {
ErpPackagingSchemeDO scheme = packagingSchemeService.getPackagingScheme(id);
return success(BeanUtils.toBean(scheme, ErpPackagingSchemeRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得包装方案分页")
@PreAuthorize("@ss.hasPermission('erp:packaging-scheme:query')")
public CommonResult<PageResult<ErpPackagingSchemeRespVO>> getPackagingSchemePage(@Valid ErpPackagingSchemePageReqVO pageReqVO) {
PageResult<ErpPackagingSchemeDO> pageResult = packagingSchemeService.getPackagingSchemePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ErpPackagingSchemeRespVO.class));
}
@GetMapping("/simple-list")
@Operation(summary = "获得包装方案精简列表", description = "只包含已启用的包装方案")
public CommonResult<List<ErpPackagingSchemeRespVO>> getPackagingSchemeSimpleList() {
List<ErpPackagingSchemeDO> list = packagingSchemeService.getPackagingSchemeListByStatus(CommonStatusEnum.ENABLE.getStatus());
return success(convertList(list, item -> BeanUtils.toBean(item, ErpPackagingSchemeRespVO.class)));
}
@GetMapping("/export-excel")
@Operation(summary = "导出包装方案 Excel")
@PreAuthorize("@ss.hasPermission('erp:packaging-scheme:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportPackagingSchemeExcel(@Valid ErpPackagingSchemePageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ErpPackagingSchemeDO> list = packagingSchemeService.getPackagingSchemePage(pageReqVO).getList();
ExcelUtils.write(response, "包装方案.xls", "数据", ErpPackagingSchemeRespVO.class,
BeanUtils.toBean(list, ErpPackagingSchemeRespVO.class));
}
}

@ -8,6 +8,8 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategoryListReqVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategoryListReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategoryRespVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategoryRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategorySaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategorySaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategoryTreeRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategoryTypeGroupRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO;
import cn.iocoder.yudao.module.erp.service.product.ErpProductCategoryService; import cn.iocoder.yudao.module.erp.service.product.ErpProductCategoryService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -21,7 +23,10 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@ -77,12 +82,30 @@ public class ErpProductCategoryController {
return success(BeanUtils.toBean(list, ErpProductCategoryRespVO.class)); return success(BeanUtils.toBean(list, ErpProductCategoryRespVO.class));
} }
@GetMapping("/group-tree")
@Operation(summary = "按类型分组获得产品分类树")
@PreAuthorize("@ss.hasPermission('erp:product-category:query')")
public CommonResult<List<ErpProductCategoryTypeGroupRespVO>> getProductCategoryGroupTree(@Valid ErpProductCategoryListReqVO listReqVO) {
List<ErpProductCategoryDO> list = productCategoryService.getProductCategoryList(listReqVO);
Map<Integer, List<ErpProductCategoryDO>> typeMap = new LinkedHashMap<>();
for (ErpProductCategoryDO category : list) {
typeMap.computeIfAbsent(category.getType(), key -> new ArrayList<>()).add(category);
}
List<ErpProductCategoryTypeGroupRespVO> result = new ArrayList<>();
for (Map.Entry<Integer, List<ErpProductCategoryDO>> entry : typeMap.entrySet()) {
ErpProductCategoryTypeGroupRespVO group = new ErpProductCategoryTypeGroupRespVO();
group.setType(entry.getKey());
group.setChildren(buildCategoryTree(entry.getValue()));
result.add(group);
}
return success(result);
}
@GetMapping("/simple-list") @GetMapping("/simple-list")
@Operation(summary = "获得产品分类精简列表", description = "只包含被开启的分类,主要用于前端的下拉选项") @Operation(summary = "获得产品分类精简列表", description = "只包含被开启的分类,主要用于前端的下拉选项")
public CommonResult<List<ErpProductCategoryRespVO>> getProductCategorySimpleList() { public CommonResult<List<ErpProductCategoryRespVO>> getProductCategorySimpleList(@RequestParam("type") Integer type) {
List<ErpProductCategoryDO> list = productCategoryService.getProductCategoryList( List<ErpProductCategoryDO> list = productCategoryService.getProductCategoryList(
new ErpProductCategoryListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus())); new ErpProductCategoryListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()).setType(type));
return success(convertList(list, category -> new ErpProductCategoryRespVO() return success(convertList(list, category -> new ErpProductCategoryRespVO()
.setId(category.getId()).setName(category.getName()).setParentId(category.getParentId()).setSort(category.getSort()))); .setId(category.getId()).setName(category.getName()).setParentId(category.getParentId()).setSort(category.getSort())));
} }
@ -94,9 +117,31 @@ public class ErpProductCategoryController {
public void exportProductCategoryExcel(@Valid ErpProductCategoryListReqVO listReqVO, public void exportProductCategoryExcel(@Valid ErpProductCategoryListReqVO listReqVO,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
List<ErpProductCategoryDO> list = productCategoryService.getProductCategoryList(listReqVO); List<ErpProductCategoryDO> list = productCategoryService.getProductCategoryList(listReqVO);
// 导出 Excel
ExcelUtils.write(response, "产品分类.xls", "数据", ErpProductCategoryRespVO.class, ExcelUtils.write(response, "产品分类.xls", "数据", ErpProductCategoryRespVO.class,
BeanUtils.toBean(list, ErpProductCategoryRespVO.class)); BeanUtils.toBean(list, ErpProductCategoryRespVO.class));
} }
private List<ErpProductCategoryTreeRespVO> buildCategoryTree(List<ErpProductCategoryDO> categories) {
Map<Long, ErpProductCategoryTreeRespVO> nodeMap = new LinkedHashMap<>();
for (ErpProductCategoryDO category : categories) {
ErpProductCategoryTreeRespVO node = BeanUtils.toBean(category, ErpProductCategoryTreeRespVO.class);
node.setChildren(new ArrayList<>());
node.setLeaf(true);
nodeMap.put(category.getId(), node);
}
List<ErpProductCategoryTreeRespVO> roots = new ArrayList<>();
for (ErpProductCategoryDO category : categories) {
ErpProductCategoryTreeRespVO node = nodeMap.get(category.getId());
Long parentId = category.getParentId();
ErpProductCategoryTreeRespVO parent = parentId == null ? null : nodeMap.get(parentId);
if (parent == null || ErpProductCategoryDO.PARENT_ID_ROOT.equals(parentId)) {
roots.add(node);
continue;
}
parent.getChildren().add(node);
parent.setLeaf(false);
}
return roots;
}
} }

@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategoryListReqVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.category.ErpProductCategoryListReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.*; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO;
@ -15,6 +16,8 @@ import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
import cn.iocoder.yudao.module.erp.framework.bean.ProductTypeEnum; import cn.iocoder.yudao.module.erp.framework.bean.ProductTypeEnum;
import cn.iocoder.yudao.module.erp.service.product.ErpProductCategoryService; import cn.iocoder.yudao.module.erp.service.product.ErpProductCategoryService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.Parameters;
@ -28,14 +31,17 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.MOLD_CODE_DUPLICATE;
@Tag(name = "管理后台 - ERP 产品") @Tag(name = "管理后台 - ERP 产品")
@RestController @RestController
@ -51,18 +57,20 @@ public class ErpProductController {
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建产品") @Operation(summary = "创建产品")
@PreAuthorize("@ss.hasPermission('erp:product:create')") @PreAuthorize("@ss.hasPermission('erp:product:create')")
public CommonResult<Long> createProduct(@Valid @RequestBody ProductSaveReqVO createReqVO) { public CommonResult<Long> createProduct(@Valid @RequestBody ProductSaveReqVO createReqVO) throws UnsupportedEncodingException {
ErpProductPageReqVO productPageReqVO = new ErpProductPageReqVO(); // ErpProductPageReqVO productPageReqVO = new ErpProductPageReqVO();
productPageReqVO.setName(createReqVO.getName()); // productPageReqVO.setName(createReqVO.getName());
productPageReqVO.setStandard(createReqVO.getStandard()); // productPageReqVO.setStandard(createReqVO.getStandard());
if (productMapper.selectProductExist(productPageReqVO)) { // if (productMapper.selectProductExist(productPageReqVO)) {
return error(400,"名称+规格不能重复"); // return error(400,"名称+规格不能重复");
} // }
productPageReqVO = new ErpProductPageReqVO(); // productPageReqVO = new ErpProductPageReqVO();
productPageReqVO.setCode(createReqVO.getBarCode());
if (!productMapper.selectProductCodeExist(productPageReqVO).getList().isEmpty()) { // productPageReqVO.setCode(createReqVO.getBarCode());
return error(400,"编码不能重复"); // if (!productMapper.selectProductCodeExist(productPageReqVO).getList().isEmpty()) {
} // return error(400,"编码不能重复");
// }
return success(productService.createProduct(createReqVO)); return success(productService.createProduct(createReqVO));
} }
@ -96,11 +104,10 @@ public class ErpProductController {
@GetMapping("/get") @GetMapping("/get")
@Operation(summary = "获得产品") @Operation(summary = "获得产品")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:product:query')") @PreAuthorize("@ss.hasPermission('erp:product:query')")
public CommonResult<ErpProductRespVO> getProduct(@RequestParam("id") Long id) { public CommonResult<ErpProductRespVO> getProduct(@RequestParam(value = "id", required = false) Long id,
ErpProductDO product = productService.getProduct(id); @RequestParam(value = "code", required = false) String code) {
return success(BeanUtils.toBean(product, ErpProductRespVO.class)); return success(productService.getProduct(id, code));
} }
@GetMapping("/page") @GetMapping("/page")
@ -117,17 +124,26 @@ public class ErpProductController {
.setName(product.getName()).setBarCode(product.getBarCode()) .setName(product.getName()).setBarCode(product.getBarCode())
.setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName()) .setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName())
.setUnitId(product.getUnitId()).setUnitName(product.getUnitName()) .setUnitId(product.getUnitId()).setUnitName(product.getUnitName())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice()).setMinPrice(product.getMinPrice()))); .setPurchaseUnitId(product.getPurchaseUnitId()).setPurchaseUnitName(product.getPurchaseUnitName())
.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice())
.setMinPrice(product.getMinPrice()).setImages(product.getImages())));
} }
@GetMapping("/simple-list-product") @GetMapping("/simple-list-product")
@Operation(summary = "获得产品精简列表", description = "只包含被开启的产品,主要用于前端的下拉选项") @Operation(summary = "获得产品精简列表", description = "只包含被开启的产品,主要用于前端的下拉选项")
public CommonResult<List<ErpProductRespVO>> getProductSimpleList() { public CommonResult<List<ErpProductRespVO>> getProductSimpleList(
List<ErpProductRespVO> list = productService.getProductVOListByCategory(ProductTypeEnum.PRODUCT.getTypeId()); @Parameter(name = "categoryType", description = "产品分类类型", example = "1")
@RequestParam(name = "categoryType", required = false) Integer categoryType) {
// List<ErpProductRespVO> list = productService.getProductVOListByCategory(ProductTypeEnum.PRODUCT.getTypeId(), categoryType);
List<ErpProductRespVO> list = productService.getProductVOListByCategory(null, categoryType);
return success(convertList(list, product -> new ErpProductRespVO().setId(product.getId()) return success(convertList(list, product -> new ErpProductRespVO().setId(product.getId())
.setName(product.getName()).setBarCode(product.getBarCode()) .setName(product.getName()).setBarCode(product.getBarCode())
.setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName()) .setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName())
.setUnitId(product.getUnitId()).setUnitName(product.getUnitName()) .setUnitId(product.getUnitId()).setUnitName(product.getUnitName())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice()).setMinPrice(product.getMinPrice()))); .setPurchaseUnitId(product.getPurchaseUnitId()).setPurchaseUnitName(product.getPurchaseUnitName())
.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice())
.setMinPrice(product.getMinPrice()).setImages(product.getImages())));
} }
@GetMapping("/simple-list-item") @GetMapping("/simple-list-item")
@Operation(summary = "获得原料精简列表", description = "只包含被开启的原料,主要用于前端的下拉选项") @Operation(summary = "获得原料精简列表", description = "只包含被开启的原料,主要用于前端的下拉选项")
@ -137,7 +153,10 @@ public class ErpProductController {
.setName(product.getName()).setBarCode(product.getBarCode()) .setName(product.getName()).setBarCode(product.getBarCode())
.setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName()) .setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName())
.setUnitId(product.getUnitId()).setUnitName(product.getUnitName()) .setUnitId(product.getUnitId()).setUnitName(product.getUnitName())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice()).setMinPrice(product.getMinPrice()))); .setPurchaseUnitId(product.getPurchaseUnitId()).setPurchaseUnitName(product.getPurchaseUnitName())
.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice())
.setMinPrice(product.getMinPrice()).setImages(product.getImages())));
} }
@Resource @Resource
private ErpProductCategoryService productCategoryService; private ErpProductCategoryService productCategoryService;
@ -159,7 +178,10 @@ public class ErpProductController {
.setName(product.getName()).setBarCode(product.getBarCode()) .setName(product.getName()).setBarCode(product.getBarCode())
.setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName()) .setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName())
.setUnitId(product.getUnitId()).setUnitName(product.getUnitName()) .setUnitId(product.getUnitId()).setUnitName(product.getUnitName())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice()).setMinPrice(product.getMinPrice()))); .setPurchaseUnitId(product.getPurchaseUnitId()).setPurchaseUnitName(product.getPurchaseUnitName())
.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice())
.setMinPrice(product.getMinPrice()).setImages(product.getImages())));
} }
@GetMapping("/simple-list-component") @GetMapping("/simple-list-component")
@Operation(summary = "获得备件精简列表", description = "用于前端的下拉选项") @Operation(summary = "获得备件精简列表", description = "用于前端的下拉选项")
@ -169,7 +191,10 @@ public class ErpProductController {
.setName(product.getName()).setBarCode(product.getBarCode()) .setName(product.getName()).setBarCode(product.getBarCode())
.setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName()) .setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName())
.setUnitId(product.getUnitId()).setUnitName(product.getUnitName()) .setUnitId(product.getUnitId()).setUnitName(product.getUnitName())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice()).setMinPrice(product.getMinPrice()))); .setPurchaseUnitId(product.getPurchaseUnitId()).setPurchaseUnitName(product.getPurchaseUnitName())
.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice())
.setMinPrice(product.getMinPrice()).setImages(product.getImages())));
} }
@GetMapping("/export-excel") @GetMapping("/export-excel")
@Operation(summary = "导出产品 Excel") @Operation(summary = "导出产品 Excel")
@ -231,4 +256,12 @@ public class ErpProductController {
return success(productService.importProductList(list, updateSupport)); return success(productService.importProductList(list, updateSupport));
} }
@PostMapping("/regenerate-code")
public CommonResult<Boolean> regenerateCode(@RequestParam("id") Long id,
@RequestParam("code") String code) throws UnsupportedEncodingException {
productService.regenerateCode(id, code);
return success(true);
// s
}
} }

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.erp.controller.admin.product; package cn.iocoder.yudao.module.erp.controller.admin.product;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
@ -10,26 +11,33 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitRespVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitImportExcelVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductUnitMapper; import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductUnitMapper;
import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService; import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
import cn.iocoder.yudao.module.system.enums.common.SexEnum;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List; import java.util.List;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.IMPORT_LIST_IS_EMPTY;
@Tag(name = "管理后台 - ERP 产品单位") @Tag(name = "管理后台 - ERP 产品单位")
@RestController @RestController
@ -92,7 +100,12 @@ public class ErpProductUnitController {
@Operation(summary = "获得产品单位精简列表", description = "只包含被开启的单位,主要用于前端的下拉选项") @Operation(summary = "获得产品单位精简列表", description = "只包含被开启的单位,主要用于前端的下拉选项")
public CommonResult<List<ErpProductUnitRespVO>> getProductUnitSimpleList() { public CommonResult<List<ErpProductUnitRespVO>> getProductUnitSimpleList() {
List<ErpProductUnitDO> list = productUnitService.getProductUnitListByStatus(CommonStatusEnum.ENABLE.getStatus()); List<ErpProductUnitDO> list = productUnitService.getProductUnitListByStatus(CommonStatusEnum.ENABLE.getStatus());
return success(convertList(list, unit -> new ErpProductUnitRespVO().setId(unit.getId()).setName(unit.getName()))); list.stream().forEach(item -> {
item.setValue(item.getId().toString());
item.setLabel(item.getName());
});
List<ErpProductUnitRespVO> erpProductUnitRespVOS = convertList(list, unit -> new ErpProductUnitRespVO().setId(unit.getId()).setName(unit.getName()).setValue(unit.getId().toString()).setLabel(unit.getName()));
return success(erpProductUnitRespVOS);
} }
@GetMapping("/export-excel") @GetMapping("/export-excel")
@ -124,4 +137,30 @@ public class ErpProductUnitController {
} }
@GetMapping("/get-import-template")
@Operation(summary = "获得导入单位模板")
public void importTemplate(HttpServletResponse response) throws IOException {
// 手动创建导出 demo
List<ErpProductUnitImportExcelVO> list = Arrays.asList(
ErpProductUnitImportExcelVO.builder().name("件").primaryFlag("N").primaryName("个").changeRate(0.02)
.status(CommonStatusEnum.ENABLE.getStatus()).build()
);
// 输出
ExcelUtils.write(response, "单位导入模板.xls", "单位列表", ErpProductUnitImportExcelVO.class, list);
}
@PostMapping("/import")
@Operation(summary = "导入单位")
@Parameters({
@Parameter(name = "file", description = "Excel 文件", required = true),
@Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
})
@PreAuthorize("@ss.hasPermission('system:user:import')")
public CommonResult<String> importExcel(@RequestParam("file") MultipartFile file,
@RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
List<ErpProductUnitImportExcelVO> list = ExcelUtils.read(file, ErpProductUnitImportExcelVO.class);
productUnitService.importUnitList(list, updateSupport);
return success("导入成功");
}
} }

@ -10,6 +10,15 @@ public class ErpProductCategoryListReqVO {
@Schema(description = "分类名称", example = "芋艿") @Schema(description = "分类名称", example = "芋艿")
private String name; private String name;
@Schema(description = "分类编码", example = "S110")
private String code;
@Schema(description = "父分类编号", example = "0")
private Long parentId;
@Schema(description = "分类类型", example = "1")
private Integer type;
@Schema(description = "开启状态", example = "1") @Schema(description = "开启状态", example = "1")
private Integer status; private Integer status;

@ -2,12 +2,14 @@ package cn.iocoder.yudao.module.erp.controller.admin.product.vo.category;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import static cn.iocoder.yudao.module.erp.enums.DictTypeConstants.PRODUCT_CATEGORY_TYPE;
import static cn.iocoder.yudao.module.system.enums.DictTypeConstants.COMMON_STATUS;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@Schema(description = "管理后台 - ERP 产品分类 Response VO") @Schema(description = "管理后台 - ERP 产品分类 Response VO")
@ -35,9 +37,14 @@ public class ErpProductCategoryRespVO {
@ExcelProperty("分类排序") @ExcelProperty("分类排序")
private Integer sort; private Integer sort;
@Schema(description = "分类类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty(value = "分类类型", converter = DictConvert.class)
@DictFormat(PRODUCT_CATEGORY_TYPE)
private Integer type;
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty(value = "开启状态", converter = DictConvert.class) @ExcelProperty(value = "开启状态", converter = DictConvert.class)
@DictFormat(DictTypeConstants.COMMON_STATUS) @DictFormat(COMMON_STATUS)
private Integer status; private Integer status;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)

@ -29,6 +29,10 @@ public class ErpProductCategorySaveReqVO {
@NotNull(message = "分类排序不能为空") @NotNull(message = "分类排序不能为空")
private Integer sort; private Integer sort;
@Schema(description = "分类类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
// @NotNull(message = "分类类型不能为空")
private Integer type;
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "开启状态不能为空") @NotNull(message = "开启状态不能为空")
private Integer status; private Integer status;

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.category;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@Schema(description = "管理后台 - ERP 产品分类树状 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
public class ErpProductCategoryTreeRespVO extends ErpProductCategoryRespVO {
@Schema(description = "子分类列表")
private List<ErpProductCategoryTreeRespVO> children;
@Schema(description = "是否叶子节点", example = "true")
private Boolean leaf = true;
}

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.category;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - ERP 产品分类按类型分组 Response VO")
@Data
public class ErpProductCategoryTypeGroupRespVO {
@Schema(description = "分类类型", example = "1")
private Integer type;
@Schema(description = "该类型下的树状分类列表")
private List<ErpProductCategoryTreeRespVO> children;
}

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.packagingscheme;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.List;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - ERP 包装方案分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ErpPackagingSchemePageReqVO extends PageParam {
@Schema(description = "方案编码", example = "BZFA202501010001")
private String code;
@Schema(description = "方案名称", example = "标准包装方案")
private String name;
@Schema(description = "状态", example = "0")
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,56 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.packagingscheme;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - ERP 包装方案 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ErpPackagingSchemeRespVO {
@Schema(description = "包装方案编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("编号")
private Long id;
@Schema(description = "方案编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "BZFA202501010001")
@ExcelProperty("方案编码")
private String code;
@Schema(description = "方案名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "标准包装方案")
@ExcelProperty("方案名称")
private String name;
@Schema(description = "每包数量(件)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
@ExcelProperty("每包数量(件)")
private BigDecimal packageQuantity;
@Schema(description = "每托包数(包)", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
@ExcelProperty("每托包数(包)")
private BigDecimal palletPackageQuantity;
@Schema(description = "每托总数量(件)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000")
@ExcelProperty("每托总数量(件)")
private BigDecimal palletTotalQuantity;
@Schema(description = "备注", example = "默认包装")
@ExcelProperty("备注")
private String remark;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
@ExcelProperty(value = "状态", converter = DictConvert.class)
@DictFormat(DictTypeConstants.COMMON_STATUS)
private Integer status;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -0,0 +1,48 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.packagingscheme;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@Schema(description = "管理后台 - ERP 包装方案新增/修改 Request VO")
@Data
public class ErpPackagingSchemeSaveReqVO {
@Schema(description = "包装方案编号", example = "1")
private Long id;
@Schema(description = "方案编码", example = "BZFA202501010001")
private String code;
@Schema(description = "方案名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "标准包装方案")
@NotBlank(message = "方案名称不能为空")
private String name;
@Schema(description = "每包数量(件)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
@NotNull(message = "每包数量不能为空")
@DecimalMin(value = "0", inclusive = false, message = "每包数量必须大于 0")
private BigDecimal packageQuantity;
@Schema(description = "每托包数(包)", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
@NotNull(message = "每托包数不能为空")
@DecimalMin(value = "0", inclusive = false, message = "每托包数必须大于 0")
private BigDecimal palletPackageQuantity;
@Schema(description = "每托总数量(件)", example = "2000")
private BigDecimal palletTotalQuantity;
@Schema(description = "备注", example = "默认包装")
private String remark;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
@NotNull(message = "状态不能为空")
@InEnum(CommonStatusEnum.class)
private Integer status;
}

@ -62,6 +62,15 @@ public class ErpProductImportExcelVO {
@ExcelIgnore @ExcelIgnore
private Long unitId; // 单位ID private Long unitId; // 单位ID
@ExcelIgnore
private Long purchaseUnitId; // 采购单位ID
@ExcelIgnore
private String purchaseUnitName; // 采购单位名称
@ExcelIgnore
private BigDecimal purchaseUnitConvertQuantity; // 采购单位换算数量
@ExcelIgnore @ExcelIgnore
private LocalDateTime createTime; private LocalDateTime createTime;

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.product;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - ERP 产品列表 Request VO")
@Data
public class ErpProductListReqVO {
@Schema(description = "产品名称", example = "零件A")
private String name;
@Schema(description = "产品分类编号", example = "11161")
private Long categoryId;
@Schema(description = "产品分类类型", example = "1")
private Integer categoryType;
@Schema(description = "产品编号", example = "11161")
private String code;
@Schema(description = "产品规格", example = "红色")
private String standard;
@Schema(description = "产品 id 集合")
private List<Long> ids;
}

@ -20,6 +20,9 @@ public class ErpProductPageReqVO extends PageParam {
@Schema(description = "产品分类编号", example = "11161") @Schema(description = "产品分类编号", example = "11161")
private Long categoryId; private Long categoryId;
@Schema(description = "产品分类类型", example = "1")
private Integer categoryType;
@Schema(description = "创建时间") @Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime; private LocalDateTime[] createTime;
@ -27,6 +30,9 @@ public class ErpProductPageReqVO extends PageParam {
@Schema(description = "产品编号", example = "11161") @Schema(description = "产品编号", example = "11161")
private String code; private String code;
@Schema(description = "产品编码", example = "P-001")
private String barCode;
@Schema(description = "产品规格", example = "红色") @Schema(description = "产品规格", example = "红色")
private String standard; private String standard;

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.product; package cn.iocoder.yudao.module.erp.controller.admin.product.vo.product;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
@ -7,11 +8,12 @@ import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - ERP 产品 Response VO") @Schema(description = "管理后台 - ERP 产品 Response VO")
@Data @Data
@ExcelIgnoreUnannotated @ExcelIgnoreUnannotated
public class ErpProductRespVO { public class ErpProductRespVO extends ErpProductDO {
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15672") @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15672")
@ExcelProperty("产品编号") @ExcelProperty("产品编号")
@ -21,12 +23,19 @@ public class ErpProductRespVO {
@ExcelProperty("产品名称") @ExcelProperty("产品名称")
private String name; private String name;
@Schema(description = "规格型号", example = "")
@ExcelProperty("规格型号")
private String deviceSpec;
@Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "X110") @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "X110")
@ExcelProperty("产品条码") @ExcelProperty("产品条码")
private String barCode; private String barCode;
@Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11161") @Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11161")
private Long categoryId; private Long categoryId;
@Schema(description = "产品分类类型")
private Integer categoryType;
@Schema(description = "产品分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "水果") @Schema(description = "产品分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "水果")
@ExcelProperty("产品分类") @ExcelProperty("产品分类")
private String categoryName; private String categoryName;
@ -44,6 +53,18 @@ public class ErpProductRespVO {
@ExcelProperty("单位") @ExcelProperty("单位")
private String unitName; private String unitName;
@Schema(description = "采购单位编号", example = "8890")
@ExcelProperty("采购单位编号")
private Long purchaseUnitId;
@Schema(description = "采购单位", example = "包")
@ExcelProperty("采购单位")
private String purchaseUnitName;
@Schema(description = "采购单位换算数量", example = "100")
@ExcelProperty("采购单位换算数量")
private BigDecimal purchaseUnitConvertQuantity;
@Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("产品状态") @ExcelProperty("产品状态")
private Integer status; private Integer status;
@ -83,4 +104,59 @@ public class ErpProductRespVO {
@Schema(description = "预警库存", example = "161.87") @Schema(description = "预警库存", example = "161.87")
@ExcelProperty("预警库存") @ExcelProperty("预警库存")
private BigDecimal safetyNumber; private BigDecimal safetyNumber;
@Schema(description = "默认仓库 ID", example = "1")
private Long defaultWarehouseId;
@Schema(description = "默认仓库名称", example = "成品仓")
private String defaultWarehouseName;
@Schema(description = "是否易损件", example = "1")
private Integer fragileFlag;
@Schema(description = "采购周期(天)", example = "30")
private Integer purchaseCycle;
@Schema(description = "备件等级", example = "A")
private String sparePartLevel;
@Schema(description = "品牌", example = "SKF")
private String brand;
@Schema(description = "型号", example = "6205-2RS")
private String model;
@Schema(description = "图片", example = "https://xxx.com/a.png")
@ExcelProperty("图片")
private String images;
@Schema(description = "二维码地址", example = "")
private String qrcodeUrl;
//
// @Schema(description = "关联设备ID列表", example = "[11,15,23]")
// private List<Long> deviceIds;
//
// @Schema(description = "关联模具D列表", example = "[11,15,23]")
// private List<Long> moldIds;
@Schema(description = "打印模板Json", example = "")
private String templateJson;
@Schema(description = "关联设备列表")
private List<ProductRelationRespVO> devices;
@Schema(description = "关联模具列表")
private List<ProductRelationRespVO> molds;
@Schema(description = "可用包装方案列表")
private List<ProductPackagingSchemeRespVO> packagingSchemes;
@Schema(description = "默认包装方案 ID", example = "1")
private Long defaultPackagingSchemeId;
@Schema(description = "供应商列表")
private List<ProductSupplierRespVO> suppliers;
@Schema(description = "默认供应商 ID", example = "1")
private Long defaultSupplierId;
} }

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.product;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 产品关联包装方案 Response VO")
@Data
public class ProductPackagingSchemeRespVO {
@Schema(description = "关联记录 ID", example = "1")
private Long id;
@Schema(description = "包装方案 ID", example = "1")
private Long packagingSchemeId;
@Schema(description = "包装方案名称", example = "标准包装方案")
private String packagingSchemeName;
@Schema(description = "每包数量(件)", example = "100")
private BigDecimal packageQuantity;
@Schema(description = "每托包数(包)", example = "20")
private BigDecimal palletPackageQuantity;
@Schema(description = "每托总数量(件)", example = "2000")
private BigDecimal palletTotalQuantity;
@Schema(description = "是否默认方案", example = "1")
private Integer defaultStatus;
}

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.product;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 产品关联包装方案 Request VO")
@Data
public class ProductPackagingSchemeSaveReqVO {
@Schema(description = "包装方案 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "包装方案 ID 不能为空")
private Long packagingSchemeId;
@Schema(description = "是否默认方案", example = "1")
private Integer defaultStatus;
}

@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.product;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class ProductRelationRespVO {
@Schema(description = "ID", example = "1")
private Long id;
@Schema(description = "名称", example = "设备A")
private String name;
}

@ -1,11 +1,14 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.product; package cn.iocoder.yudao.module.erp.controller.admin.product.vo.product;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List;
@Schema(description = "管理后台 - ERP 产品新增/修改 Request VO") @Schema(description = "管理后台 - ERP 产品新增/修改 Request VO")
@Data @Data
@ -18,8 +21,11 @@ public class ProductSaveReqVO {
@NotEmpty(message = "产品名称不能为空") @NotEmpty(message = "产品名称不能为空")
private String name; private String name;
@Schema(description = "规格型号", example = "")
private String deviceSpec;
@Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "X110") @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "X110")
@NotEmpty(message = "产品条码不能为空") // @NotEmpty(message = "产品条码不能为空")
private String barCode; private String barCode;
@Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11161") @Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11161")
@ -30,6 +36,15 @@ public class ProductSaveReqVO {
@NotNull(message = "单位编号不能为空") @NotNull(message = "单位编号不能为空")
private Long unitId; private Long unitId;
@Schema(description = "采购单位编号", example = "8890")
private Long purchaseUnitId;
@Schema(description = "采购单位名称", example = "包")
private String purchaseUnitName;
@Schema(description = "采购单位换算数量", example = "100")
private BigDecimal purchaseUnitConvertQuantity;
@Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "产品状态不能为空") @NotNull(message = "产品状态不能为空")
private Integer status; private Integer status;
@ -57,4 +72,45 @@ public class ProductSaveReqVO {
@Schema(description = "预警库存", example = "161.87") @Schema(description = "预警库存", example = "161.87")
private BigDecimal safetyNumber; private BigDecimal safetyNumber;
@Schema(description = "默认仓库 ID", example = "1")
private Long defaultWarehouseId;
@Schema(description = "是否易损件", example = "1")
private Integer fragileFlag;
@Schema(description = "采购周期(天)", example = "30")
private Integer purchaseCycle;
@Schema(description = "备件等级", example = "A")
private String sparePartLevel;
@Schema(description = "品牌", example = "SKF")
private String brand;
@Schema(description = "型号", example = "6205-2RS")
private String model;
@Schema(description = "图片", example = "https://xxx.com/a.png")
private String images;
@Schema(description = "关联设备ID列表", example = "[11,15,23]")
private List<Long> deviceIds;
@Schema(description = "关联模具D列表", example = "[11,15,23]")
private List<Long> moldIds;
@Schema(description = "可用包装方案列表")
@Valid
private List<ProductPackagingSchemeSaveReqVO> packagingSchemes;
@Schema(description = "默认包装方案 ID", example = "1")
private Long defaultPackagingSchemeId;
@Schema(description = "供应商列表")
@Valid
private List<ProductSupplierSaveReqVO> suppliers;
@Schema(description = "默认供应商 ID", example = "1")
private Long defaultSupplierId;
} }

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.product;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 产品关联供应商 Response VO")
@Data
public class ProductSupplierRespVO {
@Schema(description = "关联记录 ID", example = "1")
private Long id;
@Schema(description = "供应商 ID", example = "1")
private Long supplierId;
@Schema(description = "供应商名称", example = "默认供应商")
private String supplierName;
@Schema(description = "是否默认供应商", example = "1")
private Integer defaultStatus;
}

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.product;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 产品关联供应商 Request VO")
@Data
public class ProductSupplierSaveReqVO {
@Schema(description = "供应商 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "供应商 ID 不能为空")
private Long supplierId;
@Schema(description = "是否默认供应商", example = "1")
private Integer defaultStatus;
}

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* Excel VO
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = false) // 设置 chain = false避免用户导入有问题
public class ErpProductUnitImportExcelVO {
@ExcelProperty("单位名称")
private String name;
@ExcelProperty(value = "是否主单位", converter = DictConvert.class)
@DictFormat("primary_flag")
private String primaryFlag;
private Long primaryId;
@ExcelProperty("关联主单位")
private String primaryName;
@ExcelProperty("换算比例")
private Double changeRate;
@ExcelProperty(value ="单位状态", converter = DictConvert.class)
@DictFormat("common_status")
private Integer status;
}

@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants; import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
@ -43,4 +44,7 @@ public class ErpProductUnitRespVO {
@ExcelProperty("创建时间") @ExcelProperty("创建时间")
private LocalDateTime createTime; private LocalDateTime createTime;
private String value;
private String label;
} }

@ -0,0 +1,96 @@
package cn.iocoder.yudao.module.erp.controller.admin.productdevicerel;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.erp.controller.admin.productdevicerel.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.productdevicerel.ProductDeviceRelDO;
import cn.iocoder.yudao.module.erp.service.productdevicerel.ProductDeviceRelService;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
@Tag(name = "管理后台 - 产品-设备关联")
@RestController
@RequestMapping("/erp/product-device-rel")
@Validated
public class ProductDeviceRelController {
@Resource
private ProductDeviceRelService productDeviceRelService;
@PostMapping("/create")
@Operation(summary = "创建产品-设备关联")
@PreAuthorize("@ss.hasPermission('erp:product-device-rel:create')")
public CommonResult<Long> createProductDeviceRel(@Valid @RequestBody ProductDeviceRelSaveReqVO createReqVO) {
return success(productDeviceRelService.createProductDeviceRel(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新产品-设备关联")
@PreAuthorize("@ss.hasPermission('erp:product-device-rel:update')")
public CommonResult<Boolean> updateProductDeviceRel(@Valid @RequestBody ProductDeviceRelSaveReqVO updateReqVO) {
productDeviceRelService.updateProductDeviceRel(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除产品-设备关联")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('erp:product-device-rel:delete')")
public CommonResult<Boolean> deleteProductDeviceRel(@RequestParam("id") Long id) {
productDeviceRelService.deleteProductDeviceRel(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得产品-设备关联")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:product-device-rel:query')")
public CommonResult<ProductDeviceRelRespVO> getProductDeviceRel(@RequestParam("id") Long id) {
ProductDeviceRelDO productDeviceRel = productDeviceRelService.getProductDeviceRel(id);
return success(BeanUtils.toBean(productDeviceRel, ProductDeviceRelRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得产品-设备关联分页")
@PreAuthorize("@ss.hasPermission('erp:product-device-rel:query')")
public CommonResult<PageResult<ProductDeviceRelRespVO>> getProductDeviceRelPage(@Valid ProductDeviceRelPageReqVO pageReqVO) {
PageResult<ProductDeviceRelDO> pageResult = productDeviceRelService.getProductDeviceRelPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ProductDeviceRelRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出产品-设备关联 Excel")
@PreAuthorize("@ss.hasPermission('erp:product-device-rel:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportProductDeviceRelExcel(@Valid ProductDeviceRelPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ProductDeviceRelDO> list = productDeviceRelService.getProductDeviceRelPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "产品-设备关联.xls", "数据", ProductDeviceRelRespVO.class,
BeanUtils.toBean(list, ProductDeviceRelRespVO.class));
}
}

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.erp.controller.admin.productdevicerel.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 产品-设备关联分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductDeviceRelPageReqVO extends PageParam {
@Schema(description = "产品ID", example = "18574")
private Long productId;
@Schema(description = "设备ID", example = "21075")
private Long deviceId;
@Schema(description = "排序")
private Integer sort;
@Schema(description = "备注", example = "随便")
private String remark;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.erp.controller.admin.productdevicerel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 产品-设备关联 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ProductDeviceRelRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "28748")
@ExcelProperty("主键")
private Long id;
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "18574")
@ExcelProperty("产品ID")
private Long productId;
@Schema(description = "设备ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "21075")
@ExcelProperty("设备ID")
private Long deviceId;
@Schema(description = "排序")
@ExcelProperty("排序")
private Integer sort;
@Schema(description = "备注", example = "随便")
@ExcelProperty("备注")
private String remark;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.erp.controller.admin.productdevicerel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import javax.validation.constraints.NotNull;
import java.util.*;
@Schema(description = "管理后台 - 产品-设备关联新增/修改 Request VO")
@Data
public class ProductDeviceRelSaveReqVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "28748")
private Long id;
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "18574")
@NotNull(message = "产品ID不能为空")
private Long productId;
@Schema(description = "设备ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "21075")
@NotNull(message = "设备ID不能为空")
private Long deviceId;
@Schema(description = "排序")
private Integer sort;
@Schema(description = "备注", example = "随便")
private String remark;
}

@ -0,0 +1,95 @@
package cn.iocoder.yudao.module.erp.controller.admin.productmoldrel;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.erp.controller.admin.productmoldrel.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.productmoldrel.ProductMoldRelDO;
import cn.iocoder.yudao.module.erp.service.productmoldrel.ProductMoldRelService;
@Tag(name = "管理后台 - 产品-模具关联")
@RestController
@RequestMapping("/erp/product-mold-rel")
@Validated
public class ProductMoldRelController {
@Resource
private ProductMoldRelService productMoldRelService;
@PostMapping("/create")
@Operation(summary = "创建产品-模具关联")
@PreAuthorize("@ss.hasPermission('erp:product-mold-rel:create')")
public CommonResult<Long> createProductMoldRel(@Valid @RequestBody ProductMoldRelSaveReqVO createReqVO) {
return success(productMoldRelService.createProductMoldRel(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新产品-模具关联")
@PreAuthorize("@ss.hasPermission('erp:product-mold-rel:update')")
public CommonResult<Boolean> updateProductMoldRel(@Valid @RequestBody ProductMoldRelSaveReqVO updateReqVO) {
productMoldRelService.updateProductMoldRel(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除产品-模具关联")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('erp:product-mold-rel:delete')")
public CommonResult<Boolean> deleteProductMoldRel(@RequestParam("id") Long id) {
productMoldRelService.deleteProductMoldRel(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得产品-模具关联")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:product-mold-rel:query')")
public CommonResult<ProductMoldRelRespVO> getProductMoldRel(@RequestParam("id") Long id) {
ProductMoldRelDO productMoldRel = productMoldRelService.getProductMoldRel(id);
return success(BeanUtils.toBean(productMoldRel, ProductMoldRelRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得产品-模具关联分页")
@PreAuthorize("@ss.hasPermission('erp:product-mold-rel:query')")
public CommonResult<PageResult<ProductMoldRelRespVO>> getProductMoldRelPage(@Valid ProductMoldRelPageReqVO pageReqVO) {
PageResult<ProductMoldRelDO> pageResult = productMoldRelService.getProductMoldRelPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ProductMoldRelRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出产品-模具关联 Excel")
@PreAuthorize("@ss.hasPermission('erp:product-mold-rel:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportProductMoldRelExcel(@Valid ProductMoldRelPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ProductMoldRelDO> list = productMoldRelService.getProductMoldRelPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "产品-模具关联.xls", "数据", ProductMoldRelRespVO.class,
BeanUtils.toBean(list, ProductMoldRelRespVO.class));
}
}

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.erp.controller.admin.productmoldrel.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 产品-模具关联分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductMoldRelPageReqVO extends PageParam {
@Schema(description = "产品ID", example = "30420")
private Long productId;
@Schema(description = "模具ID", example = "243")
private Long moldId;
@Schema(description = "排序")
private Integer sort;
@Schema(description = "备注", example = "随便")
private String remark;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.erp.controller.admin.productmoldrel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 产品-模具关联 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ProductMoldRelRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "11772")
@ExcelProperty("主键")
private Long id;
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30420")
@ExcelProperty("产品ID")
private Long productId;
@Schema(description = "模具ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "243")
@ExcelProperty("模具ID")
private Long moldId;
@Schema(description = "排序")
@ExcelProperty("排序")
private Integer sort;
@Schema(description = "备注", example = "随便")
@ExcelProperty("备注")
private String remark;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.erp.controller.admin.productmoldrel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 产品-模具关联新增/修改 Request VO")
@Data
public class ProductMoldRelSaveReqVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "11772")
private Long id;
@Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30420")
@NotNull(message = "产品ID不能为空")
private Long productId;
@Schema(description = "模具ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "243")
@NotNull(message = "模具ID不能为空")
private Long moldId;
@Schema(description = "排序")
private Integer sort;
@Schema(description = "备注", example = "随便")
private String remark;
}

@ -6,16 +6,28 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckApproveRecordRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckAuditReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByLocationReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByProductReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSubmitReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckApproveRecordDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockCheckService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockCheckService;
import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -23,21 +35,32 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - ERP 库存调拨单") @Tag(name = "管理后台 - ERP 库存盘点单")
@RestController @RestController
@RequestMapping("/erp/stock-check") @RequestMapping("/erp/stock-check")
@Validated @Validated
@ -47,19 +70,22 @@ public class ErpStockCheckController {
private ErpStockCheckService stockCheckService; private ErpStockCheckService stockCheckService;
@Resource @Resource
private ErpProductService productService; private ErpProductService productService;
@Resource
private ErpWarehouseService warehouseService;
@Resource
private WarehouseAreaService warehouseAreaService;
@Resource @Resource
private AdminUserApi adminUserApi; private AdminUserApi adminUserApi;
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建库存调拨单") @Operation(summary = "创建库存盘点单")
@PreAuthorize("@ss.hasPermission('erp:stock-check:create')") @PreAuthorize("@ss.hasPermission('erp:stock-check:create')")
public CommonResult<Long> createStockCheck(@Valid @RequestBody ErpStockCheckSaveReqVO createReqVO) { public CommonResult<Long> createStockCheck(@Valid @RequestBody ErpStockCheckSaveReqVO createReqVO) {
return success(stockCheckService.createStockCheck(createReqVO)); return success(stockCheckService.createStockCheck(createReqVO));
} }
@PutMapping("/update") @PutMapping("/update")
@Operation(summary = "更新库存调拨单") @Operation(summary = "更新库存盘点单")
@PreAuthorize("@ss.hasPermission('erp:stock-check:update')") @PreAuthorize("@ss.hasPermission('erp:stock-check:update')")
public CommonResult<Boolean> updateStockCheck(@Valid @RequestBody ErpStockCheckSaveReqVO updateReqVO) { public CommonResult<Boolean> updateStockCheck(@Valid @RequestBody ErpStockCheckSaveReqVO updateReqVO) {
stockCheckService.updateStockCheck(updateReqVO); stockCheckService.updateStockCheck(updateReqVO);
@ -67,16 +93,56 @@ public class ErpStockCheckController {
} }
@PutMapping("/update-status") @PutMapping("/update-status")
@Operation(summary = "更新库存调拨单的状态") @Operation(summary = "更新库存盘点单状态")
@PreAuthorize("@ss.hasPermission('erp:stock-check:update-status')") @PreAuthorize("@ss.hasPermission('erp:stock-check:update-status')")
@RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS)
public CommonResult<Boolean> updateStockCheckStatus(@RequestParam("id") Long id, public CommonResult<Boolean> updateStockCheckStatus(@RequestParam("id") Long id,
@RequestParam("status") Integer status) { @RequestParam("status") Integer status) {
stockCheckService.updateStockCheckStatus(id, status); stockCheckService.updateStockCheckStatus(id, status);
return success(true); return success(true);
} }
@PutMapping("/submit")
@Operation(summary = "提交库存盘点单审核")
@PreAuthorize("@ss.hasPermission('erp:stock-check:update')")
@RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS)
public CommonResult<Boolean> submitStockCheckAudit(@Valid @RequestBody ErpStockCheckSubmitReqVO submitReqVO) {
stockCheckService.submitStockCheckAudit(submitReqVO);
return success(true);
}
@PutMapping("/audit")
@Operation(summary = "审核库存盘点单")
@PreAuthorize("@ss.hasPermission('erp:stock-check:update-status')")
@RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS)
public CommonResult<Boolean> auditStockCheck(@Valid @RequestBody ErpStockCheckAuditReqVO auditReqVO) {
stockCheckService.auditStockCheck(auditReqVO);
return success(true);
}
@GetMapping("/approve-record-list")
@Operation(summary = "获得库存盘点单审核记录")
@PreAuthorize("@ss.hasPermission('erp:stock-check:query')")
public CommonResult<List<ErpStockCheckApproveRecordRespVO>> getApproveRecordList(@RequestParam("id") Long id) {
return success(buildApproveRecordRespList(stockCheckService.getStockCheckApproveRecordList(id)));
}
@PostMapping("/generate-items/by-location")
@Operation(summary = "按仓库/库区生成盘点项")
@PreAuthorize("@ss.hasPermission('erp:stock-check:query')")
public CommonResult<List<ErpStockCheckRespVO.Item>> generateItemsByLocation(@Valid @RequestBody ErpStockCheckGenerateByLocationReqVO reqVO) {
return success(stockCheckService.generateStockCheckItemsByLocation(reqVO));
}
@PostMapping("/generate-items/by-product")
@Operation(summary = "按产品生成盘点项")
@PreAuthorize("@ss.hasPermission('erp:stock-check:query')")
public CommonResult<List<ErpStockCheckRespVO.Item>> generateItemsByProduct(@Valid @RequestBody ErpStockCheckGenerateByProductReqVO reqVO) {
return success(stockCheckService.generateStockCheckItemsByProduct(reqVO));
}
@DeleteMapping("/delete") @DeleteMapping("/delete")
@Operation(summary = "删除库存调拨单") @Operation(summary = "删除库存盘点单")
@Parameter(name = "ids", description = "编号数组", required = true) @Parameter(name = "ids", description = "编号数组", required = true)
@PreAuthorize("@ss.hasPermission('erp:stock-check:delete')") @PreAuthorize("@ss.hasPermission('erp:stock-check:delete')")
public CommonResult<Boolean> deleteStockCheck(@RequestParam("ids") List<Long> ids) { public CommonResult<Boolean> deleteStockCheck(@RequestParam("ids") List<Long> ids) {
@ -85,7 +151,7 @@ public class ErpStockCheckController {
} }
@GetMapping("/get") @GetMapping("/get")
@Operation(summary = "获得库存调拨单") @Operation(summary = "获得库存盘点单")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('erp:stock-check:query')") @PreAuthorize("@ss.hasPermission('erp:stock-check:query')")
public CommonResult<ErpStockCheckRespVO> getStockCheck(@RequestParam("id") Long id) { public CommonResult<ErpStockCheckRespVO> getStockCheck(@RequestParam("id") Long id) {
@ -93,56 +159,88 @@ public class ErpStockCheckController {
if (stockCheck == null) { if (stockCheck == null) {
return success(null); return success(null);
} }
List<ErpStockCheckItemDO> stockCheckItemList = stockCheckService.getStockCheckItemListByCheckId(id); return success(buildStockCheckRespVO(stockCheck,
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( stockCheckService.getStockCheckItemListByCheckId(id),
convertSet(stockCheckItemList, ErpStockCheckItemDO::getProductId)); stockCheckService.getStockCheckApproveRecordList(id)));
return success(BeanUtils.toBean(stockCheck, ErpStockCheckRespVO.class, stockCheckVO ->
stockCheckVO.setItems(BeanUtils.toBean(stockCheckItemList, ErpStockCheckRespVO.Item.class, item ->
MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()))))));
} }
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得库存调拨单分页") @Operation(summary = "获得库存盘点单分页")
@PreAuthorize("@ss.hasPermission('erp:stock-check:query')") @PreAuthorize("@ss.hasPermission('erp:stock-check:query')")
public CommonResult<PageResult<ErpStockCheckRespVO>> getStockCheckPage(@Valid ErpStockCheckPageReqVO pageReqVO) { public CommonResult<PageResult<ErpStockCheckRespVO>> getStockCheckPage(@Valid ErpStockCheckPageReqVO pageReqVO) {
PageResult<ErpStockCheckDO> pageResult = stockCheckService.getStockCheckPage(pageReqVO); return success(buildStockCheckVOPageResult(stockCheckService.getStockCheckPage(pageReqVO)));
return success(buildStockCheckVOPageResult(pageResult));
} }
@GetMapping("/export-excel") @GetMapping("/export-excel")
@Operation(summary = "导出库存调拨单 Excel") @Operation(summary = "导出库存盘点单 Excel")
@PreAuthorize("@ss.hasPermission('erp:stock-check:export')") @PreAuthorize("@ss.hasPermission('erp:stock-check:export')")
@ApiAccessLog(operateType = EXPORT) @ApiAccessLog(operateType = EXPORT)
public void exportStockCheckExcel(@Valid ErpStockCheckPageReqVO pageReqVO, public void exportStockCheckExcel(@Valid ErpStockCheckPageReqVO pageReqVO,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ErpStockCheckRespVO> list = buildStockCheckVOPageResult(stockCheckService.getStockCheckPage(pageReqVO)).getList(); List<ErpStockCheckRespVO> list = buildStockCheckVOPageResult(stockCheckService.getStockCheckPage(pageReqVO)).getList();
// 导出 Excel ExcelUtils.write(response, "库存盘点单.xls", "数据", ErpStockCheckRespVO.class, list);
ExcelUtils.write(response, "库存调拨单.xls", "数据", ErpStockCheckRespVO.class, list);
} }
private PageResult<ErpStockCheckRespVO> buildStockCheckVOPageResult(PageResult<ErpStockCheckDO> pageResult) { private PageResult<ErpStockCheckRespVO> buildStockCheckVOPageResult(PageResult<ErpStockCheckDO> pageResult) {
if (CollUtil.isEmpty(pageResult.getList())) { if (CollUtil.isEmpty(pageResult.getList())) {
return PageResult.empty(pageResult.getTotal()); return PageResult.empty(pageResult.getTotal());
} }
// 1.1 盘点项
List<ErpStockCheckItemDO> stockCheckItemList = stockCheckService.getStockCheckItemListByCheckIds( List<ErpStockCheckItemDO> stockCheckItemList = stockCheckService.getStockCheckItemListByCheckIds(
convertSet(pageResult.getList(), ErpStockCheckDO::getId)); convertSet(pageResult.getList(), ErpStockCheckDO::getId));
Map<Long, List<ErpStockCheckItemDO>> stockCheckItemMap = convertMultiMap(stockCheckItemList, ErpStockCheckItemDO::getCheckId); Map<Long, List<ErpStockCheckItemDO>> stockCheckItemMap = convertMultiMap(stockCheckItemList, ErpStockCheckItemDO::getCheckId);
// 1.2 产品信息
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(stockCheckItemList, ErpStockCheckItemDO::getProductId));
// 1.3 管理员信息
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
convertSet(pageResult.getList(), stockCheck -> Long.parseLong(stockCheck.getCreator())));
// 2. 开始拼接
return BeanUtils.toBean(pageResult, ErpStockCheckRespVO.class, stockCheck -> { return BeanUtils.toBean(pageResult, ErpStockCheckRespVO.class, stockCheck -> {
stockCheck.setItems(BeanUtils.toBean(stockCheckItemMap.get(stockCheck.getId()), ErpStockCheckRespVO.Item.class, stockCheck.setItems(buildItemRespList(stockCheckItemMap.get(stockCheck.getId())));
item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) stockCheck.setProductNames(CollUtil.join(stockCheck.getItems(), ",", ErpStockCheckRespVO.Item::getProductName));
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); fillUserInfo(stockCheck);
stockCheck.setProductNames(CollUtil.join(stockCheck.getItems(), "", ErpStockCheckRespVO.Item::getProductName)); });
MapUtils.findAndThen(userMap, Long.parseLong(stockCheck.getCreator()), user -> stockCheck.setCreatorName(user.getNickname())); }
private ErpStockCheckRespVO buildStockCheckRespVO(ErpStockCheckDO stockCheck, List<ErpStockCheckItemDO> stockCheckItemList,
List<ErpStockCheckApproveRecordDO> approveRecords) {
ErpStockCheckRespVO stockCheckVO = BeanUtils.toBean(stockCheck, ErpStockCheckRespVO.class);
stockCheckVO.setItems(buildItemRespList(stockCheckItemList));
stockCheckVO.setProductNames(CollUtil.join(stockCheckVO.getItems(), ",", ErpStockCheckRespVO.Item::getProductName));
stockCheckVO.setApproveRecords(buildApproveRecordRespList(approveRecords));
fillUserInfo(stockCheckVO);
return stockCheckVO;
}
private List<ErpStockCheckRespVO.Item> buildItemRespList(List<ErpStockCheckItemDO> itemList) {
if (CollUtil.isEmpty(itemList)) {
return new ArrayList<>();
}
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(convertSet(itemList, ErpStockCheckItemDO::getProductId));
Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(convertSet(itemList, ErpStockCheckItemDO::getWarehouseId));
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(convertSet(itemList, ErpStockCheckItemDO::getAreaId));
return BeanUtils.toBean(itemList, ErpStockCheckRespVO.Item.class, item -> {
MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()));
MapUtils.findAndThen(warehouseMap, item.getWarehouseId(), warehouse -> item.setWarehouseName(warehouse.getName()));
if (item.getAreaName() == null) {
MapUtils.findAndThen(areaMap, item.getAreaId(), area -> item.setAreaName(area.getAreaName()));
}
});
}
private void fillUserInfo(ErpStockCheckRespVO stockCheck) {
List<Long> userIds = new ArrayList<>();
userIds.add(NumberUtils.parseLong(stockCheck.getCreator()));
userIds.add(stockCheck.getAuditUserId());
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
MapUtils.findAndThen(userMap, NumberUtils.parseLong(stockCheck.getCreator()), user -> stockCheck.setCreatorName(user.getNickname()));
MapUtils.findAndThen(userMap, stockCheck.getAuditUserId(), user -> stockCheck.setAuditUserName(user.getNickname()));
}
private List<ErpStockCheckApproveRecordRespVO> buildApproveRecordRespList(List<ErpStockCheckApproveRecordDO> records) {
if (CollUtil.isEmpty(records)) {
return new ArrayList<>();
}
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(records,
record -> Stream.of(NumberUtils.parseLong(record.getCreator()), record.getTargetUserId())));
return BeanUtils.toBean(records, ErpStockCheckApproveRecordRespVO.class, record -> {
MapUtils.findAndThen(userMap, NumberUtils.parseLong(record.getCreator()), user -> record.setCreatorName(user.getNickname()));
MapUtils.findAndThen(userMap, record.getTargetUserId(), user -> record.setTargetUserName(user.getNickname()));
}); });
} }

@ -9,13 +9,17 @@ import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPackagingSchemeRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockRecordService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService; import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.Parameters;
@ -51,6 +55,10 @@ public class ErpStockController {
private ErpProductService productService; private ErpProductService productService;
@Resource @Resource
private ErpWarehouseService warehouseService; private ErpWarehouseService warehouseService;
@Resource
private WarehouseAreaService warehouseAreaService;
@Resource
private ErpStockRecordService stockRecordService;
@GetMapping("/get") @GetMapping("/get")
@Operation(summary = "获得产品库存") @Operation(summary = "获得产品库存")
@ -62,9 +70,10 @@ public class ErpStockController {
@PreAuthorize("@ss.hasPermission('erp:stock:query')") @PreAuthorize("@ss.hasPermission('erp:stock:query')")
public CommonResult<ErpStockRespVO> getStock(@RequestParam(value = "id", required = false) Long id, public CommonResult<ErpStockRespVO> getStock(@RequestParam(value = "id", required = false) Long id,
@RequestParam(value = "productId", required = false) Long productId, @RequestParam(value = "productId", required = false) Long productId,
@RequestParam(value = "warehouseId", required = false) Long warehouseId) { @RequestParam(value = "warehouseId", required = false) Long warehouseId,
ErpStockDO stock = id != null ? stockService.getStock(id) : stockService.getStock(productId, warehouseId); @RequestParam(value = "areaId", required = false) Long areaId) {
return success(BeanUtils.toBean(stock, ErpStockRespVO.class)); ErpStockDO stock = id != null ? stockService.getStock(id) : stockService.getStock(productId, warehouseId, areaId);
return success(buildStockRespVO(stock));
} }
@GetMapping("/get-count") @GetMapping("/get-count")
@ -102,11 +111,72 @@ public class ErpStockController {
convertSet(pageResult.getList(), ErpStockDO::getProductId)); convertSet(pageResult.getList(), ErpStockDO::getProductId));
Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap( Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
convertSet(pageResult.getList(), ErpStockDO::getWarehouseId)); convertSet(pageResult.getList(), ErpStockDO::getWarehouseId));
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
convertSet(pageResult.getList(), ErpStockDO::getAreaId));
return BeanUtils.toBean(pageResult, ErpStockRespVO.class, stock -> { return BeanUtils.toBean(pageResult, ErpStockRespVO.class, stock -> {
MapUtils.findAndThen(productMap, stock.getProductId(), product -> stock.setProductName(product.getName()).setBarCode(product.getBarCode()) MapUtils.findAndThen(productMap, stock.getProductId(), product -> {
.setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName())); stock.setProductName(product.getName()).setBarCode(product.getBarCode())
.setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName())
.setCategoryType(product.getCategoryType());
fillProductExtraInfo(stock, product);
});
MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName())); MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName()));
if (stock.getAreaName() == null) {
MapUtils.findAndThen(areaMap, stock.getAreaId(), area -> stock.setAreaName(area.getAreaName()));
}
fillRecentRecordTime(stock);
}); });
} }
private ErpStockRespVO buildStockRespVO(ErpStockDO stock) {
if (stock == null) {
return null;
}
ErpStockRespVO respVO = BeanUtils.toBean(stock, ErpStockRespVO.class);
ErpProductRespVO product = productService.getProduct(stock.getProductId());
if (product != null) {
respVO.setProductName(product.getName());
respVO.setBarCode(product.getBarCode());
respVO.setCategoryName(product.getCategoryName());
respVO.setUnitName(product.getUnitName());
respVO.setCategoryType(product.getCategoryType());
fillProductExtraInfo(respVO, product);
}
ErpWarehouseDO warehouse = warehouseService.getWarehouse(stock.getWarehouseId());
if (warehouse != null) {
respVO.setWarehouseName(warehouse.getName());
}
if (respVO.getAreaName() == null && respVO.getAreaId() != null) {
WarehouseAreaDO area = warehouseAreaService.getWarehouseArea(respVO.getAreaId());
if (area != null) {
respVO.setAreaName(area.getAreaName());
}
}
fillRecentRecordTime(respVO);
return respVO;
}
private void fillRecentRecordTime(ErpStockRespVO stock) {
stock.setRecentInTime(stockRecordService.getLatestRecordTime(
stock.getProductId(), stock.getWarehouseId(), stock.getAreaId(), true));
stock.setRecentOutTime(stockRecordService.getLatestRecordTime(
stock.getProductId(), stock.getWarehouseId(), stock.getAreaId(), false));
}
private void fillProductExtraInfo(ErpStockRespVO stock, ErpProductRespVO product) {
stock.setUnitId(product.getUnitId());
stock.setPurchaseUnitId(product.getPurchaseUnitId());
stock.setPurchaseUnitName(product.getPurchaseUnitName());
stock.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity());
stock.setDefaultPackagingSchemeId(product.getDefaultPackagingSchemeId());
stock.setDefaultPackagingScheme(findDefaultPackagingScheme(product));
}
private ProductPackagingSchemeRespVO findDefaultPackagingScheme(ErpProductRespVO product) {
if (product.getDefaultPackagingSchemeId() == null || CollUtil.isEmpty(product.getPackagingSchemes())) {
return null;
}
return product.getPackagingSchemes().stream()
.filter(item -> product.getDefaultPackagingSchemeId().equals(item.getPackagingSchemeId()))
.findFirst()
.orElse(null);
}
} }

@ -6,31 +6,40 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter; import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter;
import cn.iocoder.yudao.module.common.controller.admin.mold.vo.MoldRespVO; import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandDO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInApproveRecordRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInAuditReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSubmitReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.StockInTypeEnum; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.StockInTypeEnum;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO; import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInApproveRecordDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO;
import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService;
import cn.iocoder.yudao.module.erp.service.mold.MoldService; import cn.iocoder.yudao.module.erp.service.mold.MoldService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockInService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockInService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -42,14 +51,17 @@ import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - ERP 其它入库单") @Tag(name = "管理后台 - ERP 其它入库单")
@ -66,10 +78,14 @@ public class ErpStockInController {
private ErpProductService productService; private ErpProductService productService;
@Resource @Resource
private ErpSupplierService supplierService; private ErpSupplierService supplierService;
@Resource
private ErpWarehouseService warehouseService;
@Resource
private WarehouseAreaService warehouseAreaService;
@Resource
private MoldBrandService moldBrandService;
@Resource @Resource
private MoldService moldService; private MoldService moldService;
@Resource @Resource
private AdminUserApi adminUserApi; private AdminUserApi adminUserApi;
@ -94,11 +110,36 @@ public class ErpStockInController {
@RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS) @RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS)
public CommonResult<Boolean> updateStockInStatus(@RequestParam("id") Long id, public CommonResult<Boolean> updateStockInStatus(@RequestParam("id") Long id,
@RequestParam("status") Integer status, @RequestParam("status") Integer status,
@RequestParam(name = "status",required = false) Integer bizType) { @RequestParam(name = "bizType", required = false) Integer bizType) {
stockInService.updateStockInStatus(id, status,bizType); stockInService.updateStockInStatus(id, status, bizType);
return success(true);
}
@PutMapping("/submit")
@Operation(summary = "提交其它入库单审核")
@PreAuthorize("@ss.hasPermission('erp:stock-in:update')")
@RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS)
public CommonResult<Boolean> submitStockInAudit(@Valid @RequestBody ErpStockInSubmitReqVO submitReqVO) {
stockInService.submitStockInAudit(submitReqVO);
return success(true); return success(true);
} }
@PutMapping("/audit")
@Operation(summary = "审核其它入库单")
@PreAuthorize("@ss.hasPermission('erp:stock-in:update-status')")
@RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS)
public CommonResult<Boolean> auditStockIn(@Valid @RequestBody ErpStockInAuditReqVO auditReqVO) {
stockInService.auditStockIn(auditReqVO);
return success(true);
}
@GetMapping("/approve-record-list")
@Operation(summary = "获得其它入库单审核记录")
@PreAuthorize("@ss.hasPermission('erp:stock-in:query')")
public CommonResult<List<ErpStockInApproveRecordRespVO>> getApproveRecordList(@RequestParam("id") Long id) {
return success(buildApproveRecordRespList(stockInService.getStockInApproveRecordList(id)));
}
@DeleteMapping("/delete") @DeleteMapping("/delete")
@Operation(summary = "删除其它入库单") @Operation(summary = "删除其它入库单")
@Parameter(name = "ids", description = "编号数组", required = true) @Parameter(name = "ids", description = "编号数组", required = true)
@ -117,45 +158,17 @@ public class ErpStockInController {
if (stockIn == null) { if (stockIn == null) {
return success(null); return success(null);
} }
List<ErpStockInItemDO> stockInItemList = stockInService.getStockInItemListByInId(id); return success(buildStockInRespVO(stockIn,
if (Objects.equals(stockIn.getInType(), "模具入库")) { stockInService.getStockInItemListByInId(id),
Map<Long, MoldRespVO> moldMap = moldService.getMoldVOMap( stockInService.getStockInApproveRecordList(id)));
convertSet(stockInItemList, ErpStockInItemDO::getProductId));
return success(BeanUtils.toBean(stockIn, ErpStockInRespVO.class, stockInVO ->
stockInVO.setItems(BeanUtils.toBean(stockInItemList, ErpStockInRespVO.Item.class, item -> {
ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
MapUtils.findAndThen(moldMap, item.getProductId(), mold -> item.setProductName(mold.getName())
.setProductBarCode(mold.getCode()).setProductUnitName(mold.getUnitName()));
}))));
} else {
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(stockInItemList, ErpStockInItemDO::getProductId));
return success(BeanUtils.toBean(stockIn, ErpStockInRespVO.class, stockInVO ->
stockInVO.setItems(BeanUtils.toBean(stockInItemList, ErpStockInRespVO.Item.class, item -> {
ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()));
}))));
}
} }
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得其它入库单分页") @Operation(summary = "获得其它入库单分页")
@PreAuthorize("@ss.hasPermission('erp:stock-in:query')") @PreAuthorize("@ss.hasPermission('erp:stock-in:query')")
public CommonResult<PageResult<ErpStockInRespVO>> getStockInPage(@Valid ErpStockInPageReqVO pageReqVO) { public CommonResult<PageResult<ErpStockInRespVO>> getStockInPage(@Valid ErpStockInPageReqVO pageReqVO) {
if(StringUtils.isEmpty(pageReqVO.getInType())){ fillPageReqDefault(pageReqVO);
List<String> list = new ArrayList<>(); return success(buildStockInVOPageResult(stockInService.getStockInPage(pageReqVO)));
list.add(StockInTypeEnum..getValue());
list.add(StockInTypeEnum..getValue());
list.add(StockInTypeEnum..getValue());
list.add(StockInTypeEnum..getValue());
pageReqVO.setInTypeList(list);
}
PageResult<ErpStockInDO> pageResult = stockInService.getStockInPage(pageReqVO);
return success(buildStockInVOPageResult(pageResult));
} }
@GetMapping("/export-excel") @GetMapping("/export-excel")
@ -164,52 +177,128 @@ public class ErpStockInController {
@ApiAccessLog(operateType = EXPORT) @ApiAccessLog(operateType = EXPORT)
public void exportStockInExcel(@Valid ErpStockInPageReqVO pageReqVO, public void exportStockInExcel(@Valid ErpStockInPageReqVO pageReqVO,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
fillPageReqDefault(pageReqVO);
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ErpStockInRespVO> list = buildStockInVOPageResult(stockInService.getStockInPage(pageReqVO)).getList(); List<ErpStockInRespVO> list = buildStockInVOPageResult(stockInService.getStockInPage(pageReqVO)).getList();
// 导出 Excel
ExcelUtils.write(response, "其它入库单.xls", "数据", ErpStockInRespVO.class, list); ExcelUtils.write(response, "其它入库单.xls", "数据", ErpStockInRespVO.class, list);
} }
private void fillPageReqDefault(ErpStockInPageReqVO pageReqVO) {
if (StringUtils.isEmpty(pageReqVO.getInType())) {
List<String> list = new ArrayList<>();
list.add(StockInTypeEnum..getValue());
list.add(StockInTypeEnum..getValue());
list.add(StockInTypeEnum..getValue());
list.add(StockInTypeEnum..getValue());
pageReqVO.setInTypeList(list);
}
}
private PageResult<ErpStockInRespVO> buildStockInVOPageResult(PageResult<ErpStockInDO> pageResult) { private PageResult<ErpStockInRespVO> buildStockInVOPageResult(PageResult<ErpStockInDO> pageResult) {
if (CollUtil.isEmpty(pageResult.getList())) { if (CollUtil.isEmpty(pageResult.getList())) {
return PageResult.empty(pageResult.getTotal()); return PageResult.empty(pageResult.getTotal());
} }
// 1.1 入库项 List<ErpStockInRespVO> list = convertList(pageResult.getList(), stockIn -> buildStockInRespVO(
List<ErpStockInItemDO> stockInItemList = stockInService.getStockInItemListByInIds( stockIn, stockInService.getStockInItemListByInId(stockIn.getId()), Collections.emptyList()));
convertSet(pageResult.getList(), ErpStockInDO::getId)); return new PageResult<>(list, pageResult.getTotal());
Map<Long, List<ErpStockInItemDO>> stockInItemMap = convertMultiMap(stockInItemList, ErpStockInItemDO::getInId); }
// 1.2 产品信息
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( private ErpStockInRespVO buildStockInRespVO(ErpStockInDO stockIn, List<ErpStockInItemDO> stockInItemList,
convertSet(stockInItemList, ErpStockInItemDO::getProductId)); List<ErpStockInApproveRecordDO> approveRecords) {
// 1.3 供应商信息 ErpStockInRespVO stockInVO = BeanUtils.toBean(stockIn, ErpStockInRespVO.class);
Map<Long, ErpSupplierDO> supplierMap = supplierService.getSupplierMap( Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
convertSet(pageResult.getList(), ErpStockInDO::getSupplierId)); convertSet(stockInItemList, ErpStockInItemDO::getWarehouseId));
// 1.4 管理员信息 Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( convertSet(stockInItemList, ErpStockInItemDO::getAreaId));
convertSet(pageResult.getList(), stockIn -> Long.parseLong(stockIn.getCreator()))); Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(
// 1.7 模具信息 Collections.singletonList(stockIn), item -> Stream.of(NumberUtils.parseLong(item.getCreator()),
Map<Long, MoldRespVO> moldMap = moldService.getMoldVOMap( item.getStockUserId(), item.getAuditUserId())));
convertSet(stockInItemList, ErpStockInItemDO::getProductId)); MapUtils.findAndThen(userMap, NumberUtils.parseLong(stockIn.getCreator()), user -> stockInVO.setCreatorName(user.getNickname()));
MapUtils.findAndThen(userMap, stockIn.getStockUserId(), user -> stockInVO.setStockUserName(user.getNickname()));
MapUtils.findAndThen(userMap, stockIn.getAuditUserId(), user -> stockInVO.setAuditUserName(user.getNickname()));
// 2. 开始拼接
return BeanUtils.toBean(pageResult, ErpStockInRespVO.class, stockIn -> {
if (Objects.equals(stockIn.getInType(), "模具入库")) { if (Objects.equals(stockIn.getInType(), "模具入库")) {
stockIn.setItems(BeanUtils.toBean(stockInItemMap.get(stockIn.getId()), ErpStockInRespVO.Item.class, Map<Long, MoldBrandDO> moldMap = moldBrandService.getMoldVOMap(
item -> MapUtils.findAndThen(moldMap, item.getProductId(), mold -> item.setProductName(mold.getName()) convertSet(stockInItemList, ErpStockInItemDO::getMoldSetId));
.setProductBarCode(mold.getCode()).setProductUnitName(mold.getUnitName())))); Map<Long, List<cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO>> moldListMap = moldService.getMoldListMapByBrandIds(
stockIn.setProductNames(CollUtil.join(stockIn.getItems(), "", ErpStockInRespVO.Item::getProductName)); convertSet(stockInItemList, ErpStockInItemDO::getMoldSetId));
stockInVO.setItems(convertList(stockInItemList, source -> {
ErpStockInRespVO.Item item = BeanUtils.toBean(source, ErpStockInRespVO.Item.class);
ErpStockDO stock = stockService.getStock(source.getMoldSetId(), source.getWarehouseId(), source.getAreaId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
item.setMoldList(moldListMap.getOrDefault(source.getMoldSetId(), new ArrayList<>()));
fillWarehouseInfo(item, source, warehouseMap, areaMap);
MapUtils.findAndThen(moldMap, source.getMoldSetId(), mold -> {
item.setMoldSetName(mold.getName());
item.setProductName(mold.getName());
item.setProductBarCode(mold.getCode());
});
return item;
}));
stockInVO.setMoldSetNames(CollUtil.join(stockInVO.getItems(), ",", ErpStockInRespVO.Item::getMoldSetName));
stockInVO.setProductNames(stockInVO.getMoldSetNames());
} else { } else {
stockIn.setItems(BeanUtils.toBean(stockInItemMap.get(stockIn.getId()), ErpStockInRespVO.Item.class, Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) convertSet(stockInItemList, ErpStockInItemDO::getProductId));
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); stockInVO.setItems(BeanUtils.toBean(stockInItemList, ErpStockInRespVO.Item.class, item -> {
stockIn.setProductNames(CollUtil.join(stockIn.getItems(), "", ErpStockInRespVO.Item::getProductName)); ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId(), item.getAreaId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
if (StringUtils.isBlank(item.getWarehouseName())) {
MapUtils.findAndThen(warehouseMap, item.getWarehouseId(), warehouse -> item.setWarehouseName(warehouse.getName()));
}
if (StringUtils.isBlank(item.getAreaName())) {
MapUtils.findAndThen(areaMap, item.getAreaId(), area -> item.setAreaName(area.getAreaName()));
}
MapUtils.findAndThen(productMap, item.getProductId(), product -> {
item.setProductName(product.getName());
item.setProductBarCode(product.getBarCode());
item.setProductUnitName(product.getUnitName());
item.setCategoryType(product.getCategoryType());
item.setSupplierId(product.getDefaultSupplierId());
if (product.getDefaultSupplierId() != null && CollUtil.isNotEmpty(product.getSuppliers())) {
product.getSuppliers().stream()
.filter(supplier -> Objects.equals(supplier.getSupplierId(), product.getDefaultSupplierId()))
.findFirst()
.ifPresent(supplier -> item.setSupplierName(supplier.getSupplierName()));
}
});
}));
stockInVO.setProductNames(CollUtil.join(stockInVO.getItems(), ",", ErpStockInRespVO.Item::getProductName));
}
if (stockIn.getSupplierId() != null) {
Map<Long, ErpSupplierDO> supplierMap = supplierService.getSupplierMap(Collections.singleton(stockIn.getSupplierId()));
MapUtils.findAndThen(supplierMap, stockIn.getSupplierId(), supplier -> stockInVO.setSupplierName(supplier.getName()));
}
stockInVO.setApproveRecords(buildApproveRecordRespList(approveRecords));
return stockInVO;
}
private List<ErpStockInApproveRecordRespVO> buildApproveRecordRespList(List<ErpStockInApproveRecordDO> records) {
if (CollUtil.isEmpty(records)) {
return new ArrayList<>();
} }
MapUtils.findAndThen(supplierMap, stockIn.getSupplierId(), supplier -> stockIn.setSupplierName(supplier.getName())); Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(records,
MapUtils.findAndThen(userMap, Long.parseLong(stockIn.getCreator()), user -> stockIn.setCreatorName(user.getNickname())); record -> Stream.of(NumberUtils.parseLong(record.getCreator()), record.getTargetUserId())));
return BeanUtils.toBean(records, ErpStockInApproveRecordRespVO.class, record -> {
MapUtils.findAndThen(userMap, NumberUtils.parseLong(record.getCreator()), user -> record.setCreatorName(user.getNickname()));
MapUtils.findAndThen(userMap, record.getTargetUserId(), user -> record.setTargetUserName(user.getNickname()));
}); });
} }
private void fillWarehouseInfo(ErpStockInRespVO.Item item, ErpStockInItemDO source,
Map<Long, ErpWarehouseDO> warehouseMap,
Map<Long, WarehouseAreaDO> areaMap) {
item.setWarehouseName(ObjectUtils.defaultIfNull(source.getWarehouseName(), item.getWarehouseName()));
item.setAreaName(ObjectUtils.defaultIfNull(source.getAreaName(), item.getAreaName()));
if (StringUtils.isBlank(item.getWarehouseName())) {
MapUtils.findAndThen(warehouseMap, source.getWarehouseId(), warehouse -> item.setWarehouseName(warehouse.getName()));
}
if (StringUtils.isBlank(item.getAreaName())) {
MapUtils.findAndThen(areaMap, source.getAreaId(), area -> item.setAreaName(area.getAreaName()));
}
}
@PostMapping("/createMesStockIn") @PostMapping("/createMesStockIn")
@Operation(summary = "创建生产入库单") @Operation(summary = "创建生产入库单")
@PreAuthorize("@ss.hasPermission('erp:stock-in:create')") @PreAuthorize("@ss.hasPermission('erp:stock-in:create')")
@ -217,21 +306,32 @@ public class ErpStockInController {
createReqVO.setInType(StockInTypeEnum..getValue()); createReqVO.setInType(StockInTypeEnum..getValue());
return success(stockInService.createStockIn(createReqVO)); return success(stockInService.createStockIn(createReqVO));
} }
@GetMapping("/pageMesStockIn") @GetMapping("/pageMesStockIn")
@Operation(summary = "获得生产入库单分页") @Operation(summary = "获得生产入库单分页")
@PreAuthorize("@ss.hasPermission('erp:stock-in:query')") @PreAuthorize("@ss.hasPermission('erp:stock-in:query')")
public CommonResult<PageResult<ErpStockInRespVO>> pageMesStockIn(@Valid ErpStockInPageReqVO pageReqVO) { public CommonResult<PageResult<ErpStockInRespVO>> pageMesStockIn(@Valid ErpStockInPageReqVO pageReqVO) {
pageReqVO.setInType(StockInTypeEnum..getValue()); pageReqVO.setInType(StockInTypeEnum..getValue());
PageResult<ErpStockInDO> pageResult = stockInService.getStockInPage(pageReqVO); fillPageReqDefault(pageReqVO);
return success(buildStockInVOPageResult(pageResult)); return success(buildStockInVOPageResult(stockInService.getStockInPage(pageReqVO)));
} }
@GetMapping("/pageComponent") @GetMapping("/pageComponent")
@Operation(summary = "获得备件入库单分页") @Operation(summary = "获得备件入库单分页")
@PreAuthorize("@ss.hasPermission('erp:stock-in:query')") @PreAuthorize("@ss.hasPermission('erp:stock-in:query')")
public CommonResult<PageResult<ErpStockInRespVO>> pageComponent(@Valid ErpStockInPageReqVO pageReqVO) { public CommonResult<PageResult<ErpStockInRespVO>> pageComponent(@Valid ErpStockInPageReqVO pageReqVO) {
pageReqVO.setInType(StockInTypeEnum..getValue()); pageReqVO.setInType(StockInTypeEnum..getValue());
PageResult<ErpStockInDO> pageResult = stockInService.getStockInPage(pageReqVO); fillPageReqDefault(pageReqVO);
return success(buildStockInVOPageResult(pageResult)); return success(buildStockInVOPageResult(stockInService.getStockInPage(pageReqVO)));
} }
@PutMapping("/update-mold-status")
@Operation(summary = "更新模具入库单的状态")
@PreAuthorize("@ss.hasPermission('erp:stock-out:update-status')")
@RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS)
public CommonResult<Boolean> updateMoldStatus(@RequestParam("id") Long id,
@RequestParam("status") Integer status) {
stockInService.updateMoldStatus(id, status);
return success(true);
}
} }

@ -6,20 +6,25 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter; import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter;
import cn.iocoder.yudao.module.common.controller.admin.mold.vo.MoldRespVO; import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandDO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutApproveRecordRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutAuditReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSubmitReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.StockOutTypeEnum; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.StockOutTypeEnum;
import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO; import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutApproveRecordDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO;
import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService;
import cn.iocoder.yudao.module.erp.service.mold.MoldService; import cn.iocoder.yudao.module.erp.service.mold.MoldService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService; import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService;
@ -33,7 +38,14 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -41,14 +53,17 @@ import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - ERP 其它出库单") @Tag(name = "管理后台 - ERP 其它出库单")
@ -65,10 +80,10 @@ public class ErpStockOutController {
private ErpProductService productService; private ErpProductService productService;
@Resource @Resource
private ErpCustomerService customerService; private ErpCustomerService customerService;
@Resource
private MoldBrandService moldBrandService;
@Resource @Resource
private MoldService moldService; private MoldService moldService;
@Resource @Resource
private AdminUserApi adminUserApi; private AdminUserApi adminUserApi;
@ -93,8 +108,43 @@ public class ErpStockOutController {
@RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS) @RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS)
public CommonResult<Boolean> updateStockOutStatus(@RequestParam("id") Long id, public CommonResult<Boolean> updateStockOutStatus(@RequestParam("id") Long id,
@RequestParam("status") Integer status, @RequestParam("status") Integer status,
@RequestParam(name = "status",required = false) Integer bizType) { @RequestParam(name = "bizType", required = false) Integer bizType) {
stockOutService.updateStockOutStatus(id, status,bizType); stockOutService.updateStockOutStatus(id, status, bizType);
return success(true);
}
@PutMapping("/submit")
@Operation(summary = "提交其它出库单审核")
@PreAuthorize("@ss.hasPermission('erp:stock-out:update')")
@RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS)
public CommonResult<Boolean> submitStockOutAudit(@Valid @RequestBody ErpStockOutSubmitReqVO submitReqVO) {
stockOutService.submitStockOutAudit(submitReqVO);
return success(true);
}
@PutMapping("/audit")
@Operation(summary = "审核其它出库单")
@PreAuthorize("@ss.hasPermission('erp:stock-out:update-status')")
@RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS)
public CommonResult<Boolean> auditStockOut(@Valid @RequestBody ErpStockOutAuditReqVO auditReqVO) {
stockOutService.auditStockOut(auditReqVO);
return success(true);
}
@GetMapping("/approve-record-list")
@Operation(summary = "获得其它出库单审核记录")
@PreAuthorize("@ss.hasPermission('erp:stock-out:query')")
public CommonResult<List<ErpStockOutApproveRecordRespVO>> getApproveRecordList(@RequestParam("id") Long id) {
return success(buildApproveRecordRespList(stockOutService.getStockOutApproveRecordList(id)));
}
@PutMapping("/update-mold-status")
@Operation(summary = "更新模具出库单的状态")
@PreAuthorize("@ss.hasPermission('erp:stock-out:update-status')")
@RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS)
public CommonResult<Boolean> updateMoldStatus(@RequestParam("id") Long id,
@RequestParam("status") Integer status) {
stockOutService.updateMoldStatus(id, status);
return success(true); return success(true);
} }
@ -116,98 +166,119 @@ public class ErpStockOutController {
if (stockOut == null) { if (stockOut == null) {
return success(null); return success(null);
} }
List<ErpStockOutItemDO> stockOutItemList = stockOutService.getStockOutItemListByOutId(id); return success(buildStockOutRespVO(stockOut,
if (Objects.equals(stockOut.getOutType(), "模具出库")) { stockOutService.getStockOutItemListByOutId(id),
Map<Long, MoldRespVO> moldMap = moldService.getMoldVOMap( stockOutService.getStockOutApproveRecordList(id)));
convertSet(stockOutItemList, ErpStockOutItemDO::getProductId));
return success(BeanUtils.toBean(stockOut, ErpStockOutRespVO.class, stockOutVO ->
stockOutVO.setItems(BeanUtils.toBean(stockOutItemList, ErpStockOutRespVO.Item.class, item -> {
ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
MapUtils.findAndThen(moldMap, item.getProductId(), mold -> item.setProductName(mold.getName())
.setProductBarCode(mold.getCode()).setProductUnitName(mold.getUnitName()));
}))));
} else {
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(stockOutItemList, ErpStockOutItemDO::getProductId));
return success(BeanUtils.toBean(stockOut, ErpStockOutRespVO.class, stockOutVO ->
stockOutVO.setItems(BeanUtils.toBean(stockOutItemList, ErpStockOutRespVO.Item.class, item -> {
ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName()));
}))));
}
} }
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得其它出库单分页") @Operation(summary = "获得其它出库单分页")
@PreAuthorize("@ss.hasPermission('erp:stock-out:query')") @PreAuthorize("@ss.hasPermission('erp:stock-out:query')")
public CommonResult<PageResult<ErpStockOutRespVO>> getStockOutPage(@Valid ErpStockOutPageReqVO pageReqVO) { public CommonResult<PageResult<ErpStockOutRespVO>> getStockOutPage(@Valid ErpStockOutPageReqVO pageReqVO) {
if(StringUtils.isEmpty(pageReqVO.getOutType())){ fillPageReqDefault(pageReqVO);
List<String> list = new ArrayList<>(); return success(buildStockOutVOPageResult(stockOutService.getStockOutPage(pageReqVO)));
list.add(StockOutTypeEnum..getValue());
list.add(StockOutTypeEnum..getValue());
list.add(StockOutTypeEnum..getValue());
list.add(StockOutTypeEnum..getValue());
pageReqVO.setOutTypeList(list);
}
PageResult<ErpStockOutDO> pageResult = stockOutService.getStockOutPage(pageReqVO);
return success(buildStockOutVOPageResult(pageResult));
} }
@GetMapping("/export-excel") @GetMapping("/export-excel")
@Operation(summary = "导出其它出库单 Excel") @Operation(summary = "导出其它出库单 Excel")
@PreAuthorize("@ss.hasPermission('erp:stock-out:export')") @PreAuthorize("@ss.hasPermission('erp:stock-out:export')")
@ApiAccessLog(operateType = EXPORT) @ApiAccessLog(operateType = EXPORT)
public void exportStockOutExcel(@Valid ErpStockOutPageReqVO pageReqVO, public void exportStockOutExcel(@Valid ErpStockOutPageReqVO pageReqVO,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
fillPageReqDefault(pageReqVO);
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ErpStockOutRespVO> list = buildStockOutVOPageResult(stockOutService.getStockOutPage(pageReqVO)).getList(); List<ErpStockOutRespVO> list = buildStockOutVOPageResult(stockOutService.getStockOutPage(pageReqVO)).getList();
// 导出 Excel
ExcelUtils.write(response, "其它出库单.xls", "数据", ErpStockOutRespVO.class, list); ExcelUtils.write(response, "其它出库单.xls", "数据", ErpStockOutRespVO.class, list);
} }
private void fillPageReqDefault(ErpStockOutPageReqVO pageReqVO) {
if (StringUtils.isEmpty(pageReqVO.getOutType())) {
List<String> list = new ArrayList<>();
list.add(StockOutTypeEnum..getValue());
list.add(StockOutTypeEnum..getValue());
list.add(StockOutTypeEnum..getValue());
list.add(StockOutTypeEnum..getValue());
pageReqVO.setOutTypeList(list);
}
}
private PageResult<ErpStockOutRespVO> buildStockOutVOPageResult(PageResult<ErpStockOutDO> pageResult) { private PageResult<ErpStockOutRespVO> buildStockOutVOPageResult(PageResult<ErpStockOutDO> pageResult) {
if (CollUtil.isEmpty(pageResult.getList())) { if (CollUtil.isEmpty(pageResult.getList())) {
return PageResult.empty(pageResult.getTotal()); return PageResult.empty(pageResult.getTotal());
} }
// 1.1 出库项 List<ErpStockOutRespVO> list = convertList(pageResult.getList(), stockOut -> buildStockOutRespVO(
List<ErpStockOutItemDO> stockOutItemList = stockOutService.getStockOutItemListByOutIds( stockOut, stockOutService.getStockOutItemListByOutId(stockOut.getId()), Collections.emptyList()));
convertSet(pageResult.getList(), ErpStockOutDO::getId)); return new PageResult<>(list, pageResult.getTotal());
Map<Long, List<ErpStockOutItemDO>> stockOutItemMap = convertMultiMap(stockOutItemList, ErpStockOutItemDO::getOutId); }
// 1.2 产品信息
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap( private ErpStockOutRespVO buildStockOutRespVO(ErpStockOutDO stockOut, List<ErpStockOutItemDO> stockOutItemList,
convertSet(stockOutItemList, ErpStockOutItemDO::getProductId)); List<ErpStockOutApproveRecordDO> approveRecords) {
// 1.3 客户信息 ErpStockOutRespVO stockOutVO = BeanUtils.toBean(stockOut, ErpStockOutRespVO.class);
Map<Long, ErpCustomerDO> customerMap = customerService.getCustomerMap( Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(
convertSet(pageResult.getList(), ErpStockOutDO::getCustomerId)); Collections.singletonList(stockOut), item -> Stream.of(NumberUtils.parseLong(item.getCreator()),
// 1.5 管理员信息 item.getResponserId(), item.getAuditUserId())));
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( MapUtils.findAndThen(userMap, NumberUtils.parseLong(stockOut.getCreator()), user -> stockOutVO.setCreatorName(user.getNickname()));
convertSet(pageResult.getList(), stockOut -> Long.parseLong(stockOut.getCreator()))); MapUtils.findAndThen(userMap, stockOut.getResponserId(), user -> stockOutVO.setResponserName(user.getNickname()));
// 1.6 领料员信息 MapUtils.findAndThen(userMap, stockOut.getAuditUserId(), user -> stockOutVO.setAuditUserName(user.getNickname()));
Map<Long, AdminUserRespDTO> responserMap = adminUserApi.getUserMap(
convertSet(pageResult.getList(), ErpStockOutDO::getResponserId));
// 1.7 模具信息
Map<Long, MoldRespVO> moldMap = moldService.getMoldVOMap(
convertSet(stockOutItemList, ErpStockOutItemDO::getProductId));
// 2. 开始拼接
return BeanUtils.toBean(pageResult, ErpStockOutRespVO.class, stockOut -> {
if (Objects.equals(stockOut.getOutType(), "模具出库")) { if (Objects.equals(stockOut.getOutType(), "模具出库")) {
stockOut.setItems(BeanUtils.toBean(stockOutItemMap.get(stockOut.getId()), ErpStockOutRespVO.Item.class, Map<Long, MoldBrandDO> moldMap = moldBrandService.getMoldVOMap(
item -> MapUtils.findAndThen(moldMap, item.getProductId(), mold -> item.setProductName(mold.getName()) convertSet(stockOutItemList, ErpStockOutItemDO::getMoldSetId));
.setProductBarCode(mold.getCode()).setProductUnitName(mold.getUnitName())))); Map<Long, List<cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO>> moldListMap = moldService.getMoldListMapByBrandIds(
stockOut.setProductNames(CollUtil.join(stockOut.getItems(), "", ErpStockOutRespVO.Item::getProductName)); convertSet(stockOutItemList, ErpStockOutItemDO::getMoldSetId));
stockOutVO.setItems(convertList(stockOutItemList, source -> {
ErpStockOutRespVO.Item item = BeanUtils.toBean(source, ErpStockOutRespVO.Item.class);
ErpStockDO stock = stockService.getStock(source.getMoldSetId(), source.getWarehouseId(), source.getAreaId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
item.setMoldList(moldListMap.getOrDefault(source.getMoldSetId(), new ArrayList<>()));
MapUtils.findAndThen(moldMap, source.getMoldSetId(), mold -> {
item.setMoldSetName(mold.getName());
item.setProductName(mold.getName());
item.setProductBarCode(mold.getCode());
});
return item;
}));
stockOutVO.setMoldSetNames(CollUtil.join(stockOutVO.getItems(), ",", ErpStockOutRespVO.Item::getMoldSetName));
stockOutVO.setProductNames(stockOutVO.getMoldSetNames());
} else { } else {
stockOut.setItems(BeanUtils.toBean(stockOutItemMap.get(stockOut.getId()), ErpStockOutRespVO.Item.class, Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) convertSet(stockOutItemList, ErpStockOutItemDO::getProductId));
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); stockOutVO.setItems(BeanUtils.toBean(stockOutItemList, ErpStockOutRespVO.Item.class, item -> {
stockOut.setProductNames(CollUtil.join(stockOut.getItems(), "", ErpStockOutRespVO.Item::getProductName)); ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId(), item.getAreaId());
} item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
MapUtils.findAndThen(customerMap, stockOut.getCustomerId(), supplier -> stockOut.setCustomerName(supplier.getName())); MapUtils.findAndThen(productMap, item.getProductId(), product -> {
MapUtils.findAndThen(userMap, Long.parseLong(stockOut.getCreator()), user -> stockOut.setCreatorName(user.getNickname())); item.setProductName(product.getName());
MapUtils.findAndThen(responserMap, stockOut.getResponserId(), user -> stockOut.setResponserName(user.getNickname())); item.setProductBarCode(product.getBarCode());
item.setProductUnitName(product.getUnitName());
item.setCategoryType(product.getCategoryType());
item.setSupplierId(product.getDefaultSupplierId());
if (product.getDefaultSupplierId() != null && CollUtil.isNotEmpty(product.getSuppliers())) {
product.getSuppliers().stream()
.filter(supplier -> Objects.equals(supplier.getSupplierId(), product.getDefaultSupplierId()))
.findFirst()
.ifPresent(supplier -> item.setSupplierName(supplier.getSupplierName()));
}
});
}));
stockOutVO.setProductNames(CollUtil.join(stockOutVO.getItems(), ",", ErpStockOutRespVO.Item::getProductName));
}
if (stockOut.getCustomerId() != null) {
Map<Long, ErpCustomerDO> customerMap = customerService.getCustomerMap(Collections.singleton(stockOut.getCustomerId()));
MapUtils.findAndThen(customerMap, stockOut.getCustomerId(), customer -> stockOutVO.setCustomerName(customer.getName()));
}
stockOutVO.setApproveRecords(buildApproveRecordRespList(approveRecords));
return stockOutVO;
}
private List<ErpStockOutApproveRecordRespVO> buildApproveRecordRespList(List<ErpStockOutApproveRecordDO> records) {
if (CollUtil.isEmpty(records)) {
return new ArrayList<>();
}
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(records,
record -> Stream.of(NumberUtils.parseLong(record.getCreator()), record.getTargetUserId())));
return BeanUtils.toBean(records, ErpStockOutApproveRecordRespVO.class, record -> {
MapUtils.findAndThen(userMap, NumberUtils.parseLong(record.getCreator()), user -> record.setCreatorName(user.getNickname()));
MapUtils.findAndThen(userMap, record.getTargetUserId(), user -> record.setTargetUserName(user.getNickname()));
}); });
} }
@ -218,13 +289,13 @@ public class ErpStockOutController {
createReqVO.setOutType(StockOutTypeEnum..getValue()); createReqVO.setOutType(StockOutTypeEnum..getValue());
return success(stockOutService.createStockOut(createReqVO)); return success(stockOutService.createStockOut(createReqVO));
} }
@GetMapping("/pageMesStockOut") @GetMapping("/pageMesStockOut")
@Operation(summary = "获得生产领料出库单分页") @Operation(summary = "获得生产领料出库单分页")
@PreAuthorize("@ss.hasPermission('erp:stock-out:query')") @PreAuthorize("@ss.hasPermission('erp:stock-out:query')")
public CommonResult<PageResult<ErpStockOutRespVO>> getMesStockOutPage(@Valid ErpStockOutPageReqVO pageReqVO) { public CommonResult<PageResult<ErpStockOutRespVO>> getMesStockOutPage(@Valid ErpStockOutPageReqVO pageReqVO) {
pageReqVO.setOutType(StockOutTypeEnum..getValue()); pageReqVO.setOutType(StockOutTypeEnum..getValue());
PageResult<ErpStockOutDO> pageResult = stockOutService.getStockOutPage(pageReqVO); return success(buildStockOutVOPageResult(stockOutService.getStockOutPage(pageReqVO)));
return success(buildStockOutVOPageResult(pageResult));
} }
} }

@ -12,10 +12,17 @@ import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProduc
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockRecordDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockRecordDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO;
import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockInService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockRecordService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockRecordService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockOutService;
import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService; import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -48,9 +55,15 @@ public class ErpStockRecordController {
@Resource @Resource
private ErpStockRecordService stockRecordService; private ErpStockRecordService stockRecordService;
@Resource @Resource
private ErpStockInService stockInService;
@Resource
private ErpStockOutService stockOutService;
@Resource
private ErpProductService productService; private ErpProductService productService;
@Resource @Resource
private ErpWarehouseService warehouseService; private ErpWarehouseService warehouseService;
@Resource
private WarehouseAreaService warehouseAreaService;
@Resource @Resource
private AdminUserApi adminUserApi; private AdminUserApi adminUserApi;
@ -61,7 +74,7 @@ public class ErpStockRecordController {
@PreAuthorize("@ss.hasPermission('erp:stock-record:query')") @PreAuthorize("@ss.hasPermission('erp:stock-record:query')")
public CommonResult<ErpStockRecordRespVO> getStockRecord(@RequestParam("id") Long id) { public CommonResult<ErpStockRecordRespVO> getStockRecord(@RequestParam("id") Long id) {
ErpStockRecordDO stockRecord = stockRecordService.getStockRecord(id); ErpStockRecordDO stockRecord = stockRecordService.getStockRecord(id);
return success(BeanUtils.toBean(stockRecord, ErpStockRecordRespVO.class)); return success(buildStockRecordRespVO(stockRecord));
} }
@GetMapping("/page") @GetMapping("/page")
@ -92,14 +105,82 @@ public class ErpStockRecordController {
convertSet(pageResult.getList(), ErpStockRecordDO::getProductId)); convertSet(pageResult.getList(), ErpStockRecordDO::getProductId));
Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap( Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
convertSet(pageResult.getList(), ErpStockRecordDO::getWarehouseId)); convertSet(pageResult.getList(), ErpStockRecordDO::getWarehouseId));
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
convertSet(pageResult.getList(), ErpStockRecordDO::getAreaId));
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
convertSet(pageResult.getList(), record -> Long.parseLong(record.getCreator()))); convertSet(pageResult.getList(), record -> Long.parseLong(record.getCreator())));
return BeanUtils.toBean(pageResult, ErpStockRecordRespVO.class, stock -> { return BeanUtils.toBean(pageResult, ErpStockRecordRespVO.class, stock -> {
stock.setBizDirection(resolveBizDirection(stock.getBizType()));
stock.setBizDocType(resolveBizDocType(stock.getBizType(), stock.getBizId()));
MapUtils.findAndThen(productMap, stock.getProductId(), product -> stock.setProductName(product.getName()) MapUtils.findAndThen(productMap, stock.getProductId(), product -> stock.setProductName(product.getName())
.setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName())); .setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName())
.setCategoryType(product.getCategoryType()));
MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName())); MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName()));
if (stock.getAreaName() == null) {
MapUtils.findAndThen(areaMap, stock.getAreaId(), area -> stock.setAreaName(area.getAreaName()));
}
MapUtils.findAndThen(userMap, Long.parseLong(stock.getCreator()), user -> stock.setCreatorName(user.getNickname())); MapUtils.findAndThen(userMap, Long.parseLong(stock.getCreator()), user -> stock.setCreatorName(user.getNickname()));
}); });
} }
private ErpStockRecordRespVO buildStockRecordRespVO(ErpStockRecordDO stockRecord) {
if (stockRecord == null) {
return null;
}
ErpStockRecordRespVO respVO = BeanUtils.toBean(stockRecord, ErpStockRecordRespVO.class);
respVO.setBizDirection(resolveBizDirection(respVO.getBizType()));
respVO.setBizDocType(resolveBizDocType(stockRecord.getBizType(), stockRecord.getBizId()));
ErpProductRespVO product = productService.getProduct(stockRecord.getProductId());
if (product != null) {
respVO.setProductName(product.getName());
respVO.setCategoryName(product.getCategoryName());
respVO.setUnitName(product.getUnitName());
respVO.setCategoryType(product.getCategoryType());
}
ErpWarehouseDO warehouse = warehouseService.getWarehouse(stockRecord.getWarehouseId());
if (warehouse != null) {
respVO.setWarehouseName(warehouse.getName());
}
if (respVO.getAreaName() == null && respVO.getAreaId() != null) {
WarehouseAreaDO area = warehouseAreaService.getWarehouseArea(respVO.getAreaId());
if (area != null) {
respVO.setAreaName(area.getAreaName());
}
}
if (respVO.getCreator() != null) {
AdminUserRespDTO user = adminUserApi.getUser(Long.parseLong(respVO.getCreator()));
if (user != null) {
respVO.setCreatorName(user.getNickname());
}
}
return respVO;
}
private String resolveBizDocType(Integer bizType, Long bizId) {
if (bizType == null || bizId == null) {
return null;
}
String bizDirection = resolveBizDirection(bizType);
if ("入库".equals(bizDirection)) {
ErpStockInDO stockIn = stockInService.getStockIn(bizId);
return stockIn != null ? stockIn.getInType() : null;
}
if ("出库".equals(bizDirection)) {
ErpStockOutDO stockOut = stockOutService.getStockOut(bizId);
return stockOut != null ? stockOut.getOutType() : null;
}
return null;
}
private String resolveBizDirection(Integer bizType) {
if (bizType == null) {
return null;
}
return java.util.Arrays.stream(ErpStockRecordBizTypeEnum.values())
.filter(item -> java.util.Objects.equals(item.getType(), bizType))
.findFirst()
.map(item -> item.getName().contains("入库") ? "入库" : "出库")
.orElse(null);
}
} }

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save