✨ 补充应收账单用户ID记录及迁移脚本
This commit is contained in:
@@ -77,6 +77,8 @@ public class ArBill extends BaseEntity {
|
|||||||
private String confirmedBy;
|
private String confirmedBy;
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private Date confirmedTime;
|
private Date confirmedTime;
|
||||||
|
/** 创建账单的用户主键。 */
|
||||||
|
private Long createUserId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账单明细;详情接口分页查询时通常不直接填充该集合。
|
* 账单明细;详情接口分页查询时通常不直接填充该集合。
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ public class ArBillExport implements Serializable {
|
|||||||
* 导出状态:PROCESSING生成中、SUCCESS成功可下载、FAILED失败。
|
* 导出状态:PROCESSING生成中、SUCCESS成功可下载、FAILED失败。
|
||||||
*/
|
*/
|
||||||
private String exportStatus;
|
private String exportStatus;
|
||||||
|
/** 发起导出的用户主键。 */
|
||||||
|
private Long exportUserId;
|
||||||
private String exportBy;
|
private String exportBy;
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private Date exportTime;
|
private Date exportTime;
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ public class ArBillGenerateTask implements Serializable {
|
|||||||
* 发起任务的用户。
|
* 发起任务的用户。
|
||||||
*/
|
*/
|
||||||
private String createBy;
|
private String createBy;
|
||||||
|
/** 创建任务的用户主键。 */
|
||||||
|
private Long createUserId;
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class ArBillLog implements Serializable {
|
|||||||
private String toStatus;
|
private String toStatus;
|
||||||
private String beforeData;
|
private String beforeData;
|
||||||
private String afterData;
|
private String afterData;
|
||||||
private String operatorId;
|
private Long operatorId;
|
||||||
private String operatorName;
|
private String operatorName;
|
||||||
/**
|
/**
|
||||||
* 操作来源:WEB网页端、API接口、JOB定时任务、IMPORT数据导入。
|
* 操作来源:WEB网页端、API接口、JOB定时任务、IMPORT数据导入。
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ public interface IArBillLogService {
|
|||||||
void record(ArBillLog log);
|
void record(ArBillLog log);
|
||||||
|
|
||||||
void recordFailure(Long arBillId, ArLogObjectType objectType, String objectId, ArLogOperationType operationType,
|
void recordFailure(Long arBillId, ArLogObjectType objectType, String objectId, ArLogOperationType operationType,
|
||||||
String fromStatus, String message, String operator, String requestId);
|
String fromStatus, String message, Long operatorId, String operatorName, String requestId);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -26,11 +26,11 @@ import com.bms.ar.mapper.ArBillMapper;
|
|||||||
import com.bms.ar.service.IArBalanceWriteoffService;
|
import com.bms.ar.service.IArBalanceWriteoffService;
|
||||||
import com.bms.ar.service.IArBillLogService;
|
import com.bms.ar.service.IArBillLogService;
|
||||||
import com.bms.common.exception.ServiceException;
|
import com.bms.common.exception.ServiceException;
|
||||||
|
import com.bms.common.utils.SecurityUtils;
|
||||||
import com.bms.customer.customermoney.domain.CustomerReceipt;
|
import com.bms.customer.customermoney.domain.CustomerReceipt;
|
||||||
import com.bms.customer.customermoney.domain.ReceiptWriteoffPlan;
|
import com.bms.customer.customermoney.domain.ReceiptWriteoffPlan;
|
||||||
import com.bms.customer.customermoney.mapper.CustomerMoneyMapper;
|
import com.bms.customer.customermoney.mapper.CustomerMoneyMapper;
|
||||||
import com.bms.customer.customermoney.mapper.ReceiptWriteoffPlanMapper;
|
import com.bms.customer.customermoney.mapper.ReceiptWriteoffPlanMapper;
|
||||||
import com.bms.common.utils.SecurityUtils;
|
|
||||||
import com.bms.common.utils.uuid.IdUtils;
|
import com.bms.common.utils.uuid.IdUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -286,7 +286,7 @@ public class ArBalanceWriteoffServiceImpl implements IArBalanceWriteoffService {
|
|||||||
log.setOperationDesc(desc);
|
log.setOperationDesc(desc);
|
||||||
log.setFromStatus(fromStatus);
|
log.setFromStatus(fromStatus);
|
||||||
log.setToStatus(toStatus);
|
log.setToStatus(toStatus);
|
||||||
log.setOperatorId(operator);
|
log.setOperatorId(SecurityUtils.getUserId());
|
||||||
log.setOperatorName(operator);
|
log.setOperatorName(operator);
|
||||||
log.setOperationSource(ArLogOperationSource.WEB.getCode());
|
log.setOperationSource(ArLogOperationSource.WEB.getCode());
|
||||||
log.setRequestId(requestId);
|
log.setRequestId(requestId);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class ArBillLogServiceImpl implements IArBillLogService {
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||||
public void recordFailure(Long arBillId, ArLogObjectType objectType, String objectId, ArLogOperationType operationType,
|
public void recordFailure(Long arBillId, ArLogObjectType objectType, String objectId, ArLogOperationType operationType,
|
||||||
String fromStatus, String message, String operator, String requestId) {
|
String fromStatus, String message, Long operatorId, String operatorName, String requestId) {
|
||||||
ArBillLog log = new ArBillLog();
|
ArBillLog log = new ArBillLog();
|
||||||
log.setArBillId(arBillId);
|
log.setArBillId(arBillId);
|
||||||
log.setObjectType(objectType.getCode());
|
log.setObjectType(objectType.getCode());
|
||||||
@@ -44,8 +44,8 @@ public class ArBillLogServiceImpl implements IArBillLogService {
|
|||||||
log.setOperationType(operationType.getCode());
|
log.setOperationType(operationType.getCode());
|
||||||
log.setOperationDesc(message);
|
log.setOperationDesc(message);
|
||||||
log.setFromStatus(fromStatus);
|
log.setFromStatus(fromStatus);
|
||||||
log.setOperatorId(operator);
|
log.setOperatorId(operatorId);
|
||||||
log.setOperatorName(operator);
|
log.setOperatorName(operatorName);
|
||||||
log.setOperationSource(ArLogOperationSource.WEB.getCode());
|
log.setOperationSource(ArLogOperationSource.WEB.getCode());
|
||||||
log.setRequestId(requestId == null ? IdUtils.fastSimpleUUID() : requestId);
|
log.setRequestId(requestId == null ? IdUtils.fastSimpleUUID() : requestId);
|
||||||
log.setResult(ArLogResult.FAILED.getCode());
|
log.setResult(ArLogResult.FAILED.getCode());
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ import com.bms.ar.domain.vo.ArBillQuery;
|
|||||||
import com.bms.common.config.BmsConfig;
|
import com.bms.common.config.BmsConfig;
|
||||||
import com.bms.common.exception.ServiceException;
|
import com.bms.common.exception.ServiceException;
|
||||||
import com.bms.common.utils.DateUtils;
|
import com.bms.common.utils.DateUtils;
|
||||||
|
import com.bms.common.utils.SecurityUtils;
|
||||||
import com.bms.common.utils.StringUtils;
|
import com.bms.common.utils.StringUtils;
|
||||||
import com.bms.common.utils.file.FileUtils;
|
import com.bms.common.utils.file.FileUtils;
|
||||||
import com.bms.common.utils.file.OssStorage;
|
import com.bms.common.utils.file.OssStorage;
|
||||||
@@ -326,6 +327,7 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public ArBillGenerateTask generateBill(ArBillGenerateRequest request, String operator, String requestId) {
|
public ArBillGenerateTask generateBill(ArBillGenerateRequest request, String operator, String requestId) {
|
||||||
long startedAt = System.nanoTime();
|
long startedAt = System.nanoTime();
|
||||||
|
Long createUserId = SecurityUtils.getUserId();
|
||||||
validatePeriod(request);
|
validatePeriod(request);
|
||||||
ArBillGenerateTask existed = generateTaskMapper.selectByRequestToken(requestId);
|
ArBillGenerateTask existed = generateTaskMapper.selectByRequestToken(requestId);
|
||||||
if (existed != null) {
|
if (existed != null) {
|
||||||
@@ -400,6 +402,7 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
bill.setBankName(bankAccount.getBankName());
|
bill.setBankName(bankAccount.getBankName());
|
||||||
bill.setRemark(request.getRemark());
|
bill.setRemark(request.getRemark());
|
||||||
bill.setCreateBy(operator);
|
bill.setCreateBy(operator);
|
||||||
|
bill.setCreateUserId(createUserId);
|
||||||
bill.setUpdateBy(operator);
|
bill.setUpdateBy(operator);
|
||||||
billMapper.insertArBill(bill);
|
billMapper.insertArBill(bill);
|
||||||
|
|
||||||
@@ -417,6 +420,7 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
task.setStatus(ArBillGenerateTaskStatus.WAITING);
|
task.setStatus(ArBillGenerateTaskStatus.WAITING);
|
||||||
task.setRequestToken(requestId);
|
task.setRequestToken(requestId);
|
||||||
task.setCreateBy(operator);
|
task.setCreateBy(operator);
|
||||||
|
task.setCreateUserId(createUserId);
|
||||||
generateTaskMapper.insert(task);
|
generateTaskMapper.insert(task);
|
||||||
eventPublisher.publishEvent(new ArBillGenerateTaskEvent(task.getTaskId()));
|
eventPublisher.publishEvent(new ArBillGenerateTaskEvent(task.getTaskId()));
|
||||||
log.info("应收账单生成任务已创建,operator={}, requestId={}, customerId={}, billPeriodEnd={}, selectionMode={}, selectedCount={}, excludedCount={}, taskId={}, status={}, costMs={}",
|
log.info("应收账单生成任务已创建,operator={}, requestId={}, customerId={}, billPeriodEnd={}, selectionMode={}, selectedCount={}, excludedCount={}, taskId={}, status={}, costMs={}",
|
||||||
@@ -798,7 +802,7 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
try {
|
try {
|
||||||
logService.recordFailure(task.getArBillId(), ArLogObjectType.BILL,
|
logService.recordFailure(task.getArBillId(), ArLogObjectType.BILL,
|
||||||
String.valueOf(task.getTaskId()), ArLogOperationType.CREATE, ArBillStatus.DRAFT.getCode(),
|
String.valueOf(task.getTaskId()), ArLogOperationType.CREATE, ArBillStatus.DRAFT.getCode(),
|
||||||
message, operator, requestId);
|
message, task.getCreateUserId(), operator, requestId);
|
||||||
} catch (Exception logException) {
|
} catch (Exception logException) {
|
||||||
log.warn("账单生成失败日志写入失败,但任务清理已完成,taskId={}", task.getTaskId(), logException);
|
log.warn("账单生成失败日志写入失败,但任务清理已完成,taskId={}", task.getTaskId(), logException);
|
||||||
}
|
}
|
||||||
@@ -851,7 +855,7 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
}
|
}
|
||||||
recordSuccess(finalBill, ArLogObjectType.BILL, ArLogOperationType.CREATE,
|
recordSuccess(finalBill, ArLogObjectType.BILL, ArLogOperationType.CREATE,
|
||||||
"异步生成正式账单", ArBillStatus.DRAFT.getCode(), ArBillStatus.DRAFT.getCode(),
|
"异步生成正式账单", ArBillStatus.DRAFT.getCode(), ArBillStatus.DRAFT.getCode(),
|
||||||
task.getRequestToken(), task.getCreateBy());
|
task.getRequestToken(), task.getCreateUserId(), task.getCreateBy());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateFailureMessage(Exception e) {
|
private String generateFailureMessage(Exception e) {
|
||||||
@@ -903,7 +907,8 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
}
|
}
|
||||||
// 应收账单只负责形成应收,不参与客户余额或授信额度变更。
|
// 应收账单只负责形成应收,不参与客户余额或授信额度变更。
|
||||||
recordSuccess(bill, ArLogObjectType.BILL, ArLogOperationType.CONFIRM,
|
recordSuccess(bill, ArLogObjectType.BILL, ArLogOperationType.CONFIRM,
|
||||||
"确认应收账单", ArBillStatus.DRAFT.getCode(), ArBillStatus.CONFIRMED.getCode(), requestId, operator);
|
"确认应收账单", ArBillStatus.DRAFT.getCode(), ArBillStatus.CONFIRMED.getCode(), requestId,
|
||||||
|
SecurityUtils.getUserId(), operator);
|
||||||
ArBill result = selectArBillById(arBillId);
|
ArBill result = selectArBillById(arBillId);
|
||||||
log.info("应收账单确认处理完成,operator={}, requestId={}, arBillId={}, status={}, costMs={}",
|
log.info("应收账单确认处理完成,operator={}, requestId={}, arBillId={}, status={}, costMs={}",
|
||||||
safeLogValue(operator), safeLogValue(requestId), arBillId, result.getStatus(), elapsedMillis(startedAt));
|
safeLogValue(operator), safeLogValue(requestId), arBillId, result.getStatus(), elapsedMillis(startedAt));
|
||||||
@@ -946,7 +951,8 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
sourceFeeMapper.restoreUnbilledIfNoActiveArBillByArBillId(arBillId);
|
sourceFeeMapper.restoreUnbilledIfNoActiveArBillByArBillId(arBillId);
|
||||||
sourceBillMapper.refreshArBillStatusByArBillId(arBillId);
|
sourceBillMapper.refreshArBillStatusByArBillId(arBillId);
|
||||||
recordSuccess(bill, ArLogObjectType.BILL, ArLogOperationType.VOID,
|
recordSuccess(bill, ArLogObjectType.BILL, ArLogOperationType.VOID,
|
||||||
"作废应收账单:" + remark, bill.getStatus(), ArBillStatus.VOID.getCode(), requestId, operator);
|
"作废应收账单:" + remark, bill.getStatus(), ArBillStatus.VOID.getCode(), requestId,
|
||||||
|
SecurityUtils.getUserId(), operator);
|
||||||
ArBill result = selectArBillById(arBillId);
|
ArBill result = selectArBillById(arBillId);
|
||||||
log.info("应收账单作废处理完成,operator={}, requestId={}, arBillId={}, status={}, costMs={}",
|
log.info("应收账单作废处理完成,operator={}, requestId={}, arBillId={}, status={}, costMs={}",
|
||||||
safeLogValue(operator), safeLogValue(requestId), arBillId, result.getStatus(), elapsedMillis(startedAt));
|
safeLogValue(operator), safeLogValue(requestId), arBillId, result.getStatus(), elapsedMillis(startedAt));
|
||||||
@@ -960,6 +966,7 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public ArBillExport exportBill(Long arBillId, String operator, String requestId) {
|
public ArBillExport exportBill(Long arBillId, String operator, String requestId) {
|
||||||
long startedAt = System.nanoTime();
|
long startedAt = System.nanoTime();
|
||||||
|
Long exportUserId = SecurityUtils.getUserId();
|
||||||
ArBillLog previous = logMapper.selectSuccessByRequestId(requestId, ArLogObjectType.EXPORT.getCode(),
|
ArBillLog previous = logMapper.selectSuccessByRequestId(requestId, ArLogObjectType.EXPORT.getCode(),
|
||||||
ArLogResult.SUCCESS.getCode());
|
ArLogResult.SUCCESS.getCode());
|
||||||
if (previous != null && isNumber(previous.getObjectId())) {
|
if (previous != null && isNumber(previous.getObjectId())) {
|
||||||
@@ -1010,13 +1017,15 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
export.setTemplateStorageType(template.getStorageType());
|
export.setTemplateStorageType(template.getStorageType());
|
||||||
export.setTemplateStorageKey(template.getStorageKey());
|
export.setTemplateStorageKey(template.getStorageKey());
|
||||||
export.setTemplateHash(template.getFileHash());
|
export.setTemplateHash(template.getFileHash());
|
||||||
|
export.setExportUserId(exportUserId);
|
||||||
export.setExportBy(operator);
|
export.setExportBy(operator);
|
||||||
export.setRowCount(bill.getOrderCount());
|
export.setRowCount(bill.getOrderCount());
|
||||||
export.setStorageKey("");
|
export.setStorageKey("");
|
||||||
export.setExportStatus(ArExportStatus.PROCESSING.getCode());
|
export.setExportStatus(ArExportStatus.PROCESSING.getCode());
|
||||||
exportMapper.insert(export);
|
exportMapper.insert(export);
|
||||||
recordSuccess(bill, ArLogObjectType.EXPORT, ArLogOperationType.EXPORT,
|
recordSuccess(bill, ArLogObjectType.EXPORT, ArLogOperationType.EXPORT,
|
||||||
"已提交账单导出任务", bill.getStatus(), bill.getStatus(), requestId, operator, export.getExportId());
|
"已提交账单导出任务", bill.getStatus(), bill.getStatus(), requestId,
|
||||||
|
exportUserId, operator, export.getExportId());
|
||||||
eventPublisher.publishEvent(new ArBillExportTaskEvent(export.getExportId()));
|
eventPublisher.publishEvent(new ArBillExportTaskEvent(export.getExportId()));
|
||||||
log.info("应收账单导出任务已创建,operator={}, requestId={}, arBillId={}, exportId={}, status={}, costMs={}",
|
log.info("应收账单导出任务已创建,operator={}, requestId={}, arBillId={}, exportId={}, status={}, costMs={}",
|
||||||
safeLogValue(operator), safeLogValue(requestId), arBillId, export.getExportId(),
|
safeLogValue(operator), safeLogValue(requestId), arBillId, export.getExportId(),
|
||||||
@@ -1087,7 +1096,8 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
exportId, export.getArBillId(), safeLogValue(message), elapsedMillis(startedAt), e);
|
exportId, export.getArBillId(), safeLogValue(message), elapsedMillis(startedAt), e);
|
||||||
if (exportMapper.markFailed(exportId, message) > 0) {
|
if (exportMapper.markFailed(exportId, message) > 0) {
|
||||||
logService.recordFailure(export.getArBillId(), ArLogObjectType.EXPORT, String.valueOf(exportId),
|
logService.recordFailure(export.getArBillId(), ArLogObjectType.EXPORT, String.valueOf(exportId),
|
||||||
ArLogOperationType.EXPORT, bill == null ? null : bill.getStatus(), message, export.getExportBy(), null);
|
ArLogOperationType.EXPORT, bill == null ? null : bill.getStatus(), message,
|
||||||
|
export.getExportUserId(), export.getExportBy(), null);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (temp != null) {
|
if (temp != null) {
|
||||||
@@ -1233,12 +1243,13 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void recordSuccess(ArBill bill, ArLogObjectType objectType, ArLogOperationType operationType, String desc, String fromStatus,
|
private void recordSuccess(ArBill bill, ArLogObjectType objectType, ArLogOperationType operationType, String desc, String fromStatus,
|
||||||
String toStatus, String requestId, String operator) {
|
String toStatus, String requestId, Long operatorId, String operatorName) {
|
||||||
recordSuccess(bill, objectType, operationType, desc, fromStatus, toStatus, requestId, operator, null);
|
recordSuccess(bill, objectType, operationType, desc, fromStatus, toStatus, requestId,
|
||||||
|
operatorId, operatorName, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordSuccess(ArBill bill, ArLogObjectType objectType, ArLogOperationType operationType, String desc, String fromStatus,
|
private void recordSuccess(ArBill bill, ArLogObjectType objectType, ArLogOperationType operationType, String desc, String fromStatus,
|
||||||
String toStatus, String requestId, String operator, Long objectId) {
|
String toStatus, String requestId, Long operatorId, String operatorName, Long objectId) {
|
||||||
ArBillLog log = new ArBillLog();
|
ArBillLog log = new ArBillLog();
|
||||||
log.setArBillId(bill.getArBillId());
|
log.setArBillId(bill.getArBillId());
|
||||||
log.setObjectType(objectType.getCode());
|
log.setObjectType(objectType.getCode());
|
||||||
@@ -1249,8 +1260,8 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
log.setToStatus(toStatus);
|
log.setToStatus(toStatus);
|
||||||
log.setBeforeData(safeStatusJson(fromStatus));
|
log.setBeforeData(safeStatusJson(fromStatus));
|
||||||
log.setAfterData(safeStatusJson(toStatus));
|
log.setAfterData(safeStatusJson(toStatus));
|
||||||
log.setOperatorId(operator);
|
log.setOperatorId(operatorId);
|
||||||
log.setOperatorName(operator);
|
log.setOperatorName(operatorName);
|
||||||
log.setOperationSource(ArLogOperationSource.WEB.getCode());
|
log.setOperationSource(ArLogOperationSource.WEB.getCode());
|
||||||
log.setRequestId(requestId);
|
log.setRequestId(requestId);
|
||||||
log.setResult(ArLogResult.SUCCESS.getCode());
|
log.setResult(ArLogResult.SUCCESS.getCode());
|
||||||
@@ -1259,7 +1270,8 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
|
|
||||||
private ServiceException failure(Long arBillId, ArLogObjectType objectType, String objectId, ArLogOperationType operationType,
|
private ServiceException failure(Long arBillId, ArLogObjectType objectType, String objectId, ArLogOperationType operationType,
|
||||||
String fromStatus, String message, String operator, String requestId) {
|
String fromStatus, String message, String operator, String requestId) {
|
||||||
logService.recordFailure(arBillId, objectType, objectId, operationType, fromStatus, message, operator, requestId);
|
logService.recordFailure(arBillId, objectType, objectId, operationType, fromStatus, message,
|
||||||
|
SecurityUtils.getUserId(), operator, requestId);
|
||||||
return new ServiceException(message);
|
return new ServiceException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="fileHash" column="file_hash"/>
|
<result property="fileHash" column="file_hash"/>
|
||||||
<result property="rowCount" column="row_count"/>
|
<result property="rowCount" column="row_count"/>
|
||||||
<result property="exportStatus" column="export_status"/>
|
<result property="exportStatus" column="export_status"/>
|
||||||
|
<result property="exportUserId" column="export_user_id"/>
|
||||||
<result property="exportBy" column="export_by"/>
|
<result property="exportBy" column="export_by"/>
|
||||||
<result property="exportTime" column="export_time"/>
|
<result property="exportTime" column="export_time"/>
|
||||||
<result property="remark" column="remark"/>
|
<result property="remark" column="remark"/>
|
||||||
@@ -41,6 +42,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
file_hash,
|
file_hash,
|
||||||
row_count,
|
row_count,
|
||||||
export_status,
|
export_status,
|
||||||
|
export_user_id,
|
||||||
export_by,
|
export_by,
|
||||||
export_time,
|
export_time,
|
||||||
remark
|
remark
|
||||||
@@ -71,11 +73,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
insert into ar_bill_detail_export (
|
insert into ar_bill_detail_export (
|
||||||
ar_bill_id, file_name, file_type, template_id, template_code, template_version,
|
ar_bill_id, file_name, file_type, template_id, template_code, template_version,
|
||||||
template_storage_type, template_storage_key, template_hash, storage_key,
|
template_storage_type, template_storage_key, template_hash, storage_key,
|
||||||
file_size, file_hash, row_count, export_status, export_by, export_time, remark
|
file_size, file_hash, row_count, export_status, export_user_id, export_by, export_time, remark
|
||||||
) values (
|
) values (
|
||||||
#{arBillId}, #{fileName}, #{fileType}, #{templateId}, #{templateCode}, #{templateVersion},
|
#{arBillId}, #{fileName}, #{fileType}, #{templateId}, #{templateCode}, #{templateVersion},
|
||||||
#{templateStorageType}, #{templateStorageKey}, #{templateHash}, #{storageKey},
|
#{templateStorageType}, #{templateStorageKey}, #{templateHash}, #{storageKey},
|
||||||
#{fileSize}, #{fileHash}, #{rowCount}, #{exportStatus}, #{exportBy}, sysdate(), #{remark}
|
#{fileSize}, #{fileHash}, #{rowCount}, #{exportStatus}, #{exportUserId}, #{exportBy}, sysdate(), #{remark}
|
||||||
)
|
)
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
<result property="errorMessage" column="error_message"/>
|
<result property="errorMessage" column="error_message"/>
|
||||||
<result property="requestToken" column="request_token"/>
|
<result property="requestToken" column="request_token"/>
|
||||||
<result property="createBy" column="create_by"/>
|
<result property="createBy" column="create_by"/>
|
||||||
|
<result property="createUserId" column="create_user_id"/>
|
||||||
<result property="createTime" column="create_time"/>
|
<result property="createTime" column="create_time"/>
|
||||||
<result property="startedAt" column="started_at"/>
|
<result property="startedAt" column="started_at"/>
|
||||||
<result property="heartbeatTime" column="heartbeat_time"/>
|
<result property="heartbeatTime" column="heartbeat_time"/>
|
||||||
@@ -42,6 +43,7 @@
|
|||||||
error_message,
|
error_message,
|
||||||
request_token,
|
request_token,
|
||||||
create_by,
|
create_by,
|
||||||
|
create_user_id,
|
||||||
create_time,
|
create_time,
|
||||||
started_at,
|
started_at,
|
||||||
heartbeat_time,
|
heartbeat_time,
|
||||||
@@ -79,11 +81,11 @@
|
|||||||
insert into ar_bill_generate_task (task_no, ar_bill_id, selection_mode, request_payload, snapshot_create_time,
|
insert into ar_bill_generate_task (task_no, ar_bill_id, selection_mode, request_payload, snapshot_create_time,
|
||||||
last_source_bill_id, total_count, processed_count, success_count,
|
last_source_bill_id, total_count, processed_count, success_count,
|
||||||
total_amount,
|
total_amount,
|
||||||
status, error_message, request_token, create_by, create_time, started_at,
|
status, error_message, request_token, create_by, create_user_id, create_time, started_at,
|
||||||
heartbeat_time, finished_at)
|
heartbeat_time, finished_at)
|
||||||
values (#{taskNo}, #{arBillId}, #{selectionMode}, #{requestPayload}, #{snapshotCreateTime},
|
values (#{taskNo}, #{arBillId}, #{selectionMode}, #{requestPayload}, #{snapshotCreateTime},
|
||||||
#{lastSourceBillId}, #{totalCount}, #{processedCount}, #{successCount}, #{totalAmount},
|
#{lastSourceBillId}, #{totalCount}, #{processedCount}, #{successCount}, #{totalAmount},
|
||||||
#{status}, #{errorMessage}, #{requestToken}, #{createBy}, sysdate(), #{startedAt},
|
#{status}, #{errorMessage}, #{requestToken}, #{createBy}, #{createUserId}, sysdate(), #{startedAt},
|
||||||
#{heartbeatTime}, #{finishedAt})
|
#{heartbeatTime}, #{finishedAt})
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
<result property="confirmedBy" column="confirmed_by"/>
|
<result property="confirmedBy" column="confirmed_by"/>
|
||||||
<result property="confirmedTime" column="confirmed_time"/>
|
<result property="confirmedTime" column="confirmed_time"/>
|
||||||
<result property="createBy" column="create_by"/>
|
<result property="createBy" column="create_by"/>
|
||||||
|
<result property="createUserId" column="create_user_id"/>
|
||||||
<result property="createTime" column="create_time"/>
|
<result property="createTime" column="create_time"/>
|
||||||
<result property="updateBy" column="update_by"/>
|
<result property="updateBy" column="update_by"/>
|
||||||
<result property="updateTime" column="update_time"/>
|
<result property="updateTime" column="update_time"/>
|
||||||
@@ -59,6 +60,7 @@
|
|||||||
confirmed_by,
|
confirmed_by,
|
||||||
confirmed_time,
|
confirmed_time,
|
||||||
create_by,
|
create_by,
|
||||||
|
create_user_id,
|
||||||
create_time,
|
create_time,
|
||||||
update_by,
|
update_by,
|
||||||
update_time
|
update_time
|
||||||
@@ -138,13 +140,13 @@
|
|||||||
bill_date, currency, order_count, total_amount, written_off_amount, unwritten_amount,
|
bill_date, currency, order_count, total_amount, written_off_amount, unwritten_amount,
|
||||||
status, generation_status, bill_version, bank_account_name, bank_account_no, bank_name,
|
status, generation_status, bill_version, bank_account_name, bank_account_no, bank_name,
|
||||||
remark,
|
remark,
|
||||||
confirmed_by, confirmed_time, create_by, create_time, update_by, update_time)
|
confirmed_by, confirmed_time, create_by, create_user_id, create_time, update_by, update_time)
|
||||||
values (#{billNo}, #{billName}, #{customerId}, #{customerCode}, #{customerName}, #{billPeriodStart},
|
values (#{billNo}, #{billName}, #{customerId}, #{customerCode}, #{customerName}, #{billPeriodStart},
|
||||||
#{billPeriodEnd},
|
#{billPeriodEnd},
|
||||||
#{billDate}, #{currency}, #{orderCount}, #{totalAmount}, #{writtenOffAmount}, #{unwrittenAmount},
|
#{billDate}, #{currency}, #{orderCount}, #{totalAmount}, #{writtenOffAmount}, #{unwrittenAmount},
|
||||||
#{status}, #{generationStatus}, #{billVersion}, #{bankAccountName}, #{bankAccountNo}, #{bankName},
|
#{status}, #{generationStatus}, #{billVersion}, #{bankAccountName}, #{bankAccountNo}, #{bankName},
|
||||||
#{remark},
|
#{remark},
|
||||||
#{confirmedBy}, #{confirmedTime}, #{createBy}, sysdate(), #{updateBy}, sysdate())
|
#{confirmedBy}, #{confirmedTime}, #{createBy}, #{createUserId}, sysdate(), #{updateBy}, sysdate())
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
<update id="updateArBillStatus">
|
<update id="updateArBillStatus">
|
||||||
|
|||||||
@@ -0,0 +1,294 @@
|
|||||||
|
-- =============================================================
|
||||||
|
-- 为应收账单、导出任务和生成任务增加稳定的创建用户主键。
|
||||||
|
-- 日志表使用 operator_id 保存用户主键,operator_name 保留操作人名称快照。
|
||||||
|
-- 本脚本可重复执行。
|
||||||
|
-- =============================================================
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 1. ar_bill 增加 create_user_id,并放到 confirmed_time 之后
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
SET @column_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
);
|
||||||
|
SET @sql := IF(@column_exists = 0,
|
||||||
|
'ALTER TABLE `ar_bill` ADD COLUMN `create_user_id` bigint(20) DEFAULT NULL COMMENT ''创建用户ID'' AFTER `confirmed_time`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 字段已存在时统一放到 confirmed_time 后(幂等,位置一致时无副作用)
|
||||||
|
ALTER TABLE `ar_bill`
|
||||||
|
MODIFY COLUMN `create_user_id` bigint(20) DEFAULT NULL COMMENT '创建用户ID' AFTER `confirmed_time`;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 2. ar_bill_detail_export 增加 export_user_id,兼容旧字段 create_user_id
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
SET @export_create_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_detail_export'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
);
|
||||||
|
SET @export_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_detail_export'
|
||||||
|
AND COLUMN_NAME = 'export_user_id'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 2.1 旧列存在、新列不存在:直接改名
|
||||||
|
SET @sql := IF(@export_create_user_id_exists > 0 AND @export_user_id_exists = 0,
|
||||||
|
'ALTER TABLE `ar_bill_detail_export` CHANGE COLUMN `create_user_id` `export_user_id` bigint(20) DEFAULT NULL COMMENT ''导出用户ID'' AFTER `export_status`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 2.2 新列不存在(旧列也不存在):新增
|
||||||
|
SET @export_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_detail_export'
|
||||||
|
AND COLUMN_NAME = 'export_user_id'
|
||||||
|
);
|
||||||
|
SET @sql := IF(@export_user_id_exists = 0,
|
||||||
|
'ALTER TABLE `ar_bill_detail_export` ADD COLUMN `export_user_id` bigint(20) DEFAULT NULL COMMENT ''导出用户ID'' AFTER `export_status`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 2.3 新旧列同时存在:保留新列已有值,用旧列补空
|
||||||
|
SET @export_create_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_detail_export'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
);
|
||||||
|
SET @sql := IF(@export_create_user_id_exists > 0,
|
||||||
|
'UPDATE `ar_bill_detail_export` SET `export_user_id` = `create_user_id` WHERE `export_user_id` IS NULL AND `create_user_id` IS NOT NULL',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 2.4 删除旧列
|
||||||
|
SET @sql := IF(@export_create_user_id_exists > 0,
|
||||||
|
'ALTER TABLE `ar_bill_detail_export` DROP COLUMN `create_user_id`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 2.5 统一 export_user_id 位置到 export_by 前(幂等)
|
||||||
|
ALTER TABLE `ar_bill_detail_export`
|
||||||
|
MODIFY COLUMN `export_user_id` bigint(20) DEFAULT NULL COMMENT '导出用户ID' AFTER `export_status`;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 3. ar_bill_generate_task 增加 create_user_id,并放到 request_token 之后
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
SET @column_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_generate_task'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
);
|
||||||
|
SET @sql := IF(@column_exists = 0,
|
||||||
|
'ALTER TABLE `ar_bill_generate_task` ADD COLUMN `create_user_id` bigint(20) DEFAULT NULL COMMENT ''创建用户ID'' AFTER `request_token`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
ALTER TABLE `ar_bill_generate_task`
|
||||||
|
MODIFY COLUMN `create_user_id` bigint(20) DEFAULT NULL COMMENT '创建用户ID' AFTER `request_token`;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 4. 按登录名补齐历史账单和异步任务的创建用户ID
|
||||||
|
-- 两边都加 COLLATE,确保 general_ci / unicode_ci 混用时不报 1267。
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
UPDATE `ar_bill`
|
||||||
|
INNER JOIN `sys_user`
|
||||||
|
ON `sys_user`.`user_name` COLLATE utf8mb4_unicode_ci = `ar_bill`.`create_by` COLLATE utf8mb4_unicode_ci
|
||||||
|
SET `ar_bill`.`create_user_id` = `sys_user`.`user_id`
|
||||||
|
WHERE `ar_bill`.`create_user_id` IS NULL;
|
||||||
|
|
||||||
|
UPDATE `ar_bill_detail_export`
|
||||||
|
INNER JOIN `sys_user`
|
||||||
|
ON `sys_user`.`user_name` COLLATE utf8mb4_unicode_ci = `ar_bill_detail_export`.`export_by` COLLATE utf8mb4_unicode_ci
|
||||||
|
SET `ar_bill_detail_export`.`export_user_id` = `sys_user`.`user_id`
|
||||||
|
WHERE `ar_bill_detail_export`.`export_user_id` IS NULL;
|
||||||
|
|
||||||
|
UPDATE `ar_bill_generate_task`
|
||||||
|
INNER JOIN `sys_user`
|
||||||
|
ON `sys_user`.`user_name` COLLATE utf8mb4_unicode_ci = `ar_bill_generate_task`.`create_by` COLLATE utf8mb4_unicode_ci
|
||||||
|
SET `ar_bill_generate_task`.`create_user_id` = `sys_user`.`user_id`
|
||||||
|
WHERE `ar_bill_generate_task`.`create_user_id` IS NULL;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 5. 兼容曾加过 ar_bill_log.create_user_id 的库:
|
||||||
|
-- 先把 create_user_id 迁入 operator_id,再删除重复列。
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
SET @log_create_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_log'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 5.1 迁移前先把 operator_name 空值用 operator_id 字符串补齐
|
||||||
|
SET @sql := IF(@log_create_user_id_exists > 0,
|
||||||
|
'UPDATE `ar_bill_log` SET `operator_name` = CAST(`operator_id` AS CHAR) WHERE (`operator_name` IS NULL OR `operator_name` = '''') AND `operator_id` IS NOT NULL',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 5.2 把 create_user_id 迁入 operator_id
|
||||||
|
SET @sql := IF(@log_create_user_id_exists > 0,
|
||||||
|
'UPDATE `ar_bill_log` SET `operator_id` = CAST(`create_user_id` AS CHAR) WHERE `create_user_id` IS NOT NULL',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 5.3 删除重复列
|
||||||
|
SET @sql := IF(@log_create_user_id_exists > 0,
|
||||||
|
'ALTER TABLE `ar_bill_log` DROP COLUMN `create_user_id`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 6. ar_bill_log.operator_id 处理
|
||||||
|
-- 目标:operator_id 最终为 bigint(20) NULL,存 sys_user.user_id。
|
||||||
|
-- 流程:先确保可空 -> 若为字符串则把登录名/数字映射成用户ID -> 最后统一改成 bigint。
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
|
||||||
|
-- 6.1 先确保 operator_id 可空(否则后面 UPDATE 置 NULL 会失败)
|
||||||
|
SET @operator_id_nullable := (
|
||||||
|
SELECT IS_NULLABLE FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_log'
|
||||||
|
AND COLUMN_NAME = 'operator_id'
|
||||||
|
);
|
||||||
|
SET @sql := IF(@operator_id_nullable <> 'YES',
|
||||||
|
'ALTER TABLE `ar_bill_log` MODIFY COLUMN `operator_id` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT ''操作人ID''',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 6.2 重新读取类型
|
||||||
|
SET @operator_id_type := (
|
||||||
|
SELECT DATA_TYPE FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_log'
|
||||||
|
AND COLUMN_NAME = 'operator_id'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 6.3 若 operator_id 为字符串:先用 operator_id 补齐 operator_name 空值
|
||||||
|
SET @sql := IF(@operator_id_type <> 'bigint',
|
||||||
|
'UPDATE `ar_bill_log` SET `operator_name` = CAST(`operator_id` AS CHAR) WHERE (`operator_name` IS NULL OR `operator_name` = '''') AND `operator_id` IS NOT NULL',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 6.4 若 operator_id 为字符串:登录名 -> sys_user.user_id;纯数字保留;其余置 NULL
|
||||||
|
SET @sql := IF(@operator_id_type <> 'bigint',
|
||||||
|
'UPDATE `ar_bill_log` l
|
||||||
|
LEFT JOIN `sys_user` u
|
||||||
|
ON u.`user_name` COLLATE utf8mb4_unicode_ci = l.`operator_id` COLLATE utf8mb4_unicode_ci
|
||||||
|
SET l.`operator_id` = CASE
|
||||||
|
WHEN u.`user_id` IS NOT NULL THEN CAST(u.`user_id` AS CHAR)
|
||||||
|
WHEN CAST(l.`operator_id` AS CHAR) REGEXP ''^[0-9]+$'' THEN CAST(l.`operator_id` AS CHAR)
|
||||||
|
ELSE NULL END
|
||||||
|
WHERE l.`operator_id` IS NOT NULL',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 6.5 最终统一改成 bigint(20) NULL
|
||||||
|
SET @operator_id_type := (
|
||||||
|
SELECT DATA_TYPE FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_log'
|
||||||
|
AND COLUMN_NAME = 'operator_id'
|
||||||
|
);
|
||||||
|
SET @operator_id_nullable := (
|
||||||
|
SELECT IS_NULLABLE FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_log'
|
||||||
|
AND COLUMN_NAME = 'operator_id'
|
||||||
|
);
|
||||||
|
SET @sql := IF(@operator_id_type <> 'bigint' OR @operator_id_nullable <> 'YES',
|
||||||
|
'ALTER TABLE `ar_bill_log` MODIFY COLUMN `operator_id` bigint(20) DEFAULT NULL COMMENT ''操作人用户ID''',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 7. ar_bill_generate_task 索引:确保 idx_ar_bill_generate_creator
|
||||||
|
-- 以 create_user_id 为首列。
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
SET @creator_index_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.STATISTICS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_generate_task'
|
||||||
|
AND INDEX_NAME = 'idx_ar_bill_generate_creator'
|
||||||
|
);
|
||||||
|
SET @creator_index_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.STATISTICS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_generate_task'
|
||||||
|
AND INDEX_NAME = 'idx_ar_bill_generate_creator'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
AND SEQ_IN_INDEX = 1
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 7.1 旧索引存在但不以 create_user_id 为首列:先删
|
||||||
|
SET @sql := IF(@creator_index_exists > 0 AND @creator_index_user_id_exists = 0,
|
||||||
|
'ALTER TABLE `ar_bill_generate_task` DROP INDEX `idx_ar_bill_generate_creator`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 7.2 重新读取,确认需要创建
|
||||||
|
SET @creator_index_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.STATISTICS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_generate_task'
|
||||||
|
AND INDEX_NAME = 'idx_ar_bill_generate_creator'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
AND SEQ_IN_INDEX = 1
|
||||||
|
);
|
||||||
|
SET @sql := IF(@creator_index_user_id_exists = 0,
|
||||||
|
'ALTER TABLE `ar_bill_generate_task` ADD KEY `idx_ar_bill_generate_creator` (`create_user_id`,`status`,`create_time`)',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
@@ -0,0 +1,293 @@
|
|||||||
|
-- =============================================================
|
||||||
|
-- 生产环境统一迁移脚本:应收账单用户归属字段及日志操作人ID迁移
|
||||||
|
-- 本脚本不包含 ar_bill_export 表改名。
|
||||||
|
-- 执行前确认目标库已存在 ar_bill_detail_export 表,并确认当前连接为生产库。
|
||||||
|
-- 本脚本包含字段新增/改名、历史数据回填、日志字段转换及索引整理。
|
||||||
|
-- =============================================================
|
||||||
|
-- 1. ar_bill 增加 create_user_id,并放到 confirmed_time 之后
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
SET @column_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
);
|
||||||
|
SET @sql := IF(@column_exists = 0,
|
||||||
|
'ALTER TABLE `ar_bill` ADD COLUMN `create_user_id` bigint(20) DEFAULT NULL COMMENT ''创建用户ID'' AFTER `confirmed_time`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 字段已存在时统一放到 confirmed_time 后(幂等,位置一致时无副作用)
|
||||||
|
ALTER TABLE `ar_bill`
|
||||||
|
MODIFY COLUMN `create_user_id` bigint(20) DEFAULT NULL COMMENT '创建用户ID' AFTER `confirmed_time`;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 2. ar_bill_detail_export 增加 export_user_id,兼容旧字段 create_user_id
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
SET @export_create_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_detail_export'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
);
|
||||||
|
SET @export_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_detail_export'
|
||||||
|
AND COLUMN_NAME = 'export_user_id'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 2.1 旧列存在、新列不存在:直接改名
|
||||||
|
SET @sql := IF(@export_create_user_id_exists > 0 AND @export_user_id_exists = 0,
|
||||||
|
'ALTER TABLE `ar_bill_detail_export` CHANGE COLUMN `create_user_id` `export_user_id` bigint(20) DEFAULT NULL COMMENT ''导出用户ID'' AFTER `export_status`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 2.2 新列不存在(旧列也不存在):新增
|
||||||
|
SET @export_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_detail_export'
|
||||||
|
AND COLUMN_NAME = 'export_user_id'
|
||||||
|
);
|
||||||
|
SET @sql := IF(@export_user_id_exists = 0,
|
||||||
|
'ALTER TABLE `ar_bill_detail_export` ADD COLUMN `export_user_id` bigint(20) DEFAULT NULL COMMENT ''导出用户ID'' AFTER `export_status`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 2.3 新旧列同时存在:保留新列已有值,用旧列补空
|
||||||
|
SET @export_create_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_detail_export'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
);
|
||||||
|
SET @sql := IF(@export_create_user_id_exists > 0,
|
||||||
|
'UPDATE `ar_bill_detail_export` SET `export_user_id` = `create_user_id` WHERE `export_user_id` IS NULL AND `create_user_id` IS NOT NULL',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 2.4 删除旧列
|
||||||
|
SET @sql := IF(@export_create_user_id_exists > 0,
|
||||||
|
'ALTER TABLE `ar_bill_detail_export` DROP COLUMN `create_user_id`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 2.5 统一 export_user_id 位置到 export_by 前(幂等)
|
||||||
|
ALTER TABLE `ar_bill_detail_export`
|
||||||
|
MODIFY COLUMN `export_user_id` bigint(20) DEFAULT NULL COMMENT '导出用户ID' AFTER `export_status`;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 3. ar_bill_generate_task 增加 create_user_id,并放到 request_token 之后
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
SET @column_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_generate_task'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
);
|
||||||
|
SET @sql := IF(@column_exists = 0,
|
||||||
|
'ALTER TABLE `ar_bill_generate_task` ADD COLUMN `create_user_id` bigint(20) DEFAULT NULL COMMENT ''创建用户ID'' AFTER `request_token`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
ALTER TABLE `ar_bill_generate_task`
|
||||||
|
MODIFY COLUMN `create_user_id` bigint(20) DEFAULT NULL COMMENT '创建用户ID' AFTER `request_token`;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 4. 按登录名补齐历史账单和异步任务的创建用户ID
|
||||||
|
-- 两边都加 COLLATE,确保 general_ci / unicode_ci 混用时不报 1267。
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
UPDATE `ar_bill`
|
||||||
|
INNER JOIN `sys_user`
|
||||||
|
ON `sys_user`.`user_name` COLLATE utf8mb4_unicode_ci = `ar_bill`.`create_by` COLLATE utf8mb4_unicode_ci
|
||||||
|
SET `ar_bill`.`create_user_id` = `sys_user`.`user_id`
|
||||||
|
WHERE `ar_bill`.`create_user_id` IS NULL;
|
||||||
|
|
||||||
|
UPDATE `ar_bill_detail_export`
|
||||||
|
INNER JOIN `sys_user`
|
||||||
|
ON `sys_user`.`user_name` COLLATE utf8mb4_unicode_ci = `ar_bill_detail_export`.`export_by` COLLATE utf8mb4_unicode_ci
|
||||||
|
SET `ar_bill_detail_export`.`export_user_id` = `sys_user`.`user_id`
|
||||||
|
WHERE `ar_bill_detail_export`.`export_user_id` IS NULL;
|
||||||
|
|
||||||
|
UPDATE `ar_bill_generate_task`
|
||||||
|
INNER JOIN `sys_user`
|
||||||
|
ON `sys_user`.`user_name` COLLATE utf8mb4_unicode_ci = `ar_bill_generate_task`.`create_by` COLLATE utf8mb4_unicode_ci
|
||||||
|
SET `ar_bill_generate_task`.`create_user_id` = `sys_user`.`user_id`
|
||||||
|
WHERE `ar_bill_generate_task`.`create_user_id` IS NULL;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 5. 兼容曾加过 ar_bill_log.create_user_id 的库:
|
||||||
|
-- 先把 create_user_id 迁入 operator_id,再删除重复列。
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
SET @log_create_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_log'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 5.1 迁移前先把 operator_name 空值用 operator_id 字符串补齐
|
||||||
|
SET @sql := IF(@log_create_user_id_exists > 0,
|
||||||
|
'UPDATE `ar_bill_log` SET `operator_name` = CAST(`operator_id` AS CHAR) WHERE (`operator_name` IS NULL OR `operator_name` = '''') AND `operator_id` IS NOT NULL',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 5.2 把 create_user_id 迁入 operator_id
|
||||||
|
SET @sql := IF(@log_create_user_id_exists > 0,
|
||||||
|
'UPDATE `ar_bill_log` SET `operator_id` = CAST(`create_user_id` AS CHAR) WHERE `create_user_id` IS NOT NULL',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 5.3 删除重复列
|
||||||
|
SET @sql := IF(@log_create_user_id_exists > 0,
|
||||||
|
'ALTER TABLE `ar_bill_log` DROP COLUMN `create_user_id`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 6. ar_bill_log.operator_id 处理
|
||||||
|
-- 目标:operator_id 最终为 bigint(20) NULL,存 sys_user.user_id。
|
||||||
|
-- 流程:先确保可空 -> 若为字符串则把登录名/数字映射成用户ID -> 最后统一改成 bigint。
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
|
||||||
|
-- 6.1 先确保 operator_id 可空(否则后面 UPDATE 置 NULL 会失败)
|
||||||
|
SET @operator_id_nullable := (
|
||||||
|
SELECT IS_NULLABLE FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_log'
|
||||||
|
AND COLUMN_NAME = 'operator_id'
|
||||||
|
);
|
||||||
|
SET @sql := IF(@operator_id_nullable <> 'YES',
|
||||||
|
'ALTER TABLE `ar_bill_log` MODIFY COLUMN `operator_id` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT ''操作人ID''',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 6.2 重新读取类型
|
||||||
|
SET @operator_id_type := (
|
||||||
|
SELECT DATA_TYPE FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_log'
|
||||||
|
AND COLUMN_NAME = 'operator_id'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 6.3 若 operator_id 为字符串:先用 operator_id 补齐 operator_name 空值
|
||||||
|
SET @sql := IF(@operator_id_type <> 'bigint',
|
||||||
|
'UPDATE `ar_bill_log` SET `operator_name` = CAST(`operator_id` AS CHAR) WHERE (`operator_name` IS NULL OR `operator_name` = '''') AND `operator_id` IS NOT NULL',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 6.4 若 operator_id 为字符串:登录名 -> sys_user.user_id;纯数字保留;其余置 NULL
|
||||||
|
SET @sql := IF(@operator_id_type <> 'bigint',
|
||||||
|
'UPDATE `ar_bill_log` l
|
||||||
|
LEFT JOIN `sys_user` u
|
||||||
|
ON u.`user_name` COLLATE utf8mb4_unicode_ci = l.`operator_id` COLLATE utf8mb4_unicode_ci
|
||||||
|
SET l.`operator_id` = CASE
|
||||||
|
WHEN u.`user_id` IS NOT NULL THEN CAST(u.`user_id` AS CHAR)
|
||||||
|
WHEN CAST(l.`operator_id` AS CHAR) REGEXP ''^[0-9]+$'' THEN CAST(l.`operator_id` AS CHAR)
|
||||||
|
ELSE NULL END
|
||||||
|
WHERE l.`operator_id` IS NOT NULL',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 6.5 最终统一改成 bigint(20) NULL
|
||||||
|
SET @operator_id_type := (
|
||||||
|
SELECT DATA_TYPE FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_log'
|
||||||
|
AND COLUMN_NAME = 'operator_id'
|
||||||
|
);
|
||||||
|
SET @operator_id_nullable := (
|
||||||
|
SELECT IS_NULLABLE FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_log'
|
||||||
|
AND COLUMN_NAME = 'operator_id'
|
||||||
|
);
|
||||||
|
SET @sql := IF(@operator_id_type <> 'bigint' OR @operator_id_nullable <> 'YES',
|
||||||
|
'ALTER TABLE `ar_bill_log` MODIFY COLUMN `operator_id` bigint(20) DEFAULT NULL COMMENT ''操作人用户ID''',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
-- 7. ar_bill_generate_task 索引:确保 idx_ar_bill_generate_creator
|
||||||
|
-- 以 create_user_id 为首列。
|
||||||
|
-- -------------------------------------------------------------
|
||||||
|
SET @creator_index_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.STATISTICS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_generate_task'
|
||||||
|
AND INDEX_NAME = 'idx_ar_bill_generate_creator'
|
||||||
|
);
|
||||||
|
SET @creator_index_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.STATISTICS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_generate_task'
|
||||||
|
AND INDEX_NAME = 'idx_ar_bill_generate_creator'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
AND SEQ_IN_INDEX = 1
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 7.1 旧索引存在但不以 create_user_id 为首列:先删
|
||||||
|
SET @sql := IF(@creator_index_exists > 0 AND @creator_index_user_id_exists = 0,
|
||||||
|
'ALTER TABLE `ar_bill_generate_task` DROP INDEX `idx_ar_bill_generate_creator`',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
-- 7.2 重新读取,确认需要创建
|
||||||
|
SET @creator_index_user_id_exists := (
|
||||||
|
SELECT COUNT(1) FROM information_schema.STATISTICS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'ar_bill_generate_task'
|
||||||
|
AND INDEX_NAME = 'idx_ar_bill_generate_creator'
|
||||||
|
AND COLUMN_NAME = 'create_user_id'
|
||||||
|
AND SEQ_IN_INDEX = 1
|
||||||
|
);
|
||||||
|
SET @sql := IF(@creator_index_user_id_exists = 0,
|
||||||
|
'ALTER TABLE `ar_bill_generate_task` ADD KEY `idx_ar_bill_generate_creator` (`create_user_id`,`status`,`create_time`)',
|
||||||
|
'SELECT 1'
|
||||||
|
);
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
Reference in New Issue
Block a user