Commit 2bafb3ed by 刘栋

UDI

parents
Showing with 4889 additions and 0 deletions
/saas-udi/saas-udi-api/target/*
/saas-udi/saas-udi-service/target/*
/logs/
/.idea/
No preview for this file type
No preview for this file type
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>saas-udi</artifactId>
<groupId>com.infynova</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>saas-udi-api</artifactId>
<properties>
<jeecg-autopoi.version>1.3.6</jeecg-autopoi.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.4.6</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
</dependency>
<dependency>
<groupId>com.infynova</groupId>
<artifactId>saas-core</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../libs/saas-core-1.0.0.jar</systemPath>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.infynova.udi;
import com.infynova.common.core.api.ServiceCode;
import java.util.Arrays;
public enum UdiCode implements ServiceCode {
NOFOUND(720001, "数据不存在")
, ILLEGAL(720002, "非法操作")
, UNKNOWN(720003, "未知错误")
, PARAMETER_ERROR(720004, "参数错误")
, SYSTEM_DATA_NOT_REMOVE(750001, "系统数据无法移除")
, GET_COMPANY_ERROR(750002, "获取分公司出现异常")
, IMPORT_ERROR(750003, "导入错误")
, IMPORT_NULL_ERROR(750004,"导入数据为空")
, FILE_IS_NOT_NULL(750005, "文件不允许为空")
, GET_REGION_ERROR(750006, "获取大区出现异常")
, GET_SELLER_ERROR(750007, "获取销售人员出现异常")
;
private int code;
private String msg;
@Override
public int getCode() {
return code;
}
@Override
public String getMsg() {
return msg;
}
UdiCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
public static ServiceCode getServiceCode(int code) {
return Arrays.stream(UdiCode.values()).filter(p -> p.getCode() == code).findFirst().orElse(UdiCode.UNKNOWN);
}
}
package com.infynova.udi.config;
import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
*
* @description long类型id避免丢长度
* @author zoupx
* @date 2020/9/15
* @return
*/
@Configuration
public class JsonSerializerManage {
@Bean
public ObjectMapper jacksonObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule=new JavaTimeModule();
// java8时间序列化
javaTimeModule.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
javaTimeModule.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
SimpleModule longModule = new SimpleModule();
longModule.addSerializer(new LongToStringSerializer(Long.class));
objectMapper.registerModule(longModule);
objectMapper.registerModules(longModule, javaTimeModule);
objectMapper.setDateFormat(new SimpleDateFormat(DatePattern.NORM_DATETIME_PATTERN));
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return objectMapper;
}
}
package com.infynova.udi.config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
public class LongToStringSerializer extends StdSerializer<Long> {
protected LongToStringSerializer(Class<Long> t) {
super(t);
}
@Override
public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
if (value == null) {
jsonGenerator.writeString("");
} else {
jsonGenerator.writeString(value.toString());
}
}
}
\ No newline at end of file
package com.infynova.udi.constant;
public interface UdiConstant {
String UDI_PACKAGE_NAME = "com.infynova.udi";
String INFYNOVA_PACKAGE_NAME = "com.infynova";
String MAPPER_PACKAGE_NAME = "com.infynova.udi.mapper";
}
package com.infynova.udi.dto;
import com.infynova.common.core.entity.PageVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.util.Collection;
/**
* idList分页入参
* @author liudong
* 2022-08-05 19:48
*/
@Data
@ApiModel(value="IdListPageQry",description="IdListPageQry")
public class IdListPageQry extends PageVo {
/**
* 租户号
*/
@ApiModelProperty(value = "租户号")
private Long tenantId;
/**
* id集合
*/
@NotEmpty(message = "idList不能为空")
@ApiModelProperty(value = "id集合",required = true)
private Collection<Long> idList;
}
package com.infynova.udi.dto;
import com.infynova.common.core.api.BaseVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.util.Collection;
/**
* idList入参
* @author liudong
* 2022-08-05 19:48
*/
@Data
@ApiModel(value="IdListQry",description="IdListQry")
public class IdListQry extends BaseVo {
/**
* 租户号
*/
@ApiModelProperty(value = "租户号")
private Long tenantId;
/**
* id集合
*/
@NotEmpty(message = "idList不能为空")
@ApiModelProperty(value = "id集合",required = true)
private Collection<Long> idList;
}
package com.infynova.udi.dto;
import com.infynova.common.core.entity.PageVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* id分页入参
* @author liudong
* 2022-08-05 19:48
*/
@Data
@ApiModel(value="IdPageQry",description="IdPageQry")
public class IdPageQry extends PageVo {
/**
* 租户号
*/
@ApiModelProperty(value = "租户号")
private Long tenantId;
/**
* id集合
*/
@NotNull(message = "id不能为空")
@ApiModelProperty(value = "id",required = true)
private Long id;
}
package com.infynova.udi.dto;
import com.infynova.common.core.api.BaseVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
/**
* id入参
* @author liudong
* 2022-08-05 19:48
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
@ApiModel(value="IdQry",description="IdQry")
public class IdQry extends BaseVo {
/**
* 租户号
*/
@ApiModelProperty(value = "租户号")
private Long tenantId;
/**
* id集合
*/
@NotNull(message = "id不能为空")
@ApiModelProperty(value = "id",required = true)
private Long id;
}
package com.infynova.udi.dto;
import lombok.Getter;
/**
* 照搬obs导入返回结果集
* 2023-11-08 16:12:00
*/
@Getter
public class ImportItemCount {
private int totalNum;
private int successNum;
private int failNum;
public void addTotalNum() {
this.totalNum ++;
}
public void addSuccessNum() {
this.successNum ++;
}
public void addFailNum() {
this.failNum ++;
}
public void addTotalNum(int num) {
this.totalNum = this.totalNum + num;
}
public void addSuccessNum(int num) {
this.successNum = this.successNum + num;
}
public void addFailNum(int num) {
this.failNum = this.failNum + num;
}
}
package com.infynova.udi.dto;
import com.infynova.common.core.entity.UploadResultVo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 照搬obs导入返回结果集
* 2023-11-08 16:12:00
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ImportItemResp {
private UploadResultVo upload;
private ImportItemCount count;
}
package com.infynova.udi.dto;
import com.infynova.common.core.api.BaseVo;
import com.infynova.udi.helper.validator.FixedValueValidator;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* @author liudong
* 2024/2/22 19:44
* @version 1.0
*/
@Data
public class UdiAllMatchQry extends BaseVo {
@NotNull(message = "对码状态不能为空")
@FixedValueValidator(message = "对码状态类型错误", fixedValue = {"11","22","33","44"})
@ApiModelProperty(value = "对码状态:11-全部 22-部分对码 33-100%对码 44-完全未对码")
private Integer taskStatus;
@NotNull(message = "任务id不能为空")
@ApiModelProperty(value = "任务id")
private Long taskId;
}
package com.infynova.udi.dto;
import com.infynova.common.core.api.BaseVo;
import com.infynova.udi.helper.validator.FixedValueValidator;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* @author liudong
* 2024/2/22 19:44
* @version 1.0
*/
@Data
public class UdiBatchMatchQry extends BaseVo {
@NotNull(message = "对码状态不能为空")
@FixedValueValidator(message = "对码状态类型错误", fixedValue = {"11","22","33","44"})
@ApiModelProperty(value = "对码状态:11-全部 22-部分对码 33-100%对码 44-完全未对码")
private Integer taskStatus;
@NotNull(message = "matchId集合不能为空")
@ApiModelProperty(value = "matchId集合")
private List<Long> matchIdList;
}
package com.infynova.udi.dto;
import com.infynova.common.core.entity.PageVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class UdiListQry extends PageVo {
@ApiModelProperty(value = "DI码")
private String udiCode;
@ApiModelProperty(value = "医保一级编码")
private String yiBaoOneCode;
@ApiModelProperty(value = "医保二级编码")
private String yiBaoTwoCode;
@ApiModelProperty(value = "医保编码")
private String yiBaoCode;
@ApiModelProperty(value = "企业名称")
private String companyName;
@ApiModelProperty(value = "品牌")
private String brandName;
@ApiModelProperty(value = "注册备案号")
private String registryNo;
@ApiModelProperty(value = "注册备案产品名称")
private String registryName;
@ApiModelProperty(value = "产品编码")
private String productCode;
@ApiModelProperty(value = "厂家产品货号/编号")
private String productFactoryCode;
@ApiModelProperty(value = "无境UDI库分配编码")
private String infynovaCode;
@ApiModelProperty(value = "单件产品名称")
private String productName;
@ApiModelProperty(value = "产品类型")
private String productType;
@ApiModelProperty(value = "规格")
private String specification;
@ApiModelProperty(value = "型号")
private String model;
@ApiModelProperty(value = "是否为无菌包装 0:否 1:是")
private Boolean asepticPackaging;
@ApiModelProperty(value = "使用前是否需要进行灭菌 0:否 1:是")
private Boolean beforeSterilize;
}
package com.infynova.udi.dto;
import com.infynova.common.core.api.BaseVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @author liudong
* 2024/2/22 19:44
* @version 1.0
*/
@Data
public class UdiMatchConfirmationDto extends BaseVo {
@NotNull(message = "matchId不能为空")
@ApiModelProperty(value = "matchId")
private Long matchId;
@NotBlank(message = "DI码不能为空")
@ApiModelProperty(value = "DI码")
private String udiCode;
//@NotBlank(message = "医保编码不能为空")
@ApiModelProperty(value = "医保编码")
private String yiBaoCode;
@NotBlank(message = "厂家名称不能为空")
@ApiModelProperty(value = "厂家名称")
private String companyName;
//@NotBlank(message = "厂家产品货号或编号")
@ApiModelProperty(value = "厂家产品货号或编号")
private String productFactoryCode;
@NotBlank(message = "品牌")
@ApiModelProperty(value = "品牌")
private String brandName;
@NotBlank(message = "产品名称不能为空")
@ApiModelProperty(value = "单件产品名称")
private String productName;
@NotBlank(message = "规格不能为空")
@ApiModelProperty(value = "规格")
private String specification;
@NotBlank(message = "型号不能为空")
@ApiModelProperty(value = "型号")
private String model;
@NotBlank(message = "注册备案号不能为空")
@ApiModelProperty(value = "注册备案号(注册证)")
private String registryNo;
}
package com.infynova.udi.dto;
import com.infynova.common.core.entity.PageVo;
import com.infynova.udi.enums.match.MatchStatusEnum;
import com.infynova.udi.enums.match.MatchUpdateStatusEnum;
import com.infynova.udi.helper.validator.FixedValueValidator;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
@ApiModel(value = "UdiMatchDetailListQry", description = "UdiMatchDetailListQry")
public class UdiMatchDetailListQry extends PageVo {
@NotNull(message = "查询类型不能为空")
@FixedValueValidator(message = "查询类型值错误", fixedValue = {"11","22","33","44"})
@ApiModelProperty(value = "查询类型:11-全部 22-部分对码 33-100%对码 44-完全未对码", required = true)
private Integer queryType;
@ApiModelProperty(value = "任务id")
private Long taskId;
@ApiModelProperty(value = "任务编号")
private String taskNo;
/** udi码 */
@ApiModelProperty(value = "udi码")
private String udiCode;
/** 医保编码 */
@ApiModelProperty(value = "医保编码")
private String yiBaoCode;
/** 企业名称 */
@ApiModelProperty(value = "企业名称")
private String companyName;
/** 品牌 */
@ApiModelProperty(value = "品牌")
private String brandName;
/** 厂家产品货号或编号 */
@ApiModelProperty(value = "厂家产品货号或编号")
private String productFactoryCode;
/** 产品编码 */
@ApiModelProperty(value = "产品编码")
private String productCode;
/** 规格 */
@ApiModelProperty(value = "规格")
private String specification;
/** 型号 */
@ApiModelProperty(value = "型号")
private String model;
/**
* @see MatchStatusEnum
*/
@ApiModelProperty(value = "对码状态: 对码状态:0-未开始、10-部分对码、20-100%对码、99-完全未对码")
private List<Integer> matchStatusList;
/**
* 处理状态:0-待处理、10-处理中、44-无需处理、100-已处理
* @see MatchUpdateStatusEnum
*/
@ApiModelProperty(value = "处理状态:0-待处理、10-处理中、44-无需处理、100-已处理")
private List<Integer> updateStatusList;
}
package com.infynova.udi.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author liudong
* 2024/3/26 18:06
* @version 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ApiModel(value = "UdiMatchTaskFileDto", description = "UdiMatchTaskFileDto")
public class UdiMatchTaskFileDto implements Serializable {
@ApiModelProperty(value = "文件地址")
private String filePath;
@ApiModelProperty(value = "文件名称")
private String fileName;
@ApiModelProperty(value = "文件id")
private Long fileId;
}
package com.infynova.udi.dto;
import com.infynova.common.core.entity.PageVo;
import com.infynova.udi.helper.validator.FixedValueValidator;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
import java.util.List;
@Data
public class UdiMatchTaskListQry extends PageVo {
@NotNull(message = "查询类型不能为空")
@FixedValueValidator(message = "查询类型值错误", fixedValue = {"0","1","99"})
@ApiModelProperty(value = "查询类型:0:上传中 1:已上传 99:全部")
private Integer queryType;
@ApiModelProperty(value = "任务状态",hidden = true)
private List<Integer> taskStatusList;
@ApiModelProperty(value = "任务编号")
private String taskNo;
@ApiModelProperty(value = "操作人")
private String operator;
@ApiModelProperty(value = "上传时间开始")
private LocalDate uploadTimeStart;
@ApiModelProperty(value = "上传时间结束")
private LocalDate uploadTimeEnd;
}
package com.infynova.udi.dto;
import com.infynova.udi.vo.UdiVo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* @author liudong
* 2024/4/29 10:38
* @version 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class UdiQueryDto implements Serializable {
private Integer total;
private List<UdiVo> data;
}
package com.infynova.udi.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.infynova.udi.enums.match.MatchStatusEnum;
import com.infynova.udi.enums.match.MatchUpdateStatusEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 对码实体类
* @author liudong
* 2024/3/1 15:41
* @version 1.0
*/
@Data
public class MatchData {
/** 主键ID,自增 */
@TableId(type = IdType.AUTO)
private Long id;
/** 任务ID */
@ApiModelProperty(value = "任务ID")
private Long taskId;
@TableField(exist = false)
@ApiModelProperty(value = "任务编码")
private String taskNo;
/**
* 对码状态:0-未开始、10-部分对码、20-100%对码、99-完全未对码
* @see MatchStatusEnum
*/
@ApiModelProperty(value = "对码状态:0-未开始 10-部分对码、20-100%对码、99-完全未对码")
private Integer matchStatus;
@TableField(exist = false)
@ApiModelProperty(value = "对码状态名称")
private String matchStatusDesc;
/**
* 处理状态:0-待处理、10-处理中、44-无需处理、100-已处理
* @see MatchUpdateStatusEnum
*/
@ApiModelProperty(value = "处理状态:0-待处理、10-处理中、44-无需处理、100-已处理")
private Integer updateStatus;
@TableField(exist = false)
@ApiModelProperty(value = "处理状态名称")
private String updateStatusDesc;
/** udi码 */
@ApiModelProperty(value = "udi码")
private String udiCode;
/** 医保一级编码 */
@ApiModelProperty(value = "医保一级编码")
private String yiBaoOneCode;
/** 医保二级编码 */
@ApiModelProperty(value = "医保二级编码")
private String yiBaoTwoCode;
/** 医保编码 */
@ApiModelProperty(value = "医保编码")
private String yiBaoCode;
/** 医保编码前缀 */
@ApiModelProperty(value = "医保编码前缀")
private String yiBaoCodePrefix;
/** 企业名称 */
@ApiModelProperty(value = "企业名称")
private String companyName;
/** 品牌 */
@ApiModelProperty(value = "品牌")
private String brandName;
/** 注册备案号(注册证) */
@ApiModelProperty(value = "注册备案号(注册证)")
private String registryNo;
/** 注册备案产品名称 */
@ApiModelProperty(value = "注册备案产品名称")
private String registryName;
/** 注册备案批准日期 */
@ApiModelProperty(value = "注册备案批准日期")
private LocalDate registryStartTime;
/** 注册备案有效期 */
@ApiModelProperty(value = "注册备案有效期")
private LocalDate registryEndTime;
/** 注册备案人 */
@ApiModelProperty(value = "注册备案人")
private String registry;
/** 产品编码 */
@ApiModelProperty(value = "产品编码")
private String productCode;
/** 厂家产品货号或编号 */
@ApiModelProperty(value = "厂家产品货号或编号")
private String productFactoryCode;
/** 无境UDI库分配编码 */
@ApiModelProperty(value = "无境UDI库分配编码")
private String infynovaCode;
/** 单件产品名称 */
@ApiModelProperty(value = "单件产品名称")
private String productName;
/** 产品类型 */
@ApiModelProperty(value = "产品类型")
private String productType;
/** 规格 */
@ApiModelProperty(value = "规格")
private String specification;
/** 型号 */
@ApiModelProperty(value = "型号")
private String model;
/** 材质 */
@ApiModelProperty(value = "材质")
private String material;
/** 是否为无菌包装 0:否 1:是 */
@ApiModelProperty(value = "是否为无菌包装 0:否 1:是")
private Boolean asepticPackaging;
@TableField(exist = false)
@ApiModelProperty(value = "是否为无菌包装")
private String asepticPackagingDesc;
/** 使用前是否需要进行灭菌 0:否 1:是 */
@ApiModelProperty(value = "使用前是否需要进行灭菌 0:否 1:是")
private Boolean beforeSterilize;
@TableField(exist = false)
@ApiModelProperty(value = "使用前是否需要进行灭菌")
private String beforeSterilizeDesc;
/** 灭菌方式 */
@ApiModelProperty(value = "灭菌方式")
private String sterilizationMethod;
/** 创建人id */
@ApiModelProperty(value = "创建人id")
private Long createBy;
/** 创建人 */
@ApiModelProperty(value = "创建人")
private String createName;
/** 创建时间 */
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
/** 修改人id */
@ApiModelProperty(value = "修改人id")
private Long updateBy;
/** 修改人 */
@ApiModelProperty(value = "修改人")
private String updateName;
/** 修改时间 */
@ApiModelProperty(value = "修改时间")
private LocalDateTime updateTime;
/** 版本号,默认为1 */
@ApiModelProperty(value = "版本号,默认为1")
@Version
@TableField(fill = FieldFill.INSERT_UPDATE, update="%s+1")
private Integer version;
}
package com.infynova.udi.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 对码表匹配表实体类
* @author liudong
* 2024/3/1 15:43
* @version 1.0
*/
@Data
public class MatchTemp {
/** 主键ID,自增 */
@TableId(type = IdType.AUTO)
private Long id;
/** 对码ID */
@ApiModelProperty(value = "对码ID")
private Long matchId;
/** 任务ID */
@ApiModelProperty(value = "任务ID")
private Long taskId;
/** 原始记录:0-否、1-是 */
@ApiModelProperty(value = "原始记录:0-否、1-是")
private Boolean originalRecord;
/** 匹配率 */
@ApiModelProperty(value = "匹配率")
private BigDecimal matchRate;
/** udi库主键ID */
@ApiModelProperty(value = "udi库主键ID")
private Long productId;
/** udi码 */
@ApiModelProperty(value = "udi码")
private String udiCode;
/** 医保一级编码 */
@ApiModelProperty(value = "医保一级编码")
private String yiBaoOneCode;
/** 医保二级编码 */
@ApiModelProperty(value = "医保二级编码")
private String yiBaoTwoCode;
/** 医保编码 */
@ApiModelProperty(value = "医保编码")
private String yiBaoCode;
/** 医保编码前缀 */
@ApiModelProperty(value = "医保编码前缀")
private String yiBaoCodePrefix;
/** 企业名称 */
@ApiModelProperty(value = "企业名称")
private String companyName;
/** 品牌 */
@ApiModelProperty(value = "品牌")
private String brandName;
/** 注册备案号(注册证) */
@ApiModelProperty(value = "注册备案号(注册证)")
private String registryNo;
/** 注册备案产品名称 */
@ApiModelProperty(value = "注册备案产品名称")
private String registryName;
/** 注册备案批准日期 */
@ApiModelProperty(value = "注册备案批准日期")
private LocalDate registryStartTime;
/** 注册备案有效期 */
@ApiModelProperty(value = "注册备案有效期")
private LocalDate registryEndTime;
/** 注册备案人 */
@ApiModelProperty(value = "注册备案人")
private String registry;
/** 产品编码 */
@ApiModelProperty(value = "产品编码")
private String productCode;
/** 厂家产品货号或编号 */
@ApiModelProperty(value = "厂家产品货号或编号")
private String productFactoryCode;
/** 无境UDI库分配编码 */
@ApiModelProperty(value = "无境UDI库分配编码")
private String infynovaCode;
/** 单件产品名称 */
@ApiModelProperty(value = "单件产品名称")
private String productName;
/** 产品类型 */
@ApiModelProperty(value = "产品类型")
private String productType;
/** 规格 */
@ApiModelProperty(value = "规格")
private String specification;
/** 型号 */
@ApiModelProperty(value = "型号")
private String model;
/** 材质 */
@ApiModelProperty(value = "材质")
private String material;
/** 是否为无菌包装 0:否 1:是 */
@ApiModelProperty(value = "是否为无菌包装 0:否 1:是")
private Boolean asepticPackaging;
/** 使用前是否需要进行灭菌 0:否 1:是 */
@ApiModelProperty(value = "使用前是否需要进行灭菌 0:否 1:是")
private Boolean beforeSterilize;
/** 灭菌方式 */
@ApiModelProperty(value = "灭菌方式")
private String sterilizationMethod;
/** 创建人id */
@ApiModelProperty(value = "创建人id")
private Long createBy;
/** 创建人 */
@ApiModelProperty(value = "创建人")
private String createName;
/** 创建时间 */
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
/** 修改人id */
@ApiModelProperty(value = "修改人id")
private Long updateBy;
/** 修改人 */
@ApiModelProperty(value = "修改人")
private String updateName;
/** 修改时间 */
@ApiModelProperty(value = "修改时间")
private LocalDateTime updateTime;
}
package com.infynova.udi.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.infynova.udi.enums.task.TaskMatchStatusEnum;
import com.infynova.udi.enums.task.TaskStatusEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author liudong
* 2024/2/29 15:40
* @version 1.0
*/
@Data
public class Task {
/** 主键ID,自增 */
@TableId(type = IdType.AUTO)
private Long id;
/** 任务编码 */
@ApiModelProperty(value = "任务编码")
private String taskNo;
/**
* @see TaskStatusEnum
* 任务上传状态:新建、暂停、完毕
* */
@ApiModelProperty(value = "任务上传状态:0-新建、10-上传中、11-暂停、20-完毕")
private Integer taskStatus;
@TableField(exist = false)
@ApiModelProperty(value = "任务上传状态-转换")
private String taskStatusDesc;
/** 上传文件大小 */
@ApiModelProperty(value = "上传文件大小")
private String taskFileSize;
@TableField(exist = false)
@ApiModelProperty(value = "上传文件大小-转换")
private String taskFileSizeDesc;
/** 上传文件后的数据量 */
@ApiModelProperty(value = "上传文件后的数据量")
private Integer taskFileCount;
/** 上传的数据量 */
@ApiModelProperty(value = "上传的数据量")
private Integer taskUploadNum;
/** 上传文件地址 */
@ApiModelProperty(value = "上传文件地址")
private String taskFileAddress;
/** 上传文件id */
@ApiModelProperty(value = "上传文件id - 获取地址用")
private Long taskFileId;
/** 上传耗时(以秒为单位保存) */
@ApiModelProperty(value = "上传耗时(以秒为单位保存)")
private Integer uploadTime;
@TableField(exist = false)
@ApiModelProperty(value = "上传耗时(以秒为单位保存)-展示")
private String uploadTimeDesc;
/**
* @see TaskMatchStatusEnum
* 对码状态:待对码、对码中、已对码 */
@ApiModelProperty(value = "对码状态:对码状态:0-待对码、10-对码中、99-已对码")
private Integer taskMatchStatus;
@TableField(exist = false)
@ApiModelProperty(value = "对码状态-转换")
private String taskMatchStatusDesc;
/** 对码耗时(以秒为单位保存) */
@ApiModelProperty(value = "对码耗时(以秒为单位保存)")
private Integer matchTime;
@TableField(exist = false)
@ApiModelProperty(value = "对码耗时(以秒为单位保存)-展示")
private String matchTimeDesc;
/** 操作人id */
@ApiModelProperty(value = "操作人id")
private Long operatorId;
/** 操作人 */
@ApiModelProperty(value = "操作人")
private String operator;
/** 创建人id */
@ApiModelProperty(value = "创建人id")
private Long createBy;
/** 创建人 */
@ApiModelProperty(value = "创建人")
private Long creator;
/** 创建时间 */
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
/** 修改时间 */
@ApiModelProperty(value = "修改时间")
private LocalDateTime updateTime;
/** 删除标识 */
@ApiModelProperty(value = "删除标识")
private Boolean delFlag;
/** 版本号,默认为1 */
@ApiModelProperty(value = "版本号")
@Version
@TableField(fill = FieldFill.INSERT_UPDATE, update="%s+1")
private Integer version;
}
package com.infynova.udi.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.infynova.udi.enums.task.TaskRecordEnum;
import com.infynova.udi.enums.task.TaskRecordTypeEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 任务操作记录实体类
* @author liudong
* 2024/2/29 16:14
* @version 1.0
*/
@Data
public class TaskRecord {
/** 主键ID,自增 */
@TableId(type = IdType.AUTO)
private Long id;
/** 任务ID */
@ApiModelProperty(value = "任务ID")
private Long taskId;
/**
* @see TaskRecordEnum
* 记录内容(任务操作记录:创建任务-启动上传-暂停上传-上传完成-启动对码-暂停对码-对码完成) */
@ApiModelProperty(value = "记录内容(任务操作记录:创建任务-启动上传-暂停上传-上传完成-启动对码-暂停对码-对码完成)")
private String record;
/**
* @see TaskRecordTypeEnum
* 记录标识:0-普通、1-上传、2-对码 */
@ApiModelProperty(value = "记录标识:0-普通、1-上传、2-对码")
private Integer recordType;
/** 创建人id */
@ApiModelProperty(value = "创建人id")
private Long createBy;
/** 创建人 */
@ApiModelProperty(value = "创建人")
private Long creator;
/** 创建时间 */
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
}
package com.infynova.udi.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* @author liudong
* 2024/2/22 16:42
* @version 1.0
*/
@Data
@ApiModel(value="udi", description="")
public class Udi implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "udi")
private String udiCode;
@ApiModelProperty(value = "医保一级编码")
private String yiBaoOneCode;
@ApiModelProperty(value = "医保二级编码")
private String yiBaoTwoCode;
@ApiModelProperty(value = "医保编码")
private String yiBaoCode;
@ApiModelProperty(value = "医保编码前缀")
private String yiBaoCodePrefix;
@ApiModelProperty(value = "企业名称")
private String companyName;
@ApiModelProperty(value = "品牌")
private String brandName;
@ApiModelProperty(value = "注册备案号(注册证)")
private String registryNo;
@ApiModelProperty(value = "注册备案产品名称")
private String registryName;
@ApiModelProperty(value = "注册备案批准日期")
private LocalDate registryStartTime;
@ApiModelProperty(value = "注册备案有效期")
private LocalDate registryEndTime;
@ApiModelProperty(value = "注册备案人")
private String registry;
@ApiModelProperty(value = "产品编码")
private String productCode;
@ApiModelProperty(value = "厂家产品货号/编号")
private String productFactoryCode;
@ApiModelProperty(value = "无境UDI库分配编码")
private String infynovaCode;
@ApiModelProperty(value = "单件产品名称")
private String productName;
@ApiModelProperty(value = "产品类型")
private String productType;
@ApiModelProperty(value = "规格")
private String specification;
@ApiModelProperty(value = "型号")
private String model;
@ApiModelProperty(value = "材质")
private String material;
@ApiModelProperty(value = "是否为无菌包装 0:否 1:是")
private Boolean asepticPackaging;
@ApiModelProperty(value = "使用前是否需要进行灭菌 0:否 1:是")
private Boolean beforeSterilize;
@ApiModelProperty(value = "灭菌方式")
private String sterilizationMethod;
@ApiModelProperty(value = "药监外部id")
private String yjForeignId;
@ApiModelProperty(value = "医保外部id")
private String ybForeignId;
@ApiModelProperty(value = "创建来源")
private String sourceName;
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
@ApiModelProperty(value = "修改时间")
private LocalDateTime updateTime;
@ApiModelProperty(value = "版本号")
private String version;
}
package com.infynova.udi.enums;
/**
* @author liudong
* 2023/4/7 14:01
* @version 1.0
*/
public interface UdiEnum {
/**
* 获取code
*/
public Integer getCode();
/**
* 获取desc
*/
public String getDesc();
}
package com.infynova.udi.enums;
import java.util.Objects;
/**
* @author liudong
* 2023/4/7 14:33
* @version 1.0
*/
public class UdiEnumUtils {
/**
* code是否存在
*/
public static <T extends UdiEnum> Boolean existsCode(Class<T> enumClass, Integer codeValue) {
for (T enumObj : enumClass.getEnumConstants()) {
if (Objects.equals(enumObj.getCode(),codeValue)) {
return true;
}
}
return false;
}
/**
* desc是否存在
*/
public static <T extends UdiEnum> Boolean existsDesc(Class<T> enumClass, String descValue) {
for (T enumObj : enumClass.getEnumConstants()) {
if (Objects.equals(enumObj.getDesc(),descValue)) {
return true;
}
}
return false;
}
/**
* 根据code获取desc
*/
public static <T extends UdiEnum> String getDescByCode(Class<T> enumClass, Integer codeValue) {
for (T enumObj : enumClass.getEnumConstants()) {
if (Objects.equals(enumObj.getCode(),codeValue)) {
return enumObj.getDesc();
}
}
return null;
}
/**
* 根据desc获取code
*/
public static <T extends UdiEnum> Integer getCodeByDesc(Class<T> enumClass, String descValue) {
for (T enumObj : enumClass.getEnumConstants()) {
if (Objects.equals(enumObj.getDesc(),descValue)) {
return enumObj.getCode();
}
}
return null;
}
}
package com.infynova.udi.enums.match;
import com.infynova.udi.enums.UdiEnum;
/**
* 任务对码状态枚举
* @author liudong
* @version 1.0
* 2024-03-04 16:15
*/
public enum MatchStatusEnum implements UdiEnum {
// 对码状态:0-未开始、10-部分对码、20-100%对码、99-完全未对码
WAITING(0, "未开始"),
SECTION(10, "部分对码"),
HUNDRED(20, "100%对码"),
NO(99, "完全未对码"),
;
private final Integer code;
private final String desc;
private MatchStatusEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
/**
* 获取code
*/
@Override
public Integer getCode() {
return this.code;
}
/**
* 获取desc
*/
@Override
public String getDesc() {
return this.desc;
}
}
package com.infynova.udi.enums.match;
import com.infynova.udi.enums.UdiEnum;
/**
* 处理状态状态枚举
* @author liudong
* @version 1.0
* 2024-03-13 16:15
*/
public enum MatchUpdateStatusEnum implements UdiEnum {
// 处理状态:0-待处理、10-处理中、44-无需处理、100-已处理
PENDING(0, "待处理"),
IN_PROGRESS(10, "处理中"),
NOT_APPLICABLE(44, "无需处理"),
PROCESSED(100, "已处理"),
;
private final Integer code;
private final String desc;
private MatchUpdateStatusEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
/**
* 获取code
*/
@Override
public Integer getCode() {
return this.code;
}
/**
* 获取desc
*/
@Override
public String getDesc() {
return this.desc;
}
}
package com.infynova.udi.enums.task;
import com.infynova.udi.enums.UdiEnum;
/**
* 任务对码状态枚举
* @author liudong
* @version 1.0
* 2024-02-29 16:15
*/
public enum TaskMatchStatusEnum implements UdiEnum {
// 对码状态:0-待对码、10-对码中、99-已对码
WAITING(0, "待对码"),
MATCHING(10, "对码中"),
FINISH(99, "已对码"),
;
private final Integer code;
private final String desc;
private TaskMatchStatusEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
/**
* 获取code
*/
@Override
public Integer getCode() {
return this.code;
}
/**
* 获取desc
*/
@Override
public String getDesc() {
return this.desc;
}
}
package com.infynova.udi.enums.task;
import com.infynova.udi.enums.UdiEnum;
/**
* 记录标识:0-普通、1-上传、2-对码
* @author liudong
* @version 1.0
* 2024-02-29 16:15
*/
public enum TaskRecordEnum implements UdiEnum {
//
IMPORT_BUILD(0, "导入-创建任务"),
UPLOAD_START(1, "启动上传"),
UPLOAD_PAUSE(2, "暂停上传"),
UPLOAD_FINISH(3, "上传完成"),
MATCH_START(4, "启动对码"),
MATCH_PAUSE(5, "暂停对码"),
MATCH_FINISH(6, "对码完成"),
DELETE(99, "删除任务"),
;
private final Integer code;
private final String desc;
private TaskRecordEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
/**
* 获取code
*/
@Override
public Integer getCode() {
return this.code;
}
/**
* 获取desc
*/
@Override
public String getDesc() {
return this.desc;
}
}
package com.infynova.udi.enums.task;
import com.infynova.udi.enums.UdiEnum;
/**
* 记录标识:0-普通、1-上传、2-对码
* @author liudong
* @version 1.0
* 2024-02-29 16:15
*/
public enum TaskRecordTypeEnum implements UdiEnum {
// 0-新建、10-上传中、11-暂停、20-完毕
DEFAULT(0, "普通"),
UPLOAD(1, "上传"),
MATCH(2, "对码"),
;
private final Integer code;
private final String desc;
private TaskRecordTypeEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
/**
* 获取code
*/
@Override
public Integer getCode() {
return this.code;
}
/**
* 获取desc
*/
@Override
public String getDesc() {
return this.desc;
}
}
package com.infynova.udi.enums.task;
import com.infynova.udi.enums.UdiEnum;
import java.util.Objects;
/**
* 任务状态枚举
* @author liudong
* @version 1.0
* 2024-02-29 16:15
*/
public enum TaskStatusEnum implements UdiEnum {
// 0-新建、10-上传中、11-暂停、20-完毕
NEW_TASK(0, "新建"),
UPLOADING(10, "上传中"),
PAUSE(11, "暂停"),
FINISH(20, "完毕"),
DELETE(99, "删除"),
;
private final Integer code;
private final String desc;
private TaskStatusEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
/**
* 获取code
*/
@Override
public Integer getCode() {
return this.code;
}
/**
* 获取desc
*/
@Override
public String getDesc() {
return this.desc;
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.exception;
import com.infynova.common.core.api.ServiceCode;
/**
* @author zoupx
* @email
* @date 2020-03-30 17:33
* @description: WEB 异常码
*/
public enum CommonExceptionCode implements ServiceCode {
SYSTEM_500(500, "未知异常,请联系管理员"),
SYSTEM_501(500, "入参错误或入参不全"),
SYSTEM_502(502, "服务调用异常"),
SYSTEM_503(504, "服务调用超时"),
SYSTEM_400(400, "请求错误"),
SYSTEM_401(401, "token失效,请重新登录。"),
SYSTEM_403(403, "接口未授权,请联系管理员"),
SYSTEM_404(404, "路径不存在,请检查路径是否正确"),
SYSTEM_405(405, "请求方式错误"),
SYSTEM_406(406, "已存在下级组织,禁止删除"),
SYSTEM_409(409, "添加的数据已存在,禁止重复添加!"),
SYSTEM_412(412, "不满足条件,禁止添加!"),
SYSTEM_416(416, "已达到添加上限,禁止添加下一层级!"),
SYSTEM_417(417, "token为空,请重新登录!"),
SYSTEM_460(46012, "上传文件太大。"),
SYSTEM_480(48010, "数据重复。"),
SENTINEL_FLOW(429, "操作过于频繁稍后重试 [Sentinel]"),
SENTINEL_DEGRADE_FLOW(430, "服务降级,请稍后重试 [Sentinel]"),
SENTINEL_PARAM_FLOW(431, "参数访问过于频繁,请稍后重试 [Sentinel]"),
SENTINEL_SYSTEM_BLOCK(432, "系统异常,繁稍后重试 [Sentinel]"),
SENTINEL_AUTHORITY(433, "服务授权异常,稍后重试 [Sentinel]"),
JWT_TOKEN_EXPIRED(401031, "token已失效,请重新登录"),
JWT_SIGNATURE(401032, "token签名错误,请重新登录"),
JWT_ILLEGAL_ARGUMENT(401033, "token为空,请重新登录"),
JWT_PARSER_TOKEN_FAIL(401034, "token解析失败,请重新登录"),
TENANT_AUTH_NULL(701, "租户未开通此端权限"),
OPT_ERROR(702, "演示环境不可操作"),
NO_OPEN_PERMISSION(703, "该账户尚未开通任何权限"),
HTTP_REQUEST_ERROR(405011, "请求方式错误"),
;
private int code;
private String msg;
CommonExceptionCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public int getCode() {
return this.code;
}
@Override
public String getMsg() {
return this.msg;
}
public void setCode(int code) {
this.code = code;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
package com.infynova.udi.exception;
import com.infynova.common.core.api.ServiceCode;
/**
* @author liudong
* 2022/12/21 20:00
*/
public class UdiCodeException extends RuntimeException {
private ServiceCode code;
public ServiceCode getCode() {
return code;
}
public UdiCodeException(ServiceCode code) {
super(code.getMsg());
this.code = code;
}
public UdiCodeException(int code,String msg){
this.code = new ServiceCode() {
/**
* 响应编码
*/
@Override
public int getCode() {
return code;
}
/**
* 响应描述
*/
@Override
public String getMsg() {
return msg;
}
};
}
}
package com.infynova.udi.exception;
import com.infynova.common.core.api.ResponseData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
@Slf4j
@Order(value = 1)
@RestControllerAdvice
public class UdiExceptionHandler {
/**
* 验证异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseData handlerNoFoundException(MethodArgumentNotValidException e, HttpServletResponse response) {
response.setStatus(200);
return ResponseData.error(CommonExceptionCode.SYSTEM_501.getCode(), Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
}
/**
* 验证异常get
*/
@ExceptionHandler(BindException.class)
public ResponseData handlerNoFoundGetException(BindException e, HttpServletResponse response) {
response.setStatus(200);
return ResponseData.error(CommonExceptionCode.SYSTEM_501.getCode(), Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
}
/**
* 业务异常
*/
@ExceptionHandler(UdiCodeException.class)
public ResponseData handlerNoFoundException(UdiCodeException e, HttpServletResponse response) {
response.setStatus(200);
return ResponseData.error(e.getCode());
}
}
package com.infynova.udi.helper;
import com.alibaba.excel.EasyExcel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.List;
/**
* @author liudong
* 2023/11/6 19:09
* @version 1.0
*/
@Slf4j
@Component("udiEasyExcelHelper")
public class UdiEasyExcelHelper {
public static <T> void exportTemplate(String name, Class<T> entity) throws IOException {
List<T> list = Collections.emptyList();
export(name, list, entity);
}
public static <T> void export(String name, List<T> list, Class<T> entity) throws IOException {
String sheetName = name;
export(name, sheetName, list, entity);
}
public static <T> void export(String name, String sheetName, List<T> list, Class<T> entity) throws IOException {
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
export(response,name,sheetName,list,entity);
}
public static <T> void export(HttpServletResponse response,String name,String sheetName, List<T> list, Class<T> entity) throws IOException {
log.info("导出excel~");
// 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode(name, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), entity)
.sheet(sheetName)
.doWrite(list);
}
}
package com.infynova.udi.helper.validator;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.Arrays;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 枚举值自定义校验
* 2023/4/2 12:06
* @author derTraum
* @since 1.0.0
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {EnumValueValidator.EnumValidator.class})
public @interface EnumValueValidator {
String message() default "FixedValue's value is invalid";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Class<? extends Enum<?>> enumClass();
class EnumValidator implements ConstraintValidator<EnumValueValidator, Object> {
private EnumValueValidator annotation;
@Override
public void initialize(EnumValueValidator constraintAnnotation) {
this.annotation = constraintAnnotation;
}
@Override
public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
if (o == null) {
return true; // 允许为空
}
Enum<?>[] enumValues = annotation.enumClass().getEnumConstants();
return Arrays.asList(enumValues).contains(o);
}
}
}
package com.infynova.udi.helper.validator;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 入参自定义值校验
* 2023/4/2 12:05
* @author derTraum
* @since 1.0.0
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {FixedValueValidator.FixedValueValid.class})
public @interface FixedValueValidator {
String message() default "FixedValue's value is invalid";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String[] fixedValue();
class FixedValueValid implements ConstraintValidator<FixedValueValidator, Object> {
String[] fixedValue = null;
public void initialize(FixedValueValidator validData) {
this.fixedValue = validData.fixedValue();
}
public boolean isValid(Object value, ConstraintValidatorContext constraintContext) {
if (fixedValue == null || fixedValue.length == 0 ) {
return false;
}
if (value == null) {
return true;
}
boolean flag = false;
for (String str : fixedValue) {
if (String.valueOf(value).equals(String.valueOf(str))) {
flag = true;
break;
}
}
return flag;
}
}
}
package com.infynova.udi.utils;
import java.util.Objects;
/**
* @author liudong
* 2023/4/7 14:33
* @version 1.0
*/
public class BooleanValueUtils {
public static String getBooleanValue(Boolean value){
if(Objects.isNull(value)){
return "";
}
return value?"是":"否";
}
public static Boolean getBoolean(String item){
if(Objects.isNull(item)){
return null;
}
switch (item){
case "是":
return true;
case "否":
return false;
default:
return null;
}
}
public static Integer getBooleanInt(Boolean value){
if(Objects.isNull(value)){
return null;
}
return value?1:0;
}
}
package com.infynova.udi.vo;
import com.infynova.udi.enums.match.MatchStatusEnum;
import com.infynova.udi.enums.match.MatchUpdateStatusEnum;
import com.infynova.udi.enums.task.TaskMatchStatusEnum;
import com.infynova.udi.enums.task.TaskStatusEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author liudong
* 2024/3/12 12:03
* @version 1.0
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class CommonEnumList {
/**
* @see TaskStatusEnum
* 任务上传状态:0-新建、10-上传中、11-暂停、20-完毕
*/
@ApiModelProperty(value = "任务上传状态:0-新建、10-上传中、11-暂停、20-完毕")
private List<enumValue> taskStatus;
/**
* @see TaskMatchStatusEnum
* 对码状态:对码状态:0-待对码、10-对码中、99-已对码
*/
@ApiModelProperty(value = "对码状态:对码状态:0-待对码、10-对码中、99-已对码")
private List<enumValue> taskMatchStatus;
/**
* 对码状态:0-未开始、10-部分对码、20-100%对码、99-完全未对码
* @see MatchStatusEnum
*/
@ApiModelProperty(value = "对码状态:0-未开始 10-部分对码、20-100%对码、99-完全未对码")
private List<enumValue> matchStatus;
/**
* 处理状态:0-待处理、10-处理中、44-无需处理、100-已处理
* @see MatchUpdateStatusEnum
*/
@ApiModelProperty(value = "处理状态:0-待处理、10-处理中、44-无需处理、100-已处理")
private List<enumValue> updateStatus;
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public static class enumValue{
private Integer code;
private String value;
}
}
package com.infynova.udi.vo;
import com.infynova.common.core.api.BaseVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author liudong
* 2024/2/29 16:18
* @version 1.0
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class TaskMatchStatisticVo extends BaseVo {
@ApiModelProperty(value = "任务id")
private Long taskId;
@ApiModelProperty(value = "任务编码")
private String taskNo;
@ApiModelProperty(value = "总数据")
private Integer total = 0;
@ApiModelProperty(value = "待上传")
private Integer uploadWaiting = 0;
@ApiModelProperty(value = "已上传")
private Integer uploadFinish = 0;
@ApiModelProperty(value = "100%对码")
private Integer hundred = 0;
@ApiModelProperty(value = "部分对码")
private Integer section = 0;
@ApiModelProperty(value = "完全未对码")
private Integer never = 0;
@ApiModelProperty(value = "待对码")
private Integer waiting = 0;
}
package com.infynova.udi.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author liudong
* 2024/2/29 14:28
* @version 1.0
*/
@Data
public class TaskUdiExcelExportVo extends TaskUdiExcelVo {
@ExcelProperty(value = "结果",order = 0)
@ColumnWidth(20)
@ApiModelProperty(value = "结果")
private String result;
}
package com.infynova.udi.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* @author liudong
* 2024/2/29 14:28
* @version 1.0
*/
@Data
public class TaskUdiExcelImportVo extends TaskUdiExcelVo {
}
package com.infynova.udi.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* @author liudong
* 2024/2/29 14:16
* @version 1.0
*/
@Data
public class TaskUdiExcelVo {
// DI码、医保一级编码、医保二级编码、医保编码、医保编码前缀、
@ExcelProperty(value = "DI码",order = 0)
@ColumnWidth(20)
@ApiModelProperty(value = "udi")
private String udiCode;
@ExcelProperty(value = "医保一级编码",order = 1)
@ColumnWidth(20)
@ApiModelProperty(value = "医保一级编码")
private String yiBaoOneCode;
@ExcelProperty(value = "医保二级编码",order = 2)
@ColumnWidth(20)
@ApiModelProperty(value = "医保二级编码")
private String yiBaoTwoCode;
@ExcelProperty(value = "医保编码",order = 3)
@ColumnWidth(20)
@ApiModelProperty(value = "医保编码")
private String yiBaoCode;
@ExcelProperty(value = "医保编码前缀",order = 4)
@ColumnWidth(20)
@ApiModelProperty(value = "医保编码前缀")
private String yiBaoCodePrefix;
// 企业名称、品牌、注册备案号、注册备案产品名称、注册备案批准日期、注册备案有效期、注册备案人、
@ExcelProperty(value = "企业名称",order = 5)
@ColumnWidth(20)
@ApiModelProperty(value = "企业名称")
private String companyName;
@ExcelProperty(value = "品牌",order = 6)
@ColumnWidth(20)
@ApiModelProperty(value = "品牌")
private String brandName;
@ExcelProperty(value = "注册备案号",order = 7)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案号(注册证)")
private String registryNo;
@ExcelProperty(value = "注册备案产品名称",order = 8)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案产品名称")
private String registryName;
@ExcelProperty(value = "注册备案批准日期",order = 9)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案批准日期")
private String registryStartTime;
@ExcelProperty(value = "注册备案有效期",order = 10)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案有效期")
private String registryEndTime;
@ExcelProperty(value = "注册备案人",order = 11)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案人")
private String registry;
// 产品编码、厂家产品货号/编号、无境UDI库分配编码、单件产品名称、产品类型、规格、型号、材质、是否为无菌包装、使用前是否需要进行灭菌、灭菌方式;
@ExcelProperty(value = "产品编码",order = 12)
@ColumnWidth(20)
@ApiModelProperty(value = "产品编码")
private String productCode;
@ExcelProperty(value = "厂家产品货号/编号",order = 13)
@ColumnWidth(20)
@ApiModelProperty(value = "厂家产品货号/编号")
private String productFactoryCode;
// @ExcelProperty(value = "无境UDI库分配编码",order = 14)
// @ColumnWidth(20)
// @ApiModelProperty(value = "无境UDI库分配编码")
// private String infynovaCode;
@ExcelProperty(value = "单件产品名称",order = 15)
@ColumnWidth(20)
@ApiModelProperty(value = "单件产品名称")
private String productName;
@ExcelProperty(value = "产品类型",order = 16)
@ColumnWidth(20)
@ApiModelProperty(value = "产品类型")
private String productType;
@ExcelProperty(value = "规格",order = 17)
@ColumnWidth(20)
@ApiModelProperty(value = "规格")
private String specification;
@ExcelProperty(value = "型号",order = 18)
@ColumnWidth(20)
@ApiModelProperty(value = "型号")
private String model;
@ExcelProperty(value = "材质",order = 19)
@ColumnWidth(20)
@ApiModelProperty(value = "材质")
private String material;
@ExcelProperty(value = "是否为无菌包装",order = 20)
@ColumnWidth(20)
@ApiModelProperty(value = "是否为无菌包装 0:否 1:是")
private String asepticPackaging;
@ExcelProperty(value = "使用前是否需要进行灭菌",order = 21)
@ColumnWidth(20)
@ApiModelProperty(value = "使用前是否需要进行灭菌 0:否 1:是")
private String beforeSterilize;
@ExcelProperty(value = "灭菌方式",order = 22)
@ColumnWidth(20)
@ApiModelProperty(value = "灭菌方式")
private String sterilizationMethod;
}
package com.infynova.udi.vo;
import com.infynova.udi.entity.Task;
import com.infynova.udi.entity.TaskRecord;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author liudong
* 2024/2/29 16:18
* @version 1.0
*/
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class TaskVo {
private Task task;
private List<TaskRecord> taskRecordList;
}
package com.infynova.udi.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.infynova.common.core.api.BaseVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author liudong
* 2024/2/22 17:17
* @version 1.0
*/
@Data
public class UdiExportVo extends BaseVo {
@ExcelProperty(value = "DI码",order = 0)
@ColumnWidth(20)
@ApiModelProperty(value = "udi")
private String udiCode;
@ExcelProperty(value = "医保一级编码",order = 1)
@ColumnWidth(20)
@ApiModelProperty(value = "医保一级编码")
private String yiBaoOneCode;
@ExcelProperty(value = "医保二级编码",order = 2)
@ColumnWidth(20)
@ApiModelProperty(value = "医保二级编码")
private String yiBaoTwoCode;
@ExcelProperty(value = "医保编码",order = 3)
@ColumnWidth(20)
@ApiModelProperty(value = "医保编码")
private String yiBaoCode;
@ExcelProperty(value = "医保编码前缀",order = 4)
@ColumnWidth(20)
@ApiModelProperty(value = "医保编码前缀")
private String yiBaoCodePrefix;
@ExcelProperty(value = "企业名称",order = 5)
@ColumnWidth(20)
@ApiModelProperty(value = "企业名称")
private String companyName;
@ExcelProperty(value = "品牌",order = 6)
@ColumnWidth(20)
@ApiModelProperty(value = "品牌")
private String brandName;
@ExcelProperty(value = "注册备案号",order = 7)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案号(注册证)")
private String registryNo;
@ExcelProperty(value = "注册备案产品名称",order = 8)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案产品名称")
private String registryName;
@ExcelProperty(value = "注册备案批准日期",order = 9)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案批准日期")
private String registryStartTime;
@ExcelProperty(value = "注册备案有效期",order = 10)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案有效期")
private String registryEndTime;
@ExcelProperty(value = "注册备案人",order = 11)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案人")
private String registry;
@ExcelProperty(value = "产品编码",order = 12)
@ColumnWidth(20)
@ApiModelProperty(value = "产品编码")
private String productCode;
@ExcelProperty(value = "厂家产品货号/编号",order = 13)
@ColumnWidth(20)
@ApiModelProperty(value = "厂家产品货号/编号")
private String productFactoryCode;
@ExcelProperty(value = "无境UDI库分配编码",order = 14)
@ColumnWidth(20)
@ApiModelProperty(value = "无境UDI库分配编码")
private String infynovaCode;
@ExcelProperty(value = "单件产品名称",order = 15)
@ColumnWidth(20)
@ApiModelProperty(value = "单件产品名称")
private String productName;
@ExcelProperty(value = "产品类型",order = 16)
@ColumnWidth(20)
@ApiModelProperty(value = "产品类型")
private String productType;
@ExcelProperty(value = "规格",order = 17)
@ColumnWidth(20)
@ApiModelProperty(value = "规格")
private String specification;
@ExcelProperty(value = "型号",order = 18)
@ColumnWidth(20)
@ApiModelProperty(value = "型号")
private String model;
@ExcelProperty(value = "材质",order = 19)
@ColumnWidth(20)
@ApiModelProperty(value = "材质")
private String material;
@ExcelProperty(value = "是否为无菌包装",order = 20)
@ColumnWidth(20)
@ApiModelProperty(value = "是否为无菌包装 0:否 1:是")
private String asepticPackaging;
@ExcelProperty(value = "使用前是否需要进行灭菌",order = 21)
@ColumnWidth(20)
@ApiModelProperty(value = "使用前是否需要进行灭菌 0:否 1:是")
private String beforeSterilize;
@ExcelProperty(value = "灭菌方式",order = 22)
@ColumnWidth(20)
@ApiModelProperty(value = "灭菌方式")
private String sterilizationMethod;
}
package com.infynova.udi.vo;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.infynova.common.core.api.BaseVo;
import com.infynova.udi.enums.match.MatchStatusEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author liudong
* 2024/2/22 19:11
* @version 1.0
*/
@Data
public class UdiMatchDataExportVo extends BaseVo {
@ExcelProperty(value = "任务编码",order = 0)
@ColumnWidth(20)
@ApiModelProperty(value = "任务编码")
private String taskNo;
/**
* 对码状态:0-未开始、10-部分对码、20-100%对码、99-完全未对码
* @see MatchStatusEnum
*/
@ExcelIgnore
@ApiModelProperty(value = "对码状态:0-未开始 10-部分对码、20-100%对码、99-完全未对码")
private Integer matchStatus;
@ExcelProperty(value = "对码状态",order = 2)
@ColumnWidth(20)
@ApiModelProperty(value = "对码状态名称")
private String matchStatusDesc;
/** udi码 */
@ExcelProperty(value = "DI码",order = 1)
@ColumnWidth(20)
@ApiModelProperty(value = "udi码")
private String udiCode;
/** 医保一级编码 */
@ExcelProperty(value = "医保一级编码",order = 3)
@ColumnWidth(20)
@ApiModelProperty(value = "医保一级编码")
private String yiBaoOneCode;
/** 医保二级编码 */
@ExcelProperty(value = "医保二级编码",order = 4)
@ColumnWidth(20)
@ApiModelProperty(value = "医保二级编码")
private String yiBaoTwoCode;
/** 医保编码 */
@ExcelProperty(value = "医保编码",order = 5)
@ColumnWidth(20)
@ApiModelProperty(value = "医保编码")
private String yiBaoCode;
/** 医保编码前缀 */
@ExcelProperty(value = "医保编码前缀",order = 6)
@ColumnWidth(20)
@ApiModelProperty(value = "医保编码前缀")
private String yiBaoCodePrefix;
/** 企业名称 */
@ExcelProperty(value = "企业名称",order = 7)
@ColumnWidth(20)
@ApiModelProperty(value = "企业名称")
private String companyName;
/** 品牌 */
@ExcelProperty(value = "品牌",order = 8)
@ColumnWidth(20)
@ApiModelProperty(value = "品牌")
private String brandName;
/** 注册备案号(注册证) */
@ExcelProperty(value = "注册备案号",order = 9)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案号(注册证)")
private String registryNo;
/** 注册备案产品名称 */
@ExcelProperty(value = "注册备案产品名称",order = 10)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案产品名称")
private String registryName;
/** 注册备案批准日期 */
@ExcelProperty(value = "注册备案批准日期",order = 11)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案批准日期")
private LocalDateTime registryStartTime;
/** 注册备案有效期 */
@ExcelProperty(value = "注册备案有效期",order = 12)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案有效期")
private LocalDateTime registryEndTime;
/** 注册备案人 */
@ExcelProperty(value = "注册备案人",order = 13)
@ColumnWidth(20)
@ApiModelProperty(value = "注册备案人")
private String registry;
/** 产品编码 */
@ExcelProperty(value = "产品编码",order = 14)
@ColumnWidth(20)
@ApiModelProperty(value = "产品编码")
private String productCode;
/** 厂家产品货号或编号 */
@ExcelProperty(value = "厂家产品货号/编号",order = 15)
@ColumnWidth(20)
@ApiModelProperty(value = "厂家产品货号或编号")
private String productFactoryCode;
/** 无境UDI库分配编码 */
@ExcelIgnore
@ApiModelProperty(value = "无境UDI库分配编码")
private String infynovaCode;
/** 单件产品名称 */
@ExcelProperty(value = "单件产品名称",order = 16)
@ColumnWidth(20)
@ApiModelProperty(value = "单件产品名称")
private String productName;
/** 产品类型 */
@ExcelProperty(value = "产品类型",order = 17)
@ColumnWidth(20)
@ApiModelProperty(value = "产品类型")
private String productType;
/** 规格 */
@ExcelProperty(value = "规格",order = 18)
@ColumnWidth(20)
@ApiModelProperty(value = "规格")
private String specification;
/** 型号 */
@ExcelProperty(value = "型号",order = 19)
@ColumnWidth(20)
@ApiModelProperty(value = "型号")
private String model;
/** 材质 */
@ExcelProperty(value = "材质",order = 20)
@ColumnWidth(20)
@ApiModelProperty(value = "材质")
private String material;
/** 是否为无菌包装 0:否 1:是 */
@ExcelIgnore
@ApiModelProperty(value = "是否为无菌包装 0:否 1:是")
private Boolean asepticPackaging;
@ExcelProperty(value = "是否为无菌包装",order = 21)
@ColumnWidth(20)
@ApiModelProperty(value = "是否为无菌包装")
private String asepticPackagingDesc;
/** 使用前是否需要进行灭菌 0:否 1:是 */
@ExcelIgnore
@ApiModelProperty(value = "使用前是否需要进行灭菌 0:否 1:是")
private Boolean beforeSterilize;
@ExcelProperty(value = "使用前是否需要进行灭菌",order = 22)
@ColumnWidth(20)
@ApiModelProperty(value = "使用前是否需要进行灭菌")
private String beforeSterilizeDesc;
/** 灭菌方式 */
@ExcelProperty(value = "灭菌方式",order = 23)
@ColumnWidth(20)
@ApiModelProperty(value = "灭菌方式")
private String sterilizationMethod;
}
package com.infynova.udi.vo;
import com.infynova.udi.entity.MatchData;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author liudong
* 2024/2/22 19:11
* @version 1.0
*/
@Data
public class UdiMatchDataVo extends MatchData {
}
package com.infynova.udi.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author liudong
* 2024/2/22 17:58
* @version 1.0
*/
@Data
public class UdiMatchListVo {
private Long id;
@ApiModelProperty(value = "任务编号")
private String taskNo;
@ApiModelProperty(value = "任务上传状态:0-新建、10-上传中、11-暂停、20-完毕")
private Integer taskStatus;
@ApiModelProperty(value = "任务上传状态:0-新建、10-上传中、11-暂停、20-完毕")
private String taskStatusDesc;
@ApiModelProperty(value = "大小")
private String taskFileSize;
@ApiModelProperty(value = "大小-转换展示")
private String taskFileSizeDesc;
@ApiModelProperty(value = "数据量")
private Integer taskFileCount;
@ApiModelProperty(value = "上传的数据量")
private Integer taskUploadNum;
@ApiModelProperty(value = "上传文件地址")
private String taskFileAddress;
@ApiModelProperty(value = "上传文件id - 获取地址用")
private Long taskFileId;
@ApiModelProperty(value = "上传耗时")
private Integer uploadTime;
@ApiModelProperty(value = "上传耗时-展示")
private String uploadTimeDesc;
@ApiModelProperty(value = "对码状态:对码状态:0-待对码、10-对码中、99-已对码")
private Integer taskMatchStatus;
@ApiModelProperty(value = "对码状态:对码状态:0-待对码、10-对码中、99-已对码")
private String taskMatchStatusDesc;
@ApiModelProperty(value = "对码耗时")
private Integer matchTime;
@ApiModelProperty(value = "对码耗时-展示")
private String matchTimeDesc;
@ApiModelProperty(value = "上传时间")
private String createTime;
@ApiModelProperty(value = "操作人")
private String operator;
@ApiModelProperty(value = "版本号")
private Integer version;
}
package com.infynova.udi.vo;
import com.infynova.udi.entity.Udi;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* @author liudong
* 2024/2/22 17:16
* @version 1.0
*/
@Data
public class UdiMatchRateVo extends Udi {
@ApiModelProperty(value = "匹配率")
private BigDecimal matchRatio;
@ApiModelProperty(value = "输入值")
private String userItem;
}
package com.infynova.udi.vo;
import com.infynova.udi.entity.Udi;
/**
* @author liudong
* 2024/2/22 17:16
* @version 1.0
*/
public class UdiVo extends Udi {
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>saas-udi</artifactId>
<groupId>com.infynova</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>saas-udi-service</artifactId>
<properties>
<jetcache.version>2.6.2</jetcache.version>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<exclusions>
<exclusion>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.infynova</groupId>
<artifactId>saas-udi-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alicp.jetcache</groupId>
<artifactId>jetcache-starter-redis</artifactId>
<version>${jetcache.version}</version>
</dependency>
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.7.0</version>
</dependency>
<!-- ikAnalyzer 中文分词器 -->
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
<exclusions>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- lucene-queryParser 查询分析器模块 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>7.3.0</version>
</dependency>
<!-- sqlite jdbc 驱动 -->
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.45.1.0</version>
</dependency>
<dependency>
<groupId>com.redislabs</groupId>
<artifactId>jredisearch</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.12.0</version>
</dependency>
<!-- elasticsearch 的客户端 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.12.0</version>
</dependency>
<!-- elasticsearch 依赖 2.x 的 log4j -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
<dependency>
<groupId>com.infynova</groupId>
<artifactId>saas-ucpm-api</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../libs/saas-ucpm-api-1.0.0.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!--跳过测试-->
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.infynova.udi;
import com.alicp.jetcache.anno.config.EnableMethodCache;
import com.infynova.udi.constant.UdiConstant;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@Slf4j
@EnableAsync
@EnableScheduling
@EnableConfigurationProperties
@EnableFeignClients(basePackages = {UdiConstant.INFYNOVA_PACKAGE_NAME})
@EnableDiscoveryClient
@MapperScan(UdiConstant.MAPPER_PACKAGE_NAME)
@EnableMethodCache(basePackages = {UdiConstant.UDI_PACKAGE_NAME})
@SpringBootApplication(scanBasePackages = {"com.infynova.udi"})
public class UdiApplication {
public static void main(String[] args) {
SpringApplication.run(UdiApplication.class, args);
}
}
package com.infynova.udi.controller;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infynova.common.core.api.ResponseData;
import com.infynova.udi.enums.match.MatchStatusEnum;
import com.infynova.udi.enums.match.MatchUpdateStatusEnum;
import com.infynova.udi.enums.task.TaskMatchStatusEnum;
import com.infynova.udi.enums.task.TaskStatusEnum;
import com.infynova.udi.vo.CommonEnumList;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author liudong
* 2024/3/12 12:01
* @version 1.0
*/
@Slf4j
@Api(tags = "对码平台-公共接口")
@ApiSupport(order = 1)
@RestController
@RequestMapping("/common")
public class CommonController {
@ApiOperationSupport(order = 100)
@ApiOperation(value = "获取枚举", notes = "获取枚举")
@GetMapping("getEnumList")
public ResponseData<CommonEnumList> getEnumList(){
log.info("getEnumList");
return ResponseData.ok(this.get());
}
private CommonEnumList get(){
List<CommonEnumList.enumValue> taskStatus = new ArrayList<>();
for (TaskStatusEnum value : TaskStatusEnum.values()) {
CommonEnumList.enumValue enumValue = CommonEnumList.enumValue.builder().code(value.getCode()).value(value.getDesc()).build();
taskStatus.add(enumValue);
}
List<CommonEnumList.enumValue> taskMatchStatus = new ArrayList<>();
for (TaskMatchStatusEnum value : TaskMatchStatusEnum.values()) {
CommonEnumList.enumValue enumValue = CommonEnumList.enumValue.builder().code(value.getCode()).value(value.getDesc()).build();
taskMatchStatus.add(enumValue);
}
List<CommonEnumList.enumValue> matchStatus = new ArrayList<>();
for (MatchStatusEnum value : MatchStatusEnum.values()) {
CommonEnumList.enumValue enumValue = CommonEnumList.enumValue.builder().code(value.getCode()).value(value.getDesc()).build();
matchStatus.add(enumValue);
}
List<CommonEnumList.enumValue> updateStatus = new ArrayList<>();
for (MatchUpdateStatusEnum value : MatchUpdateStatusEnum.values()) {
CommonEnumList.enumValue enumValue = CommonEnumList.enumValue.builder().code(value.getCode()).value(value.getDesc()).build();
updateStatus.add(enumValue);
}
return CommonEnumList.builder()
.taskStatus(taskStatus)
.taskMatchStatus(taskMatchStatus)
.matchStatus(matchStatus)
.updateStatus(updateStatus)
.build();
}
}
package com.infynova.udi.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infynova.common.core.api.ResponseData;
import com.infynova.udi.dto.UdiListQry;
import com.infynova.udi.helper.UdiEasyExcelHelper;
import com.infynova.udi.service.UdiService;
import com.infynova.udi.service.helper.EsSearchHelper;
import com.infynova.udi.service.helper.RedisSearchHelper;
import com.infynova.udi.service.helper.RedisSearchIndexer;
import com.infynova.udi.vo.UdiExportVo;
import com.infynova.udi.vo.UdiVo;
import io.redisearch.SearchResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Api(tags = "udi查询")
@ApiSupport(order = 100)
@RestController
@RequestMapping("/udiList")
public class UdiController {
@Resource
private UdiService udiService;
private static final Integer MAX_EXPORT = 20000;
@ApiOperationSupport(order = 100)
@ApiOperation(value = "udi查询列表", notes = "udi查询列表")
@PostMapping("list")
public ResponseData<Page<UdiVo>> list(@RequestBody UdiListQry udiListQry){
log.info("list:"+ JSON.toJSONString(udiListQry));
return ResponseData.ok(udiService.getUdiPage(udiListQry));
}
@ApiOperationSupport(order = 101)
@ApiOperation(value = "导出udi查询列表", notes = "导出udi查询列表")
@PostMapping("export")
public void export(@RequestBody UdiListQry udiListQry) throws IOException {
log.info("export:"+ JSON.toJSONString(udiListQry));
// 如何大量导出避免内存溢出 todo
udiListQry.setPageSize(MAX_EXPORT);
Page<UdiVo> udiPage = udiService.getUdiPage(udiListQry);
List<UdiExportVo> udiExportVos = new ArrayList<>();
for (UdiVo record : udiPage.getRecords()) {
UdiExportVo udiExportVo = new UdiExportVo();
BeanUtils.copyProperties(record, udiExportVo);
udiExportVos.add(udiExportVo);
}
UdiEasyExcelHelper.export("udi查询导出列表", udiExportVos, UdiExportVo.class);
}
@Resource
private RedisSearchIndexer redisSearchIndexer;
@Resource
private RedisSearchHelper redisSearchHelper;
@Resource
private EsSearchHelper esSearchHelper;
@ApiOperationSupport(order = 200)
@ApiOperation(value = "createIndex", notes = "createIndex",hidden = true)
@PostMapping("createIndex")
public void createIndex(){
//redisSearchIndexer.createIndex();
esSearchHelper.createIndex();
}
@ApiOperationSupport(order = 200)
@ApiOperation(value = "deleteIndex", notes = "deleteIndex",hidden = true)
@PostMapping("deleteIndex")
public void deleteIndex(){
//redisSearchIndexer.deleteIndex();
esSearchHelper.deleteIndex();
}
@ApiOperationSupport(order = 200)
@ApiOperation(value = "initData", notes = "initData",hidden = true)
@PostMapping("initData")
public void initData(){
//redisSearchIndexer.initData();
esSearchHelper.initData();
}
@ApiOperationSupport(order = 200)
@ApiOperation(value = "searchThree", notes = "searchThree",hidden = true)
@PostMapping("searchThree")
public SearchResult searchThree(@RequestParam(value = "companyName", required = false) String companyName,
@RequestParam(value = "productFactoryCode", required = false) String productFactoryCode){
return redisSearchHelper.searchThree(companyName,productFactoryCode);
}
}
package com.infynova.udi.controller;
import com.alibaba.fastjson.JSON;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infynova.common.core.api.ResponseData;
import com.infynova.udi.dto.*;
import com.infynova.udi.service.helper.IKAnalyzerSupport;
import com.infynova.udi.service.helper.MatchHelper;
import com.infynova.udi.service.helper.TaskHelper;
import com.infynova.udi.service.helper.TaskUploadHelper;
import com.infynova.udi.vo.TaskVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Api(tags = "对码平台-辅助",hidden = true)
@ApiSupport(order = 400)
@RestController
@RequestMapping("/helper")
public class UdiHelperController {
@Resource
private MatchHelper matchHelper;
@ApiOperationSupport(order = 10000)
@ApiOperation(value = "测试对码匹配", notes = "测试对码匹配", hidden = true)
@GetMapping("tranMatchRate")
public ResponseData<?> tranMatchRate() {
log.info("tranMatchRate");
matchHelper.tranMatchRate();
return ResponseData.ok();
}
@ApiOperationSupport(order = 10000)
@ApiOperation(value = "测试分词器", notes = "测试分词器", hidden = true)
@GetMapping("splitWord")
public ResponseData<String> splitWord(@RequestParam(name = "word") String word) throws Exception {
log.info("splitWord:");
List<String> splitWord = IKAnalyzerSupport.iKSegmenterToList(word);
String result = splitWord.stream().map(String::valueOf).distinct().collect(Collectors.joining("|")) ;
return ResponseData.ok(result);
}
@Resource
private TaskUploadHelper taskUploadHelper;
@Resource
private TaskHelper taskHelper;
@ApiOperationSupport(order = 10000)
@ApiOperation(value = "测试转换数据", notes = "测试转换数据", hidden = true)
@PostMapping("testTranData")
public ResponseData<?> testTranData(@RequestBody @Valid IdQry idQry) {
log.info("testTranData:"+ JSON.toJSONString(idQry));
taskUploadHelper.tranUpload(idQry.getId());
return ResponseData.ok();
}
@ApiOperationSupport(order = 10001)
@ApiOperation(value = "获取任务数据", notes = "获取任务数据", hidden = true)
@PostMapping("getTaskVo")
public ResponseData<List<TaskVo>> getTaskVo(@RequestBody @Valid IdListQry idListQry) {
log.info("getTaskVo:"+ JSON.toJSONString(idListQry));
return ResponseData.ok(taskHelper.getTaskVoList(new ArrayList<>(idListQry.getIdList())));
}
@ApiOperationSupport(order = 10002)
@ApiOperation(value = "测试获取任务编码", notes = "测试获取任务编码", hidden = true)
@GetMapping("getTaskNo")
public ResponseData<String> getTaskNo() {
log.info("getTaskNo:");
return ResponseData.ok(taskHelper.getTaskNo());
}
}
package com.infynova.udi.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infynova.common.core.api.ResponseData;
import com.infynova.udi.dto.*;
import com.infynova.udi.entity.MatchData;
import com.infynova.udi.entity.MatchTemp;
import com.infynova.udi.helper.UdiEasyExcelHelper;
import com.infynova.udi.service.MatchDataService;
import com.infynova.udi.service.MatchTempService;
import com.infynova.udi.vo.UdiMatchDataExportVo;
import com.infynova.udi.vo.UdiMatchDataVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Api(tags = "对码平台-对码")
@ApiSupport(order = 300)
@RestController
@RequestMapping("/match/data")
public class UdiMatchDataController {
@Resource
private MatchDataService matchDataService;
@Resource
private MatchTempService matchTempService;
@ApiOperationSupport(order = 100)
@ApiOperation(value = "对码管理列表", notes = "对码管理列表")
@PostMapping("list")
public ResponseData<Page<UdiMatchDataVo>> list(@RequestBody @Valid UdiMatchDetailListQry udiMatchDetailListQry){
log.info("list:"+ JSON.toJSONString(udiMatchDetailListQry));
return ResponseData.ok(matchDataService.queryMatchDataPage(udiMatchDetailListQry));
}
@ApiOperationSupport(order = 120)
@ApiOperation(value = "导出对码管理列表", notes = "导出对码管理列表")
@PostMapping("export")
public void export(@RequestBody @Valid UdiMatchDetailListQry udiMatchDetailListQry) throws IOException {
log.info("export:"+ JSON.toJSONString(udiMatchDetailListQry));
udiMatchDetailListQry.setPageSize(-1);
Page<UdiMatchDataVo> page = matchDataService.queryMatchDataPage(udiMatchDetailListQry);
List<UdiMatchDataExportVo> exportList = new ArrayList<>();
for (UdiMatchDataVo record : page.getRecords()) {
UdiMatchDataExportVo exportVo = new UdiMatchDataExportVo();
BeanUtils.copyProperties(record,exportVo);
exportList.add(exportVo);
}
UdiEasyExcelHelper.export("udi查询导出列表", exportList, UdiMatchDataExportVo.class);
}
@ApiOperationSupport(order = 130)
@ApiOperation(value = "批量匹配UDI库", notes = "批量匹配UDI库")
@PostMapping("batchMatchUdi")
public ResponseData<Integer> batchMatchUdi(@RequestBody @Valid UdiBatchMatchQry udiBatchMatchQry){
log.info("batchMatchUdi:"+ JSON.toJSONString(udiBatchMatchQry));
return ResponseData.ok(matchDataService.batchMatchUdi(udiBatchMatchQry));
}
@ApiOperationSupport(order = 140)
@ApiOperation(value = "全量匹配UDI库", notes = "全量匹配UDI库")
@PostMapping("allMatchUdi")
public ResponseData<Integer> allMatchUdi(@RequestBody @Valid UdiAllMatchQry udiAllMatchQry){
// 该任务中部分未对码 全量匹配UDI库
log.info("allMatchUdi:"+ JSON.toJSONString(udiAllMatchQry));
return ResponseData.ok(matchDataService.allMatchUdi(udiAllMatchQry));
}
@ApiOperationSupport(order = 150)
@ApiOperation(value = "查询匹配数据", notes = "查询匹配数据")
@PostMapping("queryMatchTemp")
public ResponseData<List<MatchTemp>> queryMatchTemp(@RequestBody @Valid IdQry idQry){
// 该任务中部分未对码 全量匹配UDI库
log.info("queryMatchTemp:"+ JSON.toJSONString(idQry));
return ResponseData.ok(matchTempService.queryMatchTemp(idQry.getId()));
}
@ApiOperationSupport(order = 160)
@ApiOperation(value = "确认对码", notes = "确认对码")
@PostMapping("confirmationMatch")
public ResponseData<MatchData> confirmationMatch(@RequestBody @Valid UdiMatchConfirmationDto udiMatchConfirmationDto){
// 该任务中部分未对码 全量匹配UDI库
log.info("confirmationMatch:"+ JSON.toJSONString(udiMatchConfirmationDto));
return ResponseData.ok(matchDataService.confirmationMatch(udiMatchConfirmationDto));
}
}
package com.infynova.udi.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infynova.common.core.api.ResponseData;
import com.infynova.udi.dto.*;
import com.infynova.udi.helper.UdiEasyExcelHelper;
import com.infynova.udi.service.TaskImportService;
import com.infynova.udi.service.TaskService;
import com.infynova.udi.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Slf4j
@Api(tags = "对码平台-任务")
@ApiSupport(order = 200)
@RestController
@RequestMapping("/match/task")
public class UdiMatchTaskController {
@Resource
private TaskService taskService;
@Resource
private TaskImportService taskImportService;
@ApiOperationSupport(order = 100)
@ApiOperation(value = "udi对码导入模板下载", notes = "udi对码导入模板下载")
@GetMapping("template")
public void template() throws IOException {
log.info("template");
TaskUdiExcelImportVo udiExcelVo = new TaskUdiExcelImportVo();
String example = "样例-";
udiExcelVo.setUdiCode(example + "6938954499349");
udiExcelVo.setYiBaoOneCode(example + "C03380310700000");
udiExcelVo.setYiBaoTwoCode(example + "C0338031070000001523");
udiExcelVo.setYiBaoCode(example + "C03380310700000015230000046");
udiExcelVo.setYiBaoCodePrefix(example + "C03");
udiExcelVo.setCompanyName(example + "深圳市无境创新有限公司");
udiExcelVo.setBrandName(example + "无境创新");
udiExcelVo.setRegistryNo(example + "国械注准20240000001");
udiExcelVo.setRegistryName(example + "人工踝关节假体");
udiExcelVo.setRegistryStartTime("2000-01-01");
udiExcelVo.setRegistryEndTime("2099-12-31");
udiExcelVo.setRegistry(example + "深圳市无境创新有限公司");
udiExcelVo.setProductCode(example + "infynova-DEMO-001");
udiExcelVo.setProductFactoryCode(example + "0116001");
//udiExcelVo.setInfynovaCode(example + );
udiExcelVo.setProductName(example + "人工踝关节假体-跟距骨假体QH型26×26×23");
udiExcelVo.setProductType("耗材");
udiExcelVo.setSpecification(example + "QH型 26×26×23");
udiExcelVo.setModel(example + "QH型 26×26×23");
udiExcelVo.setMaterial(example + "不区分");
udiExcelVo.setAsepticPackaging(example + "否");
udiExcelVo.setBeforeSterilize(example + "是");
udiExcelVo.setSterilizationMethod(example + "按照说明书要求进行灭菌");
UdiEasyExcelHelper.export("udi对码导入模板", Collections.singletonList(udiExcelVo), TaskUdiExcelImportVo.class);
}
@ApiOperationSupport(order = 110)
@ApiOperation(value = "udi对码导入", notes = "udi对码导入")
@PostMapping("importData")
public ResponseData<ImportItemResp> importData(@RequestParam("file") MultipartFile file) throws IOException {
log.info("importData");
return ResponseData.ok(taskImportService.importData(file));
}
@ApiOperationSupport(order = 120)
@ApiOperation(value = "udi对码列表", notes = "udi对码列表")
@PostMapping("list")
public ResponseData<Page<UdiMatchListVo>> list(@RequestBody @Valid UdiMatchTaskListQry udiMatchTaskListQry){
log.info("list:"+ JSON.toJSONString(udiMatchTaskListQry));
return ResponseData.ok(taskService.queryTaskPage(udiMatchTaskListQry));
}
@ApiOperationSupport(order = 130)
@ApiOperation(value = "全部暂停", notes = "全部暂停")
@PostMapping("allPause")
public ResponseData<?> allPause(@RequestBody @Valid IdListQry idListQry){
log.info("allPause:"+ JSON.toJSONString(idListQry));
return ResponseData.ok(taskService.pauseTask(new ArrayList<>(idListQry.getIdList())));
}
@ApiOperationSupport(order = 131)
@ApiOperation(value = "单个暂停", notes = "单个暂停")
@PostMapping("onePause")
public ResponseData<?> onePause(@RequestBody @Valid IdQry idQry){
log.info("onePause:"+ JSON.toJSONString(idQry));
return ResponseData.ok(taskService.pauseTask(Collections.singletonList(idQry.getId())));
}
@ApiOperationSupport(order = 140)
@ApiOperation(value = "全部开始", notes = "全部开始")
@PostMapping("allStart")
public ResponseData<?> allStart(@RequestBody @Valid IdListQry idListQry){
log.info("allStart:"+ JSON.toJSONString(idListQry));
return ResponseData.ok(taskService.startTask(new ArrayList<>(idListQry.getIdList())));
}
@ApiOperationSupport(order = 141)
@ApiOperation(value = "单个开始-开始上传", notes = "单个开始")
@PostMapping("oneStart")
public ResponseData<?> oneStart(@RequestBody @Valid IdQry idQry){
log.info("oneStart:"+ JSON.toJSONString(idQry));
return ResponseData.ok(taskService.startTask(Collections.singletonList(idQry.getId())));
}
@ApiOperationSupport(order = 150)
@ApiOperation(value = "全部删除", notes = "全部删除")
@PostMapping("allDelete")
public ResponseData<?> allDelete(@RequestBody @Valid IdListQry idListQry){
log.info("allDelete:"+ JSON.toJSONString(idListQry));
return ResponseData.ok(taskService.deleteTask(new ArrayList<>(idListQry.getIdList())));
}
@ApiOperationSupport(order = 151)
@ApiOperation(value = "单个删除", notes = "单个删除")
@PostMapping("oneDelete")
public ResponseData<?> oneDelete(@RequestBody @Valid IdQry idQry){
log.info("oneDelete:"+ JSON.toJSONString(idQry));
return ResponseData.ok(taskService.deleteTask(Collections.singletonList(idQry.getId())));
}
@ApiOperationSupport(order = 160)
@ApiOperation(value = "对码进度", notes = "对码进度")
@PostMapping("matchResult")
public ResponseData<TaskMatchStatisticVo> matchResult(@RequestBody @Valid IdQry idQry){
log.info("matchResult:"+ JSON.toJSONString(idQry));
return ResponseData.ok(taskService.matchResult(idQry.getId()));
}
@ApiOperationSupport(order = 170)
@ApiOperation(value = "获取下载链接", notes = "获取下载链接")
@PostMapping("getDownloadUrl")
public ResponseData<List<UdiMatchTaskFileDto>> getDownloadUrl(@RequestBody @Valid IdListQry idListQry){
log.info("getDownloadUrl:"+ JSON.toJSONString(idListQry));
return ResponseData.ok(taskService.getDownloadUrl(idListQry));
}
}
package com.infynova.udi.manager;
import com.infynova.common.core.api.ResponseData;
import com.infynova.common.core.entity.UploadResultVo;
import com.infynova.common.core.exception.SaasException;
import com.infynova.ucpm.client.OSSServiceClient;
import com.infynova.ucpm.vo.request.OSSBatchIdReqVo;
import com.infynova.udi.dto.UdiMatchTaskFileDto;
import com.infynova.udi.exception.UdiCodeException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.*;
@Slf4j
@Component
public class OssManager {
@Resource
private OSSServiceClient oSSServiceClient;
protected <T> T handleResponse(ResponseData<T> resp){
if (resp.isSuccess()) {
return resp.getData();
} else {
throw new SaasException("服务调用失败:错误码=" + resp.getCode() + ",原因=" + resp.getMsg());
}
}
public UploadResultVo upload(MultipartFile multipartFile) {
ResponseData<UploadResultVo> result = oSSServiceClient.upload(multipartFile);
return handleResponse(result);
}
public String getUrlById(Long id){
ResponseData<String> responseData = oSSServiceClient.getUrlById(id);
return responseData.getData();
}
public List<UdiMatchTaskFileDto> queryBatchById(List<Long> ids){
OSSBatchIdReqVo ossBatchId = new OSSBatchIdReqVo();
ossBatchId.setIds(ids);
ResponseData<List<UploadResultVo>> responseData = oSSServiceClient.queryBatchById(ossBatchId);
if(responseData.isSuccess() && CollectionUtils.isNotEmpty(responseData.getData())){
List<UploadResultVo> data = responseData.getData();
List<UdiMatchTaskFileDto> resultList = new ArrayList<>(data.size());
for (UploadResultVo datum : data) {
resultList.add(UdiMatchTaskFileDto.builder().fileId(datum.getId()).fileName(datum.getFileName()).filePath(datum.getFilePath()).build());
}
return resultList;
}else{
return null;
}
}
}
package com.infynova.udi.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infynova.udi.dto.UdiMatchDetailListQry;
import com.infynova.udi.entity.MatchData;
import com.infynova.udi.mapper.base.SuperMapper;
import com.infynova.udi.vo.TaskMatchStatisticVo;
import com.infynova.udi.vo.UdiMatchDataVo;
import org.apache.ibatis.annotations.Param;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* @author liudong
* 2024/2/29 16:41
* @version 1.0
*/
public interface MatchDataMapper extends SuperMapper<MatchData> {
Page<UdiMatchDataVo> queryMatchDataPage(IPage page,@Param("query") UdiMatchDetailListQry udiMatchDetailListQry);
Set<Long> queryMatchWaitingTask();
List<TaskMatchStatisticVo> queryTaskMatchStatistic(@Param("taskIds") Collection<Long> taskIds);
}
package com.infynova.udi.mapper;
import com.infynova.udi.entity.MatchTemp;
import com.infynova.udi.mapper.base.SuperMapper;
/**
* @author liudong
* 2024/2/29 16:41
* @version 1.0
*/
public interface MatchTempMapper extends SuperMapper<MatchTemp> {
}
package com.infynova.udi.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infynova.udi.dto.UdiMatchTaskListQry;
import com.infynova.udi.entity.Task;
import com.infynova.udi.mapper.base.SuperMapper;
import com.infynova.udi.vo.UdiMatchListVo;
import org.apache.ibatis.annotations.Param;
/**
* @author liudong
* 2024/2/29 16:41
* @version 1.0
*/
public interface TaskMapper extends SuperMapper<Task> {
Page<UdiMatchListVo> queryTaskPage(IPage page, @Param("query") UdiMatchTaskListQry udiMatchTaskListQry);
Task queryTaskNo(@Param("taskNo") String taskNo);
}
package com.infynova.udi.mapper;
import com.infynova.udi.entity.TaskRecord;
import com.infynova.udi.mapper.base.SuperMapper;
/**
* @author liudong
* 2024/2/29 16:41
* @version 1.0
*/
public interface TaskRecordMapper extends SuperMapper<TaskRecord> {
}
package com.infynova.udi.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infynova.udi.dto.UdiListQry;
import com.infynova.udi.vo.UdiMatchRateVo;
import com.infynova.udi.vo.UdiVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UdiMapper {
Page<UdiVo> getUdiPage(IPage page, @Param("query") UdiListQry udiListQry);
List<UdiVo> getUdiList(@Param("query") UdiListQry udiListQry);
Page<UdiVo> getUdi(IPage page, @Param("udi") String udiCode,
@Param("yiBaoCode") String yiBaoCode,
@Param("companyName") String companyName,
@Param("productFactoryCode") String productFactoryCode,
@Param("brandName") String brandName,
@Param("productName") String productName,
@Param("specification") String specification,
@Param("model") String model
);
List<UdiMatchRateVo> getUdiCodeRegex(@Param("udiCode") String udiCode, @Param("udiCodeList") List<String> udiCodeList);
List<UdiMatchRateVo> getYiBaoCodeRegex(@Param("yiBaoCode") String yiBaoCode, @Param("yiBaoCodeList") List<String> yiBaoCodeList);
List<UdiVo> getUdiIdPage(@Param("id") Long id, @Param("pageSize") Integer pageSize);
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.mapper.base;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import java.util.Collection;
/**
* @Author: zoupx
* @Description: mybatis plus mapper层选装件 https://mp.baomidou.com/guide/crud-interface.html#select
* @Date: 2021/6/10
*/
public interface SuperMapper<T> extends BaseMapper<T> {
/**
* 批量插入 仅适用于mysql
* @param entityList 实体列表
*/
int insertBatchSomeColumn(Collection<T> entityList);
/**
* 根据 ID 更新固定的那几个字段(不包含逻辑删除),解决设置为null字段无法更新问题
* @param entity
*/
int alwaysUpdateSomeColumnById(@Param(Constants.ENTITY) T entity);
}
package com.infynova.udi.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infynova.udi.dto.UdiAllMatchQry;
import com.infynova.udi.dto.UdiBatchMatchQry;
import com.infynova.udi.dto.UdiMatchConfirmationDto;
import com.infynova.udi.dto.UdiMatchDetailListQry;
import com.infynova.udi.entity.MatchData;
import com.infynova.udi.vo.TaskMatchStatisticVo;
import com.infynova.udi.vo.UdiMatchDataVo;
import java.util.List;
/**
* @author liudong
* 2024/3/5 18:21
* @version 1.0
*/
public interface MatchDataService {
Page<UdiMatchDataVo> queryMatchDataPage(UdiMatchDetailListQry udiMatchDetailListQry);
List<TaskMatchStatisticVo> queryTaskMatchStatistic(List<Long> taskIds);
/**
* 批量匹配UDI库
*/
Integer batchMatchUdi(UdiBatchMatchQry udiBatchMatchQry);
/**
* 全量匹配UDI库
*/
Integer allMatchUdi(UdiAllMatchQry udiAllMatchQry);
/**
* 确认对码
*/
MatchData confirmationMatch(UdiMatchConfirmationDto udiMatchConfirmationDto);
}
package com.infynova.udi.service;
import com.infynova.udi.entity.MatchTemp;
import java.util.List;
/**
* @author liudong
* 2024/3/5 18:21
* @version 1.0
*/
public interface MatchTempService {
/**
* 查询匹配数据
*/
List<MatchTemp> queryMatchTemp(Long matchId);
/**
* 查询匹配率最高的一条数据
*/
MatchTemp getMatchRateTop(Long matchId);
}
package com.infynova.udi.service;
import com.infynova.udi.dto.ImportItemResp;
import com.infynova.udi.vo.TaskUdiExcelExportVo;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
/**
* @author liudong
* 2024/2/29 16:50
* @version 1.0
*/
public interface TaskImportService {
ImportItemResp importData(MultipartFile file) throws IOException;
}
package com.infynova.udi.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infynova.udi.dto.IdListQry;
import com.infynova.udi.dto.UdiMatchTaskFileDto;
import com.infynova.udi.dto.UdiMatchTaskListQry;
import com.infynova.udi.entity.Task;
import com.infynova.udi.vo.TaskMatchStatisticVo;
import com.infynova.udi.vo.UdiMatchListVo;
import java.util.List;
/**
* @author liudong
* 2024/2/29 16:39
* @version 1.0
*/
public interface TaskService {
Page<UdiMatchListVo> queryTaskPage(UdiMatchTaskListQry udiMatchTaskListQry);
/**
* 任务开始
*/
Integer startTask(List<Long> taskIds);
/**
* 任务暂停
*/
Integer pauseTask(List<Long> taskIds);
/**
* 任务删除
*/
Integer deleteTask(List<Long> taskIds);
Task getOne(Long taskId);
List<Task> getList(List<Long> taskIds);
List<Task> getUploadingTask();
/**
* 对码进度查询
*/
TaskMatchStatisticVo matchResult(Long taskId);
List<UdiMatchTaskFileDto> getDownloadUrl(IdListQry idListQry);
}
package com.infynova.udi.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infynova.udi.dto.UdiListQry;
import com.infynova.udi.vo.UdiVo;
/**
* @author liudong
* 2024/2/27 14:30
* @version 1.0
*/
public interface UdiService {
Page<UdiVo> getUdiPage(UdiListQry udiListQry);
}
package com.infynova.udi.service.base;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infynova.common.core.entity.PageVo;
/**
* @author liudong
* 2024/2/29 16:44
* @version 1.0
*/
public class BaseService {
public <T> IPage<T> getPage(PageVo reqVo) {
return new Page<>(reqVo.getPageNo(), reqVo.getPageSize());
}
}
package com.infynova.udi.service.helper;
import com.infynova.udi.mapper.UdiMapper;
import com.infynova.udi.vo.UdiVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author liudong
* 2024/4/29 16:16
* @version 1.0
*/
@Slf4j
@Component
public class EsSearchHelper {
private static final String INDEX_NAME = "udi";
public static final RestHighLevelClient client;
static{
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
}
public void closeClient() throws IOException {
client.close();
}
@SneakyThrows
public void createIndex(){
log.info("创建索引");
CreateIndexRequest createIndexRequest = new CreateIndexRequest(INDEX_NAME);
CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
}
@SneakyThrows
public void deleteIndex(){
log.info("删除索引");
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(INDEX_NAME);
AcknowledgedResponse delete = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
}
@Resource
private UdiMapper udiMapper;
@SneakyThrows
public void initData(){
log.info("同步数据");
StopWatch stopWatch = new StopWatch("开始");
Integer pageSize = 1000;
Long lastId = 0L;
int i = 1;
try{
while (true){
stopWatch.start("第"+i+"页");
log.info("同步索引:第{}页,lastId:{}",i,lastId);
List<UdiVo> records = udiMapper.getUdiIdPage(lastId,pageSize);
if(CollectionUtils.isEmpty(records)){
return;
}
indexDocument(records);
UdiVo udiVo = records.get(records.size()-1);
lastId = udiVo.getId();
i++;
stopWatch.stop();
}
}catch (Exception e){
log.error("");
log.error("",e);
}finally {
stopWatch.stop();
log.info(stopWatch.prettyPrint());
log.info("总计耗时:{}",stopWatch.getTotalTimeSeconds());
}
}
private Map<String,Object> getDoc(UdiVo udiVo){
Map<String,Object> map = new HashMap<>();
map.put("id",udiVo.getId());
map.put("companyName",udiVo.getCompanyName());
map.put("productFactoryCode",udiVo.getProductFactoryCode());
map.put("brandName",udiVo.getBrandName());
map.put("productName",udiVo.getProductName());
map.put("specification",udiVo.getSpecification());
map.put("model",udiVo.getModel());
return map;
}
public void indexDocument(List<UdiVo> udiVos) throws IOException {
BulkRequest bulkRequest = new BulkRequest();
for (UdiVo udiVo : udiVos) {
Map<String, Object> doc = getDoc(udiVo);
IndexRequest request = new IndexRequest(INDEX_NAME)
.id(String.valueOf(udiVo.getId()))
.source(doc, XContentType.JSON);
bulkRequest.add(request);
}
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
if (bulkResponse.hasFailures()) {
// 处理失败的情况
log.error("Some documents failed to index: " + bulkResponse.buildFailureMessage());
} else {
log.info("Bulk indexing successful.");
}
}
@SneakyThrows
public void updateIndex(String id, Map<String, Object> updatedDocument) throws IOException {
UpdateRequest request = new UpdateRequest(INDEX_NAME, id)
.doc(updatedDocument, XContentType.JSON);
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
}
@SneakyThrows
public Map<String, Object> searchThree(String id){
GetRequest getRequest = new GetRequest(INDEX_NAME, id);
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
return getResponse.getSourceAsMap();
}
}
package com.infynova.udi.service.helper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
/**
* @author liudong
* 2024/3/14 18:27
* @version 1.0
*/
@Slf4j
public class IKAnalyzerSupport {
/**
* IK分词
* @param target
* @return
*/
public static List<String> iKSegmenterToList(String target) throws Exception {
if (StringUtils.isEmpty(target)){
return new ArrayList<>();
}
List<String> result = new ArrayList<>();
StringReader sr = new StringReader(target);
// false:关闭智能分词 (对分词的精度影响较大)
IKSegmenter ik = new IKSegmenter(sr, true);
Lexeme lex;
while((lex=ik.next())!=null) {
String lexemeText = lex.getLexemeText();
result.add(lexemeText);
}
return result;
}
}
package com.infynova.udi.service.helper;
import com.alibaba.fastjson.JSONObject;
import com.infynova.udi.dto.UdiQueryDto;
import com.infynova.udi.vo.UdiVo;
import io.redisearch.AggregationResult;
import io.redisearch.Document;
import io.redisearch.aggregation.AggregationBuilder;
import io.redisearch.aggregation.SortedField;
import io.redisearch.client.Client;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import io.redisearch.Query;
import io.redisearch.SearchResult;
import redis.clients.jedis.Jedis;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* @author liudong
* 2024/4/28 17:33
* @version 1.0
*/
@Slf4j
@Component
public class RedisSearchHelper {
private static Client redisClient;
static{
redisClient = new Client("udi:index","127.0.0.1", 6379);
}
public SearchResult searchThree(String companyName, String productFactoryCode){
String queryKeyCompanyName = String.format("@companyName:%s", companyName);
Query query = new Query(queryKeyCompanyName);
query.limit(0,10);
query.setWithScores();
query.setLanguage("chinese");
SearchResult search = redisClient.search(query);
if(search.totalResults>0){
List<UdiVo> data = new ArrayList<>(Math.toIntExact(search.totalResults));
for (Document doc : search.docs) {
UdiVo udiVo = new UdiVo();
udiVo.setId((Long) doc.get("id"));
udiVo.setCompanyName((String) doc.get("companyName"));
udiVo.setProductFactoryCode((String) doc.get("productFactoryCode"));
udiVo.setBrandName((String) doc.get("brandName"));
udiVo.setProductName((String) doc.get("productName"));
udiVo.setSpecification((String) doc.get("specification"));
udiVo.setModel((String) doc.get("model"));
data.add(udiVo);
}
//return UdiQueryDto.builder().total(Math.toIntExact(search.totalResults)).data(data).build();
}
//return UdiQueryDto.builder().build();
return search;
}
}
package com.infynova.udi.service.helper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infynova.udi.dto.UdiListQry;
import com.infynova.udi.entity.Udi;
import com.infynova.udi.mapper.UdiMapper;
import com.infynova.udi.service.UdiService;
import com.infynova.udi.vo.UdiVo;
import io.redisearch.Document;
import io.redisearch.Schema;
import io.redisearch.client.Client;
import io.redisearch.client.IndexDefinition;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author liudong
* 2024/4/28 17:43
* @version 1.0
*/
@Slf4j
@Component
public class RedisSearchIndexer {
private static Client redisClient;
static{
redisClient = new Client("udi:index","127.0.0.1", 6379);
}
@Resource
private UdiMapper udiMapper;
//@PostConstruct
public void createIndex() {
log.info("创建索引");
Schema schema = new Schema()
.addTextField("companyName", 1.0)
.addTextField("productFactoryCode", 1.0)
.addTextField("brandName", 1.0)
.addTextField("productName", 1.0)
.addTextField("specification", 1.0)
.addTextField("model", 1.0);
IndexDefinition indexDefinition = new IndexDefinition()
.setPrefixes("udi:") // 设置索引名称前缀
.setLanguage("chinese")
// .setIndex(Schema.Index.PREFIX) // 使用前缀索引
.setFilter("@type == \"udi\""); // 过滤条件,只索引类型为 "udi" 的数据
redisClient.createIndex(schema, Client.IndexOptions.defaultOptions().setDefinition(indexDefinition));
}
public void deleteIndex(){
log.info("删除索引");
redisClient.dropIndex(true);
}
public void initData(){
ExecutorService executorService = Executors.newFixedThreadPool(10);
log.info("同步数据");
StopWatch stopWatch = new StopWatch("开始");
Integer pageSize = 1000;
Long lastId = 3059000L;
int i = 1;
try{
while (true){
stopWatch.start("第"+i+"页");
log.info("同步索引:第{}页,lastId:{}",i,lastId);
List<UdiVo> records = udiMapper.getUdiIdPage(lastId,pageSize);
if(CollectionUtils.isEmpty(records)){
return;
}
List<Document> documents = new ArrayList<>();
for (UdiVo udiVo : records) {
documents.add(this.indexData(udiVo));
}
executorService.execute(() -> {
try {
Document[] array = documents.toArray(new Document[0]);
redisClient.addDocuments(array);
} catch (Exception e) {
e.printStackTrace();
}
});
UdiVo udiVo = records.get(records.size()-1);
lastId = udiVo.getId();
i++;
stopWatch.stop();
}
}catch (Exception e){
log.error("");
log.error("",e);
}finally {
stopWatch.stop();
log.info(stopWatch.prettyPrint());
log.info("总计耗时:{}",stopWatch.getTotalTimeSeconds());
}
}
public io.redisearch.Document indexData(UdiVo udi) {
redisClient.deleteDocument("udi:" + udi.getId(),true);
return new io.redisearch.Document("udi:" + udi.getId())
.set("companyName", Optional.ofNullable(udi.getCompanyName()).orElse(""))
.set("productFactoryCode", Optional.ofNullable(udi.getProductFactoryCode()).orElse(""))
.set("brandName", Optional.ofNullable(udi.getBrandName()).orElse(""))
.set("productName", Optional.ofNullable(udi.getProductName()).orElse(""))
.set("specification", Optional.ofNullable(udi.getSpecification()).orElse(""))
.set("model", Optional.ofNullable(udi.getModel()).orElse(""));
}
}
package com.infynova.udi.service.helper;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.FileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.infynova.udi.entity.MatchData;
import com.infynova.udi.entity.Task;
import com.infynova.udi.enums.match.MatchStatusEnum;
import com.infynova.udi.enums.match.MatchUpdateStatusEnum;
import com.infynova.udi.enums.task.TaskMatchStatusEnum;
import com.infynova.udi.enums.task.TaskStatusEnum;
import com.infynova.udi.exception.CommonExceptionCode;
import com.infynova.udi.exception.UdiCodeException;
import com.infynova.udi.manager.OssManager;
import com.infynova.udi.mapper.MatchDataMapper;
import com.infynova.udi.service.TaskService;
import com.infynova.udi.utils.BooleanValueUtils;
import com.infynova.udi.vo.TaskUdiExcelImportVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.*;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
/**
* @author liudong
* 2024/3/1 11:35
* @version 1.0
*/
@Slf4j
@Component("taskUploadHelper")
public class TaskUploadHelper {
@Resource
private TaskService taskService;
@Resource
private MatchDataMapper matchDataMapper;
@Resource
private TaskHelper taskHelper;
@Resource
private UdiLock udiLock;
@Resource
private OssManager ossManager;
private String getKey(String key){
return "upload:" + key;
}
public void tranTask(){
// 扫描上传中的任务
List<Task> uploadingTaskList = taskService.getUploadingTask();
if(CollectionUtils.isEmpty(uploadingTaskList)){
log.info("任务上传转换定时执行-没有需要进行转换处理的任务");
return;
}else{
log.info("任务上传转换定时执行-此次处理的任务数量:{}",uploadingTaskList.size());
}
for (Task uploadingTask : uploadingTaskList) {
tranUpload(uploadingTask.getId());
}
}
@SneakyThrows
public void tranUpload(Long taskId) {
log.info("上传中任务转换成待对码数据-taskId:{}",taskId);
// 获取任务
Task task = taskService.getOne(taskId);
if(Objects.isNull(task)){
log.error("上传中任务转换成待对码数据-taskId:{}-查询数据为空",taskId);
throw new UdiCodeException(CommonExceptionCode.SYSTEM_501.getCode(),"查找数据为空");
}
log.info("上传中任务转换成待对码数据-taskNo:{}",task.getTaskNo());
if(!Objects.equals(task.getTaskStatus(), TaskStatusEnum.UPLOADING.getCode())){
log.warn("上传中任务转换成待对码数据-任务状态不对");
return;
}
// 需要做一个唯一锁,用于控制任务唯一进行
String key = this.getKey(String.valueOf(taskId));
if(udiLock.hasKey(key)){
log.info("上传中任务转换成待对码数据-taskId:{},转换已在运行中;",key);
return ;
}
try{
log.info("上传中任务转换成待对码数据-key:{},上锁;",key);
udiLock.lock(key,1440L);
// 下载源文件转换成数据
Long taskFileId = task.getTaskFileId();
String taskFileAddress = ossManager.getUrlById(taskFileId);
if(StringUtils.isBlank(taskFileAddress)){
log.error("上传中任务转换成待对码数据:错误-taskId:{},来源文件为空;",key);
return;
}
File file = downloadExcel(taskFileAddress);
// 将文件中的数据转换成待对码数据
List<TaskUdiExcelImportVo> excelList = new ArrayList<>();
EasyExcel.read(file, TaskUdiExcelImportVo.class, new PageReadListener<TaskUdiExcelImportVo>(excelList::addAll)).sheet().doRead();
// 每一次转换最大数量100
int oneMaxNum = 100;
int size = excelList.size();
// 已上传的数量
int startNum = task.getTaskUploadNum();
for (int i = startNum; i < size; i += oneMaxNum) {
//Thread.sleep(300000);
// 用于控制任务暂停的情况
Task taskNow = taskService.getOne(taskId);
if(!Objects.equals(taskNow.getTaskStatus(),TaskMatchStatusEnum.MATCHING.getCode())){
// 如果任务不是【对码中】这个状态,则直接返回整个方法,有可能被暂停或删除了
log.warn("任务:{},状态不对。", taskNow.getTaskNo());
return;
}
List<MatchData> matchDataList = new ArrayList<>();
// 计算当前批次大小
int batchSize = Math.min(oneMaxNum, size - i);
for (int j = i; j < i + batchSize; j++) {
TaskUdiExcelImportVo taskUdiExcelImportVo = excelList.get(j);
MatchData matchData = new MatchData();
BeanUtils.copyProperties(taskUdiExcelImportVo, matchData);
matchData.setRegistryStartTime(LocalDateTimeUtil.parseDate(taskUdiExcelImportVo.getRegistryStartTime(), DatePattern.NORM_DATE_PATTERN));
matchData.setRegistryEndTime(LocalDateTimeUtil.parseDate(taskUdiExcelImportVo.getRegistryEndTime(), DatePattern.NORM_DATE_PATTERN));
matchData.setBeforeSterilize(BooleanValueUtils.getBoolean(taskUdiExcelImportVo.getBeforeSterilize()));
matchData.setAsepticPackaging(BooleanValueUtils.getBoolean(taskUdiExcelImportVo.getAsepticPackaging()));
matchData.setTaskId(taskId);
matchData.setMatchStatus(MatchStatusEnum.WAITING.getCode());
matchData.setUpdateStatus(MatchUpdateStatusEnum.PENDING.getCode());
matchData.setCreateBy(null);
matchData.setCreateName(null);
matchData.setCreateTime(LocalDateTime.now());
matchData.setUpdateBy(null);
matchData.setUpdateName(null);
matchData.setUpdateTime(LocalDateTime.now());
matchData.setVersion(1);
matchDataList.add(matchData);
}
this.saveData(taskId, matchDataList,matchDataList.size());
log.info("任务:{},开始数量:{}, 批次完成数量:{}, 批次已完成数量:{}",taskNow.getTaskNo(),startNum,oneMaxNum,taskNow.getTaskUploadNum());
}
// 完成转换后,改成任务状态和信息 -- 上传完成
taskHelper.taskStatusUploadFinish(taskId);
// 删除临时文件
try {
FileUtil.del(file);
} catch (Exception e) {
}
log.info("任务:{};完成",task.getTaskNo());
}finally {
log.info("上传中任务转换成待对码数据-key:{},解锁;",key);
udiLock.del(key);
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveData(Long taskId, List<MatchData> matchDataList, int uploadNum){
matchDataMapper.insertBatchSomeColumn(matchDataList);
taskHelper.taskUploadNum(taskId,uploadNum);
}
private File downloadExcel(String url) throws IOException {
HttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = entity.getContent();
String uuid = UUID.randomUUID().toString().replace("-", "");
File file = File.createTempFile("temp_excel_"+uuid, ".xlsx");
OutputStream outputStream = Files.newOutputStream(file.toPath());
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
EntityUtils.consume(entity);
return file;
}
return null;
}
}
package com.infynova.udi.service.helper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.Arrays;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author liudong
* 2024/3/13 16:57
* @version 1.0
*/
@Slf4j
@Component
public class UdiLock {
public static final String KEY_PREFIX = "UDI:LOCK:";
@Resource
private RedisTemplate<String, Object> redisTemplate;
private final Lock lock = new ReentrantLock();
/**
* [公共]判断key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public Boolean hasKey(String key) {
try {
lock.lock(); // 获取锁
key = KEY_PREFIX + key;
return redisTemplate.hasKey(key);
} catch (Exception e) {
log.error("redis -- hasKey,key:"+key,e);
return false;
} finally {
lock.unlock(); // 释放锁
}
}
/**
* [公共]删除缓存
*
* @param keys 可以传一个值 或多个
*/
public void del(String... keys) {
if (keys != null && keys.length > 0) {
if (keys.length == 1) {
String key = KEY_PREFIX + keys[0];
redisTemplate.delete(key);
} else {
for (int i = 0; i < keys.length; i++) {
keys[i] = KEY_PREFIX + keys[i];
}
redisTemplate.delete(Arrays.asList(keys));
}
}
}
public Boolean lock(String key,Long second){
key = KEY_PREFIX + key;
Boolean aBoolean = null;
try {
aBoolean = redisTemplate.opsForValue().setIfAbsent(key, "lock", Duration.ofSeconds(second));
} catch (Exception e) {
log.error("redis -- lock,key:"+key,e);
}
return aBoolean;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment