调整结算

This commit is contained in:
2026-09-05 23:26:00 +08:00
parent 14a3c23c9d
commit 397e9f3b62
11 changed files with 213 additions and 19 deletions
@@ -0,0 +1,15 @@
package org.springblade.transport.pojo.dto;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/** 正式结算发票认领请求。 */
@Data
public class FormalSettlementInvoiceClaimRequest implements Serializable {
@Serial private static final long serialVersionUID = 1L;
private Long formalSettlementId;
private List<FormalSettlementSaveRequest.Invoice> invoices;
}
@@ -47,6 +47,12 @@ public class PreSettlementChangeRecord extends TenantEntity {
@Schema(description = "变更内容")
private String changeContent;
@Schema(description = "变更前数据JSON")
private String beforeData;
@Schema(description = "变更后数据JSON")
private String afterData;
@Schema(description = "操作人")
private String operatorName;
@@ -22,6 +22,7 @@ import org.springblade.transport.pojo.dto.FormalSettlementSaveRequest;
import org.springblade.transport.pojo.dto.FormalSettlementPaymentRequest;
import org.springblade.transport.pojo.dto.FormalSettlementBatchPaymentRequest;
import org.springblade.transport.pojo.dto.FormalSettlementStatusRequest;
import org.springblade.transport.pojo.dto.FormalSettlementInvoiceClaimRequest;
import org.springblade.transport.pojo.dto.PreSettlementDetailAdjustRequest;
import org.springblade.transport.pojo.entity.FormalSettlementDetailFee;
import org.springblade.transport.pojo.vo.FormalSettlementVO;
@@ -169,6 +170,14 @@ public class FormalSettlementController extends BladeController {
return R.data(formalSettlementService.applyPayments(request));
}
@PostMapping("/claim-invoices")
@ApiOperationSupport(order = 18)
@Operation(summary = "认领发票并同步付款申请")
public R claimInvoices(@RequestBody FormalSettlementInvoiceClaimRequest request) {
formalSettlementService.claimInvoices(request);
return R.success("发票认领成功");
}
@GetMapping("/receipt-claims")
@ApiOperationSupport(order = 19)
@Operation(summary = "应收正式结算单收款认领信息")
@@ -21,6 +21,7 @@ import org.springblade.transport.pojo.entity.FormalSettlementDetailFee;
import java.util.List;
import org.springblade.transport.pojo.dto.FormalSettlementPaymentRequest;
import org.springblade.transport.pojo.dto.FormalSettlementBatchPaymentRequest;
import org.springblade.transport.pojo.dto.FormalSettlementInvoiceClaimRequest;
/**
* 正式结算单服务
@@ -45,4 +46,5 @@ public interface IFormalSettlementService extends BaseService<FormalSettlement>
void refreshPaymentSummariesForPreSettlement(Long preSettlementId);
String applyPayment(FormalSettlementPaymentRequest request);
List<String> applyPayments(FormalSettlementBatchPaymentRequest request);
void claimInvoices(FormalSettlementInvoiceClaimRequest request);
}
@@ -32,6 +32,7 @@ import org.springblade.transport.mapper.PreSettlementDetailFeeMapper;
import org.springblade.transport.mapper.PreSettlementMapper;
import org.springblade.transport.mapper.PreSettlementSummaryFeeMapper;
import org.springblade.transport.mapper.PaymentApplicationMapper;
import org.springblade.transport.mapper.PaymentApplicationInvoiceMapper;
import org.springblade.transport.mapper.PaymentApplicationSettlementMapper;
import org.springblade.transport.mapper.ReceiptClaimSettlementMapper;
import org.springblade.transport.mapper.ReceivablePayableDetailMapper;
@@ -40,6 +41,7 @@ import org.springblade.transport.mapper.SettlementAdjustmentMapper;
import org.springblade.transport.pojo.dto.FormalSettlementSaveRequest;
import org.springblade.transport.pojo.dto.FormalSettlementPaymentRequest;
import org.springblade.transport.pojo.dto.FormalSettlementBatchPaymentRequest;
import org.springblade.transport.pojo.dto.FormalSettlementInvoiceClaimRequest;
import org.springblade.transport.pojo.dto.FormalSettlementStatusRequest;
import org.springblade.transport.pojo.dto.PreSettlementDetailAdjustRequest;
import org.springblade.transport.pojo.entity.FormalSettlement;
@@ -58,6 +60,7 @@ import org.springblade.transport.pojo.entity.PreSettlementDetail;
import org.springblade.transport.pojo.entity.PreSettlementDetailFee;
import org.springblade.transport.pojo.entity.PreSettlementSummaryFee;
import org.springblade.transport.pojo.entity.PaymentApplication;
import org.springblade.transport.pojo.entity.PaymentApplicationInvoice;
import org.springblade.transport.pojo.entity.PaymentApplicationSettlement;
import org.springblade.transport.pojo.entity.ReceiptClaimSettlement;
import org.springblade.transport.pojo.entity.ReceivablePayableDetail;
@@ -125,6 +128,7 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
private final ReceivablePayableDetailMapper receivablePayableMapper;
private final ReceivablePayableCargoFeeMapper receivablePayableCargoFeeMapper;
private final PaymentApplicationMapper paymentApplicationMapper;
private final PaymentApplicationInvoiceMapper paymentApplicationInvoiceMapper;
private final PaymentApplicationSettlementMapper paymentApplicationSettlementMapper;
private final ReceiptClaimSettlementMapper receiptClaimSettlementMapper;
private final SettlementAdjustmentMapper settlementAdjustmentMapper;
@@ -458,6 +462,81 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
return paymentNos;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void claimInvoices(FormalSettlementInvoiceClaimRequest request) {
if (request == null || request.getFormalSettlementId() == null || Func.isEmpty(request.getInvoices())) {
throw new ServiceException("请选择需要认领的发票");
}
FormalSettlement settlement = existing(request.getFormalSettlementId());
List<FormalSettlementSaveRequest.Invoice> invoices = request.getInvoices();
Set<String> invoiceNumbers = new LinkedHashSet<>();
BigDecimal matchedTotal = BigDecimal.ZERO;
for (FormalSettlementSaveRequest.Invoice item : invoices) {
String invoiceNo = item == null ? "" : requiredText(item.getInvoiceNo(), "发票号");
if (!invoiceNumbers.add(invoiceNo)) throw new ServiceException("发票号" + invoiceNo + "重复");
matchedTotal = matchedTotal.add(money(item.getMatchedAmount()));
}
if (matchedTotal.compareTo(money(settlement.getSettlementAmount())) > 0) {
throw new ServiceException("发票匹配结算单金额合计不能超过结算金额");
}
List<FormalSettlementInvoice> existingInvoices = invoiceMapper.selectList(
Wrappers.<FormalSettlementInvoice>lambdaQuery().eq(FormalSettlementInvoice::getFormalSettlementId, settlement.getId()));
Set<String> existingNumbers = existingInvoices.stream().map(FormalSettlementInvoice::getInvoiceNo)
.filter(Objects::nonNull).collect(Collectors.toSet());
int lineNo = existingInvoices.stream().map(FormalSettlementInvoice::getLineNo).filter(Objects::nonNull)
.max(Integer::compareTo).orElse(0) + 1;
BigDecimal insertedMatchedTotal = BigDecimal.ZERO;
for (FormalSettlementSaveRequest.Invoice item : invoices) {
if (existingNumbers.contains(item.getInvoiceNo())) continue;
FormalSettlementInvoice invoice = new FormalSettlementInvoice();
invoice.setFormalSettlementId(settlement.getId()); invoice.setLineNo(lineNo++);
invoice.setInvoiceNo(item.getInvoiceNo()); invoice.setInvoiceDate(item.getInvoiceDate());
invoice.setInvoiceType(item.getInvoiceType()); invoice.setTaxRate(item.getTaxRate());
invoice.setInvoiceAmount(money(item.getInvoiceAmount()));
invoice.setAvailableInvoiceAmount(money(item.getAvailableInvoiceAmount()));
invoice.setMatchedAmount(money(item.getMatchedAmount())); invoice.setAttachmentJson(item.getAttachmentJson());
invoiceMapper.insert(invoice);
insertedMatchedTotal = insertedMatchedTotal.add(money(item.getMatchedAmount()));
}
List<PaymentApplicationSettlement> relations = paymentApplicationSettlementMapper.selectList(
Wrappers.<PaymentApplicationSettlement>lambdaQuery().eq(PaymentApplicationSettlement::getFormalSettlementId, settlement.getId())
.eq(PaymentApplicationSettlement::getIsDeleted, 0));
Set<Long> paymentApplicationIds = new LinkedHashSet<>(relations.stream()
.map(PaymentApplicationSettlement::getPaymentApplicationId).filter(Objects::nonNull).toList());
paymentApplicationIds.addAll(paymentApplicationMapper.selectList(Wrappers.<PaymentApplication>lambdaQuery()
.eq(PaymentApplication::getSettlementId, settlement.getId()).eq(PaymentApplication::getIsDeleted, 0))
.stream().map(PaymentApplication::getId).toList());
for (Long paymentApplicationId : paymentApplicationIds) {
List<PaymentApplicationInvoice> old = paymentApplicationInvoiceMapper.selectList(
Wrappers.<PaymentApplicationInvoice>lambdaQuery().eq(PaymentApplicationInvoice::getPaymentApplicationId, paymentApplicationId));
Set<String> nums = old.stream().map(PaymentApplicationInvoice::getInvoiceNo).filter(Objects::nonNull).collect(Collectors.toSet());
BigDecimal paymentMatchedTotal = old.stream().map(PaymentApplicationInvoice::getMatchedAmount).map(this::money)
.reduce(BigDecimal.ZERO, BigDecimal::add);
int paymentLine = old.stream().map(PaymentApplicationInvoice::getLineNo).filter(Objects::nonNull).max(Integer::compareTo).orElse(0) + 1;
for (FormalSettlementSaveRequest.Invoice item : invoices) {
if (nums.contains(item.getInvoiceNo())) continue;
PaymentApplicationInvoice invoice = new PaymentApplicationInvoice();
invoice.setPaymentApplicationId(paymentApplicationId); invoice.setLineNo(paymentLine++);
invoice.setSettlementNo(settlement.getFormalSettlementNo()); invoice.setInvoiceNo(item.getInvoiceNo());
invoice.setInvoiceDate(item.getInvoiceDate()); invoice.setInvoiceType(item.getInvoiceType());
invoice.setTaxRate(item.getTaxRate()); invoice.setInvoiceAmount(money(item.getInvoiceAmount()));
invoice.setMatchedAmount(money(item.getMatchedAmount())); invoice.setAttachmentJson(item.getAttachmentJson());
paymentApplicationInvoiceMapper.insert(invoice);
paymentMatchedTotal = paymentMatchedTotal.add(money(item.getMatchedAmount()));
}
PaymentApplication payment = paymentApplicationMapper.selectById(paymentApplicationId);
if (payment != null) {
payment.setMatchedInvoiceAmount(paymentMatchedTotal);
payment.setInvoiceStatus(paymentMatchedTotal.compareTo(BigDecimal.ZERO) > 0 ? "matched" : "unmatched");
paymentApplicationMapper.updateById(payment);
}
}
settlement.setInvoiceAmount(money(settlement.getInvoiceAmount()).add(insertedMatchedTotal));
settlement.setInvoiceStatus(invoiceStatus(settlement.getInvoiceAmount(), settlement.getSettlementAmount()));
updateById(settlement);
}
private String createPayment(FormalSettlement settlement, BigDecimal appliedAmount, String remark) {
if (!APPROVED.equals(settlement.getApprovalStatus())) throw new ServiceException("仅审批通过的正式结算单允许发起付款申请");
if (!"payable".equals(settlement.getSettlementType())) throw new ServiceException("仅应付正式结算单允许发起付款申请");
@@ -808,8 +887,8 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
settlement.setSettlementAmount(amount);
settlement.setLocalSettlementAmount(amount.multiply(
settlement.getExchangeRate() == null ? BigDecimal.ONE : settlement.getExchangeRate()));
settlement.setRemainingPayableAmount(amount.subtract(money(settlement.getAppliedPaymentAmount()))
.subtract(money(settlement.getPaidAmount())).max(BigDecimal.ZERO));
settlement.setRemainingPayableAmount(amount.subtract(money(settlement.getPaidAmount()))
.max(BigDecimal.ZERO));
updateById(settlement);
refreshPaymentSummary(settlement.getId());
}
@@ -822,7 +901,7 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
settlement.setAppliedPaymentAmount(summary.appliedAmount());
settlement.setPaidAmount(summary.paidAmount());
settlement.setRemainingPayableAmount(money(settlement.getSettlementAmount())
.subtract(summary.appliedAmount()).subtract(summary.paidAmount()).max(BigDecimal.ZERO));
.subtract(summary.paidAmount()).max(BigDecimal.ZERO));
settlement.setPaymentStatus(paymentStatus(summary.paidAmount(), settlement.getSettlementAmount()));
updateById(settlement);
}
@@ -1024,8 +1103,8 @@ public class FormalSettlementServiceImpl extends BaseServiceImpl<FormalSettlemen
PaymentSummary summary = calculatePaymentSummary(entity);
vo.setAppliedPaymentAmount(summary.appliedAmount());
vo.setPaidAmount(summary.paidAmount());
vo.setRemainingPayableAmount(money(entity.getSettlementAmount()).subtract(summary.appliedAmount())
.subtract(summary.paidAmount()).max(BigDecimal.ZERO));
vo.setRemainingPayableAmount(money(entity.getSettlementAmount()).subtract(summary.paidAmount())
.max(BigDecimal.ZERO));
vo.setPreSettlementNos(sourceMapper.selectList(Wrappers.<FormalSettlementSource>lambdaQuery().eq(FormalSettlementSource::getFormalSettlementId, entity.getId())).stream().map(FormalSettlementSource::getPreSettlementNo).collect(Collectors.joining(",")));
return vo;
}
@@ -605,6 +605,8 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
throw new ServiceException("费用调整行数据不完整");
}
List<String> changes = new ArrayList<>();
Map<String, Object> beforeData = new LinkedHashMap<>();
Map<String, Object> afterData = new LinkedHashMap<>();
for (PreSettlementDetailAdjustRequest.FeeRow requestRow : request.getRows()) {
PreSettlementDetailFee fee = existingMap.get(requestRow.getId());
if (fee == null) {
@@ -632,19 +634,19 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
fee.setRemark(limitRemark(requestRow.getRemark(), 200));
detailFeeMapper.updateById(fee);
String prefix = "" + firstNotEmpty(fee.getCargoName(), fee.getLineNo()) + "";
appendChange(changes, prefix + "运输总量", beforeQuantity, fee.getTransportQuantity());
appendChange(changes, prefix + "里程", beforeMileage, fee.getMileage());
appendChange(changes, prefix + "运输单价", beforeUnitPrice, fee.getUnitPrice());
appendChange(changes, prefix + "运费", beforeFreight, fee.getFreightAmount());
appendChange(changes, beforeData, afterData, prefix + "运输总量", beforeQuantity, fee.getTransportQuantity());
appendChange(changes, beforeData, afterData, prefix + "里程", beforeMileage, fee.getMileage());
appendChange(changes, beforeData, afterData, prefix + "运输单价", beforeUnitPrice, fee.getUnitPrice());
appendChange(changes, beforeData, afterData, prefix + "运费", beforeFreight, fee.getFreightAmount());
Map<String, BigDecimal> afterFeeItems = parseFeeItems(fee.getFeeItemsJson());
Set<String> feeItemNames = new LinkedHashSet<>(beforeFeeItems.keySet());
feeItemNames.addAll(afterFeeItems.keySet());
feeItemNames.forEach(name -> appendChange(changes, prefix + name,
feeItemNames.forEach(name -> appendChange(changes, beforeData, afterData, prefix + name,
beforeFeeItems.get(name), afterFeeItems.get(name)));
appendChange(changes, prefix + "结算金额(含税)", beforeAmount, afterAmount);
appendChange(changes, prefix + "结算金额(不含税)", beforeNoTaxAmount,
appendChange(changes, beforeData, afterData, prefix + "结算金额(含税)", beforeAmount, afterAmount);
appendChange(changes, beforeData, afterData, prefix + "结算金额(不含税)", beforeNoTaxAmount,
fee.getSettlementAmountNoTax());
appendTextChange(changes, prefix + "备注", beforeRemark, fee.getRemark());
appendTextChange(changes, beforeData, afterData, prefix + "备注", beforeRemark, fee.getRemark());
}
if (changes.isEmpty()) {
throw new ServiceException("未修改任何结算明细费用");
@@ -653,7 +655,7 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
rebuildSummaryFees(settlement.getId(), true);
refreshSettlementAmount(settlement);
saveChange(settlement.getId(), "结算明细项", detail.getLineNo(), "调整",
String.join("", changes), changeReason);
String.join("", changes), changeReason, beforeData, afterData);
}
@Override
@@ -1313,12 +1315,19 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
private void saveChange(Long settlementId, String changeType, Integer lineNo, String operationType,
String content, String reason) {
saveChange(settlementId, changeType, lineNo, operationType, content, reason, null, null);
}
private void saveChange(Long settlementId, String changeType, Integer lineNo, String operationType,
String content, String reason, Map<String, Object> beforeData, Map<String, Object> afterData) {
PreSettlementChangeRecord record = new PreSettlementChangeRecord();
record.setPreSettlementId(settlementId);
record.setChangeType(changeType);
record.setLineNo(lineNo);
record.setOperationType(operationType);
record.setChangeContent(content);
record.setBeforeData(beforeData == null ? null : JsonUtil.toJson(beforeData));
record.setAfterData(afterData == null ? null : JsonUtil.toJson(afterData));
record.setOperatorName(Func.isEmpty(AuthUtil.getUserName()) ? "system" : AuthUtil.getUserName());
record.setChangeReason(reason);
record.setChangeTime(LocalDateTime.now());
@@ -1476,6 +1485,17 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
}
}
private void appendChange(List<String> changes, Map<String, Object> beforeData, Map<String, Object> afterData,
String fieldName, BigDecimal before, BigDecimal after) {
BigDecimal oldValue = money(before);
BigDecimal newValue = money(after);
if (oldValue.compareTo(newValue) != 0) {
changes.add("" + fieldName + "】从【" + oldValue + "】调整为【" + newValue + "");
beforeData.put(fieldName, before);
afterData.put(fieldName, after);
}
}
private void appendTextChange(List<String> changes, String fieldName, String before, String after) {
String oldValue = before == null ? "" : before;
String newValue = after == null ? "" : after;
@@ -1484,6 +1504,17 @@ public class PreSettlementServiceImpl extends BaseServiceImpl<PreSettlementMappe
}
}
private void appendTextChange(List<String> changes, Map<String, Object> beforeData, Map<String, Object> afterData,
String fieldName, String before, String after) {
String oldValue = before == null ? "" : before;
String newValue = after == null ? "" : after;
if (!Objects.equals(oldValue, newValue)) {
changes.add("" + fieldName + "】从【" + oldValue + "】调整为【" + newValue + "");
beforeData.put(fieldName, before);
afterData.put(fieldName, after);
}
}
private String firstNotEmpty(String first, String second) {
return Func.isNotEmpty(first) ? first : second;
}
@@ -1447,7 +1447,25 @@ public class ReceivablePayableDetailServiceImpl
fee.setBillingType(stringValue(rule, "billingType", ""));
fee.setTransportQuantity(measure(rule, feeWaybill));
fee.setPriceUnit(stringValue(rule, "billingUnit", feeWaybill.getPriceUnit()));
fee.setUnitPrice(decimal(rule.get("unitPrice")));
fee.setUnitPrice(resolveCalculatedUnitPrice(rule, feeWaybill));
}
/**
* 解析费用行展示用的实际命中单价。
* 区间计费的规则默认单价仅用于兜底,费用行应展示当前计费量命中的区间单价。
*/
private BigDecimal resolveCalculatedUnitPrice(Map<String, Object> rule, Waybill waybill) {
BigDecimal defaultUnitPrice = decimal(rule.get("unitPrice"));
String billingType = stringValue(rule, "billingType", "");
if (!"区间单价".equals(billingType) && !"区间阶梯一口价".equals(billingType)) {
return defaultUnitPrice;
}
Optional<Map<String, Object>> matchedRange = range(ranges(rule), measure(rule, waybill));
if (matchedRange.isEmpty()) {
return defaultUnitPrice;
}
BigDecimal rangeUnitPrice = decimal(matchedRange.get().get("unitPrice"));
return rangeUnitPrice.signum() == 0 ? defaultUnitPrice : rangeUnitPrice;
}
private List<String> cargoFeeKey(Waybill waybill, Map<String, String> feeGoods) {
@@ -255,8 +255,8 @@ public class SettlementAdjustmentServiceImpl extends BaseServiceImpl<SettlementA
BigDecimal amount = money(formal.getSettlementAmount()).add(money(adjustment.getAdjustmentAmount()));
formal.setSettlementAmount(amount);
formal.setLocalSettlementAmount(amount.multiply(formal.getExchangeRate() == null ? BigDecimal.ONE : formal.getExchangeRate()));
formal.setRemainingPayableAmount(amount.subtract(money(formal.getAppliedPaymentAmount()))
.subtract(money(formal.getPaidAmount())).max(BigDecimal.ZERO));
formal.setRemainingPayableAmount(amount.subtract(money(formal.getPaidAmount()))
.max(BigDecimal.ZERO));
formalMapper.updateById(formal);
saveFormalChange(formal.getId(), "合计费用项", null, "调整",
"调整单" + adjustment.getAdjustmentNo() + "调整金额【" + money(adjustment.getAdjustmentAmount()) + "",
@@ -32,9 +32,8 @@ public class FormalSettlementWrapper extends BaseEntityWrapper<FormalSettlement,
public FormalSettlementVO entityVO(FormalSettlement entity) {
FormalSettlementVO vo = Objects.requireNonNull(BeanUtil.copyProperties(entity, FormalSettlementVO.class));
BigDecimal settlementAmount = entity.getSettlementAmount() == null ? BigDecimal.ZERO : entity.getSettlementAmount();
BigDecimal appliedPaymentAmount = entity.getAppliedPaymentAmount() == null ? BigDecimal.ZERO : entity.getAppliedPaymentAmount();
BigDecimal paidAmount = entity.getPaidAmount() == null ? BigDecimal.ZERO : entity.getPaidAmount();
vo.setRemainingPayableAmount(settlementAmount.subtract(appliedPaymentAmount).subtract(paidAmount).max(BigDecimal.ZERO));
vo.setRemainingPayableAmount(settlementAmount.subtract(paidAmount).max(BigDecimal.ZERO));
vo.setInvoiceAmount(entity.getInvoiceAmount() == null ? BigDecimal.ZERO : entity.getInvoiceAmount());
vo.setCreateUserName(UserCache.getUserRealName(entity.getCreateUser()));
vo.setSettlementTypeName("receivable".equals(entity.getSettlementType()) ? "应收" : "应付");
@@ -182,6 +182,8 @@ CREATE TABLE IF NOT EXISTS `blade_pre_settlement_change_record` (
`line_no` int(11) DEFAULT NULL COMMENT '行号',
`operation_type` varchar(30) COLLATE utf8mb4_general_ci NOT NULL COMMENT '操作类型',
`change_content` text COLLATE utf8mb4_general_ci NOT NULL COMMENT '变更内容',
`before_data` longtext COLLATE utf8mb4_general_ci COMMENT '变更前数据JSON',
`after_data` longtext COLLATE utf8mb4_general_ci COMMENT '变更后数据JSON',
`operator_name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '操作人',
`change_reason` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '变更原因',
`change_time` datetime NOT NULL COMMENT '变更时间',
@@ -0,0 +1,33 @@
-- 预结算变更记录补充前后值明细,供调整弹窗“查看详情”展示。
-- 兼容 MySQL 5.7ADD COLUMN 不支持 IF NOT EXISTS),并支持重复执行。
SET @before_data_exists := (
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'blade_pre_settlement_change_record'
AND COLUMN_NAME = 'before_data'
);
SET @before_data_sql := IF(
@before_data_exists = 0,
'ALTER TABLE `blade_pre_settlement_change_record` ADD COLUMN `before_data` longtext COLLATE utf8mb4_general_ci COMMENT ''变更前数据JSON'' AFTER `change_content`',
'SELECT 1'
);
PREPARE before_data_stmt FROM @before_data_sql;
EXECUTE before_data_stmt;
DEALLOCATE PREPARE before_data_stmt;
SET @after_data_exists := (
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'blade_pre_settlement_change_record'
AND COLUMN_NAME = 'after_data'
);
SET @after_data_sql := IF(
@after_data_exists = 0,
'ALTER TABLE `blade_pre_settlement_change_record` ADD COLUMN `after_data` longtext COLLATE utf8mb4_general_ci COMMENT ''变更后数据JSON'' AFTER `before_data`',
'SELECT 1'
);
PREPARE after_data_stmt FROM @after_data_sql;
EXECUTE after_data_stmt;
DEALLOCATE PREPARE after_data_stmt;