调整结算模块

This commit is contained in:
2026-09-08 10:58:21 +08:00
parent 4e9bb19b23
commit a3eeb24f4f
7 changed files with 249 additions and 41 deletions
@@ -0,0 +1,40 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
*/
package org.springblade.transport.pojo.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.core.tenant.mp.TenantEntity;
import java.io.Serial;
/**
* 凭证压缩包解压文件明细。
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("blade_voucher_file")
@Schema(description = "凭证文件明细")
public class VoucherFile extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
private Long voucherId;
private String voucherBatchNo;
private Long waybillId;
private String waybillNo;
private String plateNo;
private String folderName;
private String entryName;
private String fileName;
private String objectKey;
private Long fileSize;
private String contentType;
private String fileType;
private Integer matched;
}
@@ -0,0 +1,32 @@
package org.springblade.transport.pojo.vo;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 凭证解压文件详情。
*/
@Data
public class VoucherFileVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private Long id;
private Long voucherId;
private String voucherBatchNo;
private Long waybillId;
private String waybillNo;
private String plateNo;
private String folderName;
private String entryName;
private String fileName;
private String objectKey;
private Long fileSize;
private String contentType;
private String fileType;
private Integer matched;
private String url;
}
@@ -7,6 +7,7 @@ import org.springblade.transport.pojo.entity.VoucherManage;
import java.io.Serial; import java.io.Serial;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@@ -16,4 +17,5 @@ public class VoucherManageVO extends VoucherManage {
@TableField(exist = false) private String updateUserName; @TableField(exist = false) private String updateUserName;
@TableField(exist = false) private LocalDateTime createTimeStart; @TableField(exist = false) private LocalDateTime createTimeStart;
@TableField(exist = false) private LocalDateTime createTimeEnd; @TableField(exist = false) private LocalDateTime createTimeEnd;
@TableField(exist = false) private List<VoucherFileVO> voucherFiles;
} }
@@ -0,0 +1,15 @@
package org.springblade.transport.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springblade.transport.pojo.entity.VoucherFile;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Param;
/**
* 凭证解压文件明细 Mapper。
*/
public interface VoucherFileMapper extends BaseMapper<VoucherFile> {
@Delete("DELETE FROM blade_voucher_file WHERE voucher_id = #{voucherId}")
void deleteByVoucherId(@Param("voucherId") Long voucherId);
}
@@ -10,6 +10,7 @@ import org.springblade.core.tool.jackson.JsonUtil;
import org.springblade.core.tool.utils.Func; import org.springblade.core.tool.utils.Func;
import org.springblade.transport.mapper.VoucherManageMapper; import org.springblade.transport.mapper.VoucherManageMapper;
import org.springblade.transport.mapper.VoucherImageMapper; import org.springblade.transport.mapper.VoucherImageMapper;
import org.springblade.transport.mapper.VoucherFileMapper;
import org.springblade.transport.mapper.VoucherWaybillBatchMapper; import org.springblade.transport.mapper.VoucherWaybillBatchMapper;
import org.springblade.transport.event.VoucherUploadCompletedEvent; import org.springblade.transport.event.VoucherUploadCompletedEvent;
import org.springblade.transport.pojo.dto.VoucherManageSubmitRequest; import org.springblade.transport.pojo.dto.VoucherManageSubmitRequest;
@@ -18,9 +19,11 @@ import org.springblade.transport.pojo.dto.VoucherFileCompleteRequest;
import org.springblade.transport.pojo.entity.VoucherManage; import org.springblade.transport.pojo.entity.VoucherManage;
import org.springblade.transport.pojo.entity.VoucherWaybillBatch; import org.springblade.transport.pojo.entity.VoucherWaybillBatch;
import org.springblade.transport.pojo.entity.VoucherImage; import org.springblade.transport.pojo.entity.VoucherImage;
import org.springblade.transport.pojo.entity.VoucherFile;
import org.springblade.transport.pojo.entity.Waybill; import org.springblade.transport.pojo.entity.Waybill;
import org.springblade.transport.pojo.entity.ProjectApply; import org.springblade.transport.pojo.entity.ProjectApply;
import org.springblade.transport.pojo.vo.VoucherManageVO; import org.springblade.transport.pojo.vo.VoucherManageVO;
import org.springblade.transport.pojo.vo.VoucherFileVO;
import org.springblade.transport.service.IVoucherManageService; import org.springblade.transport.service.IVoucherManageService;
import org.springblade.transport.service.IProjectApplyService; import org.springblade.transport.service.IProjectApplyService;
import org.springblade.transport.service.IWaybillService; import org.springblade.transport.service.IWaybillService;
@@ -30,13 +33,17 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import io.minio.MinioClient; import io.minio.MinioClient;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.PutObjectArgs; import io.minio.PutObjectArgs;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -58,6 +65,7 @@ public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMappe
private final IProjectApplyService projectApplyService; private final IProjectApplyService projectApplyService;
private final IWaybillService waybillService; private final IWaybillService waybillService;
private final VoucherImageMapper voucherImageMapper; private final VoucherImageMapper voucherImageMapper;
private final VoucherFileMapper voucherFileMapper;
private final ApplicationEventPublisher eventPublisher; private final ApplicationEventPublisher eventPublisher;
private final MinioClient minioClient; private final MinioClient minioClient;
private final String minioBucketName; private final String minioBucketName;
@@ -65,13 +73,15 @@ public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMappe
public VoucherManageServiceImpl(VoucherWaybillBatchMapper voucherWaybillBatchMapper, IProjectApplyService projectApplyService, public VoucherManageServiceImpl(VoucherWaybillBatchMapper voucherWaybillBatchMapper, IProjectApplyService projectApplyService,
IWaybillService waybillService, IWaybillService waybillService,
VoucherImageMapper voucherImageMapper, ApplicationEventPublisher eventPublisher, MinioClient minioClient, VoucherImageMapper voucherImageMapper, VoucherFileMapper voucherFileMapper,
ApplicationEventPublisher eventPublisher, MinioClient minioClient,
@Value("${file.storage.minio.bucket-name:${minio.bucket-name:}}") String minioBucketName, @Value("${file.storage.minio.bucket-name:${minio.bucket-name:}}") String minioBucketName,
@Value("${file.storage.minio.root-directory:${minio.root-directory:}}") String minioRootDirectory) { @Value("${file.storage.minio.root-directory:${minio.root-directory:}}") String minioRootDirectory) {
this.voucherWaybillBatchMapper = voucherWaybillBatchMapper; this.voucherWaybillBatchMapper = voucherWaybillBatchMapper;
this.projectApplyService = projectApplyService; this.projectApplyService = projectApplyService;
this.waybillService = waybillService; this.waybillService = waybillService;
this.voucherImageMapper = voucherImageMapper; this.voucherImageMapper = voucherImageMapper;
this.voucherFileMapper = voucherFileMapper;
this.eventPublisher = eventPublisher; this.eventPublisher = eventPublisher;
this.minioClient = minioClient; this.minioClient = minioClient;
this.minioBucketName = minioBucketName; this.minioBucketName = minioBucketName;
@@ -87,7 +97,14 @@ public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMappe
public VoucherManageVO detail(Long id) { public VoucherManageVO detail(Long id) {
VoucherManage record = getById(id); VoucherManage record = getById(id);
if (record == null || Objects.equals(record.getIsDeleted(), 1)) throw new ServiceException("凭证批次不存在"); if (record == null || Objects.equals(record.getIsDeleted(), 1)) throw new ServiceException("凭证批次不存在");
return VoucherManageWrapper.build().entityVO(record); VoucherManageVO result = VoucherManageWrapper.build().entityVO(record);
List<VoucherFile> files = voucherFileMapper.selectList(Wrappers.<VoucherFile>lambdaQuery()
.eq(VoucherFile::getTenantId, record.getTenantId())
.eq(VoucherFile::getVoucherId, record.getId())
.eq(VoucherFile::getIsDeleted, 0)
.orderByAsc(VoucherFile::getEntryName));
result.setVoucherFiles(files.stream().map(this::toVoucherFileVO).toList());
return result;
} }
@Override @Override
@@ -225,6 +242,8 @@ public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMappe
} }
log.info("[凭证处理] 进度 20%:已建立车牌匹配索引 voucherId={}, plateCount={}", voucherId, waybillByPlate.size()); log.info("[凭证处理] 进度 20%:已建立车牌匹配索引 voucherId={}, plateCount={}", voucherId, waybillByPlate.size());
voucherImageMapper.deleteByVoucherId(voucher.getId()); voucherImageMapper.deleteByVoucherId(voucher.getId());
voucherFileMapper.deleteByVoucherId(voucher.getId());
int fileCount = 0;
int imageCount = 0; int imageCount = 0;
int matchedImageCount = 0; int matchedImageCount = 0;
Set<Long> relatedWaybillIds = new HashSet<>(); Set<Long> relatedWaybillIds = new HashSet<>();
@@ -239,51 +258,72 @@ public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMappe
if (entryName.equals("__MACOSX") || entryName.startsWith("__MACOSX/")) { if (entryName.equals("__MACOSX") || entryName.startsWith("__MACOSX/")) {
continue; continue;
} }
String[] pathParts = entryName.split("/"); List<String> pathParts = Arrays.stream(entryName.split("/"))
if (pathParts.length < 2 || !isImageFile(pathParts[pathParts.length - 1])) { .filter(Func::isNotEmpty).toList();
if (pathParts.isEmpty()) {
continue; continue;
} }
String plateNo = normalizePlateNo(pathParts[0]); String folderName = pathParts.size() > 1 ? safeArchiveSegment(pathParts.get(0)) : null;
String imageName = safeFileName(pathParts[pathParts.length - 1]); String plateNo = normalizePlateNo(folderName);
if (Func.isEmpty(plateNo) || Func.isEmpty(imageName)) { String rawFileName = pathParts.get(pathParts.size() - 1);
boolean imageFile = isImageFile(rawFileName);
String fileName = safeFileName(rawFileName);
if (Func.isEmpty(fileName)) {
continue; continue;
} }
Waybill waybill = waybillByPlate.get(plateNo); Waybill waybill = waybillByPlate.get(plateNo);
if (waybill == null) { if (imageFile && waybill == null) log.warn("[凭证处理] 图片未匹配运单 voucherId={}, plateNo={}, indexedPlates={}",
log.warn("[凭证处理] 图片未匹配运单 voucherId={}, plateNo={}, indexedPlates={}", voucherId, plateNo, waybillByPlate.keySet());
voucherId, plateNo, waybillByPlate.keySet());
} else {
log.info("[凭证处理] 图片匹配运单 voucherId={}, plateNo={}, waybillId={}, waybillNo={}",
voucherId, plateNo, waybill.getId(), waybill.getWaybillNo());
}
String waybillNo = waybill == null ? "unmatched" : safePathPart(waybill.getWaybillNo()); String waybillNo = waybill == null ? "unmatched" : safePathPart(waybill.getWaybillNo());
String objectKey = buildObjectKey(voucher.getId(), waybillNo, plateNo, imageName); String objectKey = buildObjectKey(voucher.getId(), waybillNo,
Func.isEmpty(plateNo) ? "root" : plateNo, entryName);
String contentType = contentType(fileName);
minioClient.putObject(PutObjectArgs.builder().bucket(minioBucketName).object(objectKey) minioClient.putObject(PutObjectArgs.builder().bucket(minioBucketName).object(objectKey)
.stream(zipInputStream, entry.getSize(), 10 * 1024 * 1024).build()); .stream(zipInputStream, entry.getSize(), 10 * 1024 * 1024)
VoucherImage image = new VoucherImage(); .contentType(contentType).build());
image.setVoucherId(voucher.getId()); VoucherFile file = new VoucherFile();
image.setVoucherBatchNo(voucher.getVoucherBatchNo()); file.setVoucherId(voucher.getId());
image.setWaybillId(waybill == null ? null : waybill.getId()); file.setVoucherBatchNo(voucher.getVoucherBatchNo());
image.setWaybillNo(waybill == null ? null : waybill.getWaybillNo()); file.setWaybillId(waybill == null ? null : waybill.getId());
image.setPlateNo(plateNo); file.setWaybillNo(waybill == null ? null : waybill.getWaybillNo());
image.setImageName(imageName); file.setPlateNo(Func.isEmpty(plateNo) ? null : plateNo);
image.setObjectKey(objectKey); file.setFolderName(folderName);
image.setMatched(waybill == null ? 0 : 1); file.setEntryName(entryName);
image.setTenantId(voucher.getTenantId()); file.setFileName(fileName);
voucherImageMapper.insert(image); file.setObjectKey(objectKey);
imageCount++; file.setFileSize(entry.getSize() < 0 ? null : entry.getSize());
if (waybill != null) { file.setContentType(contentType);
file.setFileType(imageFile ? "image" : "file");
file.setMatched(waybill == null ? 0 : 1);
file.setTenantId(voucher.getTenantId());
voucherFileMapper.insert(file);
fileCount++;
if (imageFile) {
VoucherImage image = new VoucherImage();
image.setVoucherId(voucher.getId());
image.setVoucherBatchNo(voucher.getVoucherBatchNo());
image.setWaybillId(waybill == null ? null : waybill.getId());
image.setWaybillNo(waybill == null ? null : waybill.getWaybillNo());
image.setPlateNo(Func.isEmpty(plateNo) ? "" : plateNo);
image.setImageName(fileName);
image.setObjectKey(objectKey);
image.setMatched(waybill == null ? 0 : 1);
image.setTenantId(voucher.getTenantId());
voucherImageMapper.insert(image);
imageCount++;
}
if (waybill != null && imageFile) {
matchedImageCount++; matchedImageCount++;
relatedWaybillIds.add(waybill.getId()); relatedWaybillIds.add(waybill.getId());
} }
if (imageCount % 10 == 0) { if (fileCount % 10 == 0) {
log.info("[凭证处理] 图片处理中 voucherId={}, processedImages={}, matchedImages={}, relatedWaybills={}", log.info("[凭证处理] 文件处理中 voucherId={}, processedFiles={}, imageCount={}, matchedImages={}, relatedWaybills={}",
voucherId, imageCount, matchedImageCount, relatedWaybillIds.size()); voucherId, fileCount, imageCount, matchedImageCount, relatedWaybillIds.size());
} }
} }
} }
log.info("[凭证处理] 进度 90%图片解压上传完成 voucherId={}, imageCount={}, matchedImageCount={}", log.info("[凭证处理] 进度 90%文件解压上传完成 voucherId={}, fileCount={}, imageCount={}, matchedImageCount={}",
voucherId, imageCount, matchedImageCount); voucherId, fileCount, imageCount, matchedImageCount);
VoucherManage update = new VoucherManage(); VoucherManage update = new VoucherManage();
update.setId(voucher.getId()); update.setId(voucher.getId());
update.setVoucherCount(imageCount); update.setVoucherCount(imageCount);
@@ -291,8 +331,8 @@ public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMappe
update.setUnRelatedWaybillCount(Math.max(waybills.size() - relatedWaybillIds.size(), 0)); update.setUnRelatedWaybillCount(Math.max(waybills.size() - relatedWaybillIds.size(), 0));
update.setProcessStatus("处理完成"); update.setProcessStatus("处理完成");
updateById(update); updateById(update);
log.info("[凭证处理] 进度 100%:处理完成 voucherId={}, voucherBatchNo={}, imageCount={}, relatedWaybillCount={}, unrelatedWaybillCount={}", log.info("[凭证处理] 进度 100%:处理完成 voucherId={}, voucherBatchNo={}, fileCount={}, imageCount={}, relatedWaybillCount={}, unrelatedWaybillCount={}",
voucherId, voucher.getVoucherBatchNo(), imageCount, relatedWaybillIds.size(), Math.max(waybills.size() - relatedWaybillIds.size(), 0)); voucherId, voucher.getVoucherBatchNo(), fileCount, imageCount, relatedWaybillIds.size(), Math.max(waybills.size() - relatedWaybillIds.size(), 0));
} catch (Exception exception) { } catch (Exception exception) {
VoucherManage update = new VoucherManage(); VoucherManage update = new VoucherManage();
update.setId(voucher.getId()); update.setId(voucher.getId());
@@ -310,6 +350,8 @@ public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMappe
if (voucher == null) throw new ServiceException("凭证批次不存在"); if (voucher == null) throw new ServiceException("凭证批次不存在");
deleteLogic(List.of(id)); deleteLogic(List.of(id));
voucherWaybillBatchMapper.delete(Wrappers.<VoucherWaybillBatch>lambdaQuery().eq(VoucherWaybillBatch::getVoucherId, id)); voucherWaybillBatchMapper.delete(Wrappers.<VoucherWaybillBatch>lambdaQuery().eq(VoucherWaybillBatch::getVoucherId, id));
voucherFileMapper.deleteByVoucherId(id);
voucherImageMapper.deleteByVoucherId(id);
} }
@Override @Override
@@ -347,26 +389,75 @@ public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMappe
} }
private InputStream openSourceFile(String fileUrl) throws Exception { private InputStream openSourceFile(String fileUrl) throws Exception {
URLConnection connection = new java.net.URL(fileUrl).openConnection(); String normalizedUrl = stripZipSuffixParameters(fileUrl);
URLConnection connection = new java.net.URL(normalizedUrl).openConnection();
connection.setConnectTimeout(30_000); connection.setConnectTimeout(30_000);
connection.setReadTimeout(300_000); connection.setReadTimeout(300_000);
return connection.getInputStream(); return connection.getInputStream();
} }
private String stripZipSuffixParameters(String fileUrl) {
if (Func.isEmpty(fileUrl)) {
return fileUrl;
}
String lowerUrl = fileUrl.toLowerCase(Locale.ROOT);
int zipEnd = lowerUrl.indexOf(".zip");
return zipEnd < 0 ? fileUrl : fileUrl.substring(0, zipEnd + 4);
}
private void validateMinioConfig() { private void validateMinioConfig() {
if (Func.isEmpty(minioBucketName)) { if (Func.isEmpty(minioBucketName)) {
throw new ServiceException("Nacos 未配置 file.storage.minio.bucket-name"); throw new ServiceException("Nacos 未配置 file.storage.minio.bucket-name");
} }
} }
private String buildObjectKey(Long voucherId, String waybillNo, String plateNo, String imageName) { private String buildObjectKey(Long voucherId, String waybillNo, String plateNo, String entryName) {
String objectKey = voucherId + "/" + waybillNo + "/" + safePathPart(plateNo) + "/" + imageName; String objectKey = voucherId + "/" + waybillNo + "/" + safePathPart(plateNo) + "/" + safeArchivePath(entryName);
if (Func.isEmpty(minioRootDirectory)) { if (Func.isEmpty(minioRootDirectory)) {
return objectKey; return objectKey;
} }
return minioRootDirectory.endsWith("/") ? minioRootDirectory + objectKey : minioRootDirectory + "/" + objectKey; return minioRootDirectory.endsWith("/") ? minioRootDirectory + objectKey : minioRootDirectory + "/" + objectKey;
} }
private String safeArchivePath(String entryName) {
return Arrays.stream(entryName == null ? new String[0] : entryName.replace('\\', '/').split("/"))
.filter(Func::isNotEmpty).map(this::safeArchiveSegment).filter(Func::isNotEmpty).collect(Collectors.joining("/"));
}
private String safeArchiveSegment(String value) {
return value == null ? "" : value.replaceAll("[^0-9A-Za-z\\u4e00-\\u9fa5._-]", "_");
}
private String contentType(String fileName) {
String contentType = URLConnection.guessContentTypeFromName(fileName);
return Func.isEmpty(contentType) ? "application/octet-stream" : contentType;
}
private VoucherFileVO toVoucherFileVO(VoucherFile file) {
VoucherFileVO result = new VoucherFileVO();
result.setId(file.getId());
result.setVoucherId(file.getVoucherId());
result.setVoucherBatchNo(file.getVoucherBatchNo());
result.setWaybillId(file.getWaybillId());
result.setWaybillNo(file.getWaybillNo());
result.setPlateNo(file.getPlateNo());
result.setFolderName(file.getFolderName());
result.setEntryName(file.getEntryName());
result.setFileName(file.getFileName());
result.setObjectKey(file.getObjectKey());
result.setFileSize(file.getFileSize());
result.setContentType(file.getContentType());
result.setFileType(file.getFileType());
result.setMatched(file.getMatched());
try {
result.setUrl(minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
.method(Method.GET).bucket(minioBucketName).object(file.getObjectKey()).expiry(1, java.util.concurrent.TimeUnit.HOURS).build()));
} catch (Exception exception) {
log.warn("生成凭证文件预览地址失败 voucherFileId={}, objectKey={}", file.getId(), file.getObjectKey(), exception);
}
return result;
}
private String normalizePlateNo(String plateNo) { private String normalizePlateNo(String plateNo) {
return plateNo == null ? null : plateNo.replaceAll("[\\s-]", "").toUpperCase(); return plateNo == null ? null : plateNo.replaceAll("[\\s-]", "").toUpperCase();
} }
@@ -412,7 +503,7 @@ public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMappe
} }
private String safeFileName(String value) { private String safeFileName(String value) {
return value == null ? "" : safePathPart(value.replaceFirst("(?s)^.*[/\\\\]", "")); return value == null ? "" : safeArchiveSegment(value.replaceFirst("(?s)^.*[/\\\\]", ""));
} }
private boolean isImageFile(String fileName) { private boolean isImageFile(String fileName) {
@@ -0,0 +1,28 @@
CREATE TABLE IF NOT EXISTS `blade_voucher_file` (
`id` bigint NOT NULL,
`tenant_id` varchar(12) NOT NULL DEFAULT '000000' COMMENT '租户ID',
`voucher_id` bigint NOT NULL COMMENT '凭证批次ID',
`voucher_batch_no` varchar(30) NOT NULL COMMENT '凭证批次号',
`waybill_id` bigint DEFAULT NULL COMMENT '关联运单ID',
`waybill_no` varchar(64) DEFAULT NULL COMMENT '关联运单号',
`plate_no` varchar(32) DEFAULT NULL COMMENT '压缩包目录车牌号',
`folder_name` varchar(255) DEFAULT NULL COMMENT '压缩包一级目录',
`entry_name` varchar(1000) NOT NULL COMMENT '压缩包内相对路径',
`file_name` varchar(255) NOT NULL COMMENT '文件名',
`object_key` varchar(1000) NOT NULL COMMENT 'MinIO对象路径',
`file_size` bigint DEFAULT NULL COMMENT '文件大小(字节)',
`content_type` varchar(100) DEFAULT NULL COMMENT '文件类型',
`file_type` varchar(20) NOT NULL DEFAULT 'file' COMMENT '文件类型:image、file',
`matched` tinyint NOT NULL DEFAULT 0 COMMENT '是否匹配运单:0否、1是',
`create_user` bigint DEFAULT NULL,
`create_dept` bigint DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`update_user` bigint DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`status` tinyint NOT NULL DEFAULT 1,
`is_deleted` tinyint NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `idx_voucher_file_voucher` (`tenant_id`, `voucher_id`),
KEY `idx_voucher_file_waybill` (`waybill_id`),
KEY `idx_voucher_file_entry` (`voucher_id`, `entry_name`(191))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='凭证解压文件明细';
+1 -1
View File
@@ -100,7 +100,7 @@ monitor(){
#启动程序模块 #启动程序模块
modules(){ modules(){
docker-compose up -d blade-gateway1 blade-gateway2 blade-auth1 blade-auth2 blade-report blade-desk blade-system blade-log blade-flow blade-resource blade-job docker-compose up -d blade-gateway1 blade-gateway2 blade-auth1 blade-auth2 blade-report blade-desk blade-system blade-log blade-flow blade-resource blade-job blade-transport
} }
#启动普罗米修斯模块 #启动普罗米修斯模块