添加对比文件

master
bynt 6 months ago
parent 8388b10ac3
commit 6d35231093

@ -73,7 +73,10 @@
<version>2.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
</dependency>

@ -0,0 +1,112 @@
package com.baiye.constant;
/**
* @author
*
*/
public class FileConstant {
/**
* 0()
*/
public static final int ZERO_NUMBER = 0;
/**
* 1(UC)
*/
public static final int ONE_NUMBER = 1;
/**
* 2()
*/
public static final int TWO_NUMBER = 2;
/**
* 3()
*/
public static final int THREE_NUMBER = 3;
/**
* 4()
*/
public static final int FOUR_NUMBER = 4;
/**
* 5
*/
public static final int FIVE_NUMBER = 5;
/**
* 6()
*/
public static final int SIX_NUMBER = 6;
/**
* 1000
*/
public static final int ONE_THOUSAND_NUMBER = 1000;
/**
* 1000000
*/
public static final int ONE_MILLION_NUMBER = 1000000;
/**
* BY
*/
public static final String BY = "BY";
/**
* MM
*/
public static final String MM = "MM";
/**
* uc
*/
public static final String UC = "uc";
/**
*
*/
public static final String KS = "ks";
/**
*
*/
public static final String DY = "dy";
/**
*
*/
public static final String QT = "qt";
/**
* xlsx
*/
public static final String XLSX_FILE_SUB_NAME = "xlsx";
/**
* xls
*/
public static final String XLS_FILE_SUB_NAME = "xls";
/**
* txt
*/
public static final String TXT_FILE_SUB_NAME = "txt";
/**
* csv
*/
public static final String CSV_FILE_SUB_NAME = "csv";
/**
* zip
*/
public static final String ZIP_FILE_SUB_NAME = ".zip";
}

@ -0,0 +1,85 @@
package com.baiye.util;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.IdUtil;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.util.ArrayList;
/**
* @author Enzo
* @date : 2022/10/24
*/
public class CompressUtil {
private CompressUtil() {
}
/**
* @param zipPath
* @param filepath
* @param password
*/
public static void decryptionCompression(String zipPath, String filepath, String password) {
try {
//创建压缩文件
ZipFile zipFile = new ZipFile(zipPath);
ArrayList<File> files = new ArrayList<>();
files.add(new File(filepath));
//设置压缩文件参数
ZipParameters parameters = new ZipParameters();
//设置压缩方法
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
//设置压缩级别
//DEFLATE_LEVEL_FASTEST - Lowest compression level but higher speed of compression
//DEFLATE_LEVEL_FAST - Low compression level but higher speed of compression
//DEFLATE_LEVEL_NORMAL - Optimal balance between compression level/speed
//DEFLATE_LEVEL_MAXIMUM - High compression level with a compromise of speed
//DEFLATE_LEVEL_ULTRA - Highest compression level but low speed
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
//设置加密方法
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
//设置aes加密强度
parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
if (StringUtils.isNotBlank(password)) {
//设置压缩文件加密
parameters.setEncryptFiles(Boolean.TRUE);
//设置密码
parameters.setPassword(password);
}
//添加文件到压缩文件
zipFile.addFiles(files, parameters);
} catch (ZipException e) {
e.printStackTrace();
}
}
public static String unzipFiles(String fileUrl, String zipPath, String password) throws ZipException {
File file = new File(zipPath);
ZipFile zipFile = new ZipFile(file);
//设置文件编码,根据实际场景
zipFile.setFileNameCharset(CharsetUtil.GBK);
if (zipFile.isEncrypted()) {
zipFile.setPassword(password);
}
String uuid = IdUtil.randomUUID();
String filePath
= fileUrl.concat(StrPool.SLASH).concat(uuid);
zipFile.extractAll(filePath);
return filePath;
}
}

@ -0,0 +1,74 @@
package com.baiye.extend.mybatis.plus.converter;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Enzo
* @date : 2024/3/14
*/
@MappedJdbcTypes(JdbcType.VARCHAR) // 数据库中该字段存储的类型
@MappedTypes(List.class) // 需要转换的对象
public class ListIntToListLongTypeHandler extends BaseTypeHandler<List<Long>> {
private static ObjectMapper mObjectMapper = new ObjectMapper();
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, List<Long> longs, JdbcType jdbcType) throws SQLException {
String json = JSONUtil.toJsonStr(longs);
preparedStatement.setObject(i, json);
}
@Override
public List<Long> getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
String value = resultSet.getString(columnName);
return getLongs(value);
}
@Override
public List<Long> getNullableResult(ResultSet resultSet, int i) throws SQLException {
String value = resultSet.getString(i);
return getLongs(value);
}
@Override
public List<Long> getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
String value = callableStatement.getString(i);
return getLongs(value);
}
private List<Long> getLongs(String value) {
if (StringUtils.isNotBlank(value)) {
try {
CollectionType type = mObjectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Long.class);
List<Long> longs = mObjectMapper.readValue(value , type);
//List<Long> longs = JsonUtil.parseArray(value, Long.class);
return longs;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
return null;
}
}

