Compare commits

..

No commits in common. 'main' and 'liutao_branch' have entirely different histories.

@ -70,13 +70,10 @@
<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>
@ -592,17 +589,6 @@
<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> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
@ -662,16 +648,6 @@
<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,12 +28,9 @@ 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;
@ -388,90 +385,4 @@ 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));
}
}
} }

@ -1,16 +0,0 @@
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,12 +16,6 @@
<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>
@ -62,14 +56,6 @@
<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>

@ -16,7 +16,7 @@ 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 = "芋艿")

@ -1,122 +0,0 @@
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));
}
}

@ -1,59 +0,0 @@
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;
}

@ -1,73 +0,0 @@
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;
}

@ -1,61 +0,0 @@
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;
}

@ -113,10 +113,4 @@ public class MoldDO extends BaseDO {
@TableField(exist = false) @TableField(exist = false)
private String moldType; private String moldType;
/**
*
*/
@TableField(exist = false)
private String qrcodeUrl;
} }

@ -1,81 +0,0 @@
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;
}

@ -1,36 +0,0 @@
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));
}
}

@ -1,30 +0,0 @@
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;
}
}

@ -1,28 +0,0 @@
package cn.iocoder.yudao.module.common.enums;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum QrcodeBizTypeEnum {
PRODUCT("PRODUCTMATERIAL", "产品物料"),
EQUIPMENT("EQUIPMENT", "设备"),
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;
}
}

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

@ -1,83 +0,0 @@
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.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<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;
}

@ -1,605 +0,0 @@
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.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<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);
}
}
}

@ -1,12 +0,0 @@
<?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>

@ -133,11 +133,6 @@ 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, "产品分类不存在");

@ -1,7 +1,5 @@
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;
@ -93,16 +91,6 @@ 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));

@ -1,40 +0,0 @@
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,7 +2,6 @@ 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;
@ -185,14 +184,4 @@ 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,7 +46,4 @@ 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,13 +27,6 @@ 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,8 +45,4 @@ public class AutocodeRuleSaveReqVO {
@Schema(description = "编码规则组成列表") @Schema(description = "编码规则组成列表")
private List<AutocodePartDO> autocodeParts; private List<AutocodePartDO> autocodeParts;
@Schema(description = "码类型条形码-1 二维码-2", example = "")
private Integer barcodeType;
} }

@ -27,7 +27,6 @@ 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;
@ -144,7 +143,7 @@ public class MoldBrandController {
@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) throws UnsupportedEncodingException { public CommonResult<Long> createMold(@Valid @RequestBody MoldSaveReqVO createReqVO) {
return success(moldBrandService.createMold(createReqVO)); return success(moldBrandService.createMold(createReqVO));
} }
@ -187,15 +186,6 @@ 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")

@ -7,7 +7,6 @@ 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;
@ -16,8 +15,6 @@ 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;
@ -31,17 +28,14 @@ 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
@ -57,20 +51,18 @@ 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) throws UnsupportedEncodingException { public CommonResult<Long> createProduct(@Valid @RequestBody ProductSaveReqVO createReqVO) {
// 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());
// productPageReqVO.setCode(createReqVO.getBarCode()); if (!productMapper.selectProductCodeExist(productPageReqVO).getList().isEmpty()) {
// if (!productMapper.selectProductCodeExist(productPageReqVO).getList().isEmpty()) { return error(400,"编码不能重复");
// return error(400,"编码不能重复"); }
// }
return success(productService.createProduct(createReqVO)); return success(productService.createProduct(createReqVO));
} }
@ -107,7 +99,8 @@ public class ErpProductController {
@Parameter(name = "id", description = "编号", required = true, example = "1024") @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("id") Long id) {
return success(productService.getProduct(id)); ErpProductDO product = productService.getProduct(id);
return success(BeanUtils.toBean(product, ErpProductRespVO.class));
} }
@GetMapping("/page") @GetMapping("/page")
@ -238,12 +231,4 @@ 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,6 +1,5 @@
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;
@ -11,33 +10,26 @@ 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
@ -100,12 +92,7 @@ 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());
list.stream().forEach(item -> { return success(convertList(list, unit -> new ErpProductUnitRespVO().setId(unit.getId()).setName(unit.getName())));
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")
@ -137,30 +124,4 @@ 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("导入成功");
}
} }

@ -17,9 +17,6 @@ public class ErpProductPageReqVO extends PageParam {
@Schema(description = "产品名称", example = "李四") @Schema(description = "产品名称", example = "李四")
private String name; private String name;
@Schema(description = "规格型号", example = "")
private String deviceSpec;
@Schema(description = "产品分类编号", example = "11161") @Schema(description = "产品分类编号", example = "11161")
private Long categoryId; private Long categoryId;

@ -1,6 +1,5 @@
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;
@ -8,12 +7,11 @@ 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 extends ErpProductDO { public class ErpProductRespVO {
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15672") @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15672")
@ExcelProperty("产品编号") @ExcelProperty("产品编号")
@ -23,10 +21,6 @@ public class ErpProductRespVO extends ErpProductDO {
@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;
@ -89,20 +83,4 @@ public class ErpProductRespVO extends ErpProductDO {
@Schema(description = "预警库存", example = "161.87") @Schema(description = "预警库存", example = "161.87")
@ExcelProperty("预警库存") @ExcelProperty("预警库存")
private BigDecimal safetyNumber; private BigDecimal safetyNumber;
@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 = "关联设备列表")
private List<ProductRelationRespVO> devices;
@Schema(description = "关联模具列表")
private List<ProductRelationRespVO> molds;
} }

@ -1,15 +0,0 @@
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,13 +1,11 @@
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.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
@ -20,11 +18,8 @@ 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")
@ -62,10 +57,4 @@ public class ProductSaveReqVO {
@Schema(description = "预警库存", example = "161.87") @Schema(description = "预警库存", example = "161.87")
private BigDecimal safetyNumber; private BigDecimal safetyNumber;
@Schema(description = "关联设备ID列表", example = "[11,15,23]")
private List<Long> deviceIds;
@Schema(description = "关联模具D列表", example = "[11,15,23]")
private List<Long> moldIds;
} }

@ -1,42 +0,0 @@
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,7 +4,6 @@ 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;
@ -44,7 +43,4 @@ public class ErpProductUnitRespVO {
@ExcelProperty("创建时间") @ExcelProperty("创建时间")
private LocalDateTime createTime; private LocalDateTime createTime;
private String value;
private String label;
} }

@ -1,96 +0,0 @@
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));
}
}

@ -1,34 +0,0 @@
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;
}

@ -1,39 +0,0 @@
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;
}

@ -1,30 +0,0 @@
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;
}

@ -1,95 +0,0 @@
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));
}
}

@ -1,34 +0,0 @@
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;
}

@ -1,39 +0,0 @@
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;
}

@ -1,29 +0,0 @@
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;
}

@ -70,10 +70,4 @@ public class AutocodeRuleDO extends BaseDO {
*/ */
private Boolean isEnable; private Boolean isEnable;
/**
* -1 -2
*
*/
private Integer barcodeType;
} }

@ -1,12 +1,9 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.product; package cn.iocoder.yudao.module.erp.dal.dataobject.product;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -35,11 +32,6 @@ public class ErpProductDO extends BaseDO {
* *
*/ */
private String name; private String name;
/**
*
*/
private String deviceSpec;
/** /**
* *
*/ */
@ -108,10 +100,4 @@ public class ErpProductDO extends BaseDO {
* *
*/ */
private BigDecimal safetyNumber; private BigDecimal safetyNumber;
/**
*
*/
@TableField(exist = false)
private String qrcodeUrl;
} }

@ -46,10 +46,6 @@ public class ErpProductUnitDO extends BaseDO {
/** /**
* *
*/ */
private Integer status; private Integer status;
@TableField(exist = false)
private String value;
@TableField(exist = false)
private String label;
} }

@ -1,47 +0,0 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.productdevicerel;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* - DO
*
* @author
*/
@TableName("erp_product_device_rel")
@KeySequence("erp_product_device_rel_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductDeviceRelDO extends BaseDO {
/**
*
*/
@TableId
private Long id;
/**
* ID
*/
private Long productId;
/**
* ID
*/
private Long deviceId;
/**
*
*/
private Integer sort;
/**
*
*/
private String remark;
}

@ -1,47 +0,0 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.productmoldrel;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* - DO
*
* @author
*/
@TableName("erp_product_mold_rel")
@KeySequence("erp_product_mold_rel_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductMoldRelDO extends BaseDO {
/**
*
*/
@TableId
private Long id;
/**
* ID
*/
private Long productId;
/**
* ID
*/
private Long moldId;
/**
*
*/
private Integer sort;
/**
*
*/
private String remark;
}

@ -6,12 +6,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductRelationRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
@ -41,18 +39,16 @@ public interface ErpProductMapper extends BaseMapperX<ErpProductDO> {
.orderByAsc(ErpProductDO::getId)); .orderByAsc(ErpProductDO::getId));
} }
default Boolean selectProductExist(ErpProductDO reqVO) { default Boolean selectProductExist(ErpProductPageReqVO reqVO) {
if (!StringUtils.hasText(reqVO.getName()) || !StringUtils.hasText(reqVO.getStandard())) { LambdaQueryWrapperX<ErpProductDO> queryWrapper = (LambdaQueryWrapperX<ErpProductDO>) new LambdaQueryWrapperX<ErpProductDO>()
return false; .orderByAsc(ErpProductDO::getId);
if (StringUtils.hasText(reqVO.getName()) && StringUtils.hasText(reqVO.getStandard())) {
// 组合查询name 和 standard 必须同时匹配
queryWrapper.eq(ErpProductDO::getName, reqVO.getName())
.eq(ErpProductDO::getStandard, reqVO.getStandard());
return !selectPage(reqVO, queryWrapper).getList().isEmpty();
} }
return false;
// 直接使用 count 查询
Long count = selectCount(new LambdaQueryWrapper<ErpProductDO>()
.eq(ErpProductDO::getName, reqVO.getName())
.eq(ErpProductDO::getStandard, reqVO.getStandard()));
return count > 0;
} }
default Long selectCountByCategoryId(Long categoryId) { default Long selectCountByCategoryId(Long categoryId) {
@ -87,8 +83,5 @@ public interface ErpProductMapper extends BaseMapperX<ErpProductDO> {
return selectList(new LambdaQueryWrapperX<ErpProductDO>().in(ErpProductDO::getName, names)); return selectList(new LambdaQueryWrapperX<ErpProductDO>().in(ErpProductDO::getName, names));
} }
List<ProductRelationRespVO> selectDevicesByProductId(@Param("productId") Long productId);
List<ProductRelationRespVO> selectMoldsByProductId(@Param("productId") Long productId);
} }

@ -1,31 +0,0 @@
package cn.iocoder.yudao.module.erp.dal.mysql.productdevicerel;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.erp.dal.dataobject.productdevicerel.ProductDeviceRelDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.erp.controller.admin.productdevicerel.vo.*;
/**
* - Mapper
*
* @author
*/
@Mapper
public interface ProductDeviceRelMapper extends BaseMapperX<ProductDeviceRelDO> {
default PageResult<ProductDeviceRelDO> selectPage(ProductDeviceRelPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProductDeviceRelDO>()
.eqIfPresent(ProductDeviceRelDO::getProductId, reqVO.getProductId())
.eqIfPresent(ProductDeviceRelDO::getDeviceId, reqVO.getDeviceId())
.eqIfPresent(ProductDeviceRelDO::getSort, reqVO.getSort())
.eqIfPresent(ProductDeviceRelDO::getRemark, reqVO.getRemark())
.betweenIfPresent(ProductDeviceRelDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ProductDeviceRelDO::getId));
}
}

@ -1,32 +0,0 @@
package cn.iocoder.yudao.module.erp.dal.mysql.productmoldrel;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.erp.dal.dataobject.productmoldrel.ProductMoldRelDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.erp.controller.admin.productmoldrel.vo.*;
/**
* - Mapper
*
* @author
*/
@Mapper
public interface ProductMoldRelMapper extends BaseMapperX<ProductMoldRelDO> {
default PageResult<ProductMoldRelDO> selectPage(ProductMoldRelPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProductMoldRelDO>()
.eqIfPresent(ProductMoldRelDO::getProductId, reqVO.getProductId())
.eqIfPresent(ProductMoldRelDO::getMoldId, reqVO.getMoldId())
.eqIfPresent(ProductMoldRelDO::getSort, reqVO.getSort())
.eqIfPresent(ProductMoldRelDO::getRemark, reqVO.getRemark())
.betweenIfPresent(ProductMoldRelDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ProductMoldRelDO::getId));
}
}

@ -1,34 +0,0 @@
package cn.iocoder.yudao.module.erp.handler;
import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldMapper;
import cn.iocoder.yudao.module.common.enums.QrcodeBizTypeEnum;
import cn.iocoder.yudao.module.common.handler.QrcodeBizHandler;
import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class ProductQrcodeBizHandler implements QrcodeBizHandler {
@Resource
private ErpProductMapper productMapper;
public String getBizType() {
return QrcodeBizTypeEnum.PRODUCT.getCode();
}
public boolean exists(Long id) { return productMapper.selectById(id) != null; }
public String buildDeepLink(Long id) {
// return "besure://mold/detail?id=" + id;
//TODO 替换成app连接
return "https://www.baidu.com";
}
public String buildH5Path(Long id) {
// return "/h5/mold/view?id=" + id;
//TODO 替换成app连接不存在页面
return "https://baike.baidu.com/item/%E6%98%9F%E5%BA%A7/8072715?fr=aladdin";
}
}

@ -12,7 +12,6 @@ import cn.iocoder.yudao.module.erp.controller.admin.mold.vo.MoldBrandTreeRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -97,7 +96,7 @@ public interface MoldBrandService {
* @param mold * @param mold
* @return * @return
*/ */
Long createMold(@Valid MoldSaveReqVO createReqVO) throws UnsupportedEncodingException; Long createMold(@Valid MoldSaveReqVO createReqVO);
/** /**
* *
@ -185,6 +184,4 @@ public interface MoldBrandService {
} }
List<MoldBrandTreeRespVO> getMoldBrandTree(); List<MoldBrandTreeRespVO> getMoldBrandTree();
void regenerateCode(Long id, String code) throws UnsupportedEncodingException;
} }

@ -15,10 +15,6 @@ 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.common.dal.dataobject.moldrepair.MoldRepairLineDO; import cn.iocoder.yudao.module.common.dal.dataobject.moldrepair.MoldRepairLineDO;
import cn.iocoder.yudao.module.common.dal.dataobject.moldticketresults.MoldTicketResultsDO; import cn.iocoder.yudao.module.common.dal.dataobject.moldticketresults.MoldTicketResultsDO;
import cn.iocoder.yudao.module.common.enums.CodeTypeEnum;
import cn.iocoder.yudao.module.common.enums.QrcodeBizTypeEnum;
import cn.iocoder.yudao.module.common.service.qrcordrecord.QrcodeRecordService;
import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil;
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.dal.dataobject.product.ErpProductDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
@ -33,23 +29,18 @@ import cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants;
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.product.ErpProductUnitService; import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.common.api.mold.enums.ErrorCodeConstants.FAILED_TO_REGENERATE;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
/** /**
@ -59,7 +50,6 @@ import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
*/ */
@Service @Service
@Validated @Validated
@Slf4j
public class MoldBrandServiceImpl implements MoldBrandService { public class MoldBrandServiceImpl implements MoldBrandService {
@Resource @Resource
@ -76,12 +66,6 @@ public class MoldBrandServiceImpl implements MoldBrandService {
private ErpProductUnitService productUnitService; private ErpProductUnitService productUnitService;
@Resource @Resource
private ErpProductService productService; private ErpProductService productService;
@Resource
private QrcodeRecordService qrcodeService;
@Autowired
private AutoCodeUtil autoCodeUtil;
@Override @Override
public Long createMoldBrand(MoldBrandSaveReqVO createReqVO) { public Long createMoldBrand(MoldBrandSaveReqVO createReqVO) {
// 插入 // 插入
@ -189,48 +173,19 @@ public class MoldBrandServiceImpl implements MoldBrandService {
}); });
} }
@Override @Override
public Long createMold(MoldSaveReqVO createReqVO) throws UnsupportedEncodingException { public Long createMold(MoldSaveReqVO createReqVO) {
String Code = createReqVO.getCode(); String Code = createReqVO.getCode();
// if (StrUtil.isBlank(Code)) { if (StrUtil.isBlank(Code)) {
// throw new ServiceException(ErrorCodeConstants.MOLD_CODE_EMPTY); throw new ServiceException(ErrorCodeConstants.MOLD_CODE_EMPTY);
// }
// boolean exists = moldMapper.exists(
// new LambdaQueryWrapperX<MoldDO>().eq(MoldDO::getCode, Code)
// );
// if (exists) {
// throw new ServiceException(ErrorCodeConstants.MOLD_CODE_DUPLICATE);
// }
MoldDO mold = BeanUtils.toBean(createReqVO, MoldDO.class);
if (StringUtils.isBlank(Code)) {
mold.setCode(autoCodeUtil.genSerialCode("MOLD_CODE_GENERATE",null));
} else {
if (moldMapper.selectOne(Wrappers.<MoldDO>lambdaQuery().eq(MoldDO::getCode,Code)) != null) {
throw exception(MOLD_CODE_DUPLICATE);
}
}
moldMapper.insert(mold);
CodeTypeEnum codeType = autoCodeUtil.queryCodeType("MOLD_CODE_GENERATE");
if (codeType==null){
log.warn("[创建模具]未配置码类型跳过生产ruleCode={}","MOLD_CODE_GENERATE");
return mold.getId();
} }
boolean exists = moldMapper.exists(
qrcodeService.generateOrRefresh( new LambdaQueryWrapperX<MoldDO>().eq(MoldDO::getCode, Code)
QrcodeBizTypeEnum.MOLD,
mold.getId(),
mold.getCode(),
"DETAIL",
codeType
); );
if (exists) {
throw new ServiceException(ErrorCodeConstants.MOLD_CODE_DUPLICATE);
}
MoldDO mold = BeanUtils.toBean(createReqVO, MoldDO.class);
moldMapper.insert(mold);
return mold.getId(); return mold.getId();
} }
@ -246,10 +201,6 @@ public class MoldBrandServiceImpl implements MoldBrandService {
public void deleteMold(Long id) { public void deleteMold(Long id) {
// 校验存在 // 校验存在
validateMoldExists(id); validateMoldExists(id);
// 删除二维码/条形码
qrcodeService.deleteByBiz(QrcodeBizTypeEnum.MOLD, id);
// 删除 // 删除
moldMapper.deleteById(id); moldMapper.deleteById(id);
} }
@ -304,8 +255,7 @@ public class MoldBrandServiceImpl implements MoldBrandService {
if(CollectionUtils.isNotEmpty(moldRepairDOMap)){ if(CollectionUtils.isNotEmpty(moldRepairDOMap)){
moldDO.setRepairList(moldRepairDOMap); moldDO.setRepairList(moldRepairDOMap);
} }
String qrcodeUrl = qrcodeService.selectQrcodeUrlByIdAndCode(QrcodeBizTypeEnum.MOLD.getCode(),id,moldDO.getCode());
moldDO.setQrcodeUrl(qrcodeUrl);
return moldDO; return moldDO;
} }
@Override @Override
@ -403,27 +353,6 @@ public class MoldBrandServiceImpl implements MoldBrandService {
return buildMoldBrandTree(allMoldBrands); return buildMoldBrandTree(allMoldBrands);
} }
@Override
public void regenerateCode(Long id, String code) throws UnsupportedEncodingException {
if(moldMapper.selectById(id)==null){
throw exception(MOLD_BRAND_PRODUCT_NOT_EXISTS);
}
if(StringUtils.isBlank(code)){
throw exception(MOLD_CODE_EMPTY);
}
CodeTypeEnum codeGenerate = autoCodeUtil.queryCodeType("MOLD_CODE_GENERATE");
//
qrcodeService.regenerateByCodeType(
QrcodeBizTypeEnum.MOLD,
id,
code,
"DETAIL",
codeGenerate.getCode()
);
}
/** /**
* *
*/ */

@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -31,7 +30,7 @@ public interface ErpProductService {
* @param createReqVO * @param createReqVO
* @return * @return
*/ */
Long createProduct(@Valid ProductSaveReqVO createReqVO) throws UnsupportedEncodingException; Long createProduct(@Valid ProductSaveReqVO createReqVO);
/** /**
* *
@ -61,7 +60,7 @@ public interface ErpProductService {
* @param id * @param id
* @return * @return
*/ */
ErpProductRespVO getProduct(Long id); ErpProductDO getProduct(Long id);
/** /**
* VO * VO
@ -135,6 +134,4 @@ public interface ErpProductService {
* @return * @return
*/ */
ErpProductImportRespVO importProductList(List<ErpProductImportExcelVO> importProducts, boolean isUpdateSupport); ErpProductImportRespVO importProductList(List<ErpProductImportExcelVO> importProducts, boolean isUpdateSupport);
void regenerateCode(Long id, String code) throws UnsupportedEncodingException;
} }

@ -8,29 +8,21 @@ 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.common.util.validation.ValidationUtils; import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductImportExcelVO;
import cn.iocoder.yudao.module.common.enums.CodeTypeEnum; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductImportRespVO;
import cn.iocoder.yudao.module.common.enums.QrcodeBizTypeEnum; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductPageReqVO;
import cn.iocoder.yudao.module.common.service.qrcordrecord.QrcodeRecordService; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductSaveReqVO;
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;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
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.dataobject.productdevicerel.ProductDeviceRelDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.productmoldrel.ProductMoldRelDO;
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.mysql.product.ErpProductCategoryMapper; import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductCategoryMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper; import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.productdevicerel.ProductDeviceRelMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.productmoldrel.ProductMoldRelMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -40,13 +32,11 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.ConstraintViolationException; import javax.validation.ConstraintViolationException;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 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.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@ -59,7 +49,6 @@ import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
*/ */
@Service @Service
@Validated @Validated
@Slf4j
public class ErpProductServiceImpl implements ErpProductService { public class ErpProductServiceImpl implements ErpProductService {
@Resource @Resource
@ -76,50 +65,17 @@ public class ErpProductServiceImpl implements ErpProductService {
@Resource @Resource
private ErpStockMapper erpStockMapper; private ErpStockMapper erpStockMapper;
@Resource
private ProductDeviceRelMapper productDeviceRelMapper;
@Resource
private ProductMoldRelMapper productMoldRelMapper;
@Resource @Resource
@Lazy // 延迟注入 @Lazy // 延迟注入
private ErpStockService erpStockService; private ErpStockService erpStockService;
@Resource
private QrcodeRecordService qrcodeService;
@Autowired
private AutoCodeUtil autoCodeUtil;
@Override @Override
@Transactional(rollbackFor = Exception.class) public Long createProduct(ProductSaveReqVO createReqVO) {
public Long createProduct(ProductSaveReqVO createReqVO) throws UnsupportedEncodingException {
String code = createReqVO.getBarCode();
boolean autoGeneratedCode = StringUtils.isBlank(code);
ErpProductDO product = BeanUtils.toBean(createReqVO, ErpProductDO.class);
if (productMapper.selectProductExist(product)) {
throw exception(PRODUCT_NAME_AND_STANDARD_EXISTS);
}
if (autoGeneratedCode) {
code = autoCodeUtil.genSerialCode("PRODUCT_CODE_GENERATE", null);
} else {
if (productMapper.selectOne(Wrappers.<ErpProductDO>lambdaQuery()
.eq(ErpProductDO::getBarCode, code)) != null) {
throw exception(PRODUCT_CODE_EXISTS);
}
}
// TODO 芋艿:校验分类 // TODO 芋艿:校验分类
// 插入 // 插入
ErpProductDO product = BeanUtils.toBean(createReqVO, ErpProductDO.class);
ErpProductCategoryDO productCategory = productCategoryMapper.selectById(product.getCategoryId()); ErpProductCategoryDO productCategory = productCategoryMapper.selectById(product.getCategoryId());
Long id = productCategory.getParentId(); Long id = productCategory.getParentId();
product.setSubCategoryName(productCategory.getName()); product.setSubCategoryName(productCategory.getName());
@ -129,74 +85,12 @@ public class ErpProductServiceImpl implements ErpProductService {
product.setCategoryId(id); product.setCategoryId(id);
id = productCategory.getParentId(); id = productCategory.getParentId();
} }
// 自动生成才拼接 分类编码-流水号;手工输入则原样保存
if (autoGeneratedCode) {
product.setBarCode(productCategory.getCode() + "-" + code);
} else {
product.setBarCode(code);
}
productMapper.insert(product); productMapper.insert(product);
//插入关联设备
List<Long> deviceIds = createReqVO.getDeviceIds();
if (CollUtil.isNotEmpty(deviceIds)) {
List<Long> distinctIds = deviceIds.stream().distinct().collect(Collectors.toList());
List<ProductDeviceRelDO> relList = distinctIds.stream()
.map(deviceId -> {
ProductDeviceRelDO rel = new ProductDeviceRelDO();
rel.setProductId(product.getId());
rel.setDeviceId(deviceId);
return rel;
})
.collect(Collectors.toList());
productDeviceRelMapper.insertBatch(relList);
}
// 插入关联模具
List<Long> moldIds = createReqVO.getMoldIds();
if (CollUtil.isNotEmpty(moldIds)) {
List<Long> distinctIds = moldIds.stream().distinct().collect(Collectors.toList());
List<ProductMoldRelDO> relList = distinctIds.stream()
.map(moldId -> {
ProductMoldRelDO rel = new ProductMoldRelDO();
rel.setProductId(product.getId());
rel.setMoldId(moldId);
return rel;
})
.collect(Collectors.toList());
productMoldRelMapper.insertBatch(relList);
}
// 生成二维码
CodeTypeEnum codeType = autoCodeUtil.queryCodeType("PRODUCT_CODE_GENERATE");
if (codeType==null){
log.warn("[创建产品物料]未配置码类型跳过生产ruleCode={}","PRODUCT_CODE_GENERATE");
return product.getId();
}
qrcodeService.generateOrRefresh(
QrcodeBizTypeEnum.PRODUCT,
product.getId(),
product.getBarCode(),
"DETAIL",
codeType
);
// 返回 // 返回
return product.getId(); return product.getId();
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public void updateProduct(ProductSaveReqVO updateReqVO) { public void updateProduct(ProductSaveReqVO updateReqVO) {
// TODO 芋艿:校验分类 // TODO 芋艿:校验分类
// 校验存在 // 校验存在
@ -213,49 +107,6 @@ public class ErpProductServiceImpl implements ErpProductService {
id = productCategory.getParentId(); id = productCategory.getParentId();
} }
productMapper.updateById(updateObj); productMapper.updateById(updateObj);
// 先删除旧关联(推荐逻辑删;如果你们没做逻辑删,也可以物理删)
productDeviceRelMapper.delete(Wrappers.<ProductDeviceRelDO>lambdaQuery()
.eq(ProductDeviceRelDO::getProductId,updateObj.getId()));
// 再插入新关联
List<Long> deviceIds = updateReqVO.getDeviceIds();
if (CollUtil.isNotEmpty(deviceIds)) {
List<Long> distinctIds = deviceIds.stream().distinct().collect(Collectors.toList());
List<ProductDeviceRelDO> relList = distinctIds.stream()
.map(deviceId -> {
ProductDeviceRelDO rel = new ProductDeviceRelDO();
rel.setProductId(updateReqVO.getId());
rel.setDeviceId(deviceId);
return rel;
})
.collect(Collectors.toList());
productDeviceRelMapper.insertBatch(relList);
}
// 删除旧模具关联
productMoldRelMapper.delete(Wrappers.<ProductMoldRelDO>lambdaQuery()
.eq(ProductMoldRelDO::getProductId, updateObj.getId()));
// 新增模具关联
List<Long> moldIds = updateReqVO.getMoldIds();
if (CollUtil.isNotEmpty(moldIds)) {
List<Long> distinctIds = moldIds.stream().distinct().collect(Collectors.toList());
List<ProductMoldRelDO> relList = distinctIds.stream()
.map(moldId -> {
ProductMoldRelDO rel = new ProductMoldRelDO();
rel.setProductId(updateReqVO.getId());
rel.setMoldId(moldId);
return rel;
})
.collect(Collectors.toList());
productMoldRelMapper.insertBatch(relList);
}
} }
@Override @Override
@ -302,33 +153,10 @@ public class ErpProductServiceImpl implements ErpProductService {
} }
@Override @Override
public ErpProductRespVO getProduct(Long id) { public ErpProductDO getProduct(Long id) {
ErpProductDO product = productMapper.selectById(id); return productMapper.selectById(id);
if (product == null) {
return null;
}
String qrcodeUrl = qrcodeService.selectQrcodeUrlByIdAndCode(
QrcodeBizTypeEnum.PRODUCT.getCode(), id, product.getBarCode());
product.setQrcodeUrl(qrcodeUrl);
ErpProductRespVO respVO = BeanUtils.toBean(product, ErpProductRespVO.class);
respVO.setDevices(productMapper.selectDevicesByProductId(id));
respVO.setMolds(productMapper.selectMoldsByProductId(id));
//
// respVO.setDeviceIds(respVO.getDevices().stream()
// .map(ProductRelationRespVO::getId)
// .collect(Collectors.toList()));
// respVO.setMoldIds(respVO.getMolds().stream()
// .map(ProductRelationRespVO::getId)
// .collect(Collectors.toList()));
return respVO;
} }
@Override @Override
public List<ErpProductRespVO> getProductVOListByStatus(Integer status,Integer categoryId) { public List<ErpProductRespVO> getProductVOListByStatus(Integer status,Integer categoryId) {
@ -496,26 +324,6 @@ public class ErpProductServiceImpl implements ErpProductService {
return respVO; return respVO;
} }
@Override
public void regenerateCode(Long id, String code) throws UnsupportedEncodingException {
if(productMapper.selectById(id)==null){
throw exception(PRODUCT_NOT_EXISTS);
}
if(StringUtils.isBlank(code)){
throw exception(PRODUCT_CODE_NOT_EXISTS);
}
CodeTypeEnum moldCodeGenerate = autoCodeUtil.queryCodeType("PRODUCT_CODE_GENERATE");
//s
qrcodeService.regenerateByCodeType(
QrcodeBizTypeEnum.PRODUCT,
id,
code,
"DETAIL",
moldCodeGenerate.getCode()
);
}
private ErpProductDO convertToProductDO(ErpProductImportExcelVO importProduct) { private ErpProductDO convertToProductDO(ErpProductImportExcelVO importProduct) {
ErpProductDO productDO = BeanUtils.toBean(importProduct, ErpProductDO.class); ErpProductDO productDO = BeanUtils.toBean(importProduct, ErpProductDO.class);

@ -1,9 +1,7 @@
package cn.iocoder.yudao.module.erp.service.product; package cn.iocoder.yudao.module.erp.service.product;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitImportExcelVO;
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.ErpProductUnitSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
@ -108,6 +106,4 @@ public interface ErpProductUnitService {
* @return * @return
*/ */
ErpProductUnitDO getProductUnitByName(String name); ErpProductUnitDO getProductUnitByName(String name);
void importUnitList(List<ErpProductUnitImportExcelVO> list, Boolean updateSupport);
} }

@ -1,15 +1,9 @@
package cn.iocoder.yudao.module.erp.service.product; package cn.iocoder.yudao.module.erp.service.product;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode; import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
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.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitImportExcelVO;
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.ErpProductUnitSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitSaveReqVO;
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;
@ -18,17 +12,14 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.ConstraintViolationException; import java.util.Collection;
import java.util.*; import java.util.List;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
/** /**
* ERP Service * ERP Service
@ -46,7 +37,6 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService {
@Lazy // 延迟加载,避免循环依赖 @Lazy // 延迟加载,避免循环依赖
private ErpProductService productService; private ErpProductService productService;
@Override @Override
public Long createProductUnit(ErpProductUnitSaveReqVO createReqVO) { public Long createProductUnit(ErpProductUnitSaveReqVO createReqVO) {
// 1. 校验名字唯一 // 1. 校验名字唯一
@ -140,45 +130,10 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService {
public ErpProductUnitDO getProductUnitByName(String name) { public ErpProductUnitDO getProductUnitByName(String name) {
return productUnitMapper.selectByName(name); return productUnitMapper.selectByName(name);
} }
@Override @Override
public List<ErpProductUnitDO> getProductUnitListByFlag() { public List<ErpProductUnitDO> getProductUnitListByFlag() {
QueryWrapper<ErpProductUnitDO> wrapper = new QueryWrapper<>(); QueryWrapper<ErpProductUnitDO> wrapper = new QueryWrapper<>();
wrapper.eq("primary_flag", "Y"); wrapper.eq("primary_flag", "Y");
return productUnitMapper.selectList(wrapper); return productUnitMapper.selectList(wrapper);
} }
@Override
@Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
public void importUnitList(List<ErpProductUnitImportExcelVO> list, Boolean updateSupport) {
// 1.1 参数校验
if (CollUtil.isEmpty(list)) {
throw exception(IMPORT_LIST_IS_EMPTY);
}
// 1.2 查询主单位数据
QueryWrapper<ErpProductUnitDO> wrapper = new QueryWrapper<>();
wrapper.eq("primary_flag", "Y");
List<ErpProductUnitDO> erpProductUnitDOS = productUnitMapper.selectList(wrapper);
Map<String, List<ErpProductUnitDO>> map = erpProductUnitDOS.stream().filter(Objects::nonNull)
.collect(Collectors.groupingBy(
ErpProductUnitDO::getName,
Collectors.toList()
));
List<ErpProductUnitDO> erpProductUnitDOs = new ArrayList<>();
list.stream().forEach(importUser -> {
if(importUser.getPrimaryName()!=null){
List<ErpProductUnitDO> erpProductUnitDOS1 = map.get(importUser.getPrimaryName());
if (CollUtil.isEmpty(erpProductUnitDOS1)) {
importUser.setPrimaryId(null);
} else {
importUser.setPrimaryId(erpProductUnitDOS1.get(0).getId());
}
}
ErpProductUnitDO erpProductUnitDO = BeanUtils.toBean(importUser, ErpProductUnitDO.class);
erpProductUnitDOs.add(erpProductUnitDO);
});
CollUtil.isNotEmpty(erpProductUnitDOs);productUnitMapper.insertBatch(erpProductUnitDOs);
}
} }

@ -1,57 +0,0 @@
package cn.iocoder.yudao.module.erp.service.productdevicerel;
import java.util.*;
import cn.iocoder.yudao.module.erp.controller.admin.productdevicerel.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.productdevicerel.ProductDeviceRelDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import javax.validation.Valid;
/**
* - Service
*
* @author
*/
public interface ProductDeviceRelService {
/**
* -
*
* @param createReqVO
* @return
*/
Long createProductDeviceRel(@Valid ProductDeviceRelSaveReqVO createReqVO);
/**
* -
*
* @param updateReqVO
*/
void updateProductDeviceRel(@Valid ProductDeviceRelSaveReqVO updateReqVO);
/**
* -
*
* @param id
*/
void deleteProductDeviceRel(Long id);
/**
* -
*
* @param id
* @return -
*/
ProductDeviceRelDO getProductDeviceRel(Long id);
/**
* -
*
* @param pageReqVO
* @return -
*/
PageResult<ProductDeviceRelDO> getProductDeviceRelPage(ProductDeviceRelPageReqVO pageReqVO);
}

@ -1,75 +0,0 @@
package cn.iocoder.yudao.module.erp.service.productdevicerel;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.module.erp.controller.admin.productdevicerel.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.productdevicerel.ProductDeviceRelDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.dal.mysql.productdevicerel.ProductDeviceRelMapper;
import javax.annotation.Resource;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
/**
* - Service
*
* @author
*/
@Service
@Validated
public class ProductDeviceRelServiceImpl implements ProductDeviceRelService {
@Resource
private ProductDeviceRelMapper productDeviceRelMapper;
@Override
public Long createProductDeviceRel(ProductDeviceRelSaveReqVO createReqVO) {
// 插入
ProductDeviceRelDO productDeviceRel = BeanUtils.toBean(createReqVO, ProductDeviceRelDO.class);
productDeviceRelMapper.insert(productDeviceRel);
// 返回
return productDeviceRel.getId();
}
@Override
public void updateProductDeviceRel(ProductDeviceRelSaveReqVO updateReqVO) {
// 校验存在
validateProductDeviceRelExists(updateReqVO.getId());
// 更新
ProductDeviceRelDO updateObj = BeanUtils.toBean(updateReqVO, ProductDeviceRelDO.class);
productDeviceRelMapper.updateById(updateObj);
}
@Override
public void deleteProductDeviceRel(Long id) {
// 校验存在
validateProductDeviceRelExists(id);
// 删除
productDeviceRelMapper.deleteById(id);
}
private void validateProductDeviceRelExists(Long id) {
if (productDeviceRelMapper.selectById(id) == null) {
throw exception(PRODUCT_DEVICE_REL_NOT_EXISTS);
}
}
@Override
public ProductDeviceRelDO getProductDeviceRel(Long id) {
return productDeviceRelMapper.selectById(id);
}
@Override
public PageResult<ProductDeviceRelDO> getProductDeviceRelPage(ProductDeviceRelPageReqVO pageReqVO) {
return productDeviceRelMapper.selectPage(pageReqVO);
}
}

@ -1,55 +0,0 @@
package cn.iocoder.yudao.module.erp.service.productmoldrel;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.erp.controller.admin.productmoldrel.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.productmoldrel.ProductMoldRelDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
/**
* - Service
*
* @author
*/
public interface ProductMoldRelService {
/**
* -
*
* @param createReqVO
* @return
*/
Long createProductMoldRel(@Valid ProductMoldRelSaveReqVO createReqVO);
/**
* -
*
* @param updateReqVO
*/
void updateProductMoldRel(@Valid ProductMoldRelSaveReqVO updateReqVO);
/**
* -
*
* @param id
*/
void deleteProductMoldRel(Long id);
/**
* -
*
* @param id
* @return -
*/
ProductMoldRelDO getProductMoldRel(Long id);
/**
* -
*
* @param pageReqVO
* @return -
*/
PageResult<ProductMoldRelDO> getProductMoldRelPage(ProductMoldRelPageReqVO pageReqVO);
}

@ -1,74 +0,0 @@
package cn.iocoder.yudao.module.erp.service.productmoldrel;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.module.erp.controller.admin.productmoldrel.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.productmoldrel.ProductMoldRelDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.dal.mysql.productmoldrel.ProductMoldRelMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
/**
* - Service
*
* @author
*/
@Service
@Validated
public class ProductMoldRelServiceImpl implements ProductMoldRelService {
@Resource
private ProductMoldRelMapper productMoldRelMapper;
@Override
public Long createProductMoldRel(ProductMoldRelSaveReqVO createReqVO) {
// 插入
ProductMoldRelDO productMoldRel = BeanUtils.toBean(createReqVO, ProductMoldRelDO.class);
productMoldRelMapper.insert(productMoldRel);
// 返回
return productMoldRel.getId();
}
@Override
public void updateProductMoldRel(ProductMoldRelSaveReqVO updateReqVO) {
// 校验存在
validateProductMoldRelExists(updateReqVO.getId());
// 更新
ProductMoldRelDO updateObj = BeanUtils.toBean(updateReqVO, ProductMoldRelDO.class);
productMoldRelMapper.updateById(updateObj);
}
@Override
public void deleteProductMoldRel(Long id) {
// 校验存在
validateProductMoldRelExists(id);
// 删除
productMoldRelMapper.deleteById(id);
}
private void validateProductMoldRelExists(Long id) {
if (productMoldRelMapper.selectById(id) == null) {
throw exception(PRODUCT_MOLD_REL_NOT_EXISTS);
}
}
@Override
public ProductMoldRelDO getProductMoldRel(Long id) {
return productMoldRelMapper.selectById(id);
}
@Override
public PageResult<ProductMoldRelDO> getProductMoldRelPage(ProductMoldRelPageReqVO pageReqVO) {
return productMoldRelMapper.selectPage(pageReqVO);
}
}

@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.common.controller.admin.mold.vo.MoldSaveReqVO; import cn.iocoder.yudao.module.common.controller.admin.mold.vo.MoldSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
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.ErpStockOutSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVO;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO; import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO;
@ -152,9 +151,9 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
ErpStockRecordBizTypeEnum.OTHER_OUT.getType(), stockOutItem.getOutId(), stockOutItem.getId(), stockOut.getNo(),stockOut.getOutTime())); ErpStockRecordBizTypeEnum.OTHER_OUT.getType(), stockOutItem.getOutId(), stockOutItem.getId(), stockOut.getNo(),stockOut.getOutTime()));
} else { } else {
ErpProductRespVO product = productService.getProduct(stockOutItem.getProductId()); ErpProductDO productDO = productService.getProduct(stockOutItem.getProductId());
stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO( stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
stockOutItem.getProductId(),product.getCategoryId(), stockOutItem.getWarehouseId(), count, stockOutItem.getProductId(),productDO.getCategoryId(), stockOutItem.getWarehouseId(), count,
ErpStockRecordBizTypeEnum.getTypeByName(stockOut.getOutType(),status), stockOutItem.getOutId(), stockOutItem.getId(), stockOut.getNo(),stockOut.getOutTime())); ErpStockRecordBizTypeEnum.getTypeByName(stockOut.getOutType(),status), stockOutItem.getOutId(), stockOutItem.getId(), stockOut.getNo(),stockOut.getOutTime()));
} }

@ -1,42 +0,0 @@
<?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.erp.dal.mysql.product.ErpProductMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
<select id="selectDevicesByProductId"
resultType="cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductRelationRespVO">
SELECT DISTINCT
rel.device_id AS id,
CASE
WHEN d.id IS NULL THEN CONCAT('设备[', rel.device_id, ']【已删除】')
WHEN d.deleted = b'1' THEN CONCAT(d.device_name, '(', d.device_code, ')【已删除】')
ELSE CONCAT(d.device_name, '(', d.device_code, ')')
END AS name
FROM erp_product_device_rel rel
LEFT JOIN mes_device_ledger d ON rel.device_id = d.id
WHERE rel.product_id = #{productId}
AND rel.deleted = b'0'
</select>
<select id="selectMoldsByProductId"
resultType="cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductRelationRespVO">
SELECT DISTINCT
rel.mold_id AS id,
CASE
WHEN m.id IS NULL THEN CONCAT('模具[', rel.mold_id, ']【已删除】')
WHEN m.deleted = b'1' THEN CONCAT(m.name, '(', m.code, ')【已删除】')
ELSE CONCAT(m.name, '(', m.code, ')')
END AS name
FROM erp_product_mold_rel rel
LEFT JOIN erp_mold m ON rel.mold_id = m.id
WHERE rel.product_id = #{productId}
AND rel.deleted = b'0'
</select>
</mapper>

@ -1,12 +0,0 @@
<?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.erp.dal.mysql.productdevicerel.ProductDeviceRelMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>

@ -1,12 +0,0 @@
<?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.erp.dal.mysql.productmoldrel.ProductMoldRelMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>

@ -40,7 +40,4 @@ public interface FileApi {
*/ */
Map<String,String> createFile(String name, String path, byte[] content); Map<String,String> createFile(String name, String path, byte[] content);
Long getFileByPath(String path);
void deleteFile(Long id) throws Exception;
} }

@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.infra.api.file; package cn.iocoder.yudao.module.infra.api.file;
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import cn.iocoder.yudao.module.infra.service.file.FileService; import cn.iocoder.yudao.module.infra.service.file.FileService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -25,13 +24,4 @@ public class FileApiImpl implements FileApi {
return fileService.createFile(name, path, content); return fileService.createFile(name, path, content);
} }
@Override
public Long getFileByPath(String path) {
return fileService.getFileByPath(path).getId();
}
@Override
public void deleteFile(Long id) throws Exception {
fileService.deleteFile(id);
}
} }

@ -23,7 +23,6 @@ public class SecurityConfiguration {
@Override @Override
public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) { public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
// Swagger 接口文档 // Swagger 接口文档
String aa="";
registry.requestMatchers("/v3/api-docs/**").permitAll() registry.requestMatchers("/v3/api-docs/**").permitAll()
.requestMatchers("/webjars/**").permitAll() .requestMatchers("/webjars/**").permitAll()
.requestMatchers("/swagger-ui.html").permitAll() .requestMatchers("/swagger-ui.html").permitAll()
@ -38,40 +37,6 @@ public class SecurityConfiguration {
.requestMatchers(adminSeverContextPath + "/**").permitAll(); .requestMatchers(adminSeverContextPath + "/**").permitAll();
// 文件读取 // 文件读取
registry.requestMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll(); registry.requestMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll();
//大屏跳转
registry.requestMatchers(buildAdminApi("/mes/plan/getProductPlans")).permitAll();
registry.requestMatchers(buildAdminApi("/mes/plan/getPlanCapacity")).permitAll();
registry.requestMatchers(buildAdminApi("/mes/plan/getWeekTrend")).permitAll();
registry.requestMatchers(buildAdminApi("/mes/plan/getLastSevenDaysCompletedCount")).permitAll();
registry.requestMatchers(buildAdminApi("/iot/device-operation-record/deviceOperationList")).permitAll();
registry.requestMatchers(buildAdminApi("/mes/plan/getLastDaysRate")).permitAll();
registry.requestMatchers(buildAdminApi("/mes/energy-type/list")).permitAll();
registry.requestMatchers(buildAdminApi("/mes/energy-device/latestSevenDaysStatistics")).permitAll();
registry.requestMatchers(buildAdminApi("/iot/device/getDeviceOperationalStatus")).permitAll();
registry.requestMatchers(buildAdminApi("/iot/device-warinning-record/getLastSevenHoursCount")).permitAll();
registry.requestMatchers(buildAdminApi("/mes/dashboard/getTaskStatistics")).permitAll();
registry.requestMatchers(buildAdminApi("/mes/dashboard/getAllTaskList")).permitAll();
registry.requestMatchers(buildAdminApi("/iot/device/device-attribute/batchList")).permitAll();
registry.requestMatchers(buildAdminApi("/mes/energy-device/lastEnergyStatistics")).permitAll();
registry.requestMatchers(buildAdminApi("/iot/device-warinning-record/getList")).permitAll();
} }
}; };

@ -65,7 +65,4 @@ public interface FileService {
*/ */
FilePresignedUrlRespVO getFilePresignedUrl(String path) throws Exception; FilePresignedUrlRespVO getFilePresignedUrl(String path) throws Exception;
FileDO getFileByPath(String path);
} }

@ -13,7 +13,6 @@ import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePresignedUrlRespVO; import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePresignedUrlRespVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO; import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper; import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -122,16 +121,4 @@ public class FileServiceImpl implements FileService {
object -> object.setConfigId(fileClient.getId())); object -> object.setConfigId(fileClient.getId()));
} }
@Override
public FileDO getFileByPath(String path) {
if (StrUtil.isBlank(path)) {
return null;
}
return fileMapper.selectOne(
Wrappers.<FileDO>lambdaQuery()
.eq(FileDO::getPath, path)
.orderByDesc(FileDO::getId)
.last("limit 1")
); }
} }

@ -84,7 +84,6 @@ public interface ErrorCodeConstants {
ErrorCode TABLE_CREATION_FAILED = new ErrorCode(1_004_000_008, "TDengine 表创建失败"); ErrorCode TABLE_CREATION_FAILED = new ErrorCode(1_004_000_008, "TDengine 表创建失败");
ErrorCode COLOUMN_CREATION_FAILED = new ErrorCode(1_004_000_008, "TDengine 列创建失败"); ErrorCode COLOUMN_CREATION_FAILED = new ErrorCode(1_004_000_008, "TDengine 列创建失败");
ErrorCode COLUMN_RENAME_FAILED = new ErrorCode(1_004_000_008, "列名修改失败");
} }

