新增凭证管理
This commit is contained in:
+6
@@ -59,4 +59,10 @@ public class FileTaskCreateDTO implements Serializable {
|
||||
*/
|
||||
@Schema(description = "是否强制创建新任务,默认 false,如果存在相同md5的任务,会创建失败,true则新创建一个任务")
|
||||
private boolean force;
|
||||
|
||||
@Schema(description = "业务类型")
|
||||
private String businessType;
|
||||
|
||||
@Schema(description = "业务标识")
|
||||
private String businessId;
|
||||
}
|
||||
|
||||
+6
@@ -91,6 +91,12 @@ public class FileTask implements Serializable {
|
||||
@Schema(description = "状态 uploading:正在上传 completed:上传完成 failed:上传失败 paused:已暂停")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "业务类型")
|
||||
private String businessType;
|
||||
|
||||
@Schema(description = "业务标识")
|
||||
private String businessId;
|
||||
|
||||
/**
|
||||
* 创建人-用户名称
|
||||
*/
|
||||
|
||||
+6
@@ -87,6 +87,12 @@ public class FileTaskVO implements Serializable {
|
||||
@Schema(description = "状态 uploading:正在上传 completed:上传完成 failed:上传失败 paused:已暂停")
|
||||
private String status;
|
||||
|
||||
@Schema(description = "业务类型")
|
||||
private String businessType;
|
||||
|
||||
@Schema(description = "业务标识")
|
||||
private String businessId;
|
||||
|
||||
/**
|
||||
* 创建人-用户名称
|
||||
*/
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package org.springblade.transport.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class VoucherManageSubmitRequest {
|
||||
private Long id;
|
||||
private String voucherBatchNo;
|
||||
private Long projectId;
|
||||
private String projectName;
|
||||
private String fileName;
|
||||
private String fileUrl;
|
||||
private Long fileTaskId;
|
||||
private List<Long> waybillImportBatchIds;
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package org.springblade.transport.pojo.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/** 创建执行凭证上传草稿。 */
|
||||
@Data
|
||||
public class VoucherUploadDraftRequest {
|
||||
private Long projectId;
|
||||
private String fileName;
|
||||
}
|
||||
+3
@@ -53,6 +53,9 @@ public class CustomerInvoiceInfo extends TenantEntity {
|
||||
@Schema(description = "受票方名称")
|
||||
private String invoiceTitle;
|
||||
|
||||
@Schema(description = "发票类型")
|
||||
private String invoiceType;
|
||||
|
||||
@Schema(description = "纳税人识别号")
|
||||
private String taxNo;
|
||||
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
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_manage")
|
||||
@Schema(description = "凭证管理")
|
||||
public class VoucherManage extends TenantEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Long projectId;
|
||||
private String projectName;
|
||||
private String voucherBatchNo;
|
||||
private String waybillBatchNo;
|
||||
private String fileName;
|
||||
private String fileUrl;
|
||||
private Long fileTaskId;
|
||||
private String uploadSource;
|
||||
private String carrierName;
|
||||
private String processStatus;
|
||||
private Integer voucherCount;
|
||||
private Integer relatedWaybillCount;
|
||||
private Integer unRelatedWaybillCount;
|
||||
private String auditStatus;
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package org.springblade.transport.pojo.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/** 凭证与运单批次关联。 */
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("blade_voucher_waybill_batch")
|
||||
public class VoucherWaybillBatch extends TenantEntity {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Long voucherId;
|
||||
private Long waybillImportBatchId;
|
||||
private String waybillBatchNo;
|
||||
private Integer waybillCount;
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package org.springblade.transport.pojo.vo;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.transport.pojo.entity.VoucherManage;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class VoucherManageVO extends VoucherManage {
|
||||
@Serial private static final long serialVersionUID = 1L;
|
||||
@TableField(exist = false) private String createUserName;
|
||||
@TableField(exist = false) private String updateUserName;
|
||||
@TableField(exist = false) private LocalDateTime createTimeStart;
|
||||
@TableField(exist = false) private LocalDateTime createTimeEnd;
|
||||
}
|
||||
+22
@@ -13,11 +13,14 @@ import org.springblade.core.boot.ctrl.BladeController;
|
||||
import org.springblade.core.log.annotation.ApiLog;
|
||||
import org.springblade.core.tenant.annotation.NonDS;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springblade.file.pojo.dto.FileTaskCreateDTO;
|
||||
import org.springblade.file.pojo.dto.FileTaskUpdateDTO;
|
||||
import org.springblade.file.pojo.dto.IdsDTO;
|
||||
import org.springblade.file.pojo.vo.FileTaskUpdateVO;
|
||||
import org.springblade.file.service.IFileTaskService;
|
||||
import org.springblade.file.service.IFileService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -35,6 +38,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
public class FileTaskController extends BladeController {
|
||||
|
||||
private final IFileTaskService fileTaskService;
|
||||
private final IFileService fileService;
|
||||
|
||||
@GetMapping("/queryFileTask")
|
||||
@Operation(summary = "根据文件的MD5值查询文件任务", description = "文件的MD5值检查分段,参数名:md5")
|
||||
@@ -43,6 +47,24 @@ public class FileTaskController extends BladeController {
|
||||
return R.data(fileTask);
|
||||
}
|
||||
|
||||
@GetMapping("/file-url")
|
||||
@Operation(summary = "获取已完成上传任务文件地址")
|
||||
public R<String> fileUrl(@RequestParam Long id) {
|
||||
org.springblade.file.pojo.entity.FileTask task = fileTaskService.getById(id);
|
||||
if (task == null || !org.springblade.file.pojo.enums.FileTaskStatus.COMPLETED.getCode().equals(task.getStatus())) {
|
||||
return R.fail("文件尚未上传完成");
|
||||
}
|
||||
return R.data(fileService.getFileUrl(task.getObjectKey(), null));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "上传任务分页")
|
||||
public R<IPage<FileTaskUpdateVO>> list(Query query, @RequestParam(required = false) String businessType,
|
||||
@RequestParam(required = false) String businessId, @RequestParam(required = false) String attachmentName,
|
||||
@RequestParam(required = false) String status) {
|
||||
return R.data(fileTaskService.selectPage(query, businessType, businessId, attachmentName, status));
|
||||
}
|
||||
|
||||
@ApiLog("上传任务-创建文件任务")
|
||||
@PostMapping("/createFileTask")
|
||||
@Operation(summary = "创建文件任务", description = "创建文件任务")
|
||||
|
||||
+4
@@ -26,6 +26,8 @@
|
||||
package org.springblade.file.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import org.springblade.file.pojo.dto.FileTaskCreateDTO;
|
||||
import org.springblade.file.pojo.dto.FileTaskUpdateDTO;
|
||||
import org.springblade.file.pojo.entity.FileTask;
|
||||
@@ -91,4 +93,6 @@ public interface IFileTaskService extends IService<FileTask> {
|
||||
* @return
|
||||
*/
|
||||
boolean updatePaused(List<Long> param);
|
||||
|
||||
IPage<FileTaskUpdateVO> selectPage(Query query, String businessType, String businessId, String attachmentName, String status);
|
||||
}
|
||||
|
||||
+16
@@ -28,12 +28,15 @@ package org.springblade.file.service.impl;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.tool.utils.CollectionUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.file.config.ObsProperties;
|
||||
import org.springblade.file.convert.FileTaskConvert;
|
||||
import org.springblade.file.listener.FileUploadedEvent;
|
||||
@@ -125,6 +128,8 @@ public class FileTaskServiceImpl extends ServiceImpl<FileTaskMapper, FileTask> i
|
||||
addParam.setUploadId(uploadId);
|
||||
// 正在上传
|
||||
addParam.setStatus(FileTaskStatus.UPLOADING.getCode());
|
||||
// 兼容历史表未配置 is_deleted 默认值的场景。
|
||||
addParam.setIsDeleted(0);
|
||||
this.save(addParam);
|
||||
|
||||
return addParam.getId();
|
||||
@@ -317,6 +322,17 @@ public class FileTaskServiceImpl extends ServiceImpl<FileTaskMapper, FileTask> i
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<FileTaskUpdateVO> selectPage(org.springblade.core.mp.support.Query query, String businessType, String businessId, String attachmentName, String status) {
|
||||
IPage<FileTask> page = page(Condition.getPage(query), Wrappers.<FileTask>lambdaQuery()
|
||||
.eq(StringUtil.isNotBlank(businessType), FileTask::getBusinessType, businessType)
|
||||
.eq(StringUtil.isNotBlank(businessId), FileTask::getBusinessId, businessId)
|
||||
.like(StringUtil.isNotBlank(attachmentName), FileTask::getAttachmentName, attachmentName)
|
||||
.eq(StringUtil.isNotBlank(status), FileTask::getStatus, status)
|
||||
.eq(FileTask::getCreateUser, AuthUtil.getUserId()).orderByDesc(FileTask::getCreateTime));
|
||||
return page.convert(this::getFileTaskUpdateVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询文件任务
|
||||
* @param id
|
||||
|
||||
+44
@@ -28,7 +28,10 @@ package org.springblade.file.service.impl;
|
||||
import io.minio.GetObjectArgs;
|
||||
import io.minio.GetPresignedObjectUrlArgs;
|
||||
import io.minio.MinioClient;
|
||||
import io.minio.ComposeObjectArgs;
|
||||
import io.minio.ComposeSource;
|
||||
import io.minio.PutObjectArgs;
|
||||
import io.minio.RemoveObjectArgs;
|
||||
import io.minio.UploadObjectArgs;
|
||||
import io.minio.http.Method;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -43,7 +46,10 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* MinIO文件存储
|
||||
@@ -59,6 +65,44 @@ public class MinioFileServiceImpl extends AbstractFileService {
|
||||
private final FileStorageProperties.StoreProperties properties;
|
||||
private final MinioClient minioClient;
|
||||
|
||||
@Override
|
||||
public String initiateMultipartUpload(String objectKey) {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUploadPartUrl(String objectKey, String uploadId, Integer partNumber, Long expires) {
|
||||
try {
|
||||
return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
|
||||
.method(Method.PUT).bucket(properties.getBucketName()).object(partObjectKey(objectKey, uploadId, partNumber))
|
||||
.expiry(Math.toIntExact(resolveExpires(expires))).build());
|
||||
} catch (Exception exception) {
|
||||
log.error("MinIO获取分片上传链接异常 objectKey:{}", objectKey, exception);
|
||||
throw new ServiceException("获取分片上传链接异常");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeMultipartUpload(String objectKey, String uploadId, List<org.springblade.file.pojo.vo.PartEtagVO> partEtags) {
|
||||
try {
|
||||
List<ComposeSource> sources = new ArrayList<>();
|
||||
for (org.springblade.file.pojo.vo.PartEtagVO part : partEtags) {
|
||||
sources.add(ComposeSource.builder().bucket(properties.getBucketName()).object(partObjectKey(objectKey, uploadId, part.getPartNumber())).build());
|
||||
}
|
||||
minioClient.composeObject(ComposeObjectArgs.builder().bucket(properties.getBucketName()).object(resolveObjectKey(objectKey)).sources(sources).build());
|
||||
for (org.springblade.file.pojo.vo.PartEtagVO part : partEtags) {
|
||||
minioClient.removeObject(RemoveObjectArgs.builder().bucket(properties.getBucketName()).object(partObjectKey(objectKey, uploadId, part.getPartNumber())).build());
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
log.error("MinIO合并分片异常 objectKey:{}", objectKey, exception);
|
||||
throw new ServiceException("MinIO合并分片异常");
|
||||
}
|
||||
}
|
||||
|
||||
private String partObjectKey(String objectKey, String uploadId, Integer partNumber) {
|
||||
return resolveObjectKey(".multipart/" + uploadId + "/" + objectKey + ".part-" + partNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadFile(String objectKey, InputStream inputStream) {
|
||||
try {
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package org.springblade.transport.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.boot.ctrl.BladeController;
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import org.springblade.core.secure.annotation.PreAuth;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.transport.pojo.dto.VoucherManageSubmitRequest;
|
||||
import org.springblade.transport.pojo.dto.VoucherUploadDraftRequest;
|
||||
import org.springblade.transport.pojo.entity.VoucherManage;
|
||||
import org.springblade.transport.pojo.vo.VoucherManageVO;
|
||||
import org.springblade.transport.service.IVoucherManageService;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@PreAuth(menu = "voucher_manage")
|
||||
@RequestMapping("/voucher-manage")
|
||||
@Tag(name = "凭证管理", description = "执行凭证批次管理")
|
||||
public class VoucherManageController extends BladeController {
|
||||
private final IVoucherManageService voucherManageService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "凭证管理分页")
|
||||
public R<IPage<VoucherManageVO>> list(VoucherManageVO voucherManage, Query query) {
|
||||
return R.data(voucherManageService.selectPage(Condition.getPage(query), voucherManage));
|
||||
}
|
||||
|
||||
@GetMapping("/detail")
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "凭证详情")
|
||||
public R<VoucherManageVO> detail(@RequestParam Long id) { return R.data(voucherManageService.detail(id)); }
|
||||
|
||||
@PostMapping("/submit")
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "上传凭证或更换运输批次")
|
||||
public R submit(@RequestBody VoucherManageSubmitRequest request) { voucherManageService.submit(request); return R.success("提交成功"); }
|
||||
|
||||
@PostMapping("/upload-draft")
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "创建凭证上传草稿")
|
||||
public R<VoucherManage> createUploadDraft(@RequestBody VoucherUploadDraftRequest request) {
|
||||
return R.data(voucherManageService.createUploadDraft(request));
|
||||
}
|
||||
|
||||
@PostMapping("/remove")
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "删除凭证")
|
||||
public R remove(@RequestParam Long id) { voucherManageService.removeVoucher(id); return R.success("删除成功"); }
|
||||
|
||||
@GetMapping("/waybill-batches")
|
||||
@ApiOperationSupport(order = 6)
|
||||
@Operation(summary = "可关联运输批次")
|
||||
public R<List<Map<String, Object>>> waybillBatches(@RequestParam(required = false) String batchNo,
|
||||
@RequestParam(required = false) String createUser, @RequestParam(required = false) Integer waybillCount,
|
||||
@RequestParam(required = false) String createTimeStart, @RequestParam(required = false) String createTimeEnd) {
|
||||
return R.data(voucherManageService.selectableWaybillBatches(batchNo, createUser, waybillCount, createTimeStart, createTimeEnd));
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package org.springblade.transport.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springblade.transport.pojo.entity.VoucherManage;
|
||||
|
||||
public interface VoucherManageMapper extends BaseMapper<VoucherManage> { }
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package org.springblade.transport.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springblade.transport.pojo.entity.VoucherWaybillBatch;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface VoucherWaybillBatchMapper extends BaseMapper<VoucherWaybillBatch> {
|
||||
List<Map<String, Object>> selectWaybillBatches(@Param("tenantId") String tenantId, @Param("batchNo") String batchNo, @Param("createUser") String createUser,
|
||||
@Param("waybillCount") Integer waybillCount, @Param("createTimeStart") String createTimeStart, @Param("createTimeEnd") String createTimeEnd);
|
||||
List<Map<String, Object>> selectWaybillBatchesByIds(@Param("tenantId") String tenantId, @Param("ids") List<Long> ids);
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?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="org.springblade.transport.mapper.VoucherWaybillBatchMapper">
|
||||
<select id="selectWaybillBatches" resultType="java.util.LinkedHashMap">
|
||||
SELECT b.id, b.batch_no AS batchNo, b.waybill_count AS waybillCount, b.create_time AS createTime,
|
||||
b.create_user AS createUser, u.real_name AS createUserName
|
||||
FROM blade_waybill_import_batch b
|
||||
LEFT JOIN blade_user u ON u.id = b.create_user
|
||||
WHERE b.is_deleted = 0 AND b.tenant_id = #{tenantId}
|
||||
<if test="batchNo != null and batchNo != ''">AND b.batch_no LIKE CONCAT('%', #{batchNo}, '%')</if>
|
||||
<if test="createUser != null and createUser != ''">AND b.create_user = #{createUser}</if>
|
||||
<if test="waybillCount != null">AND b.waybill_count = #{waybillCount}</if>
|
||||
<if test="createTimeStart != null and createTimeStart != ''">AND b.create_time <![CDATA[>=]]> #{createTimeStart}</if>
|
||||
<if test="createTimeEnd != null and createTimeEnd != ''">AND b.create_time <![CDATA[<=]]> #{createTimeEnd}</if>
|
||||
ORDER BY b.create_time DESC
|
||||
</select>
|
||||
<select id="selectWaybillBatchesByIds" resultType="java.util.LinkedHashMap">
|
||||
SELECT b.id, b.batch_no AS batchNo, b.waybill_count AS waybillCount FROM blade_waybill_import_batch b
|
||||
INNER JOIN blade_waybill w ON w.import_batch_id = b.id AND w.is_deleted = 0
|
||||
WHERE b.is_deleted = 0 AND b.tenant_id = #{tenantId} AND w.id IN
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">#{id}</foreach>
|
||||
GROUP BY b.id, b.batch_no, b.waybill_count
|
||||
</select>
|
||||
</mapper>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package org.springblade.transport.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springblade.core.mp.base.BaseService;
|
||||
import org.springblade.transport.pojo.dto.VoucherManageSubmitRequest;
|
||||
import org.springblade.transport.pojo.dto.VoucherUploadDraftRequest;
|
||||
import org.springblade.transport.pojo.entity.VoucherManage;
|
||||
import org.springblade.transport.pojo.vo.VoucherManageVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface IVoucherManageService extends BaseService<VoucherManage> {
|
||||
IPage<VoucherManageVO> selectPage(IPage<VoucherManage> page, VoucherManageVO query);
|
||||
VoucherManageVO detail(Long id);
|
||||
void submit(VoucherManageSubmitRequest request);
|
||||
VoucherManage createUploadDraft(VoucherUploadDraftRequest request);
|
||||
void removeVoucher(Long id);
|
||||
List<Map<String, Object>> selectableWaybillBatches(String batchNo, String createUser, Integer waybillCount, String createTimeStart, String createTimeEnd);
|
||||
}
|
||||
+13
-2
@@ -216,7 +216,8 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
CustomerArchiveVO detail = detail(id);
|
||||
prepare(detail);
|
||||
validateBase(detail);
|
||||
validateApproval(detail);
|
||||
// 临时客商审核通过时由流程转为正式客商,不要求补齐正式客商材料。
|
||||
validateApproval(detail, Objects.equals(detail.getAccessType(), ACCESS_TEMPORARY));
|
||||
CustomerArchive before = Objects.requireNonNull(BeanUtil.copyProperties(detail, CustomerArchive.class));
|
||||
CustomerArchive after = copyCustomer(before);
|
||||
after.setAccessType(ACCESS_FORMAL);
|
||||
@@ -382,7 +383,11 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
}
|
||||
|
||||
private void validateApproval(CustomerArchiveVO customer) {
|
||||
if (Objects.equals(customer.getAccessType(), ACCESS_FORMAL)) {
|
||||
validateApproval(customer, false);
|
||||
}
|
||||
|
||||
private void validateApproval(CustomerArchiveVO customer, boolean temporaryToFormal) {
|
||||
if (Objects.equals(customer.getAccessType(), ACCESS_FORMAL) && !temporaryToFormal) {
|
||||
if (Func.isEmpty(customer.getQualificationAttachments())) {
|
||||
throw new ServiceException("正式客商提交审核前必须上传客商材料");
|
||||
}
|
||||
@@ -459,6 +464,12 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
if (Func.isEmpty(invoiceVO.getInvoiceTitle()) && Func.isEmpty(invoiceVO.getTaxNo())) {
|
||||
continue;
|
||||
}
|
||||
if (Func.isEmpty(invoiceVO.getInvoiceType())) {
|
||||
throw new ServiceException("发票类型不能为空");
|
||||
}
|
||||
if (!List.of("增值税专用发票", "普通发票").contains(invoiceVO.getInvoiceType())) {
|
||||
throw new ServiceException("发票类型不合法");
|
||||
}
|
||||
invoiceVO.setRegisteredAddress(buildAddress(invoiceVO.getRegisteredRegionName(), invoiceVO.getRegisteredDetailAddress(), invoiceVO.getRegisteredAddress()));
|
||||
invoiceVO.setReceiverAddress(buildAddress(invoiceVO.getReceiverRegionName(), invoiceVO.getReceiverDetailAddress(), invoiceVO.getReceiverAddress()));
|
||||
CustomerInvoiceInfo invoice = Objects.requireNonNull(BeanUtil.copyProperties(invoiceVO, CustomerInvoiceInfo.class));
|
||||
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
package org.springblade.transport.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.transport.mapper.VoucherManageMapper;
|
||||
import org.springblade.transport.mapper.VoucherWaybillBatchMapper;
|
||||
import org.springblade.transport.pojo.dto.VoucherManageSubmitRequest;
|
||||
import org.springblade.transport.pojo.dto.VoucherUploadDraftRequest;
|
||||
import org.springblade.transport.pojo.entity.VoucherManage;
|
||||
import org.springblade.transport.pojo.entity.VoucherWaybillBatch;
|
||||
import org.springblade.transport.pojo.entity.ProjectApply;
|
||||
import org.springblade.transport.pojo.vo.VoucherManageVO;
|
||||
import org.springblade.transport.service.IVoucherManageService;
|
||||
import org.springblade.transport.service.IProjectApplyService;
|
||||
import org.springblade.transport.wrapper.VoucherManageWrapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class VoucherManageServiceImpl extends BaseServiceImpl<VoucherManageMapper, VoucherManage> implements IVoucherManageService {
|
||||
|
||||
private final VoucherWaybillBatchMapper voucherWaybillBatchMapper;
|
||||
private final IProjectApplyService projectApplyService;
|
||||
|
||||
public VoucherManageServiceImpl(VoucherWaybillBatchMapper voucherWaybillBatchMapper, IProjectApplyService projectApplyService) {
|
||||
this.voucherWaybillBatchMapper = voucherWaybillBatchMapper;
|
||||
this.projectApplyService = projectApplyService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<VoucherManageVO> selectPage(IPage<VoucherManage> page, VoucherManageVO query) {
|
||||
return VoucherManageWrapper.build().pageVO(page(page, buildQuery(query)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoucherManageVO detail(Long id) {
|
||||
VoucherManage record = getById(id);
|
||||
if (record == null || Objects.equals(record.getIsDeleted(), 1)) throw new ServiceException("凭证批次不存在");
|
||||
return VoucherManageWrapper.build().entityVO(record);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public VoucherManage createUploadDraft(VoucherUploadDraftRequest request) {
|
||||
if (Func.isEmpty(request.getProjectId())) throw new ServiceException("请先选择项目名称");
|
||||
if (Func.isEmpty(request.getFileName())) throw new ServiceException("文件名称不能为空");
|
||||
ProjectApply project = projectApplyService.getById(request.getProjectId());
|
||||
if (project == null || !List.of("approved", "change_approved").contains(project.getApprovalStatus())) {
|
||||
throw new ServiceException("仅允许选择审核通过或变更审核通过的项目");
|
||||
}
|
||||
VoucherManage voucher = new VoucherManage();
|
||||
voucher.setProjectId(project.getId());
|
||||
voucher.setProjectName(project.getProjectName());
|
||||
voucher.setVoucherBatchNo(nextCode());
|
||||
voucher.setFileName(request.getFileName());
|
||||
voucher.setFileUrl("");
|
||||
voucher.setUploadSource("内部");
|
||||
voucher.setProcessStatus("上传中");
|
||||
voucher.setAuditStatus("-");
|
||||
voucher.setVoucherCount(0);
|
||||
voucher.setRelatedWaybillCount(0);
|
||||
voucher.setUnRelatedWaybillCount(0);
|
||||
save(voucher);
|
||||
return voucher;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void submit(VoucherManageSubmitRequest request) {
|
||||
if (Func.isEmpty(request.getProjectId())) throw new ServiceException("请选择项目名称");
|
||||
if (Func.isEmpty(request.getFileName()) || Func.isEmpty(request.getFileUrl())) throw new ServiceException("请上传执行凭证压缩包");
|
||||
if (Func.isEmpty(request.getWaybillImportBatchIds())) throw new ServiceException("请至少关联一个运输批次");
|
||||
VoucherManage voucher = Func.isEmpty(request.getId()) ? new VoucherManage() : getById(request.getId());
|
||||
if (voucher == null) throw new ServiceException("凭证批次不存在");
|
||||
ProjectApply project = projectApplyService.getById(request.getProjectId());
|
||||
if (project == null || !List.of("approved", "change_approved").contains(project.getApprovalStatus())) throw new ServiceException("仅允许选择审核通过或变更审核通过的项目");
|
||||
voucher.setProjectId(project.getId());
|
||||
voucher.setProjectName(project.getProjectName());
|
||||
voucher.setFileName(request.getFileName());
|
||||
voucher.setFileUrl(request.getFileUrl());
|
||||
voucher.setFileTaskId(request.getFileTaskId());
|
||||
voucher.setUploadSource("内部");
|
||||
voucher.setProcessStatus("上传中");
|
||||
voucher.setAuditStatus("-");
|
||||
voucher.setVoucherCount(0);
|
||||
voucher.setRelatedWaybillCount(0);
|
||||
voucher.setUnRelatedWaybillCount(0);
|
||||
if (Func.isEmpty(voucher.getVoucherBatchNo())) voucher.setVoucherBatchNo(nextCode());
|
||||
saveOrUpdate(voucher);
|
||||
voucherWaybillBatchMapper.delete(Wrappers.<VoucherWaybillBatch>lambdaQuery().eq(VoucherWaybillBatch::getVoucherId, voucher.getId()));
|
||||
List<Map<String, Object>> batches = selectableWaybillBatchesByIds(request.getWaybillImportBatchIds());
|
||||
if (batches.size() != request.getWaybillImportBatchIds().size()) throw new ServiceException("存在无效的运输批次");
|
||||
List<VoucherWaybillBatch> relations = new ArrayList<>();
|
||||
for (Map<String, Object> batch : batches) {
|
||||
VoucherWaybillBatch relation = new VoucherWaybillBatch();
|
||||
relation.setVoucherId(voucher.getId());
|
||||
relation.setWaybillImportBatchId(((Number) batch.get("id")).longValue());
|
||||
relation.setWaybillBatchNo((String) batch.get("batchNo"));
|
||||
relation.setWaybillCount(((Number) batch.get("waybillCount")).intValue());
|
||||
relations.add(relation);
|
||||
}
|
||||
relations.forEach(voucherWaybillBatchMapper::insert);
|
||||
voucher.setWaybillBatchNo(relations.stream().map(VoucherWaybillBatch::getWaybillBatchNo).collect(Collectors.joining(",")));
|
||||
int total = relations.stream().mapToInt(VoucherWaybillBatch::getWaybillCount).sum();
|
||||
voucher.setRelatedWaybillCount(total);
|
||||
voucher.setUnRelatedWaybillCount(0);
|
||||
updateById(voucher);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void removeVoucher(Long id) {
|
||||
VoucherManage voucher = getById(id);
|
||||
if (voucher == null) throw new ServiceException("凭证批次不存在");
|
||||
deleteLogic(List.of(id));
|
||||
voucherWaybillBatchMapper.delete(Wrappers.<VoucherWaybillBatch>lambdaQuery().eq(VoucherWaybillBatch::getVoucherId, id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> selectableWaybillBatches(String batchNo, String createUser, Integer waybillCount, String createTimeStart, String createTimeEnd) {
|
||||
return voucherWaybillBatchMapper.selectWaybillBatches(AuthUtil.getTenantId(), batchNo, createUser, waybillCount, createTimeStart, createTimeEnd);
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> selectableWaybillBatchesByIds(List<Long> ids) {
|
||||
if (Func.isEmpty(ids)) return List.of();
|
||||
return voucherWaybillBatchMapper.selectWaybillBatchesByIds(AuthUtil.getTenantId(), ids);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<VoucherManage> buildQuery(VoucherManageVO query) {
|
||||
LambdaQueryWrapper<VoucherManage> wrapper = Wrappers.<VoucherManage>lambdaQuery().eq(VoucherManage::getIsDeleted, 0)
|
||||
.like(Func.isNotEmpty(query.getVoucherBatchNo()), VoucherManage::getVoucherBatchNo, query.getVoucherBatchNo())
|
||||
.eq(Func.isNotEmpty(query.getAuditStatus()), VoucherManage::getAuditStatus, query.getAuditStatus())
|
||||
.eq(Func.isNotEmpty(query.getProcessStatus()), VoucherManage::getProcessStatus, query.getProcessStatus())
|
||||
.like(Func.isNotEmpty(query.getWaybillBatchNo()), VoucherManage::getWaybillBatchNo, query.getWaybillBatchNo())
|
||||
.eq(Func.isNotEmpty(query.getUploadSource()), VoucherManage::getUploadSource, query.getUploadSource())
|
||||
.like(Func.isNotEmpty(query.getCarrierName()), VoucherManage::getCarrierName, query.getCarrierName());
|
||||
if (query.getCreateTimeStart() != null) wrapper.ge(VoucherManage::getCreateTime, query.getCreateTimeStart());
|
||||
if (query.getCreateTimeEnd() != null) wrapper.le(VoucherManage::getCreateTime, query.getCreateTimeEnd());
|
||||
return wrapper.orderByDesc(VoucherManage::getCreateTime);
|
||||
}
|
||||
|
||||
private synchronized String nextCode() {
|
||||
String prefix = "PZ" + java.time.LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE) + "-";
|
||||
long count = count(Wrappers.<VoucherManage>lambdaQuery().likeRight(VoucherManage::getVoucherBatchNo, prefix));
|
||||
return prefix + String.format("%03d", count + 1);
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package org.springblade.transport.wrapper;
|
||||
|
||||
import org.springblade.core.mp.support.BaseEntityWrapper;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.system.cache.UserCache;
|
||||
import org.springblade.transport.pojo.entity.VoucherManage;
|
||||
import org.springblade.transport.pojo.vo.VoucherManageVO;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class VoucherManageWrapper extends BaseEntityWrapper<VoucherManage, VoucherManageVO> {
|
||||
public static VoucherManageWrapper build() { return new VoucherManageWrapper(); }
|
||||
@Override
|
||||
public VoucherManageVO entityVO(VoucherManage entity) {
|
||||
VoucherManageVO vo = Objects.requireNonNull(BeanUtil.copyProperties(entity, VoucherManageVO.class));
|
||||
vo.setCreateUserName(UserCache.getUserRealName(entity.getCreateUser()));
|
||||
vo.setUpdateUserName(UserCache.getUserRealName(entity.getUpdateUser()));
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
-- 文件服务数据库:分片上传任务主表。
|
||||
-- 本脚本需与 blade_file_task_part 表配套执行;请在 blade-file 服务配置的数据源中运行。
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_file_task` (
|
||||
`id` bigint NOT NULL COMMENT '主键ID',
|
||||
`md5` varchar(128) NOT NULL COMMENT '文件MD5',
|
||||
`object_key` varchar(1000) NOT NULL COMMENT '对象存储对象键',
|
||||
`attachment_name` varchar(500) NOT NULL COMMENT '附件名称',
|
||||
`suffix` varchar(50) DEFAULT NULL COMMENT '文件后缀',
|
||||
`size` bigint NOT NULL COMMENT '文件大小,单位:字节',
|
||||
`chunk_size` int NOT NULL COMMENT '分片大小,单位:字节',
|
||||
`chunk_total` int NOT NULL COMMENT '分片总数',
|
||||
`current_index` int NOT NULL DEFAULT 0 COMMENT '已完成分片数',
|
||||
`upload_id` varchar(255) DEFAULT NULL COMMENT '对象存储上传任务ID',
|
||||
`status` varchar(20) NOT NULL DEFAULT 'uploading' COMMENT '状态:uploading、completed、failed、paused',
|
||||
`business_type` varchar(50) DEFAULT NULL COMMENT '业务类型,例如 voucher',
|
||||
`business_id` varchar(64) DEFAULT NULL COMMENT '业务标识,例如凭证批次号',
|
||||
`create_user_name` varchar(50) DEFAULT NULL COMMENT '创建人名称',
|
||||
`create_user` bigint DEFAULT NULL COMMENT '创建人ID',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_user_name` varchar(50) DEFAULT NULL COMMENT '更新人名称',
|
||||
`update_user` bigint DEFAULT NULL COMMENT '更新人ID',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`is_deleted` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除:0否、1是',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_file_task_md5` (`md5`),
|
||||
KEY `idx_file_task_business` (`business_type`, `business_id`),
|
||||
KEY `idx_file_task_create_user_time` (`create_user`, `create_time`),
|
||||
KEY `idx_file_task_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件分片上传任务';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_file_task_part` (
|
||||
`id` bigint NOT NULL COMMENT '主键ID',
|
||||
`file_task_id` bigint NOT NULL COMMENT '文件上传任务ID',
|
||||
`part_number` int NOT NULL COMMENT '分片编号,从1开始',
|
||||
`etag` varchar(255) NOT NULL COMMENT '分片ETag',
|
||||
`create_user` bigint DEFAULT NULL COMMENT '创建人ID',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_file_task_part` (`file_task_id`, `part_number`),
|
||||
KEY `idx_file_task_part_task` (`file_task_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件分片上传任务分片记录';
|
||||
@@ -0,0 +1,4 @@
|
||||
-- 修复旧版 blade_file_task 的逻辑删除字段默认值。
|
||||
-- 请在 blade-file 服务配置的数据源执行。
|
||||
UPDATE `blade_file_task` SET `is_deleted` = 0 WHERE `is_deleted` IS NULL;
|
||||
ALTER TABLE `blade_file_task` MODIFY COLUMN `is_deleted` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除:0否、1是';
|
||||
@@ -0,0 +1,8 @@
|
||||
-- 请在 blade_file 服务所使用的数据源执行本脚本,不要在 transport 库执行。
|
||||
-- MySQL 8.0.29+ 支持 IF NOT EXISTS;若版本较低,请先确认字段和索引不存在再执行。
|
||||
ALTER TABLE `blade_file_task`
|
||||
ADD COLUMN IF NOT EXISTS `business_type` varchar(50) DEFAULT NULL COMMENT '业务类型',
|
||||
ADD COLUMN IF NOT EXISTS `business_id` varchar(64) DEFAULT NULL COMMENT '业务标识';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS `idx_file_task_business`
|
||||
ON `blade_file_task` (`business_type`, `business_id`);
|
||||
@@ -117,6 +117,7 @@ CREATE TABLE `blade_customer_invoice_info` (
|
||||
`tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '000000' COMMENT '租户ID',
|
||||
`customer_id` bigint NOT NULL COMMENT '客商ID',
|
||||
`invoice_title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '受票方名称',
|
||||
`invoice_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '发票类型',
|
||||
`tax_no` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '纳税人识别号',
|
||||
`bank_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '开户行名称',
|
||||
`registered_phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '注册电话',
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- 客商发票信息:新增发票类型
|
||||
|
||||
ALTER TABLE `blade_customer_invoice_info`
|
||||
ADD COLUMN `invoice_type` varchar(30) DEFAULT NULL COMMENT '发票类型' AFTER `invoice_title`;
|
||||
@@ -0,0 +1,42 @@
|
||||
CREATE TABLE IF NOT EXISTS `blade_voucher_manage` (
|
||||
`id` bigint NOT NULL,
|
||||
`tenant_id` varchar(12) NOT NULL DEFAULT '000000',
|
||||
`project_id` bigint NOT NULL COMMENT '项目ID',
|
||||
`project_name` varchar(200) NOT NULL COMMENT '项目名称',
|
||||
`voucher_batch_no` varchar(30) NOT NULL COMMENT '凭证批次号',
|
||||
`waybill_batch_no` varchar(1000) DEFAULT NULL COMMENT '关联运单批次号',
|
||||
`file_name` varchar(100) NOT NULL COMMENT '凭证压缩包文件名',
|
||||
`file_url` varchar(1000) NOT NULL COMMENT '凭证压缩包地址',
|
||||
`file_task_id` bigint DEFAULT NULL COMMENT '分片上传任务ID',
|
||||
`upload_source` varchar(20) NOT NULL DEFAULT '内部' COMMENT '上传来源:内部、承运商',
|
||||
`carrier_name` varchar(50) DEFAULT NULL COMMENT '承运商名称',
|
||||
`process_status` varchar(20) NOT NULL DEFAULT '上传中' COMMENT '上传中、处理中、处理完成',
|
||||
`voucher_count` int NOT NULL DEFAULT 0 COMMENT '凭证数量',
|
||||
`related_waybill_count` int NOT NULL DEFAULT 0 COMMENT '已关联运单数',
|
||||
`un_related_waybill_count` int NOT NULL DEFAULT 0 COMMENT '未关联运单数',
|
||||
`audit_status` varchar(20) NOT NULL DEFAULT '-' COMMENT '待审核、审核通过、审核驳回',
|
||||
`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`), UNIQUE KEY `uk_voucher_manage_no` (`tenant_id`, `voucher_batch_no`),
|
||||
KEY `idx_voucher_manage_create_time` (`create_time`), KEY `idx_voucher_manage_process_status` (`process_status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='凭证管理';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blade_voucher_waybill_batch` (
|
||||
`id` bigint NOT NULL, `tenant_id` varchar(12) NOT NULL DEFAULT '000000',
|
||||
`voucher_id` bigint NOT NULL COMMENT '凭证批次ID', `waybill_import_batch_id` bigint NOT NULL COMMENT '运单导入批次ID',
|
||||
`waybill_batch_no` varchar(64) NOT NULL COMMENT '运单批次号', `waybill_count` int NOT NULL DEFAULT 0 COMMENT '运单数',
|
||||
`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`), UNIQUE KEY `uk_voucher_waybill_batch` (`voucher_id`, `waybill_import_batch_id`),
|
||||
KEY `idx_voucher_waybill_batch_voucher` (`voucher_id`), KEY `idx_voucher_waybill_batch_waybill` (`waybill_import_batch_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='凭证关联运单批次';
|
||||
|
||||
INSERT INTO `blade_menu` (`id`, `parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `component`, `remark`, `is_deleted`)
|
||||
VALUES
|
||||
(2090000000000000900, 2090000000000000000, 'voucher_manage', '凭证管理', 'voucher_manage', '/business/voucher-manage', 'iconfont icon-caidanguanli', 90, 1, 0, 1, NULL, '', 0),
|
||||
(2090000000000000901, 2090000000000000900, 'voucher_manage_view', '查看', 'voucher_manage_view', '', '', 1, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000000902, 2090000000000000900, 'voucher_manage_add', '批量导入凭证', 'voucher_manage_add', '', '', 2, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000000903, 2090000000000000900, 'voucher_manage_edit', '更换运单批次', 'voucher_manage_edit', '', '', 3, 2, 0, 1, NULL, '', 0),
|
||||
(2090000000000000904, 2090000000000000900, 'voucher_manage_delete', '删除', 'voucher_manage_delete', '', '', 4, 2, 0, 1, NULL, '', 0)
|
||||
ON DUPLICATE KEY UPDATE `name` = VALUES(`name`), `path` = VALUES(`path`), `is_deleted` = 0;
|
||||
@@ -0,0 +1,93 @@
|
||||
-- MySQL 5.7+ 兼容:为已存在的 blade_voucher_manage 旧表补齐字段和索引。
|
||||
-- 请在 transport 数据库执行。本脚本使用 information_schema 判断,不依赖 IF NOT EXISTS 语法。
|
||||
|
||||
DELIMITER $$
|
||||
|
||||
DROP PROCEDURE IF EXISTS `upgrade_blade_voucher_manage_20260812`$$
|
||||
CREATE PROCEDURE `upgrade_blade_voucher_manage_20260812`()
|
||||
BEGIN
|
||||
DECLARE db_name varchar(128);
|
||||
SET db_name = DATABASE();
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'tenant_id') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `tenant_id` varchar(12) NOT NULL DEFAULT '000000' COMMENT '租户ID' AFTER `id`;
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'project_id') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `project_id` bigint NOT NULL DEFAULT 0 COMMENT '项目ID';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'project_name') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `project_name` varchar(200) NOT NULL DEFAULT '' COMMENT '项目名称';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'voucher_batch_no') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `voucher_batch_no` varchar(30) NOT NULL DEFAULT '' COMMENT '凭证批次号';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'waybill_batch_no') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `waybill_batch_no` varchar(1000) DEFAULT NULL COMMENT '关联运单批次号';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'file_name') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `file_name` varchar(100) NOT NULL DEFAULT '' COMMENT '凭证压缩包文件名';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'file_url') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `file_url` varchar(1000) NOT NULL DEFAULT '' COMMENT '凭证压缩包地址';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'file_task_id') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `file_task_id` bigint DEFAULT NULL COMMENT '分片上传任务ID';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'upload_source') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `upload_source` varchar(20) NOT NULL DEFAULT '内部' COMMENT '上传来源:内部、承运商';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'carrier_name') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `carrier_name` varchar(50) DEFAULT NULL COMMENT '承运商名称';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'process_status') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `process_status` varchar(20) NOT NULL DEFAULT '上传中' COMMENT '上传中、处理中、处理完成';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'voucher_count') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `voucher_count` int NOT NULL DEFAULT 0 COMMENT '凭证数量';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'related_waybill_count') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `related_waybill_count` int NOT NULL DEFAULT 0 COMMENT '已关联运单数';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'un_related_waybill_count') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `un_related_waybill_count` int NOT NULL DEFAULT 0 COMMENT '未关联运单数';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'audit_status') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `audit_status` varchar(20) NOT NULL DEFAULT '-' COMMENT '待审核、审核通过、审核驳回';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'create_user') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `create_user` bigint DEFAULT NULL COMMENT '创建人';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'create_dept') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `create_dept` bigint DEFAULT NULL COMMENT '创建部门';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'create_time') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `create_time` datetime DEFAULT NULL COMMENT '创建时间';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'update_user') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `update_user` bigint DEFAULT NULL COMMENT '更新人';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'update_time') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `update_time` datetime DEFAULT NULL COMMENT '更新时间';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'status') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态';
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND column_name = 'is_deleted') THEN
|
||||
ALTER TABLE `blade_voucher_manage` ADD COLUMN `is_deleted` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除';
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.statistics WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND index_name = 'idx_voucher_manage_create_time') THEN
|
||||
CREATE INDEX `idx_voucher_manage_create_time` ON `blade_voucher_manage` (`create_time`);
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.statistics WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND index_name = 'idx_voucher_manage_process_status') THEN
|
||||
CREATE INDEX `idx_voucher_manage_process_status` ON `blade_voucher_manage` (`process_status`);
|
||||
END IF;
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.statistics WHERE table_schema = db_name AND table_name = 'blade_voucher_manage' AND index_name = 'idx_voucher_manage_tenant_batch_no') THEN
|
||||
CREATE INDEX `idx_voucher_manage_tenant_batch_no` ON `blade_voucher_manage` (`tenant_id`, `voucher_batch_no`);
|
||||
END IF;
|
||||
END$$
|
||||
|
||||
CALL `upgrade_blade_voucher_manage_20260812`()$$
|
||||
DROP PROCEDURE `upgrade_blade_voucher_manage_20260812`$$
|
||||
|
||||
DELIMITER ;
|
||||
Reference in New Issue
Block a user