@ -25,6 +25,8 @@ public class FileProperties {
private ElPath windows;
private String downUrl;
public ElPath getPath() {
String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win")) {

@ -60,15 +60,17 @@
<select id="listByRoleCodeAndUserId" resultType="com.baiye.system.model.dto.SysUserNameRoleDTO">
select su.username as userName,
su.user_id as userId
su.user_id as userId,
su.status as status
from sys_user su
LEFT JOIN
sys_user_role ur
on su.user_id = ur.user_id
where su.deleted = 0
and su.status = 1
and su.which_user_id = #{userId}
and ur.role_code = #{roleCode}
<if test="userId != null">
and su.which_user_id = #{userId}
</if>
</select>
<select id="listUserNameByUserIds" resultType="com.baiye.system.model.dto.SysUserNameRoleDTO">
select

@ -18,6 +18,7 @@ import com.baiye.system.constant.SysUserConst;
import com.baiye.system.converter.SysUserConverter;
import com.baiye.system.enums.RoleCodeEnum;
import com.baiye.system.model.dto.SysUserDTO;
import com.baiye.system.model.dto.SysUserNameRoleDTO;
import com.baiye.system.model.dto.SysUserPassDTO;
import com.baiye.system.model.dto.SysUserScope;
import com.baiye.system.model.entity.SysRole;
@ -48,6 +49,7 @@ import javax.validation.groups.Default;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
*
@ -304,7 +306,10 @@ public class SysUserController {
@GetMapping("/findSalesman/{roleId}")
public R<Object> findSalesman(@PathVariable("roleId") Long roleId) {
String directSalesmanCode = RoleCodeEnum.find(roleId);
return R.ok(sysUserService.listByRoleCodeAndUserId(directSalesmanCode, SecurityUtils.getWhichUserId()));
List<SysUserNameRoleDTO> dtoList = sysUserService.listByRoleCodeAndUserId
(directSalesmanCode, SecurityUtils.getWhichUserId()).stream().filter
(vo -> vo.getStatus() == DefaultNumberConstants.ONE_NUMBER).collect(Collectors.toList());
return R.ok(dtoList);
}
@Operation(summary = "查询当前用户的指定角色子用户", description = "查询当前用户的指定角色子用户")
@ -313,4 +318,15 @@ public class SysUserController {
String directSalesmanCode = RoleCodeEnum.find(roleId);
return R.ok(sysUserService.listByRoleCodeAndUserId(directSalesmanCode, SecurityUtils.getCurrentUserId()));
}
@Operation(summary = "获取所有用户", description = "根据角色id查所有用户")
@GetMapping("/findAll/{roleId}")
public R<Object> findAllUserByRoleId(@PathVariable("roleId") Long roleId) {
String directSalesmanCode = RoleCodeEnum.find(roleId);
List<SysUserNameRoleDTO> dtoList = sysUserService.listByRoleCodeAndUserId
(directSalesmanCode, null).stream().filter(vo -> vo.getStatus() == DefaultNumberConstants.ONE_NUMBER).collect(Collectors.toList());
return R.ok(dtoList);
}
}

@ -9,5 +9,10 @@ import lombok.Data;
@Data
public class SysUserNameRoleDTO {
private Long userId;
private Integer status;
private String userName;
}

@ -0,0 +1,62 @@
package com.baiye.modules.distribute.controller;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.modules.distribute.qo.FileContrastQo;
import com.baiye.modules.distribute.service.FileContrastService;
import com.baiye.modules.distribute.vo.FileContrastVO;
import com.baiye.result.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* @author Enzo
* @date 2024-3-13
*/
@RestController
@Tag(name = "文件对比")
@RequestMapping("/api/file/contrast")
@RequiredArgsConstructor
public class FileContrastController {
private final FileContrastService fileContrastService;
@GetMapping("/page")
@Operation(summary = "分页查询", description = "分页查询")
public R<PageResult<FileContrastVO>> getSysConfigPage(@Validated PageParam pageParam, FileContrastQo fileContrastQo) {
return R.ok(fileContrastService.queryPage(pageParam, fileContrastQo));
}
@Operation(summary = "创建任务")
@PostMapping("/create")
public R<Object> createTask(@RequestParam("files") List<MultipartFile> files,
@RequestParam(value = "taskName") String taskName) {
return Boolean.TRUE.equals(fileContrastService.createTask(files, taskName)) ? R.ok() : R.failed("上传失败");
}
@Operation(summary = "追加任务资源")
@PostMapping("/addition")
public R<Object> additionTaskSource(@RequestParam("files") List<MultipartFile> files,
@RequestParam(value = "taskId") Long taskId) {
return Boolean.TRUE.equals(fileContrastService.additionTaskSource(files, taskId)) ? R.ok() : R.failed("上传失败");
}
@Operation(summary = "任务对比")
@PostMapping("/build")
public R<Object> createTask(@RequestParam("files") List<MultipartFile> files,
@RequestParam(value = "taskId") Long taskId) {
return Boolean.TRUE.equals(fileContrastService.buildContrast(files, taskId)) ? R.ok() : R.failed("上传失败");
}
}

@ -0,0 +1,36 @@
package com.baiye.modules.distribute.controller;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.modules.distribute.qo.FileContrastQo;
import com.baiye.modules.distribute.service.FileContrastRecordService;
import com.baiye.modules.distribute.vo.FileContrastRecordVO;
import com.baiye.result.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Enzo
* @date 2024-3-13
*/
@RestController
@Tag(name = "文件对比")
@RequestMapping("/api/file/contrast/record")
@RequiredArgsConstructor
public class FileContrastRecordController {
private final FileContrastRecordService fileContrastRecordService;
@GetMapping("/page")
@Operation(summary = "分页查询", description = "分页查询")
public R<PageResult<FileContrastRecordVO>> getSysConfigPage(@Validated PageParam pageParam, FileContrastQo fileContrastQo) {
return R.ok(fileContrastRecordService.queryPage(pageParam, fileContrastQo));
}
}

@ -0,0 +1,26 @@
package com.baiye.modules.distribute.converter;
import com.baiye.modules.distribute.entity.FileContrastRecordEntity;
import com.baiye.modules.distribute.entity.FileContrastSourceEntity;
import com.baiye.modules.distribute.vo.FileContrastRecordVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* @author Enzo
* @date 2024-3-13
*/
@Mapper
public interface FileContrasRecordConverter {
FileContrasRecordConverter INSTANCE = Mappers.getMapper(FileContrasRecordConverter.class);
/**
* vo
*
* @param entity
* @return
*/
FileContrastRecordVO entityToVo(FileContrastRecordEntity entity);
}

@ -0,0 +1,26 @@
package com.baiye.modules.distribute.converter;
import com.baiye.modules.distribute.entity.FileContrastEntity;
import com.baiye.modules.distribute.vo.FileContrastVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* @author Enzo
* @date 2024-3-13
*/
@Mapper
public interface FileContrastConverter {
FileContrastConverter INSTANCE = Mappers.getMapper(FileContrastConverter.class);
/**
* vo
*
* @param entity
* @return
*/
FileContrastVO entityToVo(FileContrastEntity entity);
}

@ -0,0 +1,21 @@
package com.baiye.modules.distribute.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springdoc.api.annotations.ParameterObject;
/**
* @author Enzo
* @date 2023-10-20
*/
@Data
@Schema(title = "对比dto")
@ParameterObject
public class ContrastDTO {
private String nid;
private String remark;
private String isRepeat;
}

@ -0,0 +1,29 @@
package com.baiye.modules.distribute.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
* @author wjt
* @date 2023/9/13
*/
@Data
@Schema(title = "门店管理dto")
@ParameterObject
public class FileContrastDTO {
private MultipartFile[] files;
@NotEmpty(message = "用户id不能为空")
private List<Long> userIds;
@NotBlank(message = "任务名称不能为空")
private String taskName;
}

@ -4,8 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springdoc.api.annotations.ParameterObject;
import java.math.BigDecimal;
/**
* @author Enzo
* @date 2023-10-20

@ -0,0 +1,43 @@
package com.baiye.modules.distribute.entity;
import com.baiye.entity.BaseEntity;
import com.baiye.extend.mybatis.plus.alias.TableAlias;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* @author Enzo
* @date : 2024-3-13
*/
@Getter
@Setter
@TableAlias("fl")
@Schema(title = "文件上传对比")
@TableName(value = "tb_file_contrast_task" ,autoResultMap = true)
public class FileContrastEntity extends BaseEntity {
private static final long serialVersionUID = 7079254193191231031L;
@TableId
@Schema(title = "ID")
private Long id;
@Schema(title = "任务名称")
private String taskName;
@Schema(title = "对比状态")
private Integer status;
@Schema(title = "对比数量")
private Integer contrastNum;
}

@ -0,0 +1,45 @@
package com.baiye.modules.distribute.entity;
import com.baiye.entity.BaseEntity;
import com.baiye.extend.mybatis.plus.alias.TableAlias;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
/**
* @author Enzo
* @date : 2024-3-13
*/
@Getter
@Setter
@TableAlias("fs")
@Schema(title = "文件上传对比")
@TableName(value = "tb_file_contrast_record", autoResultMap = true)
public class FileContrastRecordEntity extends BaseEntity {
private static final long serialVersionUID = 1272925960799071730L;
@TableId
@Schema(title = "ID")
private Long id;
@Schema(title = "任务id")
private Long taskId;
@Schema(title = "对比数量")
private Integer contrastNum;
@Schema(title = "对比状态")
private Integer status;
@Schema(title = "文件地址")
private String filePath;
@Schema(title = "下载地址")
private String downPath;
}

@ -0,0 +1,40 @@
package com.baiye.modules.distribute.entity;
import com.baiye.entity.BaseEntity;
import com.baiye.extend.mybatis.plus.alias.TableAlias;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
/**
* @author Enzo
* @date : 2024-3-13
*/
@Getter
@Setter
@TableAlias("fs")
@Schema(title = "文件上传对比")
@TableName(value = "tb_file_contrast_source" ,autoResultMap = true)
public class FileContrastSourceEntity extends BaseEntity {
private static final long serialVersionUID = -2751989800003535012L;
@TableId
@Schema(title = "ID")
private Long id;
@Schema(title = "任务id")
private Long taskId;
@Schema(title = "nid")
private String nid;
@Schema(title = "备注")
private String remark;
}

@ -0,0 +1,34 @@
package com.baiye.modules.distribute.mapper;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.conditions.query.LambdaQueryWrapperX;
import com.baiye.extend.mybatis.plus.mapper.ExtendMapper;
import com.baiye.extend.mybatis.plus.toolkit.WrappersX;
import com.baiye.modules.distribute.entity.FileContrastEntity;
import com.baiye.modules.distribute.qo.FileContrastQo;
import com.baiye.modules.distribute.vo.FileContrastVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.apache.ibatis.annotations.Param;
public interface FileContrastMapper extends ExtendMapper<FileContrastEntity> {
default PageResult<FileContrastVO> queryPage(PageParam pageParam, FileContrastQo qo) {
IPage<FileContrastEntity> page = this.prodPage(pageParam);
LambdaQueryWrapperX<FileContrastEntity> wrapperX = WrappersX.lambdaQueryX(FileContrastEntity.class);
if (StringUtils.isNotBlank(qo.getStartTime()) && StringUtils.isNotBlank(qo.getEndTime())) {
wrapperX.between(FileContrastEntity::getCreateTime, qo.getStartTime(), qo.getEndTime());
}
wrapperX.likeIfPresent(FileContrastEntity::getTaskName, qo.getTaskName()).orderByDesc(FileContrastEntity::getId);
IPage<FileContrastVO> selected = this.selectByPage(page, wrapperX);
// IPage<FileContrastVO> iPage = page.convert(FileContrastConverter.INSTANCE::entityToVo);
return new PageResult<>(selected.getRecords(), selected.getTotal());
}
IPage<FileContrastVO> selectByPage(IPage<FileContrastEntity> page, @Param(Constants.WRAPPER) LambdaQueryWrapperX<FileContrastEntity> wrapper);
}

@ -0,0 +1,39 @@
package com.baiye.modules.distribute.mapper;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.conditions.query.LambdaQueryWrapperX;
import com.baiye.extend.mybatis.plus.mapper.ExtendMapper;
import com.baiye.extend.mybatis.plus.toolkit.WrappersX;
import com.baiye.modules.distribute.converter.FileContrasRecordConverter;
import com.baiye.modules.distribute.entity.FileContrastRecordEntity;
import com.baiye.modules.distribute.qo.FileContrastQo;
import com.baiye.modules.distribute.vo.FileContrastRecordVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
public interface FileContrastRecordMapper extends ExtendMapper<FileContrastRecordEntity> {
/**
*
*
* @param pageParam
* @param qo
* @return
*/
default PageResult<FileContrastRecordVO> queryPage(PageParam pageParam, FileContrastQo qo) {
IPage<FileContrastRecordEntity> page = this.prodPage(pageParam);
LambdaQueryWrapperX<FileContrastRecordEntity> wrapperX = WrappersX.lambdaQueryX(FileContrastRecordEntity.class);
if (StringUtils.isNotBlank(qo.getStartTime()) && StringUtils.isNotBlank(qo.getEndTime())) {
wrapperX.between(FileContrastRecordEntity::getCreateTime, qo.getStartTime(), qo.getEndTime());
}
wrapperX.orderByDesc(FileContrastRecordEntity::getId);
this.selectPage(page, wrapperX);
IPage<FileContrastRecordVO> iPage = page.convert(FileContrasRecordConverter.INSTANCE::entityToVo);
return new PageResult<>(iPage.getRecords(), iPage.getTotal());
}
}

@ -0,0 +1,8 @@
package com.baiye.modules.distribute.mapper;
import com.baiye.extend.mybatis.plus.mapper.ExtendMapper;
import com.baiye.modules.distribute.entity.FileContrastSourceEntity;
public interface FileContrastSourceMapper extends ExtendMapper<FileContrastSourceEntity> {
}

@ -0,0 +1,28 @@
package com.baiye.modules.distribute.qo;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springdoc.api.annotations.ParameterObject;
/**
* @author Enzo
* @date 2024-3-13
*/
@Data
@Schema(title = "文件上传对比")
@ParameterObject
public class FileContrastQo {
@Parameter(description = "授权名称")
private String taskName;
@Parameter(description = "开始时间")
private String startTime;
@Parameter(description = "结束时间")
private String endTime;
}

@ -82,4 +82,11 @@ public interface ClueService extends ExtendService<ClueEntity> {
* @return
*/
List<ClueVO> findCustomIdAndCreate(Long id, Long currentUserId);
/**
* id
* @param userIdList
* @return
*/
List<ClueVO> selectListByUserId(List<Long> userIdList);
}

@ -0,0 +1,27 @@
package com.baiye.modules.distribute.service;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.service.ExtendService;
import com.baiye.modules.distribute.entity.FileContrastRecordEntity;
import com.baiye.modules.distribute.qo.FileContrastQo;
import com.baiye.modules.distribute.vo.FileContrastRecordVO;
/**
* @author Enzo
* @date
*/
public interface FileContrastRecordService extends ExtendService<FileContrastRecordEntity> {
/**
*
*
* @param pageParam
* @param qo
* @return
*/
PageResult<FileContrastRecordVO> queryPage(PageParam pageParam, FileContrastQo qo);
}

@ -0,0 +1,46 @@
package com.baiye.modules.distribute.service;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.service.ExtendService;
import com.baiye.modules.distribute.entity.FileContrastEntity;
import com.baiye.modules.distribute.qo.FileContrastQo;
import com.baiye.modules.distribute.vo.FileContrastVO;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
public interface FileContrastService extends ExtendService<FileContrastEntity> {
/**
*
*/
PageResult<FileContrastVO> queryPage(PageParam pageParam, FileContrastQo qo);
/**
*
* @param files
* @param taskName
* @return
*/
Boolean createTask(List<MultipartFile> files, String taskName);
/**
*
* @param files
* @param taskId
* @return
*/
Boolean additionTaskSource(List<MultipartFile> files, Long taskId);
/**
*
* @param files
* @param taskId
* @return
*/
Boolean buildContrast(List<MultipartFile> files, Long taskId);
}

@ -0,0 +1,19 @@
package com.baiye.modules.distribute.service;
import com.baiye.extend.mybatis.plus.service.ExtendService;
import com.baiye.modules.distribute.entity.FileContrastSourceEntity;
import java.util.List;
public interface FileContrastSourceService extends ExtendService<FileContrastSourceEntity> {
/**
* task
* @param taskId
* @return
*/
List<FileContrastSourceEntity> queryByTaskId(Long taskId);
}

@ -66,9 +66,6 @@ public class ClueServiceImpl extends ExtendServiceImpl<ClueMapper, ClueEntity> i
@Value("${snowflake.workerId}")
private int workerId;
@ -268,4 +265,11 @@ public class ClueServiceImpl extends ExtendServiceImpl<ClueMapper, ClueEntity> i
return baseMapper.findCustomIdAndCreate(id, createBy, DefaultNumberConstants.ZERO_NUMBER);
}
@Override
public List<ClueVO> selectListByUserId(List<Long> userIdList) {
List<ClueEntity> clueEntityList = baseMapper.selectList(Wrappers.lambdaQuery(ClueEntity.class).in
(ClueEntity::getAssignedBy, userIdList).eq(ClueEntity::getDeleted, DefaultNumberConstants.ZERO_NUMBER));
return Convert.toList(ClueVO.class,clueEntityList);
}
}