@ -323,7 +323,7 @@ public class DeviceController {
@GetMapping("/device-attribute/batchList") @GetMapping("/device-attribute/batchList")
@Operation(summary = "获得多个设备的属性数据") @Operation(summary = "获得多个设备的属性数据")
@Parameter(name = "goviewId", description = "大屏ID", required = true) @Parameter(name = "goviewId", description = "大屏ID", required = true)
//@PreAuthorize("@ss.hasPermission('iot:device:query')") @PreAuthorize("@ss.hasPermission('iot:device:query')")
public CommonResult<List<Map<String, Object>>> getMultiDeviceAttributes(@RequestParam("goviewId") Long goviewId) { public CommonResult<List<Map<String, Object>>> getMultiDeviceAttributes(@RequestParam("goviewId") Long goviewId) {
return success(deviceService.getMultiDeviceAttributes(goviewId)); return success(deviceService.getMultiDeviceAttributes(goviewId));
} }

@ -53,7 +53,7 @@ public class DeviceSaveReqVO {
private Boolean isEnable; private Boolean isEnable;
@Schema(description = "关联设备模型", example = "1") @Schema(description = "关联设备模型", example = "1")
// @NotNull(message = "关联设备模型ID不能为空") @NotNull(message = "关联设备模型ID不能为空")
private Long deviceModelId; private Long deviceModelId;
@Schema(description = "通讯协议", example = "OPCUA") @Schema(description = "通讯协议", example = "OPCUA")

@ -26,15 +26,15 @@ public class DeviceModelAttributeRespVO {
private String attributeName; private String attributeName;
@Schema(description = "采集点位类型编码", example = "1") @Schema(description = "采集点位类型编码", example = "1")
@ExcelProperty("点位类型编码") @ExcelProperty("采集点位类型编码")
private String attributeTypeCode; private String attributeTypeCode;
@Schema(description = "点位类型", example = "1") @Schema(description = "点位类型", example = "1")
// @ExcelProperty("点位类型") @ExcelProperty("点位类型")
private String attributeType; private String attributeType;
@Schema(description = "类型名称", example = "1") @Schema(description = "类型名称", example = "1")
// @ExcelProperty("类型名称") @ExcelProperty("类型名称")
private String typeName; private String typeName;
@Schema(description = "数据类型", example = "2") @Schema(description = "数据类型", example = "2")
@ -61,11 +61,11 @@ public class DeviceModelAttributeRespVO {
private String remark; private String remark;
@Schema(description = "采集设备模型id", requiredMode = Schema.RequiredMode.REQUIRED, example = "16848") @Schema(description = "采集设备模型id", requiredMode = Schema.RequiredMode.REQUIRED, example = "16848")
// @ExcelProperty("采集设备模型id") @ExcelProperty("采集设备模型id")
private Long deviceModelId; private Long deviceModelId;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
// @ExcelProperty("创建时间") @ExcelProperty("创建时间")
@ColumnWidth(20) // 设置此列的宽度为 20 个字符的宽度 @ColumnWidth(20) // 设置此列的宽度为 20 个字符的宽度
private LocalDateTime createTime; private LocalDateTime createTime;

@ -106,7 +106,7 @@ public class DeviceOperationRecordController {
@GetMapping("/deviceOperationList") @GetMapping("/deviceOperationList")
@Operation(summary = "产线设备运行开机率/稼动率-大屏") @Operation(summary = "产线设备运行开机率/稼动率-大屏")
// @PreAuthorize("@ss.hasPermission('iot:device-operation-record:query')") @PreAuthorize("@ss.hasPermission('iot:device-operation-record:query')")
public CommonResult<List<DeviceTotalTimeRecordRespVO>> deviceOperationList(@Valid DeviceTotalTimeRecordReqVO pageReqVO) { public CommonResult<List<DeviceTotalTimeRecordRespVO>> deviceOperationList(@Valid DeviceTotalTimeRecordReqVO pageReqVO) {
List<DeviceTotalTimeRecordRespVO> deviceTotalTimeRecordRespVOList = deviceOperationRecordService.deviceOperationList(pageReqVO); List<DeviceTotalTimeRecordRespVO> deviceTotalTimeRecordRespVOList = deviceOperationRecordService.deviceOperationList(pageReqVO);
return success(deviceTotalTimeRecordRespVOList); return success(deviceTotalTimeRecordRespVOList);

@ -80,30 +80,13 @@ public class DevicePointRulesController {
public CommonResult<PageResult<DevicePointRulesRespVO>> getDevicePointRulesPage(@Valid DevicePointRulesPageReqVO pageReqVO) { public CommonResult<PageResult<DevicePointRulesRespVO>> getDevicePointRulesPage(@Valid DevicePointRulesPageReqVO pageReqVO) {
PageResult<DevicePointRulesDO> pageResult = devicePointRulesService.getDevicePointRulesPage(pageReqVO); PageResult<DevicePointRulesDO> pageResult = devicePointRulesService.getDevicePointRulesPage(pageReqVO);
PageResult<DevicePointRulesRespVO> rulesRespVOPageResult = BeanUtils.toBean(pageResult, DevicePointRulesRespVO.class); PageResult<DevicePointRulesRespVO> rulesRespVOPageResult = BeanUtils.toBean(pageResult, DevicePointRulesRespVO.class);
// for (DevicePointRulesRespVO devicePointRulesRespVO : rulesRespVOPageResult.getList()) {
// for (DevicePointRulesRespVO respVO : rulesRespVOPageResult.getList()) { if (StringUtils.isNotBlank(devicePointRulesRespVO.getFieldRule())) {
// String fieldRule = respVO.getFieldRule(); List<PointRulesRespVO> pointRulesVOList = JSON.parseArray(devicePointRulesRespVO.getFieldRule(), PointRulesRespVO.class);
// if (StringUtils.isBlank(fieldRule)) { devicePointRulesRespVO.setPointRulesVOList(pointRulesVOList);
// continue; }
// }
// }
// String json = fieldRule.trim();
// try {
// if (json.startsWith("[")) {
// List<PointRulesRespVO> pointRulesVOList = JSON.parseArray(json, PointRulesRespVO.class);
// respVO.setPointRulesVOList(pointRulesVOList);
// continue;
// }
//
// if (json.startsWith("{")) {
// respVO.setPointRulesVOList(Collections.emptyList());
//
// }
// } catch (Exception e) {
// // 防御性处理,避免单条脏数据影响整页
// respVO.setPointRulesVOList(Collections.emptyList());
// }
// }
return success(rulesRespVOPageResult); return success(rulesRespVOPageResult);
} }

@ -97,7 +97,7 @@ public class DeviceWarinningRecordController {
@Operation(summary = "获得告警记录列表") @Operation(summary = "获得告警记录列表")
@Parameter(name = "deviceId", description = "设备Id", required = true, example = "1024") @Parameter(name = "deviceId", description = "设备Id", required = true, example = "1024")
@Parameter(name = "orgId", description = "产线组织Id", required = true, example = "1024") @Parameter(name = "orgId", description = "产线组织Id", required = true, example = "1024")
//@PreAuthorize("@ss.hasPermission('iot:device-warinning-record:query')") @PreAuthorize("@ss.hasPermission('iot:device-warinning-record:query')")
public CommonResult<List<DeviceWarinningRecordDO>> getList(@RequestParam(name = "deviceId" ,required = false) Long id, public CommonResult<List<DeviceWarinningRecordDO>> getList(@RequestParam(name = "deviceId" ,required = false) Long id,
@RequestParam(name = "orgId" ,required = false) Long orgId) { @RequestParam(name = "orgId" ,required = false) Long orgId) {
List<DeviceWarinningRecordDO> deviceWarinningRecord = deviceWarinningRecordService.getList(id); List<DeviceWarinningRecordDO> deviceWarinningRecord = deviceWarinningRecordService.getList(id);
@ -108,7 +108,7 @@ public class DeviceWarinningRecordController {
@GetMapping("/getLastSevenHoursCount") @GetMapping("/getLastSevenHoursCount")
@Operation(summary = "获取过去7小时每小时告警数量") @Operation(summary = "获取过去7小时每小时告警数量")
@Parameter(name = "orgId", description = "产线组织Id", required = true, example = "1024") @Parameter(name = "orgId", description = "产线组织Id", required = true, example = "1024")
//@PreAuthorize("@ss.hasPermission('iot:device-warinning-record:query')") @PreAuthorize("@ss.hasPermission('iot:device-warinning-record:query')")
public CommonResult<List<Map<String, Object>>> getLastSevenHoursCount( @RequestParam(name = "orgId" ,required = false) Long orgId) { public CommonResult<List<Map<String, Object>>> getLastSevenHoursCount( @RequestParam(name = "orgId" ,required = false) Long orgId) {
List<Map<String, Object>> hourCounts = deviceWarinningRecordService.getLastSevenHoursCount(); List<Map<String, Object>> hourCounts = deviceWarinningRecordService.getLastSevenHoursCount();
return success(hourCounts); return success(hourCounts);

@ -19,7 +19,7 @@ public interface DevicePointRulesMapper extends BaseMapperX<DevicePointRulesDO>
default PageResult<DevicePointRulesDO> selectPage(DevicePointRulesPageReqVO reqVO) { default PageResult<DevicePointRulesDO> selectPage(DevicePointRulesPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<DevicePointRulesDO>() return selectPage(reqVO, new LambdaQueryWrapperX<DevicePointRulesDO>()
.likeIfPresent(DevicePointRulesDO::getIdentifier, reqVO.getIdentifier()) .eqIfPresent(DevicePointRulesDO::getIdentifier, reqVO.getIdentifier())
.likeIfPresent(DevicePointRulesDO::getFieldName, reqVO.getFieldName()) .likeIfPresent(DevicePointRulesDO::getFieldName, reqVO.getFieldName())
.eqIfPresent(DevicePointRulesDO::getFieldRule, reqVO.getFieldRule()) .eqIfPresent(DevicePointRulesDO::getFieldRule, reqVO.getFieldRule())
.eqIfPresent(DevicePointRulesDO::getDefaultValue, reqVO.getDefaultValue()) .eqIfPresent(DevicePointRulesDO::getDefaultValue, reqVO.getDefaultValue())

@ -24,14 +24,11 @@ import cn.iocoder.yudao.module.iot.framework.mqtt.consumer.impl.AsyncService;
import cn.iocoder.yudao.module.iot.framework.mqtt.entity.MqttData; import cn.iocoder.yudao.module.iot.framework.mqtt.entity.MqttData;
import cn.iocoder.yudao.module.iot.framework.mqtt.utils.DateUtils; import cn.iocoder.yudao.module.iot.framework.mqtt.utils.DateUtils;
import cn.iocoder.yudao.module.iot.framework.mqtt.utils.MqttDataUtils; import cn.iocoder.yudao.module.iot.framework.mqtt.utils.MqttDataUtils;
import cn.iocoder.yudao.module.iot.framework.util.FormulaEvalUtils;
import cn.iocoder.yudao.module.iot.service.device.DeviceService; import cn.iocoder.yudao.module.iot.service.device.DeviceService;
import cn.iocoder.yudao.module.iot.service.device.TDengineService; import cn.iocoder.yudao.module.iot.service.device.TDengineService;
import cn.iocoder.yudao.module.iot.service.iotorganization.IotOrganizationService; import cn.iocoder.yudao.module.iot.service.iotorganization.IotOrganizationService;
import cn.iocoder.yudao.module.iot.service.mqttrecord.MqttRecordService; import cn.iocoder.yudao.module.iot.service.mqttrecord.MqttRecordService;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -45,7 +42,6 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -305,55 +301,21 @@ public class MqttDataHandler extends SuperConsumer<String> {
// 3. 入库 // 3. 入库
if (!validDataList.isEmpty()) { if (!validDataList.isEmpty()) {
saveToDatabase(deviceId, validDataList, successCount);
} else {
log.warn("设备 {} 未匹配到 MQTT 数据", deviceId);
}
// 4. 计算并写入产能
try {
handleCapacityFormula(device, varListMap);
} catch (Exception e) {
log.error("设备 {} 产能计算失败", deviceId, e);
}
}
// handleCapacityFormula
private void handleCapacityFormula(DeviceDO device, Map<String, Object> varListMap) {
DevicePointRulesDO formulaRule = devicePointRulesMapper.selectOne(
Wrappers.<DevicePointRulesDO>lambdaQuery()
.eq(DevicePointRulesDO::getDeviceId, device.getId())
.eq(DevicePointRulesDO::getIdentifier, "COUNT")
.orderByDesc(DevicePointRulesDO::getUpdateTime)
.last("limit 1")
);
if (formulaRule == null || StringUtils.isBlank(formulaRule.getFieldRule())) {
return;
}
BigDecimal capacity = null; saveToDatabase(
String rule = formulaRule.getFieldRule().trim(); deviceId,
validDataList,
successCount
);
if (rule.startsWith("[")) {
JSONArray steps = JSON.parseArray(rule);
capacity = FormulaEvalUtils.evalStepArrayByCode(steps, varListMap);
} else { } else {
// 如需兼容旧 expr 结构可保留
JSONObject root = JSON.parseObject(rule);
JSONObject expr = root.getJSONObject("expr");
if (expr != null) {
capacity = FormulaEvalUtils.evalExpr(expr, varListMap);
}
}
if (capacity == null) { log.warn("设备 {} 未匹配到 MQTT 数据", deviceId);
return;
} }
tDengineService.insertDeviceCapacityRecord(device.getId(), capacity.doubleValue());
} }
private DevicePointRulesDO getDevicePointRules(Long deviceId) { private DevicePointRulesDO getDevicePointRules(Long deviceId) {
List<DevicePointRulesDO> list = List<DevicePointRulesDO> list =

@ -1,96 +0,0 @@
package cn.iocoder.yudao.module.iot.framework.util;
// FormulaEvalUtils
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;
public class FormulaEvalUtils {
private FormulaEvalUtils() {}
public static BigDecimal evalExpr(JSONObject node, Map<String, Object> vars) {
if (node == null) return BigDecimal.ZERO;
if (node.containsKey("field")) {
Object value = vars.get(node.getString("field"));
return toBigDecimal(value);
}
if (node.containsKey("value")) {
return toBigDecimal(node.get("value"));
}
String op = node.getString("op");
BigDecimal left = evalExpr(node.getJSONObject("left"), vars);
BigDecimal right = evalExpr(node.getJSONObject("right"), vars);
return apply(left, right, op);
}
//
public static BigDecimal evalStepArrayByCode(JSONArray steps, Map<String, Object> vars) {
if (steps == null || steps.isEmpty()) {
return BigDecimal.ZERO;
}
BigDecimal result = null;
String pendingBigOp = null; // 上一步的 bigOperator
for (int i = 0; i < steps.size(); i++) {
JSONObject step = steps.getJSONObject(i);
if (step == null) continue;
String code = step.getString("code");
String operator = step.getString("operator");
Object valueObj = step.get("value");
BigDecimal codeValue = readCodeValue(code, vars);
BigDecimal value = toBigDecimal(valueObj);
BigDecimal current = apply(codeValue, value, operator); // A/B/C
if (result == null) {
result = current;
} else {
result = apply(result, current, pendingBigOp); // 用上一项的 bigOperator
}
pendingBigOp = step.getString("bigOperator"); // 留给下一轮使用
}
return result == null ? BigDecimal.ZERO : result;
}
private static BigDecimal readCodeValue(String code, Map<String, Object> vars) {
if (StringUtils.isBlank(code) || vars == null) {
return BigDecimal.ZERO;
}
return toBigDecimal(vars.get(code));
}
private static BigDecimal toBigDecimal(Object raw) {
if (raw == null || StringUtils.isBlank(String.valueOf(raw))) {
return BigDecimal.ZERO;
}
return new BigDecimal(String.valueOf(raw));
}
private static BigDecimal apply(BigDecimal left, BigDecimal right, String op) {
if (StringUtils.isBlank(op)) {
return left;
}
switch (op) {
case "+": return left.add(right);
case "-": return left.subtract(right);
case "*": return left.multiply(right);
case "/":
if (right.compareTo(BigDecimal.ZERO) == 0) return BigDecimal.ZERO;
return left.divide(right, 6, RoundingMode.HALF_UP);
default: throw new IllegalArgumentException("Unsupported op: " + op);
}
}
}

@ -1,7 +1,6 @@
package cn.iocoder.yudao.module.iot.service.device; package cn.iocoder.yudao.module.iot.service.device;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.DeviceConnectionStatusEnum; import cn.iocoder.yudao.framework.common.enums.DeviceConnectionStatusEnum;
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;
@ -145,9 +144,6 @@ public class DeviceServiceImpl implements DeviceService {
throw exception(DEVICE_CODE_ALREADY_EXISTS); throw exception(DEVICE_CODE_ALREADY_EXISTS);
} }
if (StrUtil.isNotBlank(createReqVO.getDeviceCode())) {
tdengineService.validateTableName(createReqVO.getDeviceCode());
}
DeviceModelDO deviceModelDO = deviceModelMapper.selectById(createReqVO.getDeviceModelId()); DeviceModelDO deviceModelDO = deviceModelMapper.selectById(createReqVO.getDeviceModelId());
@ -156,46 +152,38 @@ public class DeviceServiceImpl implements DeviceService {
device.setProtocol(deviceModelDO != null ? deviceModelDO.getProtocol() : ""); device.setProtocol(deviceModelDO != null ? deviceModelDO.getProtocol() : "");
//租户ID //租户ID
device.setTenantId("1"); device.setTenantId("1");
device.setProtocol(StringUtils.isBlank(device.getProtocol()) || device.getProtocol() == null ? "MQTT":device.getProtocol());
deviceMapper.insert(device); deviceMapper.insert(device);
//新增点位规则模板
insertTemplatePoint(createReqVO, device);
return device;
}
private void insertTemplatePoint(DeviceSaveReqVO createReqVO, DeviceDO device) {
//新增模板点位 //新增模板点位
LambdaQueryWrapper<DeviceModelAttributeDO> lambdaQueryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<DeviceModelAttributeDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(DeviceModelAttributeDO::getDeviceModelId, createReqVO.getDeviceModelId()).orderByDesc(DeviceModelAttributeDO::getId); lambdaQueryWrapper.eq(DeviceModelAttributeDO::getDeviceModelId,createReqVO.getDeviceModelId()).orderByDesc(DeviceModelAttributeDO::getId);
List<DeviceModelAttributeDO> deviceModelAttributeDOS = deviceModelAttributeMapper.selectList(lambdaQueryWrapper); List<DeviceModelAttributeDO> deviceModelAttributeDOS = deviceModelAttributeMapper.selectList(lambdaQueryWrapper);
List<DeviceContactModelDO> contactModelList = new ArrayList<>(); if (deviceModelAttributeDOS.isEmpty()){
if (!deviceModelAttributeDOS.isEmpty()) { throw exception(DEVICE_MODEL_ATTRIBUTE_NOT_EXISTS);
for (DeviceModelAttributeDO attributeDO : deviceModelAttributeDOS) {
DeviceContactModelDO contactModel = new DeviceContactModelDO();
BeanUtils.copyProperties(attributeDO, contactModel);
contactModel.setId(null);
contactModel.setDeviceId(device.getId());
contactModel.setCreateTime(LocalDateTime.now());
contactModel.setUpdateTime(LocalDateTime.now());
contactModelList.add(contactModel);
}
deviceContactModelMapper.insertBatch(contactModelList);
} }
List<DeviceContactModelDO> contactModelList = new ArrayList<>();
for (DeviceModelAttributeDO attributeDO : deviceModelAttributeDOS) {
DeviceContactModelDO contactModel = new DeviceContactModelDO();
BeanUtils.copyProperties(attributeDO, contactModel);
contactModel.setId(null);
contactModel.setDeviceId(device.getId());
contactModel.setCreateTime(LocalDateTime.now());
contactModel.setUpdateTime(LocalDateTime.now());
contactModelList.add(contactModel);
}
deviceContactModelMapper.insertBatch(contactModelList);
//创建时序数据库 //创建时序数据库
// createTDengine(device.getId()); // createTDengine(device.getId());
//新增规则点位 //新增规则点位
addNewRulePoints(createReqVO.getDeviceModelId(), device.getId()); addNewRulePoints(createReqVO.getDeviceModelId(),device.getId());
tdengineService.createTdengineTable(device.getId(), contactModelList); tdengineService.createTdengineTable(device.getId(),contactModelList);
return device;
} }
private void addNewRulePoints(Long deviceModelId,Long deviceId) { private void addNewRulePoints(Long deviceModelId,Long deviceId) {
@ -203,13 +191,6 @@ public class DeviceServiceImpl implements DeviceService {
List<DevicePointRulesDO> devicePointRulesDOList = new ArrayList<>(); List<DevicePointRulesDO> devicePointRulesDOList = new ArrayList<>();
DeviceModelDO deviceModelDO = deviceModelMapper.selectById(deviceModelId); DeviceModelDO deviceModelDO = deviceModelMapper.selectById(deviceModelId);
if(deviceModelDO == null){ if(deviceModelDO == null){
DevicePointRulesDO devicePointRulesDO = new DevicePointRulesDO();
devicePointRulesDO.setIdentifier("RUNNING");
devicePointRulesDO.setFieldName("运行");
devicePointRulesDO.setDefaultValue("运行");
devicePointRulesDO.setDeviceId(deviceId);
devicePointRulesDOList.add(devicePointRulesDO);
devicePointRulesMapper.insert(devicePointRulesDO);
return; return;
} }
List<DeviceModelRulesDO> deviceModelRulesDOList = deviceModelRulesMapper.selectList(Wrappers.<DeviceModelRulesDO>lambdaQuery() List<DeviceModelRulesDO> deviceModelRulesDOList = deviceModelRulesMapper.selectList(Wrappers.<DeviceModelRulesDO>lambdaQuery()

@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.iot.service.device; package cn.iocoder.yudao.module.iot.service.device;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.DeviceEdgeData; import cn.iocoder.yudao.framework.common.pojo.DeviceEdgeData;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.JavaToTdengineTypeEnum; import cn.iocoder.yudao.module.iot.controller.admin.device.enums.JavaToTdengineTypeEnum;
@ -39,7 +38,8 @@ import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.COLOUMN_CREATION_FAILED;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.TABLE_CREATION_FAILED;
@Service @Service
@Slf4j @Slf4j
@ -751,9 +751,11 @@ public class TDengineService {
// 1. 数据库名 // 1. 数据库名
String dbName = "besure_server"; String dbName = "besure_server";
// 2. 表名
String tableName = "d_" + deviceId; String tableName = "d_" + deviceId;
// 2. 确保数据库存在 // 3. 确保数据库存在
try { try {
String createDbSql = "CREATE DATABASE IF NOT EXISTS " + dbName; String createDbSql = "CREATE DATABASE IF NOT EXISTS " + dbName;
jdbcTemplate.execute(createDbSql); jdbcTemplate.execute(createDbSql);
@ -763,50 +765,40 @@ public class TDengineService {
throw exception(TABLE_CREATION_FAILED); throw exception(TABLE_CREATION_FAILED);
} }
// 3. 构建列SQL // 4. 构建列SQLTDengine必须有 ts
StringBuilder columnsSql = new StringBuilder("ts TIMESTAMP"); StringBuilder columnsSql = new StringBuilder("ts TIMESTAMP");
// 4. 生成唯一列名 // 5. 遍历 contactModelList 构建列
String uniqueColName = "val_" + deviceId + "_" + System.currentTimeMillis();
// 5. 如果 contactModelList 不为空,添加对应列
if (contactModelList != null && !contactModelList.isEmpty()) { if (contactModelList != null && !contactModelList.isEmpty()) {
for (DeviceContactModelDO contact : contactModelList) { for (DeviceContactModelDO contact : contactModelList) {
String attributeCode = contact.getAttributeCode(); String attributeCode = contact.getAttributeCode();
String dataType = contact.getDataType(); String dataType = contact.getDataType();
if (StrUtil.isBlank(attributeCode) || StrUtil.isBlank(dataType)) { if (attributeCode == null || dataType == null) {
continue; continue;
} }
// 使用枚举获取 TDengine 类型
String tdType = JavaToTdengineTypeEnum.getTdTypeByJavaType(dataType); String tdType = JavaToTdengineTypeEnum.getTdTypeByJavaType(dataType);
if (tdType == null) { if (tdType == null) {
tdType = "DOUBLE"; tdType = "DOUBLE"; // 默认使用 DOUBLE
} }
// 拼接列
columnsSql.append(", ").append(attributeCode).append(" ").append(tdType); columnsSql.append(", ").append(attributeCode).append(" ").append(tdType);
} }
// 确保至少有一个数据列
if (columnsSql.toString().equals("ts TIMESTAMP")) {
columnsSql.append(", ").append(uniqueColName).append(" DOUBLE"); // 使用唯一列名
}
} else {
// 6. contactModelList 为空时,添加默认数据列
columnsSql.append(", ").append(uniqueColName).append(" DOUBLE"); // 使用唯一列名
} }
// 7. 构建完整 SQL // 6. 构建完整 SQL
String fullTableName = dbName + "." + tableName; String createTableSql = "CREATE TABLE IF NOT EXISTS " + dbName + "." + tableName + " ("
String createTableSql = "CREATE TABLE IF NOT EXISTS " + fullTableName + + columnsSql.toString() + ")";
" (" + columnsSql.toString() + ")";
// 8. 执行创建表 // 7. 执行创建表
try { try {
jdbcTemplate.execute(createTableSql); jdbcTemplate.execute(createTableSql);
log.info("TDengine 表创建成功: {}", fullTableName); log.info("TDengine 表创建成功: {}.{}", dbName, tableName);
} catch (Exception e) { } catch (Exception e) {
log.error("TDengine 表创建失败: {}", fullTableName, e); log.error("TDengine 表创建失败: {}.{}", dbName, tableName, e);
throw exception(TABLE_CREATION_FAILED); throw exception(TABLE_CREATION_FAILED);
} }
} }
@ -862,8 +854,6 @@ public class TDengineService {
} }
} }
/** /**
* *
* @param deviceId * @param deviceId
@ -986,331 +976,6 @@ public class TDengineService {
} }
/**
* TDengine
* @param deviceId ID
* @param oldColumnName
* @param newColumnName
*/
@DS("tdengine")
public void renameTDColumn(Long deviceId, String oldColumnName, String newColumnName) {
if (deviceId == null || StrUtil.isBlank(oldColumnName) || StrUtil.isBlank(newColumnName)) {
log.warn("修改列名参数错误: deviceId={}, oldColumnName={}, newColumnName={}",
deviceId, oldColumnName, newColumnName);
return;
}
// 1. 验证原列是否存在
if (!columnExists(deviceId, oldColumnName)) {
log.warn("原列不存在,无法修改: deviceId={}, column={}", deviceId, oldColumnName);
throw exception(COLUMN_RENAME_FAILED, "原列 '" + oldColumnName + "' 不存在");
}
// 2. 验证新列名是否已存在
if (columnExists(deviceId, newColumnName)) {
log.warn("新列名已存在: deviceId={}, column={}", deviceId, newColumnName);
throw exception(COLUMN_RENAME_FAILED, "新列名 '" + newColumnName + "' 已存在");
}
// 3. 验证新列名是否为保留关键字
if (isReservedKeyword(newColumnName)) {
log.warn("新列名是保留关键字: {}", newColumnName);
throw exception(COLUMN_RENAME_FAILED, "新列名 '" + newColumnName + "' 是保留关键字");
}
// 表名
String tableName = "besure_server.d_" + deviceId;
// ALTER TABLE RENAME COLUMN SQL
String alterSql = "ALTER TABLE " + tableName
+ " RENAME COLUMN " + oldColumnName + " " + newColumnName;
try {
jdbcTemplate.execute(alterSql);
log.info("TDengine 表修改列名成功: table={}, oldColumn={}, newColumn={}",
tableName, oldColumnName, newColumnName);
} catch (Exception e) {
// 处理特定错误
String errorMsg = e.getMessage();
if (errorMsg != null) {
if (errorMsg.contains("column not exist") || errorMsg.contains("column does not exist")) {
log.warn("原列不存在,无法修改: table={}, column={}", tableName, oldColumnName);
}
if (errorMsg.contains("duplicate column") || errorMsg.contains("column already exists")) {
log.warn("新列名已存在: table={}, newColumn={}", tableName, newColumnName);
}
if (errorMsg.contains("reserved keyword") || errorMsg.toLowerCase().contains("syntax")) {
log.warn("新列名包含保留关键字: {}", newColumnName);
}
}
log.error("TDengine 表修改列名失败: table={}, oldColumn={}, newColumn={}",
tableName, oldColumnName, newColumnName, e);
throw exception(COLUMN_RENAME_FAILED);
}
}
/**
* 线-
*/
@DS("tdengine")
public synchronized int calculateSequence(Long deviceId, String originalName, String date) {
log.info("=== 开始计算序号 ===");
log.info("参数: deviceId={}, originalName={}, date={}", deviceId, originalName, date);
String tableName = "besure_server.d_" + deviceId;
log.info("表名: {}", tableName);
try {
// 检查表是否存在
boolean exists = tableExists(deviceId);
log.info("表是否存在: {}", exists);
if (!exists) {
log.info("表不存在,返回 1");
return 1;
}
// 查询所有列
String sql = "DESC " + tableName;
log.info("执行SQL: {}", sql);
List<Map<String, Object>> columns = jdbcTemplate.queryForList(sql);
log.info("查询到 {} 列", columns.size());
// 打印所有列
for (int i = 0; i < columns.size(); i++) {
Map<String, Object> column = columns.get(i);
String colName = (String) column.get("Field");
String colType = (String) column.get("Type");
log.info("列[{}]: {} ({})", i, colName, colType);
}
int maxSequence = 0;
String prefix = "del_" + originalName + "_" + date + "_";
log.info("查找前缀: {}", prefix);
log.info("前缀长度: {}", prefix.length());
for (Map<String, Object> column : columns) {
String colName = (String) column.get("Field");
log.info("检查列: {}", colName);
if (colName != null) {
log.info("列长度: {}, 是否以前缀开头: {}",
colName.length(), colName.startsWith(prefix));
if (colName.startsWith(prefix)) {
String seqStr = colName.substring(prefix.length());
log.info("匹配成功! 提取序号字符串: '{}'", seqStr);
try {
int seq = Integer.parseInt(seqStr);
log.info("转换为数字: {}", seq);
if (seq > maxSequence) {
maxSequence = seq;
log.info("更新最大序号为: {}", maxSequence);
}
} catch (NumberFormatException e) {
log.warn("序号不是数字: '{}'", seqStr);
}
}
}
}
int result = maxSequence + 1;
log.info("最终结果: {} + 1 = {}", maxSequence, result);
log.info("=== 计算序号结束 ===");
return result;
} catch (Exception e) {
log.error("计算历史列序号失败返回1", e);
return 1;
}
}
/**
*
*/
@DS("tdengine")
private boolean tableExists(Long deviceId) {
String tableName = "besure_server.d_" + deviceId;
try {
// 方法1直接尝试查询
String sql = "SELECT 1 FROM " + tableName + " LIMIT 0";
jdbcTemplate.execute(sql);
return true;
} catch (Exception e) {
// 如果错误包含"table not exist",说明表不存在
String errorMsg = e.getMessage();
if (errorMsg != null && (
errorMsg.contains("table not exist") ||
errorMsg.contains("table does not exist") ||
errorMsg.contains("unknown table") ||
errorMsg.contains("Table not found"))) {
return false;
}
// 其他错误,可能是权限问题等
log.warn("检查表是否存在时出错: table={}, error={}", tableName, errorMsg);
return false;
}
}
/**
*
*/
@DS("tdengine")
private boolean columnExists(Long deviceId, String columnName) {
if (deviceId == null || StrUtil.isBlank(columnName)) {
return false;
}
String tableName = "besure_server.d_" + deviceId;
try {
// 方法1直接尝试查询该列
String testSql = "SELECT " + columnName + " FROM " + tableName + " LIMIT 0";
jdbcTemplate.execute(testSql);
return true; // 执行成功,说明列存在
} catch (Exception e) {
String errorMsg = e.getMessage();
// 判断是否是"列不存在"的错误
if (errorMsg != null && (
errorMsg.contains("column not exist") ||
errorMsg.contains("column does not exist") ||
errorMsg.contains("Invalid column") ||
errorMsg.contains("column not found") ||
errorMsg.contains("unknown column"))) {
return false; // 列不存在
}
// 其他错误(如表不存在),记录日志
log.warn("检查列是否存在时发生未知错误: table={}, column={}, error={}",
tableName, columnName, errorMsg);
return false;
}
}
/**
*
*/
private boolean isReservedKeyword(String columnName) {
Set<String> reservedWords = new HashSet<>(Arrays.asList(
"value", "timestamp", "current", "database", "table",
"user", "password", "select", "insert", "update", "delete",
"create", "drop", "alter", "show", "describe", "use", "ts"
));
return reservedWords.contains(columnName.toLowerCase());
}
/**
* TDengine
*/
public void validateColumnName(String columnName) {
if (StrUtil.isBlank(columnName)) {
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS, "列名不能为空");
}
// TDengine 列名规则验证
// 1. 不能是保留关键字
Set<String> reservedKeywords = new HashSet<>(Arrays.asList(
"value", "timestamp", "current", "database", "table", "user", "password",
"select", "insert", "update", "delete", "create", "drop", "alter",
"show", "describe", "use", "ts", "now", "current_timestamp"
));
if (reservedKeywords.contains(columnName.toLowerCase())) {
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS,
"列名不能使用保留关键字: " + columnName);
}
// 2. 必须以字母开头
if (!Character.isLetter(columnName.charAt(0))) {
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS,
"列名必须以字母开头: " + columnName);
}
// 3. 只能包含字母、数字、下划线
if (!columnName.matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS,
"列名只能包含字母、数字和下划线: " + columnName);
}
// 4. 长度限制根据TDengine文档
if (columnName.length() > 64) {
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS,
"列名长度不能超过64个字符: " + columnName);
}
// 5. 不能以下划线开头(虽然不是强制,但避免潜在问题)
if (columnName.startsWith("_")) {
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS,
"列名不能以下划线开头: " + columnName);
}
}
/**
* TDengine
*/
public void validateTableName(String tableName) {
if (StrUtil.isBlank(tableName)) {
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS, "表名不能为空");
}
// TDengine 表名规则验证
// 1. 不能是保留关键字
Set<String> reservedKeywords = new HashSet<>(Arrays.asList(
"value", "timestamp", "current", "database", "table", "user", "password",
"select", "insert", "update", "delete", "create", "drop", "alter",
"show", "describe", "use", "ts", "now", "current_timestamp"
));
if (reservedKeywords.contains(tableName.toLowerCase())) {
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS,
"表名不能使用保留关键字: " + tableName);
}
// 2. 必须以字母开头
if (!Character.isLetter(tableName.charAt(0))) {
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS,
"表名必须以字母开头: " + tableName);
}
// 3. 只能包含字母、数字、下划线
if (!tableName.matches("^[a-zA-Z][a-zA-Z0-9_]*$")) {
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS,
"表名只能包含字母、数字和下划线: " + tableName);
}
// 4. 长度限制TDengine表名最大长度通常为192
if (tableName.length() > 192) {
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS,
"表名长度不能超过192个字符: " + tableName);
}
// 5. 不能以下划线开头(与列名策略保持一致)
if (tableName.startsWith("_")) {
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS,
"表名不能以下划线开头: " + tableName);
}
}
/** /**
* deviceId * deviceId
* @param deviceIds * @param deviceIds
@ -2516,23 +2181,4 @@ public class TDengineService {
return record; return record;
} }
}
// ========================= 产能相关接口 ===================
@DS("tdengine")
public boolean insertDeviceCapacityRecord(Long deviceId, Double capacityValue) {
if (deviceId == null || capacityValue == null) {
return false;
}
try {
String sql = "INSERT INTO iot_device_capacity_record (ts, capacity_value, device_id) VALUES (NOW, "
+ capacityValue + ", " + deviceId + ")";
jdbcTemplate.execute(sql);
return true;
} catch (Exception e) {
log.error("insertDeviceCapacityRecord failed, deviceId={}, capacityValue={}", deviceId, capacityValue, e);
return false;
}
}
}

@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.iot.service.devicecontactmodel; package cn.iocoder.yudao.module.iot.service.devicecontactmodel;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicecontactmodel.DeviceContactModelDO; import cn.iocoder.yudao.module.iot.dal.dataobject.devicecontactmodel.DeviceContactModelDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO; import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO;
import cn.iocoder.yudao.module.iot.dal.mysql.deviceattributetype.DeviceAttributeTypeMapper; import cn.iocoder.yudao.module.iot.dal.mysql.deviceattributetype.DeviceAttributeTypeMapper;
@ -8,8 +7,6 @@ import cn.iocoder.yudao.module.iot.service.device.TDengineService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.*; import cn.iocoder.yudao.module.iot.controller.admin.devicecontactmodel.vo.*;
@ -18,10 +15,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactModelMapper; import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactModelMapper;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List; import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.DEVICE_CONTACT_MODEL_NOT_EXISTS; import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.DEVICE_CONTACT_MODEL_NOT_EXISTS;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -58,11 +52,6 @@ public class DeviceContactModelServiceImpl implements DeviceContactModelService
throw exception(DEVICE_MODEL_POINT_CODE_EXISTS); throw exception(DEVICE_MODEL_POINT_CODE_EXISTS);
} }
// 2. 检查attributeCode是否符合TDengine列名规则
if (StrUtil.isNotBlank(createReqVO.getAttributeCode())) {
tDengineService.validateColumnName(createReqVO.getAttributeCode());
}
// 插入 // 插入
DeviceContactModelDO deviceContactModel = BeanUtils.toBean(createReqVO, DeviceContactModelDO.class); DeviceContactModelDO deviceContactModel = BeanUtils.toBean(createReqVO, DeviceContactModelDO.class);
// deviceContactModel.setTypeName(deviceAttributeTypeMapper.selectById(createReqVO.getAttributeCode()).getName()); // deviceContactModel.setTypeName(deviceAttributeTypeMapper.selectById(createReqVO.getAttributeCode()).getName());
@ -89,45 +78,11 @@ public class DeviceContactModelServiceImpl implements DeviceContactModelService
for (Long id : ids) { for (Long id : ids) {
// 校验存在 // 校验存在
validateDeviceContactModelExists(id); validateDeviceContactModelExists(id);
DeviceContactModelDO deviceContactModelDO = deviceContactModelMapper.selectById(id);
if (deviceContactModelDO == null) {
continue;
}
Long deviceId = deviceContactModelDO.getDeviceId();
String oldColumnName = deviceContactModelDO.getAttributeCode();
if (deviceId != null && StrUtil.isNotBlank(oldColumnName)) {
// 生成带序号的历史列名
String newColumnName = generateHistoryColumnName(deviceId, oldColumnName);
// 重命名列
tDengineService.renameTDColumn(deviceId, oldColumnName, newColumnName);
}
// 删除 // 删除
deviceContactModelMapper.deleteById(id); deviceContactModelMapper.deleteById(id);
} }
} }
/**
*
* : DEL_{}_{}_{}
* : DEL_temperature_20260327_1
*/
private String generateHistoryColumnName(Long deviceId, String originalName) {
String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
// 获取当前序号
int sequence = tDengineService.calculateSequence(deviceId, originalName, date);
return String.format("DEL_%s_%s_%d", originalName, date, sequence);
}
private void validateDeviceContactModelExists(Long id) { private void validateDeviceContactModelExists(Long id) {
if (deviceContactModelMapper.selectById(id) == null) { if (deviceContactModelMapper.selectById(id) == null) {
throw exception(DEVICE_CONTACT_MODEL_NOT_EXISTS); throw exception(DEVICE_CONTACT_MODEL_NOT_EXISTS);

@ -1,7 +1,6 @@
package cn.iocoder.yudao.module.iot.service.devicemodelattribute; package cn.iocoder.yudao.module.iot.service.devicemodelattribute;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
@ -69,10 +68,6 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
@Resource @Resource
private ErpProductUnitService productUnitService; private ErpProductUnitService productUnitService;
@Resource
@Lazy
private TDengineService tDengineService;
@Override @Override
public Long createDeviceModelAttribute(DeviceModelAttributeSaveReqVO createReqVO) { public Long createDeviceModelAttribute(DeviceModelAttributeSaveReqVO createReqVO) {
@ -87,15 +82,9 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
throw exception(DEVICE_MODEL_ATTRIBUTE_POTIN_CODE_EXISTS); throw exception(DEVICE_MODEL_ATTRIBUTE_POTIN_CODE_EXISTS);
} }
// 插入 // 插入
DeviceModelAttributeDO deviceModelAttribute = BeanUtils.toBean(createReqVO, DeviceModelAttributeDO.class); DeviceModelAttributeDO deviceModelAttribute = BeanUtils.toBean(createReqVO, DeviceModelAttributeDO.class);
// deviceModelAttribute.setTypeName(deviceAttributeTypeMapper.selectById(createReqVO.getAttributeCode()).getName()); // deviceModelAttribute.setTypeName(deviceAttributeTypeMapper.selectById(createReqVO.getAttributeCode()).getName());
//检查attributeCode是否符合TDengine列名规则
if (StrUtil.isNotBlank(createReqVO.getAttributeCode())) {
tDengineService.validateColumnName(createReqVO.getAttributeCode());
}
deviceModelAttributeMapper.insert(deviceModelAttribute); deviceModelAttributeMapper.insert(deviceModelAttribute);
// 返回 // 返回
return deviceModelAttribute.getId(); return deviceModelAttribute.getId();
@ -306,7 +295,7 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
// 不能为空 // 不能为空
if (StringUtils.isBlank(code)) { if (StringUtils.isBlank(code)) {
respVO.getFailureCodes().put(importAttribute.getAttributeCode(), "点位类型编码不能为空"); respVO.getFailureCodes().put(importAttribute.getAttributeCode(), "点位类型名称不能为空");
return; return;
} }
// 必须存在于数据库类型列表中(防止乱填) // 必须存在于数据库类型列表中(防止乱填)

@ -46,11 +46,11 @@ public class DevicePointRulesServiceImpl implements DevicePointRulesService {
validateDevicePointRulesExists(updateReqVO.getId()); validateDevicePointRulesExists(updateReqVO.getId());
// 更新 // 更新
DevicePointRulesDO updateObj = BeanUtils.toBean(updateReqVO, DevicePointRulesDO.class); DevicePointRulesDO updateObj = BeanUtils.toBean(updateReqVO, DevicePointRulesDO.class);
// if (!updateReqVO.getPointRulesVOList().isEmpty()){ if (!updateReqVO.getPointRulesVOList().isEmpty()){
// String jsonString = JSON.toJSONString(updateReqVO.getPointRulesVOList()); String jsonString = JSON.toJSONString(updateReqVO.getPointRulesVOList());
// updateObj.setFieldRule(jsonString); updateObj.setFieldRule(jsonString);
//
// } }
devicePointRulesMapper.updateById(updateObj); devicePointRulesMapper.updateById(updateObj);
} }

@ -17,10 +17,6 @@ public interface ErrorCodeConstants {
ErrorCode BOM_NOT_EXISTS = new ErrorCode(5_001, "产品BOM不存在"); ErrorCode BOM_NOT_EXISTS = new ErrorCode(5_001, "产品BOM不存在");
ErrorCode BOM_EXISTS = new ErrorCode(5_002, "产品BOM已存在"); ErrorCode BOM_EXISTS = new ErrorCode(5_002, "产品BOM已存在");
ErrorCode UNIT_ERROR = new ErrorCode(5_002, "物料bom单位不一致");
ErrorCode BOM_ONLY = new ErrorCode(5_002, "每个产品启用的BOM只能有一个请先禁用改产品其他BOM");
ErrorCode ORGANIZATION_NOT_EXISTS = new ErrorCode(5_0011, "产线工位不存在"); ErrorCode ORGANIZATION_NOT_EXISTS = new ErrorCode(5_0011, "产线工位不存在");
ErrorCode ORGANIZATION_ID_NOT_EXISTS = new ErrorCode(5_0011, "产线工位不存在"); ErrorCode ORGANIZATION_ID_NOT_EXISTS = new ErrorCode(5_0011, "产线工位不存在");
ErrorCode ORGANIZATION_EXITS_CHILDREN = new ErrorCode(5_0012, "存在存在子产线工位,无法删除"); ErrorCode ORGANIZATION_EXITS_CHILDREN = new ErrorCode(5_0012, "存在存在子产线工位,无法删除");
@ -148,17 +144,14 @@ public interface ErrorCodeConstants {
ErrorCode DEVICE_LEDGER_EXISTS = new ErrorCode(1002000010, "设备台账编码已存在"); ErrorCode DEVICE_LEDGER_EXISTS = new ErrorCode(1002000010, "设备台账编码已存在");
ErrorCode SUBJECT_EXISTS = new ErrorCode(1002000010, "项目编码已存在"); ErrorCode SUBJECT_EXISTS = new ErrorCode(1002000010, "项目编码已存在");
ErrorCode TASK_MANAGEMENT_NOT_EXISTS = new ErrorCode(1002000011, "设备类型不存在"); ErrorCode TASK_MANAGEMENT_NOT_EXISTS = new ErrorCode(1002000011, "设备类型不存在");
ErrorCode TASK_CORN_NOT_EXISTS = new ErrorCode(1002000012, "设备corn表达式为空"); ErrorCode TASK_CORN_NOT_EXISTS = new ErrorCode(1002000011, "设备corn表达式为空");
ErrorCode TASK_CORN_NOT_LE_HOUR = new ErrorCode(1002000013, "corn表达式不能小于一小时"); ErrorCode TASK_CORN_NOT_LE_HOUR = new ErrorCode(1002000011, "corn表达式不能小于一小时");
ErrorCode DEVICE_LEDGER_CODE_NOT_EXISTS = new ErrorCode(1002000013, "设备台账编码不存在");
ErrorCode TICKET_MANAGEMENT_NOT_EXISTS = new ErrorCode(1002000012, "工单管理不存在"); ErrorCode TICKET_MANAGEMENT_NOT_EXISTS = new ErrorCode(1002000012, "工单管理不存在");
ErrorCode TICKET_RESULTS_NOT_EXISTS = new ErrorCode(1002000013, "工单检验结果不存在"); ErrorCode TICKET_RESULTS_NOT_EXISTS = new ErrorCode(1002000013, "工单检验结果不存在");
ErrorCode TICKET_RESULTS_ID_NOT_NULL = new ErrorCode(1002000014, "工单检验结果Id不存在"); ErrorCode TICKET_RESULTS_ID_NOT_NULL = new ErrorCode(1002000014, "工单检验结果Id不存在");
ErrorCode CRITICAL_COMPONENT_NOT_EXISTS = new ErrorCode(1002000015, "设备关键件不存在"); ErrorCode CRITICAL_COMPONENT_NOT_EXISTS = new ErrorCode(1002000015, "设备关键件不存在");
ErrorCode CRITICAL_COMPONENT_CODE_EXISTS = new ErrorCode(1002000015, "设备关键件编码已存在"); ErrorCode CRITICAL_COMPONENT_CODE_EXISTS = new ErrorCode(1002000015, "设备关键件编码已存在");
ErrorCode CRITICAL_COMPONENT_CODE_NOT_EXISTS = new ErrorCode(1002000015, "设备关键件编码不存在");
ErrorCode CRITICAL_COMPONENT_REFERENCES= new ErrorCode(1002000015, "存在设备关键件已被引用,请先删除引用"); ErrorCode CRITICAL_COMPONENT_REFERENCES= new ErrorCode(1002000015, "存在设备关键件已被引用,请先删除引用");
@ -175,25 +168,4 @@ public interface ErrorCodeConstants {
ErrorCode CAL_HOLIDAY_EXISTS = new ErrorCode(6_001, "已设置成功,请勿重复点击"); ErrorCode CAL_HOLIDAY_EXISTS = new ErrorCode(6_001, "已设置成功,请勿重复点击");
ErrorCode FILE_NOT_EXISTS = new ErrorCode(6_002, "esop文件表库不存在"); ErrorCode FILE_NOT_EXISTS = new ErrorCode(6_002, "esop文件表库不存在");
//======================================排产相关 1003010000=================================================
ErrorCode SORT_RULE_NOT_EXISTS = new ErrorCode(100_301_0001, "排序规则不能为空");
ErrorCode UNSUPPORTED_SORTING_RULE = new ErrorCode(100_301_0002, "不支持的排序规则");
ErrorCode SCHEDULE_PRODUCT_ID_EMPTY = new ErrorCode(100_301_0003, "产品ID不能为空");
ErrorCode SCHEDULE_PLAN_NUMBER_INVALID = new ErrorCode(100_301_0004, "计划数量不能为空且必须大于0");
ErrorCode SCHEDULE_PRODUCT_DEVICE_NOT_FOUND = new ErrorCode(100_301_0005, "产品未关联设备productId={}");
ErrorCode SCHEDULE_PRODUCT_DEVICE_UNAVAILABLE = new ErrorCode(100_301_0006, "产品关联设备均不可用productId={}");
ErrorCode SCHEDULE_ORDER_DETAIL_DELIVERY_DATE_EMPTY = new ErrorCode(100_301_0007, "订单明细交期不能为空taskDetailId={}");
ErrorCode SCHEDULE_CAPACITY_TYPE_EMPTY = new ErrorCode(100_301_0008, "产能来源不能为空");
ErrorCode UNSUPPORTED_CAPACITY_TYPE = new ErrorCode(100_301_0009, "不支持的产能来源: {}");
ErrorCode SCHEDULE_DELIVERY_DATE_EMPTY = new ErrorCode(100_301_0010, "订单交期不能为空taskDetailId={}");
ErrorCode SCHEDULE_DEVICE_SELECT_FAILED = new ErrorCode(100_301_0011, "设备分配失败无可用设备productId={}");
ErrorCode SCHEDULE_TIME_FORMAT_INVALID = new ErrorCode(100_301_0012, "排产时间格式错误start={}, end={}格式需为HH:mm");
ErrorCode SCHEDULE_TIME_RANGE_INVALID = new ErrorCode(100_301_0013, "排产时间范围非法start={}, end={},结束时间必须晚于开始时间");
ErrorCode SCHEDULE_WORK_HOURS_INVALID = new ErrorCode(100_301_0014, "排产工时非法start={}, end={}可用工时必须大于0");
} }

@ -11,7 +11,6 @@ import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*; import javax.validation.constraints.*;
import javax.validation.*; import javax.validation.*;
import javax.servlet.http.*; import javax.servlet.http.*;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
@ -49,7 +48,7 @@ public class CriticalComponentController {
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建设备关键件") @Operation(summary = "创建设备关键件")
@PreAuthorize("@ss.hasPermission('mes:critical-component:create')") @PreAuthorize("@ss.hasPermission('mes:critical-component:create')")
public CommonResult<Long> createCriticalComponent(@Valid @RequestBody CriticalComponentSaveReqVO createReqVO) throws UnsupportedEncodingException { public CommonResult<Long> createCriticalComponent(@Valid @RequestBody CriticalComponentSaveReqVO createReqVO) {
return success(criticalComponentService.createCriticalComponent(createReqVO)); return success(criticalComponentService.createCriticalComponent(createReqVO));
} }
@ -171,12 +170,4 @@ public class CriticalComponentController {
return success(criticalComponentService.importCriticalComponentList(list, updateSupport)); return success(criticalComponentService.importCriticalComponentList(list, updateSupport));
} }
@PostMapping("/regenerate-code")
public CommonResult<Boolean> regenerateCode(@RequestParam("id") Long id,
@RequestParam("code") String code) throws UnsupportedEncodingException {
criticalComponentService.regenerateCode(id, code);
return success(true);
}
} }

@ -28,10 +28,6 @@ public class CriticalComponentExcelVO {
@ExcelProperty("名称") @ExcelProperty("名称")
private String name; private String name;
@Schema(description = "规格型号", example = "")
@ExcelProperty("规格型号")
private String deviceSpec;
@Schema(description = "描述") @Schema(description = "描述")
@ExcelProperty("描述") @ExcelProperty("描述")
private String description; private String description;

@ -27,10 +27,6 @@ public class CriticalComponentImportExcelVO {
@ExcelProperty("名称") @ExcelProperty("名称")
private String name; private String name;
@Schema(description = "规格型号", example = "")
@ExcelProperty("规格型号")
private String deviceSpec;
@ExcelProperty("描述") @ExcelProperty("描述")
private String description; private String description;

@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.mes.controller.admin.criticalcomponent.vo; package cn.iocoder.yudao.module.mes.controller.admin.criticalcomponent.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.*; import lombok.*;
import java.util.*; import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
@ -16,18 +15,12 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true) @ToString(callSuper = true)
public class CriticalComponentPageReqVO extends PageParam { public class CriticalComponentPageReqVO extends PageParam {
@Schema(description = "设备图片")
private String images;
@Schema(description = "编码(唯一标识)") @Schema(description = "编码(唯一标识)")
private String code; private String code;
@Schema(description = "名称", example = "张三") @Schema(description = "名称", example = "张三")
private String name; private String name;
@Schema(description = "规格型号", example = "")
private String deviceSpec;
@Schema(description = "描述", example = "你说的对") @Schema(description = "描述", example = "你说的对")
private String description; private String description;

@ -17,9 +17,6 @@ public class CriticalComponentRespVO {
// @ExcelProperty("主键ID") // @ExcelProperty("主键ID")
private Long id; private Long id;
@Schema(description = "设备图片")
private String images;
@Schema(description = "编码(唯一标识)", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "编码(唯一标识)", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("编码(唯一标识)") @ExcelProperty("编码(唯一标识)")
private String code; private String code;
@ -28,10 +25,6 @@ public class CriticalComponentRespVO {
@ExcelProperty("名称") @ExcelProperty("名称")
private String name; private String name;
@Schema(description = "规格型号", example = "")
@ExcelProperty("规格型号")
private String deviceSpec;
@Schema(description = "描述", example = "你说的对") @Schema(description = "描述", example = "你说的对")
@ExcelProperty("描述") @ExcelProperty("描述")
private String description; private String description;
@ -48,7 +41,4 @@ public class CriticalComponentRespVO {
@Schema(description = "数量", example = "2") @Schema(description = "数量", example = "2")
private Integer count; private Integer count;
@Schema(description = "二维码", example = "2")
private String qrcodeUrl;
} }

@ -12,20 +12,14 @@ public class CriticalComponentSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "14503") @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "14503")
private Long id; private Long id;
@Schema(description = "设备图片")
private String images;
@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 = "规格型号", example = "")
private String deviceSpec;
@Schema(description = "描述", example = "你说的对") @Schema(description = "描述", example = "你说的对")
private String description; private String description;

@ -497,7 +497,7 @@ public class DashboardController {
@GetMapping("/getTaskStatistics") @GetMapping("/getTaskStatistics")
@Operation(summary = "获得各设备统计个数") @Operation(summary = "获得各设备统计个数")
@Parameter(name = "orgId", description = "产线组织Id") @Parameter(name = "orgId", description = "产线组织Id")
//@PreAuthorize("@ss.hasPermission('mes:device-ledger:query')") @PreAuthorize("@ss.hasPermission('mes:device-ledger:query')")
public CommonResult<EventStatisticsVO> getTaskStatistics(@RequestParam(name = "orgId") Long orgId) { public CommonResult<EventStatisticsVO> getTaskStatistics(@RequestParam(name = "orgId") Long orgId) {
EventStatisticsVO vo = new EventStatisticsVO(); EventStatisticsVO vo = new EventStatisticsVO();
@ -559,7 +559,7 @@ public class DashboardController {
@GetMapping("/getAllTaskList") @GetMapping("/getAllTaskList")
@Operation(summary = "获得所有任务") @Operation(summary = "获得所有任务")
@Parameter(name = "orgId", description = "产线组织Id") @Parameter(name = "orgId", description = "产线组织Id")
//@PreAuthorize("@ss.hasPermission('mes:bom:query')") @PreAuthorize("@ss.hasPermission('mes:bom:query')")
public CommonResult<List<TaskVO>> getAllTaskList(@RequestParam(name = "orgId") Long orgId) { public CommonResult<List<TaskVO>> getAllTaskList(@RequestParam(name = "orgId") Long orgId) {
List<TaskVO> taskVOList = new ArrayList<>(); List<TaskVO> taskVOList = new ArrayList<>();

@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.mes.controller.admin.deviceledger;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
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.enums.QrcodeBizTypeEnum;
import cn.iocoder.yudao.module.common.service.qrcordrecord.QrcodeRecordService;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.mes.controller.admin.deviceledger.utils.ResumeNameUtils; import cn.iocoder.yudao.module.mes.controller.admin.deviceledger.utils.ResumeNameUtils;
import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanRespVO; import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanRespVO;
@ -24,7 +22,6 @@ import io.swagger.v3.oas.annotations.Operation;
import javax.validation.*; import javax.validation.*;
import javax.servlet.http.*; import javax.servlet.http.*;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
@ -63,14 +60,11 @@ public class DeviceLedgerController {
@Resource @Resource
private AdminUserApi adminUserApi; private AdminUserApi adminUserApi;
@Resource
private QrcodeRecordService qrcodeService;
@PostMapping("/create") @PostMapping("/create")
@Operation(summary = "创建设备台账") @Operation(summary = "创建设备台账")
@PreAuthorize("@ss.hasPermission('mes:device-ledger:create')") @PreAuthorize("@ss.hasPermission('mes:device-ledger:create')")
public CommonResult<Long> createDeviceLedger(@Valid @RequestBody DeviceLedgerSaveReqVO createReqVO) throws UnsupportedEncodingException { public CommonResult<Long> createDeviceLedger(@Valid @RequestBody DeviceLedgerSaveReqVO createReqVO) {
return success(deviceLedgerService.createDeviceLedger(createReqVO)); return success(deviceLedgerService.createDeviceLedger(createReqVO));
} }
@ -105,10 +99,6 @@ public class DeviceLedgerController {
public CommonResult<DeviceLedgerRespVO> getDeviceLedger(@RequestParam("id") Long id) { public CommonResult<DeviceLedgerRespVO> getDeviceLedger(@RequestParam("id") Long id) {
DeviceLedgerDO deviceLedger = deviceLedgerService.getDeviceLedger(id); DeviceLedgerDO deviceLedger = deviceLedgerService.getDeviceLedger(id);
DeviceLedgerRespVO respVO = BeanUtils.toBean(deviceLedger, DeviceLedgerRespVO.class); DeviceLedgerRespVO respVO = BeanUtils.toBean(deviceLedger, DeviceLedgerRespVO.class);
String qrcodeUrl = qrcodeService.selectQrcodeUrlByIdAndCode(QrcodeBizTypeEnum.EQUIPMENT.getCode(),id,respVO.getDeviceCode());
respVO.setQrcodeUrl(qrcodeUrl);
respVO.setCreatorName(adminUserApi.getUser(Long.valueOf(deviceLedger.getCreator())).getNickname()); respVO.setCreatorName(adminUserApi.getUser(Long.valueOf(deviceLedger.getCreator())).getNickname());
if (StringUtils.isNotBlank(respVO.getDeviceManager())) { if (StringUtils.isNotBlank(respVO.getDeviceManager())) {
String[] userIds = respVO.getDeviceManager().split(","); String[] userIds = respVO.getDeviceManager().split(",");
@ -260,19 +250,4 @@ public class DeviceLedgerController {
// 导出 Excel // 导出 Excel
ExcelUtils.write(response, fileName, "数据", MoldVO.class,list); ExcelUtils.write(response, fileName, "数据", MoldVO.class,list);
} }
@PostMapping("/regenerate-code")
public CommonResult<Boolean> regenerateCode(@RequestParam("id") Long id,
@RequestParam("code") String code) throws UnsupportedEncodingException {
deviceLedgerService.regenerateCode(id, code);
return success(true);
}
} }

@ -1,41 +0,0 @@
package cn.iocoder.yudao.module.mes.controller.admin.deviceledger.enums;
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum CapacityTypeEnum {
RATED(1, "额定产能") {
@Override
public Integer getCapacity(DeviceLedgerDO device) {
return device.getRatedCapacity();
}
},
DAILY_AVERAGE(2, "每日报工平均值") {
@Override
public Integer getCapacity(DeviceLedgerDO device) {
return device.getDailyAverageValue();
}
},
DATA_COLLECTION(3, "数据采集产能") {
@Override
public Integer getCapacity(DeviceLedgerDO device) {
return device.getDataCollectionCapacity();
}
};
private final Integer type;
private final String desc;
public abstract Integer getCapacity(DeviceLedgerDO device);
public static CapacityTypeEnum of(Integer type) {
for (CapacityTypeEnum item : values()) {
if (item.type.equals(type)) return item;
}
return null;
}
}

@ -17,9 +17,6 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true) @ToString(callSuper = true)
public class DeviceLedgerPageReqVO extends PageParam { public class DeviceLedgerPageReqVO extends PageParam {
@Schema(description = "设备图片")
private String images;
@Schema(description = "设备编号") @Schema(description = "设备编号")
private String deviceCode; private String deviceCode;
@ -86,10 +83,4 @@ public class DeviceLedgerPageReqVO extends PageParam {
@Schema(description = "关联采集设备id") @Schema(description = "关联采集设备id")
private Long dvId; private Long dvId;
@Schema(description = "是否排产")
private Integer isScheduled;
@Schema(description = "产品Id")
private Long productId;
} }

@ -30,9 +30,6 @@ public class DeviceLedgerRespVO extends BaseDO {
// @ExcelProperty("id") // @ExcelProperty("id")
private Long id; private Long id;
@Schema(description = "设备图片")
private String images;
@Schema(description = "设备编号") @Schema(description = "设备编号")
@ExcelProperty("设备编号") @ExcelProperty("设备编号")
private String deviceCode; private String deviceCode;
@ -154,19 +151,4 @@ public class DeviceLedgerRespVO extends BaseDO {
@Schema(description = "关联采集设备id") @Schema(description = "关联采集设备id")
private Long dvId; private Long dvId;
@Schema(description = "二维码")
private String qrcodeUrl;
@Schema(description = "是否排产")
private Integer isScheduled;
@Schema(description = "额定产能")
private Integer ratedCapacity;
@Schema(description = "每日报工平均值(根据工单报工计算)")
private Integer dailyAverageValue;
@Schema(description = "数据采集产能")
private Integer dataCollectionCapacity;
} }

@ -13,9 +13,6 @@ public class DeviceLedgerSaveReqVO {
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "24467") @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "24467")
private Long id; private Long id;
@Schema(description = "设备图片")
private String images;
@Schema(description = "设备编号") @Schema(description = "设备编号")
private String deviceCode; private String deviceCode;
@ -81,16 +78,4 @@ public class DeviceLedgerSaveReqVO {
@Schema(description = "关联采集设备id") @Schema(description = "关联采集设备id")
private Long dvId; private Long dvId;
@Schema(description = "是否排产")
private Integer isScheduled;
@Schema(description = "额定产能")
private Integer ratedCapacity;
@Schema(description = "每日报工平均值(根据工单报工计算)")
private Integer dailyAverageValue;
@Schema(description = "数据采集产能")
private Integer dataCollectionCapacity;
} }

@ -6,8 +6,6 @@ import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotEmpty;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ -46,9 +44,6 @@ public class DvSubjectPageReqVO extends PageParam {
@Schema(description = "值类型") @Schema(description = "值类型")
private String valueType; private String valueType;
@Schema(description = "作业类型")
private Integer jobType;
@Schema(description = "判定基准") @Schema(description = "判定基准")
private String judgmentCriteria; private String judgmentCriteria;

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

Loading…
Cancel
Save