@ -0,0 +1,38 @@
package com.baiye.modules.distribute.service.impl;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.service.impl.ExtendServiceImpl;
import com.baiye.modules.distribute.entity.FileContrastRecordEntity;
import com.baiye.modules.distribute.mapper.FileContrastRecordMapper;
import com.baiye.modules.distribute.mapper.FileContrastSourceMapper;
import com.baiye.modules.distribute.qo.FileContrastQo;
import com.baiye.modules.distribute.service.FileContrastRecordService;
import com.baiye.modules.distribute.vo.FileContrastRecordVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
* @author Enzo
* @date 2024-3-13
*/
@Service
@RequiredArgsConstructor
public class FileContrastRecordServiceImpl extends
ExtendServiceImpl<FileContrastRecordMapper, FileContrastRecordEntity> implements FileContrastRecordService {
private final FileContrastSourceMapper fileContrastSourceMapper;
@Override
public PageResult<FileContrastRecordVO> queryPage(PageParam pageParam, FileContrastQo qo) {
return baseMapper.queryPage(pageParam, qo);
}
}

@ -0,0 +1,198 @@
package com.baiye.modules.distribute.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.text.csv.CsvData;
import cn.hutool.core.text.csv.CsvReader;
import cn.hutool.core.text.csv.CsvRow;
import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.constant.FileConstant;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.service.impl.ExtendServiceImpl;
import com.baiye.modules.distribute.dto.ContrastDTO;
import com.baiye.modules.distribute.entity.FileContrastEntity;
import com.baiye.modules.distribute.entity.FileContrastRecordEntity;
import com.baiye.modules.distribute.entity.FileContrastSourceEntity;
import com.baiye.modules.distribute.mapper.FileContrastMapper;
import com.baiye.modules.distribute.mapper.FileContrastSourceMapper;
import com.baiye.modules.distribute.qo.FileContrastQo;
import com.baiye.modules.distribute.service.FileContrastRecordService;
import com.baiye.modules.distribute.service.FileContrastService;
import com.baiye.modules.distribute.vo.FileContrastVO;
import com.baiye.task.FileContrastTask;
import com.baiye.util.AESUtils;
import com.baiye.util.FileUtil;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.ballcat.security.properties.SecurityProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.List;
/**
* @author Enzo
* @date 2024-3-13
*/
@Service
@RequiredArgsConstructor
public class FileContrastServiceImpl extends ExtendServiceImpl<FileContrastMapper, FileContrastEntity> implements FileContrastService {
@Value("${snowflake.workerId}")
private int workerId;
@Value("${snowflake.datacenterId}")
private int datacenterId;
private final FileContrastTask fileContrastTask;
private final SecurityProperties securityProperties;
private final FileContrastSourceMapper fileContrastSourceMapper;
private final FileContrastRecordService fileContrastRecordService;
@Override
public PageResult<FileContrastVO> queryPage(PageParam pageParam, FileContrastQo qo) {
return baseMapper.queryPage(pageParam, qo);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean createTask(List<MultipartFile> files, String taskName) {
List<ContrastDTO> contrastDTOList = Lists.newArrayList();
for (MultipartFile file : files) {
String originalFilename = file.getOriginalFilename();
if (StringUtils.isNotBlank(originalFilename)) {
// 解析文件
contrastDTOList = parseFile(file, originalFilename);
}
}
contrastDTOList.forEach(dto ->
dto.setNid(AESUtils.encrypt(dto.getNid(), securityProperties.getPasswordSecretKey())));
// 雪花算法id
Long id = IdUtil.getSnowflake(workerId, datacenterId).nextId();
// 保存数据
FileContrastEntity fileContrast = new FileContrastEntity();
fileContrast.setId(id);
fileContrast.setTaskName(taskName);
fileContrast.setContrastNum(contrastDTOList.size());
// 转换数据
List<FileContrastSourceEntity> sourceEntityList =
Convert.toList(FileContrastSourceEntity.class, contrastDTOList);
sourceEntityList.forEach(str -> str.setTaskId(id));
fileContrastSourceMapper.insertBatchSomeColumn(sourceEntityList);
return this.save(fileContrast);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean additionTaskSource(List<MultipartFile> files, Long taskId) {
FileContrastEntity contrast = getById(taskId);
if (ObjectUtil.isNotNull(contrast) && ObjectUtil.isNotNull(contrast.getId())) {
List<ContrastDTO> contrastDTOList = Lists.newArrayList();
for (MultipartFile file : files) {
String originalFilename = file.getOriginalFilename();
if (StringUtils.isNotBlank(originalFilename)) {
// 解析文件
contrastDTOList = parseFile(file, originalFilename);
}
}
contrastDTOList.forEach(dto ->
dto.setNid(AESUtils.encrypt(dto.getNid(), securityProperties.getPasswordSecretKey())));
// 修改数量
contrast.setContrastNum(ObjectUtil.isNotNull(contrast.getContrastNum()) ?
contrast.getContrastNum() + contrastDTOList.size() : contrastDTOList.size());
this.updateById(contrast);
List<FileContrastSourceEntity> sourceEntityList = Convert.toList(FileContrastSourceEntity.class, contrastDTOList);
sourceEntityList.forEach(str -> str.setTaskId(taskId));
return SqlHelper.retBool(fileContrastSourceMapper.insertBatchSomeColumn(sourceEntityList));
}
return Boolean.FALSE;
}
@Override
public Boolean buildContrast(List<MultipartFile> files, Long taskId) {
FileContrastEntity contrast = baseMapper.selectById(taskId);
if (ObjectUtil.isNotNull(contrast)) {
List<ContrastDTO> contrastDTOList = Lists.newArrayList();
for (MultipartFile file : files) {
String originalFilename = file.getOriginalFilename();
if (StringUtils.isNotBlank(originalFilename)) {
// 解析文件
contrastDTOList = parseFile(file, originalFilename);
}
}
// 雪花算法id
Long id = IdUtil.getSnowflake(workerId, datacenterId).nextId();
FileContrastRecordEntity fileContrastRecord = new FileContrastRecordEntity();
fileContrastRecord.setTaskId(taskId);
fileContrastRecord.setId(id);
fileContrastRecord.setContrastNum(contrastDTOList.size());
fileContrastRecord.setStatus(DefaultNumberConstants.ZERO_NUMBER);
fileContrastRecordService.save(fileContrastRecord);
fileContrastTask.doRunTask(contrastDTOList, contrast, fileContrastRecord);
return Boolean.TRUE;
}
return Boolean.FALSE;
}
private List<ContrastDTO> parseFile(MultipartFile file, String originalFilename) {
List<ContrastDTO> dtoList = Lists.newArrayList();
// 解析 文件
File upload = FileUtil.multiToFile(file);
if (ObjectUtil.isNotNull(upload)) {
if (originalFilename.endsWith(FileConstant.XLS_FILE_SUB_NAME)
|| originalFilename.endsWith(FileConstant.XLSX_FILE_SUB_NAME)) {
ExcelReader reader = ExcelUtil.getReader(upload);
for (List<Object> objects : reader.read()) {
if (CollUtil.isNotEmpty(objects)) {
ContrastDTO dto = new ContrastDTO();
if (ObjectUtil.isNotNull(objects.get(DefaultNumberConstants.ZERO_NUMBER))) {
dto.setNid(objects.get
(DefaultNumberConstants.ZERO_NUMBER).toString());
}
if (objects.size() > DefaultNumberConstants.ONE_NUMBER) {
Object object = objects.get(DefaultNumberConstants.ONE_NUMBER);
dto.setRemark(ObjectUtil.isNotNull(object) ? object.toString() : CharSequenceUtil.EMPTY);
}
dtoList.add(dto);
}
}
}
if (originalFilename.endsWith(FileConstant.CSV_FILE_SUB_NAME)) {
CsvReader reader = CsvUtil.getReader();
CsvData read = reader.read(upload);
for (CsvRow row : read.getRows()) {
ContrastDTO dto = new ContrastDTO();
if (CollUtil.isNotEmpty(row)) {
if (ObjectUtil.isNotNull(row.get(DefaultNumberConstants.ZERO_NUMBER))) {
dto.setNid(row.get(DefaultNumberConstants.ZERO_NUMBER));
}
if (row.size() > DefaultNumberConstants.ONE_NUMBER) {
String string = row.get(DefaultNumberConstants.ONE_NUMBER);
dto.setRemark(StringUtils.isNotBlank(string) ? string : CharSequenceUtil.EMPTY);
}
dtoList.add(dto);
}
}
}
}
return dtoList;
}
}

@ -0,0 +1,29 @@
package com.baiye.modules.distribute.service.impl;
import com.baiye.extend.mybatis.plus.service.impl.ExtendServiceImpl;
import com.baiye.extend.mybatis.plus.toolkit.WrappersX;
import com.baiye.modules.distribute.entity.FileContrastSourceEntity;
import com.baiye.modules.distribute.mapper.FileContrastSourceMapper;
import com.baiye.modules.distribute.service.FileContrastSourceService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author Enzo
* @date 2024-3-13
*/
@Service
@RequiredArgsConstructor
public class FileContrastSourceServiceImpl extends
ExtendServiceImpl<FileContrastSourceMapper, FileContrastSourceEntity> implements FileContrastSourceService {
@Override
public List<FileContrastSourceEntity> queryByTaskId(Long taskId) {
return baseMapper.selectList
(WrappersX.lambdaQueryX(FileContrastSourceEntity.class).eq(FileContrastSourceEntity::getTaskId, taskId));
}
}

@ -77,7 +77,7 @@ public class PushClueServiceImpl extends ExtendServiceImpl<PlushClueMapper, Push
ObjectUtil.isNotNull(firstResponse.getMessage()) ? firstResponse.getMessage() : CharSequenceUtil.EMPTY, firstResponse.getCode());
if (ObjectUtil.isNotNull(firstResponse.getIsExist()) &&
firstResponse.getIsExist().equals(Boolean.FALSE)) {
tripartiteDTO.setOtherInfo(remark);
tripartiteDTO.setOtherInfo(Base64.encode(remark));
SendClueResponse secondResponse = new SendClueResponse();
tripartiteDTO.setRequestId(String.valueOf(requestId));
tripartiteDTO.setTimestamp(DateUtil.currentSeconds());

@ -0,0 +1,34 @@
package com.baiye.modules.distribute.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author Enzo
* @date 2023-11-6
*/
@Data
public class FileContrastRecordVO {
@Schema(title = "任务id")
private Long taskId;
@Schema(title = "对比状态")
private Integer status;
@Schema(title = "文件地址")
private String filePath;
@Schema(title = "下载地址")
private String downPath;
@Schema(title = "创建时间")
private LocalDateTime createTime;
@Schema(title = "修改时间")
private LocalDateTime updateTime;
}

@ -0,0 +1,30 @@
package com.baiye.modules.distribute.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author Enzo
* @date 2023-11-6
*/
@Data
public class FileContrastVO {
@Schema(title = "ID")
private Long id;
@Schema(title = "任务名称")
private String taskName;
@Schema(title = "对比数量")
private Integer contrastNum;
@Schema(title = "创建时间")
private LocalDateTime createTime;
@Schema(title = "修改时间")
private LocalDateTime updateTime;
}

@ -0,0 +1,120 @@
package com.baiye.task;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.core.text.csv.CsvWriter;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.constant.FileConstant;
import com.baiye.modules.distribute.dto.ContrastDTO;
import com.baiye.modules.distribute.entity.FileContrastEntity;
import com.baiye.modules.distribute.entity.FileContrastRecordEntity;
import com.baiye.modules.distribute.entity.FileContrastSourceEntity;
import com.baiye.modules.distribute.mapper.FileContrastMapper;
import com.baiye.modules.distribute.service.FileContrastRecordService;
import com.baiye.modules.distribute.service.FileContrastSourceService;
import com.baiye.system.properties.FileProperties;
import com.baiye.util.AESUtils;
import com.baiye.util.CompressUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ballcat.security.properties.SecurityProperties;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author Enzo
* @date : 2024/1/4
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class FileContrastTask {
private final FileProperties properties;
private final SecurityProperties securityProperties;
private final FileContrastMapper fileContrastMapper;
private final FileContrastSourceService fileContrastSourceService;
private final FileContrastRecordService fileContrastRecordService;
@Async
@Transactional(rollbackFor = Exception.class)
public void doRunTask(List<ContrastDTO> contrastDTOList, FileContrastEntity entity, FileContrastRecordEntity fileContrastRecord) {
log.info("================== run task begin time {} ==================", DateUtil.now());
String uuid = IdUtil.fastSimpleUUID();
String format = DateUtil.format(DateUtil.date(), DatePattern.NORM_DATE_PATTERN);
// 上传id
Set<String> uploadSet = contrastDTOList.stream().map
(ContrastDTO::getNid).collect(Collectors.toSet());
// 查询数据
List<FileContrastSourceEntity> querySet = fileContrastSourceService.queryByTaskId(entity.getId());
Set<String> selectSet = querySet.stream().map
(vo -> AESUtils.decrypt(vo.getNid(),
securityProperties.getPasswordSecretKey())).collect(Collectors.toSet());
// 交集
Set<String> strings = Sets.newHashSet(Sets.intersection(selectSet, uploadSet));
List<ContrastDTO> insertList = Lists.newArrayList();
for (ContrastDTO dto : contrastDTOList) {
if (strings.contains(dto.getNid())) {
dto.setIsRepeat("是");
} else {
dto.setIsRepeat("否");
insertList.add(dto);
}
}
// 保存文件
String fileName = properties.getPath().getPath().
concat(format).concat(properties.getPath().getSystemSeparator());
String csvPath = fileName.concat(uuid).concat(StrPool.DOT).concat(FileConstant.CSV_FILE_SUB_NAME);
CsvWriter writer = CsvUtil.getWriter(csvPath, CharsetUtil.CHARSET_UTF_8);
String zipPath = fileName.concat(uuid).concat(FileConstant.ZIP_FILE_SUB_NAME);
writer.writeHeaderLine("号码", "备注", "是否重复");
for (ContrastDTO dto : contrastDTOList) {
writer.writeLine(dto.getNid(), dto.getRemark(), dto.getIsRepeat());
}
writer.close();
// 设置压缩文件
CompressUtil.decryptionCompression(zipPath, csvPath, null);
String filePath = zipPath.substring
(zipPath.lastIndexOf(StrPool.SLASH) + DefaultNumberConstants.ONE_NUMBER);
FileUtil.del(csvPath);
String downPath = properties.getDownUrl().concat
(format).concat(properties.getPath().getSystemSeparator()).concat(filePath);
// 保存记录
List<FileContrastSourceEntity> sourceEntityList = Convert.toList(FileContrastSourceEntity.class, insertList);
sourceEntityList.forEach(dto -> dto.setTaskId(entity.getId()));
fileContrastSourceService.saveBatch(sourceEntityList);
// 修改数量
entity.setContrastNum(ObjectUtil.isNotNull(entity.getContrastNum())
? entity.getContrastNum() + contrastDTOList.size() : contrastDTOList.size());
fileContrastMapper.updateById(entity);
// 修改记录
fileContrastRecord.setDownPath(downPath);
fileContrastRecord.setStatus(DefaultNumberConstants.ONE_NUMBER);
fileContrastRecordService.updateById(fileContrastRecord);
log.info("================== run task end time {} ==================", DateUtil.now());
}
}

@ -19,6 +19,9 @@ business:
#门店专员
storeCode: ROLE_STORE_SALESMAN
file:
downUrl: http://39.100.77.21:8001/file/
urls:
dbPushUrl: http://cs.tuoz.net:8100/v1/tripartite/push/clue/

@ -20,6 +20,9 @@ business:
urls:
dbPushUrl: https://byffp.top/api/v1/tripartite/push/clue/
file:
downUrl: https://byffp.top/file/
# 生产环境关闭文档
ballcat:
openapi:

@ -33,6 +33,9 @@ springdoc:
- { name: 'admin', url: '/v3/api-docs' }
- { name: 'api', url: 'http://ballcat-api/v3/api-docs' }
file:
downUrl: http://39.100.77.21:8001/file/
# 巨量引擎配置
ocean:
engine:

@ -92,6 +92,7 @@ file:
maxSize: 300
avatarMaxSize: 5
elasticjob:
zookeeper:
namespace: springboot-elasticjob

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.baiye.modules.distribute.mapper.FileContrastMapper">
<resultMap id="BaseMap" type="com.baiye.modules.distribute.vo.FileContrastVO">
<id property="id" column="id"/>
<result property="taskName" column="task_name"/>
<result property="createTime" column="create_time"/>
<result property="contrastNum" column="contrast_num"/>
</resultMap>
<sql id="Base_Alias_Column_List">
fl.id,
fl.task_name,
fl.contrast_num,
fl.create_time,
fl.create_by
</sql>
<select id="selectByPage" resultMap="BaseMap">
SELECT
<include refid="Base_Alias_Column_List"/>
FROM
tb_file_contrast_task fl
${ew.customSqlSegment}
</select>
</mapper>

@ -52,6 +52,7 @@
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
<mybatis.version>3.5.10</mybatis.version>
<poi.version>4.1.2</poi.version>
<zip4j.version>1.3.2</zip4j.version>
<rocketmq.version>2.2.0</rocketmq.version>
<software.amazon.awssdk.version>2.20.70</software.amazon.awssdk.version>
<spring-authorization-server.version>0.4.2</spring-authorization-server.version>
@ -402,6 +403,14 @@
<artifactId>easy-captcha</artifactId>
<version>${captcha.version}</version>
</dependency>
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>${zip4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

Loading…
Cancel
Save