更新支付账单服务逻辑,调整源ID赋值方式;修改SQL映射中的源ID字段为费用ID;新增UUID到BIGINT迁移配置
This commit is contained in:
+106
@@ -0,0 +1,106 @@
|
||||
package com.bms.web.controller.monitor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
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.RestController;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.price.migration.domain.MigBiJobLog;
|
||||
import com.bms.price.migration.service.IUuidToNewMonitorService;
|
||||
|
||||
/**
|
||||
* 监控:UUID -> bigint 阴影同步进度与开关
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/monitor/uuidToNew")
|
||||
public class UuidToNewMonitorController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IUuidToNewMonitorService monitorService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:uuidToNew:list')")
|
||||
@GetMapping("/progress")
|
||||
public AjaxResult progress()
|
||||
{
|
||||
return success(monitorService.getProgress());
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('monitor:uuidToNew:list')")
|
||||
@GetMapping("/jobLog/list")
|
||||
public TableDataInfo jobLogList(MigBiJobLog query)
|
||||
{
|
||||
startPage();
|
||||
List<MigBiJobLog> list = monitorService.selectJobLogList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开/关闭连续同步。
|
||||
* body: { "enabled": true, "threadCount": 2, "batchSize": 200 }
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:uuidToNew:switch')")
|
||||
@Log(title = "UUID阴影同步开关", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/enabled")
|
||||
public AjaxResult setEnabled(@RequestBody Map<String, Object> body)
|
||||
{
|
||||
boolean enabled = false;
|
||||
Integer threadCount = null;
|
||||
Integer batchSize = null;
|
||||
if (body != null)
|
||||
{
|
||||
if (body.get("enabled") != null)
|
||||
{
|
||||
enabled = Boolean.parseBoolean(String.valueOf(body.get("enabled")));
|
||||
}
|
||||
threadCount = toInt(body.get("threadCount"));
|
||||
batchSize = toInt(body.get("batchSize"));
|
||||
}
|
||||
monitorService.setEnabled(enabled, threadCount, batchSize);
|
||||
return success(monitorService.getProgress());
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅开关关闭时修改线程/批次。
|
||||
* body: { "threadCount": 2, "batchSize": 200 }
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('monitor:uuidToNew:switch')")
|
||||
@Log(title = "UUID阴影同步配置", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/config")
|
||||
public AjaxResult updateConfig(@RequestBody Map<String, Object> body)
|
||||
{
|
||||
Integer threadCount = null;
|
||||
Integer batchSize = null;
|
||||
if (body != null)
|
||||
{
|
||||
threadCount = toInt(body.get("threadCount"));
|
||||
batchSize = toInt(body.get("batchSize"));
|
||||
}
|
||||
monitorService.updateRuntimeConfig(threadCount, batchSize);
|
||||
return success(monitorService.getProgress());
|
||||
}
|
||||
|
||||
private Integer toInt(Object v)
|
||||
{
|
||||
if (v == null || "".equals(String.valueOf(v).trim()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Integer.valueOf(String.valueOf(v).trim());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,14 @@ bms:
|
||||
tms:
|
||||
# Agreed API identification code for TMS callers
|
||||
api-code: BMS.TMS.ZYaOvlQzpcfau8TUaCFfO3Hp8ieHIqGw
|
||||
# UUID -> bigint shadow sync. Toggle on monitor page (no cron).
|
||||
mig:
|
||||
uuid-to-new:
|
||||
batch-size: 200
|
||||
# 1=single thread; sprint on 4c8g use 2~3 (max 4)
|
||||
thread-count: 2
|
||||
# sleep when no pending orders while switch is ON
|
||||
idle-sleep-ms: 3000
|
||||
billing:
|
||||
# MQ mode: redis (default list queue) | local (Spring event)
|
||||
mq-mode: redis
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.bms.price.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* UUID -> bigint 阴影同步配置(bms.mig.uuid-to-new)
|
||||
* 运行开关/线程/批次由监控页控制,不走 cron。
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "bms.mig.uuid-to-new")
|
||||
public class UuidToNewProperties
|
||||
{
|
||||
/** 每轮抓取订单数(1~1000) */
|
||||
private int batchSize = 200;
|
||||
/**
|
||||
* 批内工作线程数(1~4)。
|
||||
* 默认1;冲刺追数可设2~3(生产4核谨慎)。
|
||||
*/
|
||||
private int threadCount = 1;
|
||||
/** 无待处理订单时空转睡眠毫秒(开关仍为开时) */
|
||||
private long idleSleepMs = 3000L;
|
||||
|
||||
public int getBatchSize()
|
||||
{
|
||||
return batchSize;
|
||||
}
|
||||
|
||||
public void setBatchSize(int batchSize)
|
||||
{
|
||||
this.batchSize = batchSize;
|
||||
}
|
||||
|
||||
/** 限定在 1~1000 */
|
||||
public int resolvedBatchSize()
|
||||
{
|
||||
int n = batchSize;
|
||||
if (n < 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (n > 1000)
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public int getThreadCount()
|
||||
{
|
||||
return threadCount;
|
||||
}
|
||||
|
||||
public void setThreadCount(int threadCount)
|
||||
{
|
||||
this.threadCount = threadCount;
|
||||
}
|
||||
|
||||
/** 限定在1~4 */
|
||||
public int resolvedThreadCount()
|
||||
{
|
||||
int n = threadCount;
|
||||
if (n < 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (n > 4)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public long getIdleSleepMs()
|
||||
{
|
||||
return idleSleepMs;
|
||||
}
|
||||
|
||||
public void setIdleSleepMs(long idleSleepMs)
|
||||
{
|
||||
this.idleSleepMs = idleSleepMs;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.bms.price.migration.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
/**
|
||||
* mig_bi_job_log 批次日志
|
||||
*/
|
||||
public class MigBiJobLog
|
||||
{
|
||||
private Long id;
|
||||
private String batchNo;
|
||||
private Integer fetched;
|
||||
private Integer success;
|
||||
private Integer fail;
|
||||
private Integer skip;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date startedAt;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date finishedAt;
|
||||
private String remark;
|
||||
/** 查询:开始时间起 */
|
||||
private String beginStartedAt;
|
||||
/** 查询:开始时间止 */
|
||||
private String endStartedAt;
|
||||
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
public String getBatchNo() { return batchNo; }
|
||||
public void setBatchNo(String batchNo) { this.batchNo = batchNo; }
|
||||
public Integer getFetched() { return fetched; }
|
||||
public void setFetched(Integer fetched) { this.fetched = fetched; }
|
||||
public Integer getSuccess() { return success; }
|
||||
public void setSuccess(Integer success) { this.success = success; }
|
||||
public Integer getFail() { return fail; }
|
||||
public void setFail(Integer fail) { this.fail = fail; }
|
||||
public Integer getSkip() { return skip; }
|
||||
public void setSkip(Integer skip) { this.skip = skip; }
|
||||
public Date getStartedAt() { return startedAt; }
|
||||
public void setStartedAt(Date startedAt) { this.startedAt = startedAt; }
|
||||
public Date getFinishedAt() { return finishedAt; }
|
||||
public void setFinishedAt(Date finishedAt) { this.finishedAt = finishedAt; }
|
||||
public String getRemark() { return remark; }
|
||||
public void setRemark(String remark) { this.remark = remark; }
|
||||
public String getBeginStartedAt() { return beginStartedAt; }
|
||||
public void setBeginStartedAt(String beginStartedAt) { this.beginStartedAt = beginStartedAt; }
|
||||
public String getEndStartedAt() { return endStartedAt; }
|
||||
public void setEndStartedAt(String endStartedAt) { this.endStartedAt = endStartedAt; }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.bms.price.migration.domain;
|
||||
|
||||
/**
|
||||
* 旧费用行:用于逐行插入并建内存 Map
|
||||
*/
|
||||
public class UuidToNewFeeRow
|
||||
{
|
||||
private String feeId;
|
||||
private String parentId;
|
||||
|
||||
public String getFeeId() { return feeId; }
|
||||
public void setFeeId(String feeId) { this.feeId = feeId; }
|
||||
public String getParentId() { return parentId; }
|
||||
public void setParentId(String parentId) { this.parentId = parentId; }
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package com.bms.price.migration.domain;
|
||||
|
||||
/**
|
||||
* 阴影插入时传参 / 接收自增主键
|
||||
*/
|
||||
public class UuidToNewIdHolder
|
||||
{
|
||||
private String oldBillId;
|
||||
private Long newBillId;
|
||||
private String oldId;
|
||||
private Long newId;
|
||||
private Long newIncomeId;
|
||||
private Long newPayId;
|
||||
private String orderNo;
|
||||
private String status;
|
||||
private String failReason;
|
||||
private String batchNo;
|
||||
private Integer fetched;
|
||||
private Integer success;
|
||||
private Integer fail;
|
||||
private Integer skip;
|
||||
private Long jobLogId;
|
||||
|
||||
public String getOldBillId() { return oldBillId; }
|
||||
public void setOldBillId(String oldBillId) { this.oldBillId = oldBillId; }
|
||||
public Long getNewBillId() { return newBillId; }
|
||||
public void setNewBillId(Long newBillId) { this.newBillId = newBillId; }
|
||||
public String getOldId() { return oldId; }
|
||||
public void setOldId(String oldId) { this.oldId = oldId; }
|
||||
public Long getNewId() { return newId; }
|
||||
public void setNewId(Long newId) { this.newId = newId; }
|
||||
public Long getNewIncomeId() { return newIncomeId; }
|
||||
public void setNewIncomeId(Long newIncomeId) { this.newIncomeId = newIncomeId; }
|
||||
public Long getNewPayId() { return newPayId; }
|
||||
public void setNewPayId(Long newPayId) { this.newPayId = newPayId; }
|
||||
public String getOrderNo() { return orderNo; }
|
||||
public void setOrderNo(String orderNo) { this.orderNo = orderNo; }
|
||||
public String getStatus() { return status; }
|
||||
public void setStatus(String status) { this.status = status; }
|
||||
public String getFailReason() { return failReason; }
|
||||
public void setFailReason(String failReason) { this.failReason = failReason; }
|
||||
public String getBatchNo() { return batchNo; }
|
||||
public void setBatchNo(String batchNo) { this.batchNo = batchNo; }
|
||||
public Integer getFetched() { return fetched; }
|
||||
public void setFetched(Integer fetched) { this.fetched = fetched; }
|
||||
public Integer getSuccess() { return success; }
|
||||
public void setSuccess(Integer success) { this.success = success; }
|
||||
public Integer getFail() { return fail; }
|
||||
public void setFail(Integer fail) { this.fail = fail; }
|
||||
public Integer getSkip() { return skip; }
|
||||
public void setSkip(Integer skip) { this.skip = skip; }
|
||||
public Long getJobLogId() { return jobLogId; }
|
||||
public void setJobLogId(Long jobLogId) { this.jobLogId = jobLogId; }
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.bms.price.migration.domain;
|
||||
|
||||
/**
|
||||
* UUID 阴影同步进度概览
|
||||
*/
|
||||
public class UuidToNewProgressVo
|
||||
{
|
||||
private long oldCnt;
|
||||
private long doneCnt;
|
||||
private long newCnt;
|
||||
private long pendingCnt;
|
||||
private double donePercent;
|
||||
/** 监控页开关:是否要跑 */
|
||||
private boolean enabled;
|
||||
/** 循环是否正在执行中 */
|
||||
private boolean running;
|
||||
private int batchSize;
|
||||
private int threadCount;
|
||||
|
||||
public long getOldCnt() { return oldCnt; }
|
||||
public void setOldCnt(long oldCnt) { this.oldCnt = oldCnt; }
|
||||
public long getDoneCnt() { return doneCnt; }
|
||||
public void setDoneCnt(long doneCnt) { this.doneCnt = doneCnt; }
|
||||
public long getNewCnt() { return newCnt; }
|
||||
public void setNewCnt(long newCnt) { this.newCnt = newCnt; }
|
||||
public long getPendingCnt() { return pendingCnt; }
|
||||
public void setPendingCnt(long pendingCnt) { this.pendingCnt = pendingCnt; }
|
||||
public double getDonePercent() { return donePercent; }
|
||||
public void setDonePercent(double donePercent) { this.donePercent = donePercent; }
|
||||
public boolean isEnabled() { return enabled; }
|
||||
public void setEnabled(boolean enabled) { this.enabled = enabled; }
|
||||
public boolean isRunning() { return running; }
|
||||
public void setRunning(boolean running) { this.running = running; }
|
||||
public int getBatchSize() { return batchSize; }
|
||||
public void setBatchSize(int batchSize) { this.batchSize = batchSize; }
|
||||
public int getThreadCount() { return threadCount; }
|
||||
public void setThreadCount(int threadCount) { this.threadCount = threadCount; }
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package com.bms.price.migration.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.bms.price.migration.domain.MigBiJobLog;
|
||||
import com.bms.price.migration.domain.UuidToNewFeeRow;
|
||||
import com.bms.price.migration.domain.UuidToNewIdHolder;
|
||||
import com.bms.price.migration.domain.UuidToNewProgressVo;
|
||||
|
||||
/**
|
||||
* UUID -> bigint 阴影同步 Mapper
|
||||
*/
|
||||
public interface UuidToNewSyncMapper
|
||||
{
|
||||
List<String> selectPendingBillIds(@Param("limit") int limit);
|
||||
|
||||
String selectOrderNo(@Param("oldBillId") String oldBillId);
|
||||
|
||||
int countOrderBill(@Param("oldBillId") String oldBillId);
|
||||
|
||||
int insertOrderBillNew(UuidToNewIdHolder holder);
|
||||
|
||||
int insertOrderDone(UuidToNewIdHolder holder);
|
||||
|
||||
/** INSERT IGNORE 占坑;返回 0 表示已被占用 */
|
||||
int claimOrderDone(UuidToNewIdHolder holder);
|
||||
|
||||
int updateOrderDoneSuccess(UuidToNewIdHolder holder);
|
||||
|
||||
int insertOrderExtNew(@Param("oldBillId") String oldBillId, @Param("newBillId") Long newBillId);
|
||||
|
||||
List<String> selectIncomeIds(@Param("oldBillId") String oldBillId);
|
||||
|
||||
int insertIncomeBillNew(UuidToNewIdHolder holder);
|
||||
|
||||
List<UuidToNewFeeRow> selectIncomeFees(@Param("oldBillId") String oldBillId);
|
||||
|
||||
int insertIncomeFeeNew(UuidToNewIdHolder holder);
|
||||
|
||||
List<String> selectPayIds(@Param("oldBillId") String oldBillId);
|
||||
|
||||
int insertPayBillNew(UuidToNewIdHolder holder);
|
||||
|
||||
List<UuidToNewFeeRow> selectPayFees(@Param("oldBillId") String oldBillId);
|
||||
|
||||
int insertPayFeeNew(UuidToNewIdHolder holder);
|
||||
|
||||
int updatePayFeeIdEqualsId(@Param("id") Long id);
|
||||
|
||||
int insertArDetailNew(@Param("oldBillId") String oldBillId, @Param("newBillId") Long newBillId);
|
||||
|
||||
List<UuidToNewFeeRow> selectArDetailFees(@Param("oldBillId") String oldBillId);
|
||||
|
||||
int insertArDetailFeeNew(@Param("detailFeeId") Long detailFeeId, @Param("newFeeId") Long newFeeId);
|
||||
|
||||
List<UuidToNewFeeRow> selectPayBillLines(@Param("oldBillId") String oldBillId);
|
||||
|
||||
int insertPayBillLineNew(@Param("lineId") Long lineId, @Param("newBillId") Long newBillId,
|
||||
@Param("newFeeId") Long newFeeId);
|
||||
|
||||
int insertBillingTaskNew(@Param("oldBillId") String oldBillId, @Param("newBillId") Long newBillId);
|
||||
|
||||
int insertJobLogStart(UuidToNewIdHolder holder);
|
||||
|
||||
int updateJobLogFinish(UuidToNewIdHolder holder);
|
||||
|
||||
UuidToNewProgressVo selectProgress();
|
||||
|
||||
List<MigBiJobLog> selectJobLogList(MigBiJobLog query);
|
||||
}
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.bms.price.migration.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.bms.price.migration.domain.MigBiJobLog;
|
||||
import com.bms.price.migration.domain.UuidToNewProgressVo;
|
||||
|
||||
/**
|
||||
* UUID 阴影同步监控
|
||||
*/
|
||||
public interface IUuidToNewMonitorService
|
||||
{
|
||||
UuidToNewProgressVo getProgress();
|
||||
|
||||
List<MigBiJobLog> selectJobLogList(MigBiJobLog query);
|
||||
|
||||
/** 打开/关闭连续同步;开启前可带线程/批次 */
|
||||
void setEnabled(boolean enabled, Integer threadCount, Integer batchSize);
|
||||
|
||||
/**
|
||||
* 仅开关关闭时可改线程与批次。
|
||||
*/
|
||||
void updateRuntimeConfig(Integer threadCount, Integer batchSize);
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.bms.price.migration.service;
|
||||
|
||||
/**
|
||||
* UUID -> bigint 阴影同步服务
|
||||
*/
|
||||
public interface IUuidToNewSyncService
|
||||
{
|
||||
/**
|
||||
* 执行一批。
|
||||
* @return 本批抓取条数(fetched)
|
||||
*/
|
||||
int syncBatch(int batchSize);
|
||||
|
||||
/** 一单一事务;返回 SUCCESS / FAIL / SKIP */
|
||||
String syncOneOrder(String oldBillId);
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
package com.bms.price.migration.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.bms.common.exception.ServiceException;
|
||||
import com.bms.price.config.UuidToNewProperties;
|
||||
import com.bms.price.migration.domain.MigBiJobLog;
|
||||
import com.bms.price.migration.domain.UuidToNewProgressVo;
|
||||
import com.bms.price.migration.mapper.UuidToNewSyncMapper;
|
||||
import com.bms.price.migration.service.IUuidToNewMonitorService;
|
||||
import com.bms.price.task.UuidToNewSyncRunner;
|
||||
|
||||
/**
|
||||
* UUID 阴影同步监控
|
||||
*/
|
||||
@Service
|
||||
public class UuidToNewMonitorServiceImpl implements IUuidToNewMonitorService
|
||||
{
|
||||
@Autowired
|
||||
private UuidToNewSyncMapper syncMapper;
|
||||
|
||||
@Autowired
|
||||
private UuidToNewProperties properties;
|
||||
|
||||
@Autowired
|
||||
private UuidToNewSyncRunner syncRunner;
|
||||
|
||||
@Override
|
||||
public UuidToNewProgressVo getProgress()
|
||||
{
|
||||
UuidToNewProgressVo vo = syncMapper.selectProgress();
|
||||
if (vo == null)
|
||||
{
|
||||
vo = new UuidToNewProgressVo();
|
||||
}
|
||||
long pending = vo.getOldCnt() - vo.getDoneCnt();
|
||||
if (pending < 0L)
|
||||
{
|
||||
pending = 0L;
|
||||
}
|
||||
vo.setPendingCnt(pending);
|
||||
if (vo.getOldCnt() > 0L)
|
||||
{
|
||||
vo.setDonePercent(Math.round(vo.getDoneCnt() * 10000.0 / vo.getOldCnt()) / 100.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
vo.setDonePercent(0.0);
|
||||
}
|
||||
vo.setEnabled(syncRunner.isEnabled());
|
||||
vo.setRunning(syncRunner.isRunning());
|
||||
if (properties != null)
|
||||
{
|
||||
vo.setBatchSize(properties.resolvedBatchSize());
|
||||
vo.setThreadCount(properties.resolvedThreadCount());
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MigBiJobLog> selectJobLogList(MigBiJobLog query)
|
||||
{
|
||||
return syncMapper.selectJobLogList(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled, Integer threadCount, Integer batchSize)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
applyConfig(threadCount, batchSize);
|
||||
}
|
||||
syncRunner.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRuntimeConfig(Integer threadCount, Integer batchSize)
|
||||
{
|
||||
if (syncRunner.isEnabled() || syncRunner.isRunning())
|
||||
{
|
||||
throw new ServiceException("请先关闭连续同步再修改线程/批次");
|
||||
}
|
||||
applyConfig(threadCount, batchSize);
|
||||
}
|
||||
|
||||
private void applyConfig(Integer threadCount, Integer batchSize)
|
||||
{
|
||||
if (properties == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (threadCount != null)
|
||||
{
|
||||
int n = threadCount.intValue();
|
||||
if (n < 1)
|
||||
{
|
||||
n = 1;
|
||||
}
|
||||
if (n > 4)
|
||||
{
|
||||
n = 4;
|
||||
}
|
||||
properties.setThreadCount(n);
|
||||
}
|
||||
if (batchSize != null)
|
||||
{
|
||||
int n = batchSize.intValue();
|
||||
if (n < 1)
|
||||
{
|
||||
n = 1;
|
||||
}
|
||||
if (n > 1000)
|
||||
{
|
||||
n = 1000;
|
||||
}
|
||||
properties.setBatchSize(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
+331
@@ -0,0 +1,331 @@
|
||||
package com.bms.price.migration.service.impl;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.bms.price.config.UuidToNewProperties;
|
||||
import com.bms.price.migration.domain.UuidToNewFeeRow;
|
||||
import com.bms.price.migration.domain.UuidToNewIdHolder;
|
||||
import com.bms.price.migration.mapper.UuidToNewSyncMapper;
|
||||
import com.bms.price.migration.service.IUuidToNewSyncService;
|
||||
|
||||
/**
|
||||
* UUID -> bigint 阴影同步:一单一事务;批内可多线程
|
||||
*/
|
||||
@Service
|
||||
public class UuidToNewSyncServiceImpl implements IUuidToNewSyncService
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(UuidToNewSyncServiceImpl.class);
|
||||
|
||||
public static final String SUCCESS = "SUCCESS";
|
||||
public static final String FAIL = "FAIL";
|
||||
public static final String SKIP = "SKIP";
|
||||
public static final String RUNNING = "RUNNING";
|
||||
|
||||
@Autowired
|
||||
private UuidToNewSyncMapper syncMapper;
|
||||
|
||||
@Autowired
|
||||
private UuidToNewProperties properties;
|
||||
|
||||
@Autowired
|
||||
@Lazy
|
||||
private IUuidToNewSyncService self;
|
||||
|
||||
@Override
|
||||
public int syncBatch(int batchSize)
|
||||
{
|
||||
int limit = Math.max(1, Math.min(batchSize, 1000));
|
||||
int threads = properties == null ? 1 : properties.resolvedThreadCount();
|
||||
String batchNo = UUID.randomUUID().toString().replace("-", "");
|
||||
UuidToNewIdHolder job = new UuidToNewIdHolder();
|
||||
job.setBatchNo(batchNo);
|
||||
syncMapper.insertJobLogStart(job);
|
||||
|
||||
List<String> billIds = syncMapper.selectPendingBillIds(limit);
|
||||
AtomicInteger success = new AtomicInteger(0);
|
||||
AtomicInteger fail = new AtomicInteger(0);
|
||||
AtomicInteger skip = new AtomicInteger(0);
|
||||
|
||||
if (billIds.isEmpty())
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
else if (threads <= 1)
|
||||
{
|
||||
for (String oldBillId : billIds)
|
||||
{
|
||||
applyResult(self, oldBillId, success, fail, skip);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ExecutorService pool = Executors.newFixedThreadPool(threads);
|
||||
try
|
||||
{
|
||||
List<Future<?>> futures = new ArrayList<Future<?>>();
|
||||
for (String oldBillId : billIds)
|
||||
{
|
||||
final String id = oldBillId;
|
||||
futures.add(pool.submit(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
applyResult(self, id, success, fail, skip);
|
||||
}
|
||||
}));
|
||||
}
|
||||
for (Future<?> f : futures)
|
||||
{
|
||||
try
|
||||
{
|
||||
f.get();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
fail.incrementAndGet();
|
||||
log.warn("uuid-to-new worker future error: {}", e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
pool.shutdown();
|
||||
try
|
||||
{
|
||||
if (!pool.awaitTermination(2, TimeUnit.HOURS))
|
||||
{
|
||||
pool.shutdownNow();
|
||||
}
|
||||
}
|
||||
catch (InterruptedException ie)
|
||||
{
|
||||
pool.shutdownNow();
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
job.setFetched(billIds.size());
|
||||
job.setSuccess(success.get());
|
||||
job.setFail(fail.get());
|
||||
job.setSkip(skip.get());
|
||||
job.setFailReason("threads=" + threads);
|
||||
syncMapper.updateJobLogFinish(job);
|
||||
String summary = String.format(
|
||||
"batch=%s threads=%d fetched=%d success=%d fail=%d skip=%d",
|
||||
batchNo, threads, billIds.size(), success.get(), fail.get(), skip.get());
|
||||
log.info("uuid-to-new {}", summary);
|
||||
return billIds.size();
|
||||
}
|
||||
|
||||
private void applyResult(IUuidToNewSyncService svc, String oldBillId,
|
||||
AtomicInteger success, AtomicInteger fail, AtomicInteger skip)
|
||||
{
|
||||
try
|
||||
{
|
||||
String r = svc.syncOneOrder(oldBillId);
|
||||
if (SUCCESS.equals(r))
|
||||
{
|
||||
success.incrementAndGet();
|
||||
}
|
||||
else if (SKIP.equals(r))
|
||||
{
|
||||
skip.incrementAndGet();
|
||||
}
|
||||
else
|
||||
{
|
||||
fail.incrementAndGet();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
fail.incrementAndGet();
|
||||
log.warn("uuid-to-new sync fail billId={}: {}", oldBillId, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 占坑临时 new_bill_id:负数,避免与自增正数冲突。
|
||||
*/
|
||||
static long claimTempNewBillId(String oldBillId)
|
||||
{
|
||||
long h = UUID.nameUUIDFromBytes(oldBillId.getBytes(StandardCharsets.UTF_8)).getMostSignificantBits();
|
||||
if (h == 0L)
|
||||
{
|
||||
h = -1L;
|
||||
}
|
||||
else if (h > 0L)
|
||||
{
|
||||
h = -h;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String syncOneOrder(String oldBillId)
|
||||
{
|
||||
if (oldBillId == null || oldBillId.isEmpty())
|
||||
{
|
||||
return SKIP;
|
||||
}
|
||||
if (syncMapper.countOrderBill(oldBillId) <= 0)
|
||||
{
|
||||
return SKIP;
|
||||
}
|
||||
|
||||
String orderNo = syncMapper.selectOrderNo(oldBillId);
|
||||
UuidToNewIdHolder claim = new UuidToNewIdHolder();
|
||||
claim.setOldBillId(oldBillId);
|
||||
claim.setNewBillId(claimTempNewBillId(oldBillId));
|
||||
claim.setOrderNo(orderNo);
|
||||
claim.setStatus(RUNNING);
|
||||
if (syncMapper.claimOrderDone(claim) == 0)
|
||||
{
|
||||
return SKIP;
|
||||
}
|
||||
|
||||
Map<String, Long> incomeMap = new HashMap<String, Long>();
|
||||
Map<String, Long> feeMap = new HashMap<String, Long>();
|
||||
Map<String, Long> payMap = new HashMap<String, Long>();
|
||||
Map<String, Long> payFeeMap = new HashMap<String, Long>();
|
||||
|
||||
UuidToNewIdHolder order = new UuidToNewIdHolder();
|
||||
order.setOldBillId(oldBillId);
|
||||
syncMapper.insertOrderBillNew(order);
|
||||
Long newBillId = order.getNewBillId();
|
||||
if (newBillId == null)
|
||||
{
|
||||
throw new IllegalStateException("insert prc_order_bill_new no generated bill_id");
|
||||
}
|
||||
|
||||
UuidToNewIdHolder done = new UuidToNewIdHolder();
|
||||
done.setOldBillId(oldBillId);
|
||||
done.setNewBillId(newBillId);
|
||||
done.setOrderNo(orderNo);
|
||||
syncMapper.updateOrderDoneSuccess(done);
|
||||
|
||||
syncMapper.insertOrderExtNew(oldBillId, newBillId);
|
||||
|
||||
for (String oldIncomeId : syncMapper.selectIncomeIds(oldBillId))
|
||||
{
|
||||
UuidToNewIdHolder h = new UuidToNewIdHolder();
|
||||
h.setOldId(oldIncomeId);
|
||||
h.setNewBillId(newBillId);
|
||||
syncMapper.insertIncomeBillNew(h);
|
||||
if (h.getNewId() == null)
|
||||
{
|
||||
throw new IllegalStateException("insert income_new no id for " + oldIncomeId);
|
||||
}
|
||||
incomeMap.put(oldIncomeId, h.getNewId());
|
||||
}
|
||||
|
||||
for (UuidToNewFeeRow row : syncMapper.selectIncomeFees(oldBillId))
|
||||
{
|
||||
Long newIncomeId = null;
|
||||
if (row.getParentId() != null && !row.getParentId().isEmpty())
|
||||
{
|
||||
newIncomeId = incomeMap.get(row.getParentId());
|
||||
if (newIncomeId == null)
|
||||
{
|
||||
throw new IllegalStateException("incomeMap miss " + row.getParentId());
|
||||
}
|
||||
}
|
||||
UuidToNewIdHolder h = new UuidToNewIdHolder();
|
||||
h.setOldId(row.getFeeId());
|
||||
h.setNewBillId(newBillId);
|
||||
h.setNewIncomeId(newIncomeId);
|
||||
syncMapper.insertIncomeFeeNew(h);
|
||||
if (h.getNewId() == null)
|
||||
{
|
||||
throw new IllegalStateException("insert income_fee_new no id for " + row.getFeeId());
|
||||
}
|
||||
feeMap.put(row.getFeeId(), h.getNewId());
|
||||
}
|
||||
|
||||
for (String oldPayId : syncMapper.selectPayIds(oldBillId))
|
||||
{
|
||||
UuidToNewIdHolder h = new UuidToNewIdHolder();
|
||||
h.setOldId(oldPayId);
|
||||
h.setNewBillId(newBillId);
|
||||
syncMapper.insertPayBillNew(h);
|
||||
if (h.getNewId() == null)
|
||||
{
|
||||
throw new IllegalStateException("insert pay_new no id for " + oldPayId);
|
||||
}
|
||||
payMap.put(oldPayId, h.getNewId());
|
||||
}
|
||||
|
||||
for (UuidToNewFeeRow row : syncMapper.selectPayFees(oldBillId))
|
||||
{
|
||||
Long newPayId = null;
|
||||
if (row.getParentId() != null && !row.getParentId().isEmpty())
|
||||
{
|
||||
newPayId = payMap.get(row.getParentId());
|
||||
if (newPayId == null)
|
||||
{
|
||||
throw new IllegalStateException("payMap miss " + row.getParentId());
|
||||
}
|
||||
}
|
||||
UuidToNewIdHolder h = new UuidToNewIdHolder();
|
||||
h.setOldId(row.getFeeId());
|
||||
h.setNewBillId(newBillId);
|
||||
h.setNewPayId(newPayId);
|
||||
syncMapper.insertPayFeeNew(h);
|
||||
Long rowId = h.getNewId();
|
||||
if (rowId == null)
|
||||
{
|
||||
throw new IllegalStateException("insert pay_fee_new no id for " + row.getFeeId());
|
||||
}
|
||||
syncMapper.updatePayFeeIdEqualsId(rowId);
|
||||
payFeeMap.put(row.getFeeId(), rowId);
|
||||
}
|
||||
|
||||
syncMapper.insertArDetailNew(oldBillId, newBillId);
|
||||
|
||||
for (UuidToNewFeeRow row : syncMapper.selectArDetailFees(oldBillId))
|
||||
{
|
||||
Long newFeeId = feeMap.get(row.getFeeId());
|
||||
if (newFeeId == null)
|
||||
{
|
||||
throw new IllegalStateException("feeMap miss for ar detail fee " + row.getFeeId());
|
||||
}
|
||||
Long detailFeeId = Long.valueOf(row.getParentId());
|
||||
syncMapper.insertArDetailFeeNew(detailFeeId, newFeeId);
|
||||
}
|
||||
|
||||
for (UuidToNewFeeRow row : syncMapper.selectPayBillLines(oldBillId))
|
||||
{
|
||||
Long lineId = Long.valueOf(row.getParentId());
|
||||
Long newFeeId = null;
|
||||
if (row.getFeeId() != null && !row.getFeeId().isEmpty())
|
||||
{
|
||||
newFeeId = payFeeMap.get(row.getFeeId());
|
||||
if (newFeeId == null)
|
||||
{
|
||||
throw new IllegalStateException("payFeeMap miss for line fee " + row.getFeeId());
|
||||
}
|
||||
}
|
||||
syncMapper.insertPayBillLineNew(lineId, newBillId, newFeeId);
|
||||
}
|
||||
|
||||
syncMapper.insertBillingTaskNew(oldBillId, newBillId);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -584,7 +584,7 @@ public class PayBillServiceImpl implements IPayBillService
|
||||
adjust.setAmount(delta);
|
||||
adjust.setCurrency(line.getCurrency());
|
||||
adjust.setFeeSource("MANUAL");
|
||||
adjust.setSourceId(source != null && source.getId() != null ? String.valueOf(source.getId()) : null);
|
||||
adjust.setSourceId(source == null ? null : source.getFeeId());
|
||||
adjust.setRemark(open.getReason());
|
||||
adjust.setSettleSupplierId(bill.getSupplierId());
|
||||
adjust.setSettleSupplierName(bill.getSupplierName());
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.bms.price.task;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.bms.price.config.UuidToNewProperties;
|
||||
import com.bms.price.migration.service.IUuidToNewSyncService;
|
||||
|
||||
/**
|
||||
* UUID 阴影同步运行器:监控页开关控制;
|
||||
* 开启后立即跑批,一批结束立刻下一批;关闭后当前批结束停。
|
||||
*/
|
||||
@Component
|
||||
public class UuidToNewSyncRunner
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(UuidToNewSyncRunner.class);
|
||||
|
||||
private final AtomicBoolean wantRun = new AtomicBoolean(false);
|
||||
private final AtomicBoolean loopActive = new AtomicBoolean(false);
|
||||
|
||||
@Autowired
|
||||
private UuidToNewProperties properties;
|
||||
|
||||
@Autowired
|
||||
private IUuidToNewSyncService syncService;
|
||||
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return wantRun.get();
|
||||
}
|
||||
|
||||
public boolean isRunning()
|
||||
{
|
||||
return loopActive.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开:立即启动连续批循环;关闭:标记停止(当前批跑完)。
|
||||
*/
|
||||
public synchronized void setEnabled(boolean enabled)
|
||||
{
|
||||
wantRun.set(enabled);
|
||||
if (enabled)
|
||||
{
|
||||
startLoopIfNeeded();
|
||||
}
|
||||
else
|
||||
{
|
||||
log.info("uuid-to-new switch OFF, will stop after current batch");
|
||||
}
|
||||
}
|
||||
|
||||
private void startLoopIfNeeded()
|
||||
{
|
||||
if (!loopActive.compareAndSet(false, true))
|
||||
{
|
||||
log.info("uuid-to-new loop already running");
|
||||
return;
|
||||
}
|
||||
Thread t = new Thread(this::runLoop, "uuid-to-new-sync");
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
log.info("uuid-to-new loop started");
|
||||
}
|
||||
|
||||
private void runLoop()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (wantRun.get())
|
||||
{
|
||||
int batchSize = properties == null ? 200 : properties.resolvedBatchSize();
|
||||
int fetched = 0;
|
||||
try
|
||||
{
|
||||
fetched = syncService.syncBatch(batchSize);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("uuid-to-new batch error", e);
|
||||
}
|
||||
if (!wantRun.get())
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (fetched <= 0)
|
||||
{
|
||||
long sleepMs = properties == null ? 3000L : Math.max(500L, properties.getIdleSleepMs());
|
||||
try
|
||||
{
|
||||
Thread.sleep(sleepMs);
|
||||
}
|
||||
catch (InterruptedException ie)
|
||||
{
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// fetched > 0:立刻下一批
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
loopActive.set(false);
|
||||
log.info("uuid-to-new loop stopped");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<update id="fillSourceIdByFeeIds">
|
||||
update prc_pay_bill_fee
|
||||
set source_id = id
|
||||
set source_id = fee_id
|
||||
where (source_id is null or source_id = '')
|
||||
and fee_id in
|
||||
<foreach collection="feeIds" item="feeId" open="(" separator="," close=")">#{feeId}</foreach>
|
||||
|
||||
@@ -0,0 +1,415 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.bms.price.migration.mapper.UuidToNewSyncMapper">
|
||||
|
||||
<select id="selectPendingBillIds" resultType="String">
|
||||
select o.bill_id
|
||||
from prc_order_bill o
|
||||
left join mig_bi_order_done d on d.old_bill_id = o.bill_id
|
||||
where d.old_bill_id is null
|
||||
order by o.create_time, o.bill_id
|
||||
limit #{limit}
|
||||
</select>
|
||||
|
||||
<select id="selectOrderNo" resultType="String">
|
||||
select order_no from prc_order_bill where bill_id = #{oldBillId} limit 1
|
||||
</select>
|
||||
|
||||
<select id="countOrderBill" resultType="int">
|
||||
select count(1) from prc_order_bill where bill_id = #{oldBillId}
|
||||
</select>
|
||||
|
||||
<insert id="insertOrderBillNew" useGeneratedKeys="true" keyProperty="newBillId" keyColumn="bill_id">
|
||||
insert into prc_order_bill_new (
|
||||
bill_key, order_no, tracking_no, transfer_no,
|
||||
belong_saler, belong_saler_code, settlement_man, settlement_man_code,
|
||||
service_man, service_man_code, customer_id, customer_code,
|
||||
customer_name, pieces, actual_weight, receive_weight,
|
||||
volume, volume_weight, pkg_length, pkg_width,
|
||||
pkg_height, shipper_name, consignee_name, dest_postcode,
|
||||
warehouse_code, order_time, order_status, bl_pickup,
|
||||
pickup_date, order_remark, product_code, product_name,
|
||||
country_code, country_name, weight, biz_date,
|
||||
tms_id, product_floor_code, product_floor, price_set_id,
|
||||
price_set_code, price_set_name, set_type, bind_priority,
|
||||
customer_priceset_id, psv_id, psd_id, weight_min,
|
||||
weight_max, weight_label, effective_date, charge_weight,
|
||||
freight_rate, base_freight_rate, discount_percent, registration_fee,
|
||||
freight_amount, surcharge_amount, income_total, pay_total,
|
||||
currency, ar_bill_status, customer_active_status, credit_arrears_status,
|
||||
refund_status, billing_fail_status, error_message, round_mode,
|
||||
created_by, create_time, updated_by, update_time
|
||||
)
|
||||
select
|
||||
o.bill_key, o.order_no, o.tracking_no, o.transfer_no,
|
||||
o.belong_saler, o.belong_saler_code, o.settlement_man, o.settlement_man_code,
|
||||
o.service_man, o.service_man_code, o.customer_id, o.customer_code,
|
||||
o.customer_name, o.pieces, o.actual_weight, o.receive_weight,
|
||||
o.volume, o.volume_weight, o.pkg_length, o.pkg_width,
|
||||
o.pkg_height, o.shipper_name, o.consignee_name, o.dest_postcode,
|
||||
o.warehouse_code, o.order_time, o.order_status, o.bl_pickup,
|
||||
o.pickup_date, o.order_remark, o.product_code, o.product_name,
|
||||
o.country_code, o.country_name, o.weight, o.biz_date,
|
||||
o.tms_id, o.product_floor_code, o.product_floor, o.price_set_id,
|
||||
o.price_set_code, o.price_set_name, o.set_type, o.bind_priority,
|
||||
o.customer_priceset_id, o.psv_id, o.psd_id, o.weight_min,
|
||||
o.weight_max, o.weight_label, o.effective_date, o.charge_weight,
|
||||
o.freight_rate, o.base_freight_rate, o.discount_percent, o.registration_fee,
|
||||
o.freight_amount, o.surcharge_amount, o.income_total, o.pay_total,
|
||||
o.currency, o.ar_bill_status, o.customer_active_status, o.credit_arrears_status,
|
||||
o.refund_status, o.billing_fail_status, o.error_message, o.round_mode,
|
||||
o.created_by, o.create_time, o.updated_by, o.update_time
|
||||
from prc_order_bill o
|
||||
where o.bill_id = #{oldBillId}
|
||||
</insert>
|
||||
|
||||
<insert id="insertOrderDone">
|
||||
insert into mig_bi_order_done (old_bill_id, new_bill_id, order_no, status, fail_reason, synced_at)
|
||||
values (#{oldBillId}, #{newBillId}, #{orderNo}, #{status}, #{failReason}, now())
|
||||
</insert>
|
||||
|
||||
<insert id="claimOrderDone">
|
||||
insert ignore into mig_bi_order_done (old_bill_id, new_bill_id, order_no, status, fail_reason, synced_at)
|
||||
values (#{oldBillId}, #{newBillId}, #{orderNo}, #{status}, #{failReason}, now())
|
||||
</insert>
|
||||
|
||||
<update id="updateOrderDoneSuccess">
|
||||
update mig_bi_order_done
|
||||
set new_bill_id = #{newBillId},
|
||||
order_no = #{orderNo},
|
||||
status = 'SUCCESS',
|
||||
fail_reason = null,
|
||||
updated_at = now()
|
||||
where old_bill_id = #{oldBillId}
|
||||
</update>
|
||||
|
||||
<insert id="insertOrderExtNew">
|
||||
insert into prc_order_bill_ext_new (
|
||||
bill_id, order_no, create_time, update_time,
|
||||
upstream_id, line_no, package_num, actual_volume,
|
||||
cp_type, consignee_mobile, order_returnsign, trade_type,
|
||||
duty_type, battery_type, consignee_companyname, consignee_address,
|
||||
consignee_telephone, consignee_state, consignee_city, consignee_suburb,
|
||||
consignee_passportno, consignee_email, consignee_taxno, consignee_taxnotype,
|
||||
consignee_taxnocountry, consignee_streetno, consignee_doorno, shipper_taxnotype,
|
||||
shipper_taxno, shipper_taxnocountry, customer_id, product_imagepath,
|
||||
order_transactionurl, order_cargoamount, cargo_type, shipper_companyname,
|
||||
shipper_address1, shipper_address2, shipper_address3, shipper_city,
|
||||
shipper_state, shipper_postcode, shipper_country, shipper_telephone,
|
||||
shipper_suburb, shipper_email, shipper_passportno, import_code,
|
||||
import_name, import_companyname, import_address, import_address2,
|
||||
import_address3, import_telephone, import_email, import_postcode,
|
||||
import_city, import_state, import_country, buyerid,
|
||||
create_at, pay_type, line_code, line_name,
|
||||
product_code, product_name, product_type, line_type,
|
||||
cargo_name, order_insurance, product_sum_price, product_sum,
|
||||
shipper_doorno, tariff_payment_account, topayment, product_floor,
|
||||
latest_trajectory, way_bill, bl_baging, bag_date,
|
||||
org_order_status, status_description, zz_date, shipping_date,
|
||||
order_type, receiving_photo, freight, is_receivable,
|
||||
is_meet, bill_no_receivable, bill_no_meet, country_eingth_name,
|
||||
is_receivable_fee, settlement_fee, product_id, service_freight,
|
||||
is_pay_fee, has_added_surcharge, yf_fee, yf_totail_fee,
|
||||
trajectory_status, cargo_type_name, service_code, three_code,
|
||||
volume_height_old, volume_length_old, volume_width_old, register_man_old,
|
||||
bag_no_old, air_no_old, lading_id, box_sizi_old,
|
||||
baging_man_old, retrieval_man_old, invoice_amount_old, invoice_title_old,
|
||||
invoice_weight_old, sku_old, hs_code_old, register_date_old,
|
||||
invoice_currency_old, trajectory_sub_state, sign_in_time, warehouse_time,
|
||||
declaration_time, release_time, station_time, takeoff_time,
|
||||
landing_time, clearance_and_delivery_time, supplier_name, credit_code,
|
||||
other_id, platform_code, sync_shipment_status, update_weight,
|
||||
other_bag_no, bag_flag, online_time, outbound_time,
|
||||
air_confirm_date, shipment_type, track_query_time, air_confirm_time,
|
||||
package_type, confirm_weight, update_by, customer_pickup_site,
|
||||
barcode_number, tracking_reflect_status, remote_postcode, clearance_time,
|
||||
arrive_stock_time, departure_time, first_deliver_time, hs_code_tax_count,
|
||||
hs_code_tax_amount, hs_code_tax_currency, invoice_url, clearance_no,
|
||||
push_weight, internal_check_time, air_delay_time, first_landing_time,
|
||||
second_takeoff_time, des_port_check_time, stay_remark, miss_box_remark,
|
||||
product_channel_id, customer_track_id, register_site, package_type_financial,
|
||||
mrn, product_floor_code, order_status, pickup_date,
|
||||
bl_pickup, dimensional_weight_factor
|
||||
)
|
||||
select
|
||||
#{newBillId}, e.order_no, e.create_time, e.update_time,
|
||||
e.upstream_id, e.line_no, e.package_num, e.actual_volume,
|
||||
e.cp_type, e.consignee_mobile, e.order_returnsign, e.trade_type,
|
||||
e.duty_type, e.battery_type, e.consignee_companyname, e.consignee_address,
|
||||
e.consignee_telephone, e.consignee_state, e.consignee_city, e.consignee_suburb,
|
||||
e.consignee_passportno, e.consignee_email, e.consignee_taxno, e.consignee_taxnotype,
|
||||
e.consignee_taxnocountry, e.consignee_streetno, e.consignee_doorno, e.shipper_taxnotype,
|
||||
e.shipper_taxno, e.shipper_taxnocountry, e.customer_id, e.product_imagepath,
|
||||
e.order_transactionurl, e.order_cargoamount, e.cargo_type, e.shipper_companyname,
|
||||
e.shipper_address1, e.shipper_address2, e.shipper_address3, e.shipper_city,
|
||||
e.shipper_state, e.shipper_postcode, e.shipper_country, e.shipper_telephone,
|
||||
e.shipper_suburb, e.shipper_email, e.shipper_passportno, e.import_code,
|
||||
e.import_name, e.import_companyname, e.import_address, e.import_address2,
|
||||
e.import_address3, e.import_telephone, e.import_email, e.import_postcode,
|
||||
e.import_city, e.import_state, e.import_country, e.buyerid,
|
||||
e.create_at, e.pay_type, e.line_code, e.line_name,
|
||||
e.product_code, e.product_name, e.product_type, e.line_type,
|
||||
e.cargo_name, e.order_insurance, e.product_sum_price, e.product_sum,
|
||||
e.shipper_doorno, e.tariff_payment_account, e.topayment, e.product_floor,
|
||||
e.latest_trajectory, e.way_bill, e.bl_baging, e.bag_date,
|
||||
e.org_order_status, e.status_description, e.zz_date, e.shipping_date,
|
||||
e.order_type, e.receiving_photo, e.freight, e.is_receivable,
|
||||
e.is_meet, e.bill_no_receivable, e.bill_no_meet, e.country_eingth_name,
|
||||
e.is_receivable_fee, e.settlement_fee, e.product_id, e.service_freight,
|
||||
e.is_pay_fee, e.has_added_surcharge, e.yf_fee, e.yf_totail_fee,
|
||||
e.trajectory_status, e.cargo_type_name, e.service_code, e.three_code,
|
||||
e.volume_height_old, e.volume_length_old, e.volume_width_old, e.register_man_old,
|
||||
e.bag_no_old, e.air_no_old, e.lading_id, e.box_sizi_old,
|
||||
e.baging_man_old, e.retrieval_man_old, e.invoice_amount_old, e.invoice_title_old,
|
||||
e.invoice_weight_old, e.sku_old, e.hs_code_old, e.register_date_old,
|
||||
e.invoice_currency_old, e.trajectory_sub_state, e.sign_in_time, e.warehouse_time,
|
||||
e.declaration_time, e.release_time, e.station_time, e.takeoff_time,
|
||||
e.landing_time, e.clearance_and_delivery_time, e.supplier_name, e.credit_code,
|
||||
e.other_id, e.platform_code, e.sync_shipment_status, e.update_weight,
|
||||
e.other_bag_no, e.bag_flag, e.online_time, e.outbound_time,
|
||||
e.air_confirm_date, e.shipment_type, e.track_query_time, e.air_confirm_time,
|
||||
e.package_type, e.confirm_weight, e.update_by, e.customer_pickup_site,
|
||||
e.barcode_number, e.tracking_reflect_status, e.remote_postcode, e.clearance_time,
|
||||
e.arrive_stock_time, e.departure_time, e.first_deliver_time, e.hs_code_tax_count,
|
||||
e.hs_code_tax_amount, e.hs_code_tax_currency, e.invoice_url, e.clearance_no,
|
||||
e.push_weight, e.internal_check_time, e.air_delay_time, e.first_landing_time,
|
||||
e.second_takeoff_time, e.des_port_check_time, e.stay_remark, e.miss_box_remark,
|
||||
e.product_channel_id, e.customer_track_id, e.register_site, e.package_type_financial,
|
||||
e.mrn, e.product_floor_code, e.order_status, e.pickup_date,
|
||||
e.bl_pickup, e.dimensional_weight_factor
|
||||
from prc_order_bill_ext e
|
||||
where e.bill_id = #{oldBillId}
|
||||
</insert>
|
||||
|
||||
<select id="selectIncomeIds" resultType="String">
|
||||
select income_bill_id from prc_income_bill where bill_id = #{oldBillId}
|
||||
</select>
|
||||
|
||||
<insert id="insertIncomeBillNew" useGeneratedKeys="true" keyProperty="newId" keyColumn="income_bill_id">
|
||||
insert into prc_income_bill_new (
|
||||
bill_id, currency, product_amount, redline_amount,
|
||||
sales_amount, income_total, refund_status, belong_saler,
|
||||
belong_saler_code, settlement_man, settlement_man_code, create_by,
|
||||
create_time, update_by, update_time
|
||||
)
|
||||
select
|
||||
#{newBillId}, i.currency, i.product_amount, i.redline_amount,
|
||||
i.sales_amount, i.income_total, i.refund_status, i.belong_saler,
|
||||
i.belong_saler_code, i.settlement_man, i.settlement_man_code, i.create_by,
|
||||
i.create_time, i.update_by, i.update_time
|
||||
from prc_income_bill i
|
||||
where i.income_bill_id = #{oldId}
|
||||
</insert>
|
||||
|
||||
<select id="selectIncomeFees" resultType="com.bms.price.migration.domain.UuidToNewFeeRow">
|
||||
select fee_id as feeId, income_bill_id as parentId
|
||||
from prc_income_bill_fee
|
||||
where bill_id = #{oldBillId}
|
||||
order by fee_id
|
||||
</select>
|
||||
|
||||
<insert id="insertIncomeFeeNew" useGeneratedKeys="true" keyProperty="newId" keyColumn="fee_id">
|
||||
insert into prc_income_bill_fee_new (
|
||||
bill_id, income_bill_id, fee_type, fee_name,
|
||||
sc_id, amount, product_amount, redline_amount,
|
||||
currency, round_mode, remark, ar_bill_status,
|
||||
manual_flag, create_time
|
||||
)
|
||||
select
|
||||
#{newBillId}, #{newIncomeId}, f.fee_type, f.fee_name,
|
||||
f.sc_id, f.amount, f.product_amount, f.redline_amount,
|
||||
f.currency, f.round_mode, f.remark, f.ar_bill_status,
|
||||
f.manual_flag, f.create_time
|
||||
from prc_income_bill_fee f
|
||||
where f.fee_id = #{oldId}
|
||||
</insert>
|
||||
|
||||
<select id="selectPayIds" resultType="String">
|
||||
select pay_bill_id from prc_pay_bill where bill_id = #{oldBillId}
|
||||
</select>
|
||||
|
||||
<insert id="insertPayBillNew" useGeneratedKeys="true" keyProperty="newId" keyColumn="pay_bill_id">
|
||||
insert into prc_pay_bill_new (
|
||||
bill_id, currency, product_amount, redline_amount,
|
||||
cost_amount, pay_total, amount_a, amount_b,
|
||||
amount_c, amount_d, belong_saler, belong_saler_code,
|
||||
settlement_man, settlement_man_code, create_by, create_time,
|
||||
update_by, update_time
|
||||
)
|
||||
select
|
||||
#{newBillId}, p.currency, p.product_amount, p.redline_amount,
|
||||
p.cost_amount, p.pay_total, p.amount_a, p.amount_b,
|
||||
p.amount_c, p.amount_d, p.belong_saler, p.belong_saler_code,
|
||||
p.settlement_man, p.settlement_man_code, p.create_by, p.create_time,
|
||||
p.update_by, p.update_time
|
||||
from prc_pay_bill p
|
||||
where p.pay_bill_id = #{oldId}
|
||||
</insert>
|
||||
|
||||
<select id="selectPayFees" resultType="com.bms.price.migration.domain.UuidToNewFeeRow">
|
||||
select fee_id as feeId, pay_bill_id as parentId
|
||||
from prc_pay_bill_fee
|
||||
where bill_id = #{oldBillId}
|
||||
order by fee_id
|
||||
</select>
|
||||
|
||||
<insert id="insertPayFeeNew" useGeneratedKeys="true" keyProperty="newId" keyColumn="id">
|
||||
insert into prc_pay_bill_fee_new (
|
||||
fee_id, bill_id, pay_bill_id, fee_type,
|
||||
sc_id, fee_level, amount, currency,
|
||||
round_mode, remark, fee_source, source_id,
|
||||
is_deleted, statement_line_id, settle_supplier_id, settle_supplier_name,
|
||||
create_time
|
||||
)
|
||||
select
|
||||
0, #{newBillId}, #{newPayId}, f.fee_type,
|
||||
f.sc_id, f.fee_level, f.amount, f.currency,
|
||||
f.round_mode, f.remark, f.fee_source, f.source_id,
|
||||
f.is_deleted, f.statement_line_id, f.settle_supplier_id, f.settle_supplier_name,
|
||||
f.create_time
|
||||
from prc_pay_bill_fee f
|
||||
where f.fee_id = #{oldId}
|
||||
</insert>
|
||||
|
||||
<update id="updatePayFeeIdEqualsId">
|
||||
update prc_pay_bill_fee_new set fee_id = id where id = #{id}
|
||||
</update>
|
||||
|
||||
<insert id="insertArDetailNew">
|
||||
insert into ar_bill_detail_new (
|
||||
detail_id, ar_bill_id, prc_order_bill_id, detail_no,
|
||||
order_no, tracking_no, transfer_no, receive_time,
|
||||
product_code, product_name, goods_description, country_code,
|
||||
country_name, dest_postcode, actual_weight, receive_weight,
|
||||
volume_weight, charge_weight, freight_rate, registration_fee,
|
||||
pkg_length, pkg_width, pkg_height, currency,
|
||||
total_amount, product_amount, redline_amount, billing_fail_status,
|
||||
remark, create_by, create_time
|
||||
)
|
||||
select
|
||||
d.detail_id, d.ar_bill_id, #{newBillId}, d.detail_no,
|
||||
d.order_no, d.tracking_no, d.transfer_no, d.receive_time,
|
||||
d.product_code, d.product_name, d.goods_description, d.country_code,
|
||||
d.country_name, d.dest_postcode, d.actual_weight, d.receive_weight,
|
||||
d.volume_weight, d.charge_weight, d.freight_rate, d.registration_fee,
|
||||
d.pkg_length, d.pkg_width, d.pkg_height, d.currency,
|
||||
d.total_amount, d.product_amount, d.redline_amount, d.billing_fail_status,
|
||||
d.remark, d.create_by, d.create_time
|
||||
from ar_bill_detail d
|
||||
where d.prc_order_bill_id = #{oldBillId}
|
||||
</insert>
|
||||
|
||||
<select id="selectArDetailFees" resultType="com.bms.price.migration.domain.UuidToNewFeeRow">
|
||||
select f.prc_income_bill_fee_id as feeId, cast(f.detail_fee_id as char) as parentId
|
||||
from ar_bill_detail_fee f
|
||||
inner join ar_bill_detail d on d.detail_id = f.detail_id
|
||||
where d.prc_order_bill_id = #{oldBillId}
|
||||
order by f.detail_fee_id
|
||||
</select>
|
||||
|
||||
<insert id="insertArDetailFeeNew">
|
||||
insert into ar_bill_detail_fee_new (
|
||||
detail_fee_id, detail_id, prc_income_bill_fee_id, fee_no,
|
||||
fee_type, fee_name, sc_id, quantity,
|
||||
unit, unit_price, amount, product_amount,
|
||||
redline_amount, currency, calculation_formula, round_mode,
|
||||
remark, create_by, create_time
|
||||
)
|
||||
select
|
||||
f.detail_fee_id, f.detail_id, #{newFeeId}, f.fee_no,
|
||||
f.fee_type, f.fee_name, f.sc_id, f.quantity,
|
||||
f.unit, f.unit_price, f.amount, f.product_amount,
|
||||
f.redline_amount, f.currency, f.calculation_formula, f.round_mode,
|
||||
f.remark, f.create_by, f.create_time
|
||||
from ar_bill_detail_fee f
|
||||
where f.detail_fee_id = #{detailFeeId}
|
||||
</insert>
|
||||
|
||||
<select id="selectPayBillLines" resultType="com.bms.price.migration.domain.UuidToNewFeeRow">
|
||||
select cast(line_id as char) as parentId, fee_id as feeId
|
||||
from pay_bill_line
|
||||
where order_bill_id = #{oldBillId}
|
||||
order by line_id
|
||||
</select>
|
||||
|
||||
<insert id="insertPayBillLineNew">
|
||||
insert into pay_bill_line_new (
|
||||
line_id, bill_id, fee_id, order_bill_id,
|
||||
order_no, lading_no, lading_fee_id, fee_name,
|
||||
fee_source, fee_level, amount, supplier_amount,
|
||||
diff_amount, diff_status, tax_rate, amount_net,
|
||||
tax_amount, base_amount, currency, price_date,
|
||||
version_no, remote_flag, density_level, line_source
|
||||
)
|
||||
select
|
||||
l.line_id, l.bill_id, #{newFeeId}, #{newBillId},
|
||||
l.order_no, l.lading_no, l.lading_fee_id, l.fee_name,
|
||||
l.fee_source, l.fee_level, l.amount, l.supplier_amount,
|
||||
l.diff_amount, l.diff_status, l.tax_rate, l.amount_net,
|
||||
l.tax_amount, l.base_amount, l.currency, l.price_date,
|
||||
l.version_no, l.remote_flag, l.density_level, l.line_source
|
||||
from pay_bill_line l
|
||||
where l.line_id = #{lineId}
|
||||
</insert>
|
||||
|
||||
<insert id="insertBillingTaskNew">
|
||||
insert into prc_billing_task_new (
|
||||
task_id, transfer_no, tracking_no, order_no,
|
||||
customer_code, bill_type, success_status, bill_time,
|
||||
bill_id, fail_code, error_message, create_by,
|
||||
create_time, update_by, update_time
|
||||
)
|
||||
select
|
||||
t.task_id, t.transfer_no, t.tracking_no, t.order_no,
|
||||
t.customer_code, t.bill_type, t.success_status, t.bill_time,
|
||||
#{newBillId}, t.fail_code, t.error_message, t.create_by,
|
||||
t.create_time, t.update_by, t.update_time
|
||||
from prc_billing_task t
|
||||
where t.bill_id = #{oldBillId}
|
||||
</insert>
|
||||
|
||||
<insert id="insertJobLogStart" useGeneratedKeys="true" keyProperty="jobLogId" keyColumn="id">
|
||||
insert into mig_bi_job_log (batch_no, fetched, success, fail, skip, started_at, remark)
|
||||
values (#{batchNo}, 0, 0, 0, 0, now(), null)
|
||||
</insert>
|
||||
|
||||
<update id="updateJobLogFinish">
|
||||
update mig_bi_job_log
|
||||
set fetched = #{fetched},
|
||||
success = #{success},
|
||||
fail = #{fail},
|
||||
skip = #{skip},
|
||||
finished_at = now(),
|
||||
remark = #{failReason}
|
||||
where id = #{jobLogId}
|
||||
</update>
|
||||
|
||||
|
||||
<select id="selectProgress" resultType="com.bms.price.migration.domain.UuidToNewProgressVo">
|
||||
select
|
||||
(select count(*) from prc_order_bill) as oldCnt,
|
||||
(select count(*) from mig_bi_order_done where status = 'SUCCESS') as doneCnt,
|
||||
(select count(*) from prc_order_bill_new) as newCnt
|
||||
</select>
|
||||
|
||||
<select id="selectJobLogList" resultType="com.bms.price.migration.domain.MigBiJobLog">
|
||||
select id, batch_no as batchNo, fetched, success, fail, skip,
|
||||
started_at as startedAt, finished_at as finishedAt, remark
|
||||
from mig_bi_job_log
|
||||
<where>
|
||||
<if test="batchNo != null and batchNo != ''">
|
||||
and batch_no = #{batchNo}
|
||||
</if>
|
||||
<if test="beginStartedAt != null and beginStartedAt != ''">
|
||||
and started_at >= #{beginStartedAt}
|
||||
</if>
|
||||
<if test="endStartedAt != null and endStartedAt != ''">
|
||||
and started_at <= #{endStartedAt}
|
||||
</if>
|
||||
</where>
|
||||
order by id desc
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,381 @@
|
||||
# UUID -> bigint 阴影同步方案
|
||||
|
||||
> DDL:`20261114_uuid_to_bi_shadow_tables.sql`
|
||||
> 字段对齐**测试库** `47.106.220.100:3307/bms`(不是生产库)。
|
||||
> 测试库 `prc_pay_bill_fee` 已有 `id` 自增主键,故 `fee_id` 只改 bigint、不再设 AUTO_INCREMENT。
|
||||
|
||||
## 1. 目标
|
||||
|
||||
旧表 + 旧代码继续服务。新建 `*_new` 阴影表与定时任务先把数据拷过去;追上后再切 Long 代码并 `RENAME`。
|
||||
|
||||
要点:
|
||||
|
||||
1. `*_new` = 旧表**全字段**复制,仅 UUID 主键/外键改为 bigint
|
||||
2. **不加** `old_*` 等额外业务列
|
||||
3. 已处理 UUID **只记一张表** `mig_bi_order_done`(不建 `mig_bi_map_*`)
|
||||
4. 子表 UUID→bigint 映射仅在「一单同步事务」内存中使用,不落库
|
||||
5. 一期不改业务代码、不做换表
|
||||
|
||||
## 2. 命名
|
||||
|
||||
| 类型 | 命名 | 说明 |
|
||||
|---|---|---|
|
||||
| 阴影业务表 | `{原表}_new` | 例:`prc_order_bill_new` |
|
||||
| UUID 进度(唯一) | `mig_bi_order_done` | 已处理订单 UUID + 新 bill_id |
|
||||
| 任务日志 | `mig_bi_job_log` | 批次统计(非 UUID 映射) |
|
||||
|
||||
## 3. 表范围与改动列
|
||||
|
||||
### 3.1 核心阴影表
|
||||
|
||||
| 旧表 | 新表 | 仅改这些列 |
|
||||
|---|---|---|
|
||||
| `prc_order_bill` | `prc_order_bill_new` | `bill_id` -> bigint AI |
|
||||
| `prc_order_bill_ext` | `prc_order_bill_ext_new` | `bill_id` -> bigint |
|
||||
| `prc_income_bill` | `prc_income_bill_new` | `income_bill_id` AI;`bill_id` |
|
||||
| `prc_income_bill_fee` | `prc_income_bill_fee_new` | `fee_id` AI;`bill_id`;`income_bill_id` |
|
||||
| `prc_pay_bill` | `prc_pay_bill_new` | `pay_bill_id` AI;`bill_id` |
|
||||
| `prc_pay_bill_fee` | `prc_pay_bill_fee_new` | `fee_id`/`bill_id`/`pay_bill_id`(保留原 `id` AI) |
|
||||
|
||||
其余业务字段与旧表一致。完整列定义见 SQL。
|
||||
|
||||
### 3.2 引用类阴影表
|
||||
|
||||
| 旧表 | 新表 | 仅改这些列 |
|
||||
|---|---|---|
|
||||
| `ar_bill_detail` | `ar_bill_detail_new` | `prc_order_bill_id` |
|
||||
| `ar_bill_detail_fee` | `ar_bill_detail_fee_new` | `prc_income_bill_fee_id` |
|
||||
| `pay_bill_line` | `pay_bill_line_new` | `fee_id`、`order_bill_id` |
|
||||
| `prc_billing_task` | `prc_billing_task_new` | `bill_id` |
|
||||
| `ar_bill_generate_task` | `ar_bill_generate_task_new` | `last_source_bill_id` |
|
||||
|
||||
### 3.3 本期不动
|
||||
|
||||
`prc_quote*`;`ar_bill` / `pay_bill` 等已是 bigint 的账单主表。
|
||||
|
||||
### 3.4 控制表
|
||||
|
||||
**mig_bi_order_done**(唯一 UUID 追踪表)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| old_bill_id | varchar(36) PK | 原订单 UUID |
|
||||
| new_bill_id | bigint UK | 新订单 ID |
|
||||
| order_no | varchar(64) | 订单号 |
|
||||
| status | varchar(20) | SUCCESS / FAIL / SKIP |
|
||||
| fail_reason | varchar(500) | 失败原因 |
|
||||
| synced_at / updated_at | datetime | 时间 |
|
||||
|
||||
**mig_bi_job_log**:batch_no、fetched/success/fail/skip、started_at/finished_at、remark。
|
||||
|
||||
合计:控制 2 张 + 业务阴影 11 张。不建 `mig_bi_map_*`。
|
||||
|
||||
## 4. 建表原则
|
||||
|
||||
1. 全字段复制旧表(对齐测试库结构)
|
||||
2. 只改 UUID(varchar36)主键/外键为 bigint
|
||||
3. 业务 `*_new` **不增加**任何额外列
|
||||
4. 已处理订单只写 `mig_bi_order_done`;子表映射不落库
|
||||
5. 不建指向旧表的外键
|
||||
|
||||
## 5. 定时同步逻辑
|
||||
|
||||
### 5.1 运行约定
|
||||
|
||||
| 项 | 约定 |
|
||||
|---|---|
|
||||
| 入口类(拟) | `UuidToNewSyncRunner` / `UuidToNewSyncServiceImpl` |
|
||||
| 调度 | 监控页开关;开启后连续跑批(无 cron) |
|
||||
| 开关 | 监控页「连续同步」开关 / API `POST /monitor/uuidToNew/enabled` |
|
||||
| 批次 | `bms.mig.uuid-to-new.batch-size`(建议 200) |
|
||||
| 并发 | **单线程**:上一轮未结束不启下一轮 |
|
||||
| 事务 | **一单一事务**;失败整单回滚 |
|
||||
| 映射 | 内存 `Map<oldUuid, newId>`,事务结束即丢弃 |
|
||||
|
||||
### 5.2 总流程图
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[监控页打开开关] --> B{开关 enabled?}
|
||||
B -->|否| Z[直接结束]
|
||||
B -->|是| C{获取单机锁/防并发}
|
||||
C -->|未拿到| Z
|
||||
C -->|拿到| D[写 job_log: started<br/>生成 batch_no]
|
||||
D --> E[查询未处理订单<br/>LEFT JOIN mig_bi_order_done<br/>LIMIT batchSize]
|
||||
E --> F{fetched == 0?}
|
||||
F -->|是| G[job_log: success=0 结束]
|
||||
F -->|否| H[逐单循环]
|
||||
H --> I[syncOneOrder 一单一事务]
|
||||
I --> J{结果}
|
||||
J -->|SUCCESS| K[success++]
|
||||
J -->|FAIL| L[fail++<br/>记日志/可选写 FAIL 行]
|
||||
J -->|SKIP| M[skip++]
|
||||
K --> N{还有下一单?}
|
||||
L --> N
|
||||
M --> N
|
||||
N -->|是| H
|
||||
N -->|否| O[更新 mig_bi_job_log<br/>finished + 计数]
|
||||
O --> P[释放锁]
|
||||
P --> Z2[本轮结束]
|
||||
G --> P
|
||||
```
|
||||
|
||||
### 5.3 单订单同步流程图(syncOneOrder)
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
S[开始: oldBillId] --> T[开启事务]
|
||||
T --> U[内存 Map 清空<br/>income/pay/fee 映射]
|
||||
U --> V[读旧 prc_order_bill]
|
||||
V --> W{订单存在?}
|
||||
W -->|否| X[SKIP / 回滚]
|
||||
W -->|是| Y[INSERT prc_order_bill_new<br/>拿到 newBillId]
|
||||
Y --> Z1[INSERT mig_bi_order_done<br/>SUCCESS + newBillId]
|
||||
Z1 --> A1[拷贝 prc_order_bill_ext_new<br/>bill_id=newBillId]
|
||||
A1 --> B1[拷贝应收 prc_income_bill_new<br/>内存记 income 映射]
|
||||
B1 --> C1[拷贝 prc_income_bill_fee_new<br/>内存记 fee 映射]
|
||||
C1 --> D1[拷贝应付 prc_pay_bill_new<br/>内存记 pay 映射]
|
||||
D1 --> E1[拷贝 prc_pay_bill_fee_new<br/>内存记 payFee 映射]
|
||||
E1 --> F1[拷贝 ar_bill_detail_new<br/>prc_order_bill_id=newBillId]
|
||||
F1 --> G1[拷贝 ar_bill_detail_fee_new<br/>fee 外键用内存 map]
|
||||
G1 --> H1[拷贝 pay_bill_line_new<br/>fee_id/order_bill_id 用 map]
|
||||
H1 --> I1[可选: billing_task /<br/>ar_bill_generate_task]
|
||||
I1 --> J1[提交事务]
|
||||
J1 --> K1[返回 SUCCESS]
|
||||
X --> L1[返回 SKIP]
|
||||
V -.->|任意步骤异常| R1[整单回滚]
|
||||
R1 --> R2[返回 FAIL<br/>可另事务写 FAIL 到 done]
|
||||
```
|
||||
|
||||
### 5.4 抓单 SQL
|
||||
|
||||
```sql
|
||||
SELECT o.bill_id
|
||||
FROM prc_order_bill o
|
||||
LEFT JOIN mig_bi_order_done d ON d.old_bill_id = o.bill_id
|
||||
WHERE d.old_bill_id IS NULL
|
||||
ORDER BY o.create_time, o.bill_id
|
||||
LIMIT :batchSize;
|
||||
```
|
||||
|
||||
### 5.5 单订单写入顺序
|
||||
|
||||
```text
|
||||
1. prc_order_bill_new -> newBillId(AI)
|
||||
2. mig_bi_order_done -> oldBillId / newBillId / SUCCESS
|
||||
3. prc_order_bill_ext_new -> bill_id = newBillId
|
||||
4. prc_income_bill_new -> 内存 map: oldIncomeId -> newIncomeId
|
||||
5. prc_income_bill_fee_new -> bill_id/income_bill_id 用 map;内存记 fee
|
||||
6. prc_pay_bill_new -> 内存 map: oldPayId -> newPayId
|
||||
7. prc_pay_bill_fee_new -> bill_id/pay_bill_id 用 map;内存记 payFee
|
||||
8. ar_bill_detail_new -> prc_order_bill_id = newBillId
|
||||
9. ar_bill_detail_fee_new -> prc_income_bill_fee_id 用 fee map
|
||||
10. pay_bill_line_new -> fee_id / order_bill_id 用 map
|
||||
11. (可选)prc_billing_task_new / ar_bill_generate_task_new
|
||||
```
|
||||
|
||||
### 5.6 实例讲解(一单走完)
|
||||
|
||||
假设本轮 `batchSize=200`,抓到其中一单如下(简化 ID,仅演示映射关系)。
|
||||
|
||||
#### 旧库里已有(UUID)
|
||||
|
||||
| 表 | 主键 UUID | 关联 |
|
||||
|---|---|---|
|
||||
| `prc_order_bill` | `bill_id = aaa-001` | order_no=`O20261114001` |
|
||||
| `prc_order_bill_ext` | 同行 `bill_id=aaa-001` | |
|
||||
| `prc_income_bill` | `income_bill_id = iii-001` | `bill_id=aaa-001` |
|
||||
| `prc_income_bill_fee` | `fee_id = iff-101` | `bill_id=aaa-001`,`income_bill_id=iii-001` |
|
||||
| `prc_income_bill_fee` | `fee_id = iff-102` | 同上,另一费用行 |
|
||||
| `prc_pay_bill` | `pay_bill_id = ppp-001` | `bill_id=aaa-001` |
|
||||
| `prc_pay_bill_fee` | `fee_id = pff-201` | `bill_id=aaa-001`,`pay_bill_id=ppp-001` |
|
||||
| `ar_bill_detail` | (自有 bigint PK) | `prc_order_bill_id=aaa-001` |
|
||||
| `ar_bill_detail_fee` | (自有 bigint PK) | `prc_income_bill_fee_id=iff-101` |
|
||||
| `pay_bill_line` | (自有 bigint PK) | `order_bill_id=aaa-001`,`fee_id=pff-201` |
|
||||
|
||||
`mig_bi_order_done` 里还没有 `aaa-001` → 本轮会被抓到。
|
||||
|
||||
#### 同步过程(一单一事务)
|
||||
|
||||
```text
|
||||
步骤0 内存 Map 清空
|
||||
incomeMap={}, feeMap={}, payMap={}, payFeeMap={}
|
||||
|
||||
步骤1 INSERT prc_order_bill_new
|
||||
(其它业务字段从旧行原样拷)
|
||||
AI 得到 newBillId = 10001
|
||||
内存:本单 newBillId=10001
|
||||
|
||||
步骤2 INSERT mig_bi_order_done
|
||||
old_bill_id=aaa-001, new_bill_id=10001, order_no=O20261114001, status=SUCCESS
|
||||
|
||||
步骤3 INSERT prc_order_bill_ext_new
|
||||
bill_id = 10001 ← 已不是 aaa-001
|
||||
|
||||
步骤4 INSERT prc_income_bill_new
|
||||
AI 得到 newIncomeId = 20001
|
||||
bill_id = 10001
|
||||
内存:incomeMap[iii-001] = 20001
|
||||
|
||||
步骤5 INSERT prc_income_bill_fee_new ×2
|
||||
iff-101 → AI newFeeId=30001;bill_id=10001;income_bill_id=20001
|
||||
iff-102 → AI newFeeId=30002;bill_id=10001;income_bill_id=20001
|
||||
内存:feeMap[iff-101]=30001, feeMap[iff-102]=30002
|
||||
|
||||
步骤6 INSERT prc_pay_bill_new
|
||||
AI 得到 newPayId = 40001
|
||||
bill_id = 10001
|
||||
内存:payMap[ppp-001] = 40001
|
||||
|
||||
步骤7 INSERT prc_pay_bill_fee_new
|
||||
pff-201 → AI newPayFeeId=50001;bill_id=10001;pay_bill_id=40001
|
||||
内存:payFeeMap[pff-201] = 50001
|
||||
(测试库该表另有 id AI,照旧拷,与 fee_id 无关)
|
||||
|
||||
步骤8 INSERT ar_bill_detail_new
|
||||
prc_order_bill_id = 10001 ← 用 newBillId,不是 aaa-001
|
||||
|
||||
步骤9 INSERT ar_bill_detail_fee_new
|
||||
prc_income_bill_fee_id = 30001 ← feeMap[iff-101],不是 iff-101
|
||||
|
||||
步骤10 INSERT pay_bill_line_new
|
||||
order_bill_id = 10001
|
||||
fee_id = 50001 ← payFeeMap[pff-201]
|
||||
|
||||
步骤11 (可选)billing_task / generate_task 同类替换 bill_id
|
||||
|
||||
步骤12 COMMIT
|
||||
内存 Map 丢弃;下次再同步别的单重新建 Map
|
||||
```
|
||||
|
||||
#### 同步后对照
|
||||
|
||||
| 含义 | 旧 UUID | 新 bigint |
|
||||
|---|---|---|
|
||||
| 订单 | aaa-001 | **10001**(落在 `mig_bi_order_done`) |
|
||||
| 应收主 | iii-001 | 20001(仅内存用过,不落 map 表) |
|
||||
| 应收费用 | iff-101 / iff-102 | 30001 / 30002 |
|
||||
| 应付主 | ppp-001 | 40001 |
|
||||
| 应付费用 | pff-201 | 50001 |
|
||||
|
||||
旧表 `prc_order_bill` 等**一行未改**;现网代码仍读旧 UUID 表。
|
||||
|
||||
#### 下一轮会怎样
|
||||
|
||||
- 抓单 SQL 再 LEFT JOIN `mig_bi_order_done`:`aaa-001` 已存在 → **不会再抓**
|
||||
- 若步骤 5 抛错:整单 ROLLBACK → `*_new` 与 `done` 都没有这单 → 下轮还会抓到 `aaa-001` 重试
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph OLD[旧表 UUID]
|
||||
O1[aaa-001 订单]
|
||||
O2[iii-001 应收]
|
||||
O3[iff-101 应收费]
|
||||
O4[ppp-001 应付]
|
||||
O5[pff-201 应付费]
|
||||
end
|
||||
subgraph MEM[本单内存 Map]
|
||||
M1[aaa-001→10001]
|
||||
M2[iii-001→20001]
|
||||
M3[iff-101→30001]
|
||||
M4[ppp-001→40001]
|
||||
M5[pff-201→50001]
|
||||
end
|
||||
subgraph NEW[阴影表 bigint]
|
||||
N1[order_new 10001]
|
||||
N2[income_new 20001]
|
||||
N3[income_fee_new 30001]
|
||||
N4[pay_new 40001]
|
||||
N5[pay_fee_new 50001]
|
||||
N6[done: aaa-001→10001]
|
||||
end
|
||||
O1 --> M1 --> N1
|
||||
O1 --> N6
|
||||
O2 --> M2 --> N2
|
||||
O3 --> M3 --> N3
|
||||
O4 --> M4 --> N4
|
||||
O5 --> M5 --> N5
|
||||
```
|
||||
|
||||
|
||||
### 5.7 幂等与失败
|
||||
|
||||
| 场景 | 处理 |
|
||||
|---|---|
|
||||
| 已在 `mig_bi_order_done` | 抓单 SQL 自动排除,不重复拷 |
|
||||
| 单步异常 | 整单回滚;业务 `*_new` 不留半成品 |
|
||||
| 记 FAIL | 另开短事务写 `status=FAIL`(可选);否则下轮会再抓到 |
|
||||
| 人工重跑某单 | 先按 `new_bill_id` 删该单 `*_new` 行 + 删 `done`,再跑任务 |
|
||||
| 内存 map | 仅本单事务内有效;不落 `mig_bi_map_*` |
|
||||
|
||||
### 5.8 积压监控
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
(SELECT COUNT(*) FROM prc_order_bill) AS old_cnt,
|
||||
(SELECT COUNT(*) FROM mig_bi_order_done WHERE status='SUCCESS') AS done_cnt,
|
||||
(SELECT COUNT(*) FROM prc_order_bill_new) AS new_cnt;
|
||||
```
|
||||
|
||||
`old_cnt - done_cnt` 为积压;趋近 0 且抽查一致后再进二期。
|
||||
|
||||
### 5.9 已实现类(一期)
|
||||
|
||||
```text
|
||||
com.bms.price.task.UuidToNewSyncRunner
|
||||
com.bms.price.migration.service.IUuidToNewSyncService
|
||||
com.bms.price.migration.service.impl.UuidToNewSyncServiceImpl
|
||||
com.bms.price.migration.mapper.UuidToNewSyncMapper
|
||||
mapper/price/UuidToNewSyncMapper.xml
|
||||
com.bms.price.config.UuidToNewProperties
|
||||
```
|
||||
|
||||
配置(`application.yml`,默认关闭):
|
||||
|
||||
```yaml
|
||||
bms:
|
||||
mig:
|
||||
uuid-to-new:
|
||||
enabled: false
|
||||
batch-size: 200
|
||||
thread-count: 2 # 1~4ï¼4æ ¸8G å²åºå»ºè®® 2~3
|
||||
cron: "0/30 * * * * ?"
|
||||
```
|
||||
|
||||
æ¹å
å¤çº¿ç¨ï¼å
䏿¬¡æåï¼ååç» N 个工ä½çº¿ç¨ï¼æ¯å `INSERT IGNORE` å å `mig_bi_order_done(RUNNING)`ï¼é¿å
éå¤å¤çã
|
||||
|
||||
启用前:先在测库执行 `20261114_uuid_to_bi_shadow_tables.sql`,再把 `enabled` 改 `true`。
|
||||
|
||||
业务 Domain / 现网读写路径一期**不动**。
|
||||
|
||||
|
||||
|
||||
|
||||
### 5.10 监控菜单
|
||||
|
||||
- 页面:`monitor/uuidToNew/index`
|
||||
- 菜单:合并在 `20261114_uuid_to_bi_shadow_tables.sql` 文件末尾
|
||||
- API:`GET /monitor/uuidToNew/progress`、`GET /monitor/uuidToNew/jobLog/list`、`POST /monitor/uuidToNew/enabled`
|
||||
- 开关权限:`monitor:uuidToNew:switch`(见 `20261114_uuid_to_bi_shadow_tables.sql` 末尾菜单段)
|
||||
|
||||
## 6. 一期 / 二期
|
||||
|
||||
**一期(不影响现网)**
|
||||
|
||||
1. 测库执行 DDL
|
||||
2. ~~实现 Job/Service/Mapper~~(已完成,见 §5.9)
|
||||
3. 测库开启 `bms.mig.uuid-to-new.enabled=true` 并看 `mig_bi_job_log`
|
||||
4. 不改业务 Domain,不做 RENAME
|
||||
|
||||
**二期切换**
|
||||
|
||||
1. lag=0 并校验
|
||||
2. 发布 Long 代码
|
||||
3. `RENAME`:`xxx` → `xxx_uuid_bak`,`xxx_new` → `xxx`
|
||||
4. 冒烟后删备份与 `mig_bi_*`
|
||||
|
||||
## 7. 风险与验收
|
||||
|
||||
风险:磁盘约翻倍;仅任务写 `*_new`;一单事务内内存 map 丢失则整单回滚重试。
|
||||
|
||||
验收:DDL 成功;任务稳定;done 追上订单量;抽查一致;旧功能正常。
|
||||
@@ -0,0 +1,651 @@
|
||||
-- 方案文档:20261114_uuid_to_bi_shadow_dev.md
|
||||
-- 含:阴影表 DDL + 监控菜单
|
||||
-- 阴影表 DDL:字段结构对齐【测试库】47.106.220.100:3307/bms
|
||||
-- 全字段复制;仅 UUID(varchar36) 相关列改为 bigint;不加 old_*
|
||||
-- UUID 追踪仅 mig_bi_order_done;无 mig_bi_map_*;无外键;旧表不动
|
||||
-- 注意:测试库 prc_pay_bill_fee 已有 id AI 主键,fee_id 只改 bigint 不设 AI
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
|
||||
-- ========== 控制表 ==========
|
||||
DROP TABLE IF EXISTS `mig_bi_job_log`;
|
||||
DROP TABLE IF EXISTS `mig_bi_order_done`;
|
||||
|
||||
CREATE TABLE `mig_bi_order_done` (
|
||||
`old_bill_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '原订单UUID',
|
||||
`new_bill_id` bigint NOT NULL COMMENT '新订单bigint',
|
||||
`order_no` varchar(64) DEFAULT NULL COMMENT '订单号',
|
||||
`status` varchar(20) NOT NULL DEFAULT 'SUCCESS' COMMENT 'SUCCESS/FAIL/SKIP',
|
||||
`fail_reason` varchar(500) DEFAULT NULL COMMENT '失败原因',
|
||||
`synced_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '同步时间',
|
||||
`updated_at` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`old_bill_id`),
|
||||
UNIQUE KEY `uk_mig_bi_order_new` (`new_bill_id`),
|
||||
KEY `idx_mig_bi_order_synced` (`synced_at`),
|
||||
KEY `idx_mig_bi_order_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='已处理订单UUID进度(唯一 UUID 追踪表)';
|
||||
|
||||
CREATE TABLE `mig_bi_job_log` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`batch_no` varchar(64) NOT NULL COMMENT '批次号',
|
||||
`fetched` int NOT NULL DEFAULT 0 COMMENT '抓取数',
|
||||
`success` int NOT NULL DEFAULT 0 COMMENT '成功数',
|
||||
`fail` int NOT NULL DEFAULT 0 COMMENT '失败数',
|
||||
`skip` int NOT NULL DEFAULT 0 COMMENT '跳过数',
|
||||
`started_at` datetime NOT NULL COMMENT '开始时间',
|
||||
`finished_at` datetime DEFAULT NULL COMMENT '结束时间',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_mig_bi_job_started` (`started_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='同步任务批次日志';
|
||||
|
||||
|
||||
-- ========== 业务阴影表(结构对齐测试库)==========
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `prc_order_bill_new`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prc_order_bill_new` (
|
||||
`bill_id` bigint NOT NULL AUTO_INCREMENT COMMENT '计费ID',
|
||||
`bill_key` char(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'MD5(order_no)',
|
||||
`order_no` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '订单号',
|
||||
`tracking_no` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '运单号',
|
||||
`transfer_no` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '转单号',
|
||||
`belong_saler` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '所属销售员',
|
||||
`belong_saler_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '销售员编码',
|
||||
`settlement_man` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '结算员',
|
||||
`settlement_man_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '结算员编码',
|
||||
`service_man` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客服员',
|
||||
`service_man_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客服员编码',
|
||||
`customer_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '客户ID',
|
||||
`customer_code` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户代码',
|
||||
`customer_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户名称',
|
||||
`pieces` int(11) DEFAULT NULL COMMENT '件数',
|
||||
`actual_weight` decimal(10,3) DEFAULT NULL COMMENT '实际重量KG',
|
||||
`receive_weight` decimal(10,3) DEFAULT NULL COMMENT '收货重KG(上游TAB_ORDER.WEIGHT)',
|
||||
`volume` decimal(12,4) DEFAULT NULL COMMENT '体积m3',
|
||||
`volume_weight` decimal(10,3) DEFAULT NULL COMMENT '材积重KG',
|
||||
`pkg_length` decimal(10,2) DEFAULT NULL COMMENT '长CM',
|
||||
`pkg_width` decimal(10,2) DEFAULT NULL COMMENT '宽CM',
|
||||
`pkg_height` decimal(10,2) DEFAULT NULL COMMENT '高CM',
|
||||
`shipper_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人',
|
||||
`consignee_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人',
|
||||
`dest_postcode` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '目的邮编',
|
||||
`warehouse_code` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '仓库',
|
||||
`order_time` datetime DEFAULT NULL COMMENT '下单时间',
|
||||
`order_status` int(11) DEFAULT NULL COMMENT '上游订单状态',
|
||||
`bl_pickup` tinyint(4) DEFAULT NULL COMMENT '是否收货:0否/1是',
|
||||
`pickup_date` datetime DEFAULT NULL COMMENT '收货时间',
|
||||
`order_remark` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '订单备注',
|
||||
`product_code` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '产品代码',
|
||||
`product_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '产品名称',
|
||||
`country_code` char(2) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '国家二字码',
|
||||
`country_name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '国家名称',
|
||||
`weight` decimal(10,3) DEFAULT NULL COMMENT '计费重量KG',
|
||||
`biz_date` datetime NOT NULL COMMENT '计费时间',
|
||||
`tms_id` bigint(20) DEFAULT NULL COMMENT '多租户系统ID',
|
||||
`product_floor_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '渠道编码',
|
||||
`product_floor` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '渠道名称',
|
||||
`price_set_id` bigint(20) DEFAULT NULL COMMENT '价格套餐ID',
|
||||
`price_set_code` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '套餐编码',
|
||||
`price_set_name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '套餐名称',
|
||||
`set_type` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '计价类型',
|
||||
`bind_priority` int(11) DEFAULT NULL COMMENT '客户套餐优先级',
|
||||
`customer_priceset_id` bigint(20) DEFAULT NULL COMMENT '客户套餐绑定ID',
|
||||
`psv_id` bigint(20) DEFAULT NULL COMMENT '套餐版本ID,对应 prc_price_set_version.psv_id',
|
||||
`psd_id` bigint(20) DEFAULT NULL COMMENT '套餐明细ID,对应 prc_price_set_detail.psd_id',
|
||||
`weight_min` decimal(10,4) DEFAULT NULL COMMENT '重量段下限',
|
||||
`weight_max` decimal(10,4) DEFAULT NULL COMMENT '重量段上限',
|
||||
`weight_label` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '重量段展示',
|
||||
`effective_date` date DEFAULT NULL COMMENT '产品明细生效日',
|
||||
`charge_weight` decimal(10,3) DEFAULT NULL COMMENT '计费重量',
|
||||
`freight_rate` decimal(10,4) DEFAULT NULL COMMENT '运费单价',
|
||||
`base_freight_rate` decimal(10,4) DEFAULT NULL COMMENT '折扣前单价',
|
||||
`discount_percent` decimal(5,2) DEFAULT NULL COMMENT '折扣百分数',
|
||||
`registration_fee` decimal(10,2) DEFAULT NULL COMMENT '挂号费',
|
||||
`freight_amount` decimal(10,2) DEFAULT NULL COMMENT '运费金额',
|
||||
`surcharge_amount` decimal(10,2) DEFAULT NULL COMMENT '附加费合计',
|
||||
`income_total` decimal(10,2) DEFAULT NULL COMMENT '应收总额',
|
||||
`pay_total` decimal(10,2) DEFAULT NULL COMMENT '应付总额',
|
||||
`currency` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'CNY' COMMENT '币种',
|
||||
`ar_bill_status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'UNBILLED' COMMENT '应收账单状态:UNBILLED未出账/PARTIAL部分出账/BILLED已出账',
|
||||
`customer_active_status` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户生效状态:ACTIVE正常 MISSING不存在 DISABLED停用',
|
||||
`credit_arrears_status` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '额度欠费状态:NORMAL正常 ARREARS欠费',
|
||||
`refund_status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'NONE' COMMENT '退费状态:NONE未退费/REFUNDED已退费',
|
||||
`billing_fail_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '计费失败状态:0成功/1销售价未匹配产品/2销售价未匹配国家/3销售价未匹配重量段/23产品价未匹配产品/24产品价未匹配国家/25产品价未匹配重量段/4未绑定套餐/5无生效套餐版本/6已生成应收账单/7产品档案缺失/8未命中价格/9分区无价格/10邮编必填/11邮编未匹配分区/12上游订单不存在/13上游订单号为空/14上游客户为空/15上游产品为空/16上游重量无效/17计费时间为空/18退费订单无法解析/19客户代码为空/20客户已停用/21运费为空/22未知失败/26未计费。仅0/1/2/3/23/24/25写入应收主表,仅0写入应收费用',
|
||||
`error_message` varchar(1000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '失败原因',
|
||||
`round_mode` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'HALF_UP' COMMENT '取值方式',
|
||||
`created_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建人',
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`updated_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新人',
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`bill_id`) USING BTREE,
|
||||
UNIQUE KEY `uk_bill_order` (`order_no`) USING BTREE,
|
||||
UNIQUE KEY `uk_bill_key` (`bill_key`) USING BTREE,
|
||||
KEY `idx_bill_customer` (`customer_code`,`biz_date`) USING BTREE,
|
||||
KEY `idx_bill_product` (`product_code`,`country_code`) USING BTREE,
|
||||
KEY `idx_bill_ar_status` (`customer_id`,`currency`,`ar_bill_status`,`biz_date`) USING BTREE,
|
||||
KEY `idx_bill_ar_async_cursor` (`customer_id`,`currency`,`ar_bill_status`,`create_time`,`bill_id`) USING BTREE,
|
||||
KEY `idx_order_bill_transfer_no` (`transfer_no`) USING BTREE,
|
||||
KEY `idx_order_bill_customer_active` (`customer_active_status`) USING BTREE,
|
||||
KEY `idx_order_bill_credit_arrears` (`credit_arrears_status`) USING BTREE,
|
||||
KEY `idx_order_bill_psv` (`psv_id`) USING BTREE,
|
||||
KEY `idx_order_bill_psd` (`psd_id`) USING BTREE,
|
||||
KEY `idx_ar_order_bill_status_scope` (`customer_id`,`currency`,`ar_bill_status`,`biz_date`,`bill_id`) USING BTREE,
|
||||
KEY `idx_order_bill_refund_status` (`refund_status`) USING BTREE,
|
||||
KEY `idx_bill_biz_date_report` (`biz_date`,`bill_id`) USING BTREE,
|
||||
KEY `idx_order_bill_billing_fail_status` (`billing_fail_status`) USING BTREE,
|
||||
KEY `idx_order_bill_tracking_no` (`tracking_no`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='订单信息主表';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `prc_order_bill_ext_new`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prc_order_bill_ext_new` (
|
||||
`bill_id` bigint NOT NULL COMMENT '计费订单ID',
|
||||
`order_no` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '订单号',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`upstream_id` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'guid',
|
||||
`line_no` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '线路',
|
||||
`package_num` int(11) DEFAULT NULL COMMENT '包裹数量',
|
||||
`actual_volume` decimal(10,3) DEFAULT NULL COMMENT '实际体积重',
|
||||
`cp_type` tinyint(4) DEFAULT NULL COMMENT '线路产品类型 1全程 2干线 3尾程',
|
||||
`consignee_mobile` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人手机',
|
||||
`order_returnsign` char(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '退回标志,默认N表示不退回,Y标表示退回。中邮可以忽略该属性',
|
||||
`trade_type` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '交易类型,值为ZYXT',
|
||||
`duty_type` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '关税类型,值为DDU或DDP',
|
||||
`battery_type` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '电池类型代码,联系货代提供',
|
||||
`consignee_companyname` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件公司名,如有最好填写',
|
||||
`consignee_address` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件地址街道,必填',
|
||||
`consignee_telephone` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件电话,必填',
|
||||
`consignee_state` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '州/省',
|
||||
`consignee_city` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '城市',
|
||||
`consignee_suburb` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件区,选填',
|
||||
`consignee_passportno` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件护照号,选填',
|
||||
`consignee_email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '邮箱,选填',
|
||||
`consignee_taxno` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人税号',
|
||||
`consignee_taxnotype` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人税号类型',
|
||||
`consignee_taxnocountry` varchar(2) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人税号国家',
|
||||
`consignee_streetno` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '街道号',
|
||||
`consignee_doorno` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '门牌号',
|
||||
`shipper_taxnotype` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '税号类型,邮政产品可选值:IOSS,NO - IOSS,OTHER;DHL可选值:SDT、VAT、FTZ、DAN、EOR、CNP、EIN等(类型说明参照文档底部“DHL发件人税号类型”)',
|
||||
`shipper_taxno` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人税号',
|
||||
`shipper_taxnocountry` varchar(2) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人税号国家,用国家二字码',
|
||||
`customer_id` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户ID,必填',
|
||||
`product_imagepath` text COLLATE utf8mb4_unicode_ci COMMENT '图片地址,多图片地址用分号隔开',
|
||||
`order_transactionurl` text COLLATE utf8mb4_unicode_ci COMMENT '产品销售地址',
|
||||
`order_cargoamount` decimal(12,5) DEFAULT NULL COMMENT '选填;用于DHL/FEDEX运费;或用于白关申报(订单实际金额,特殊渠道使用);或其他用途',
|
||||
`cargo_type` char(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '包裹类型,P代表包裹,D代表文件,B代表PAK袋',
|
||||
`shipper_companyname` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人公司名,选填',
|
||||
`shipper_address1` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人地址1,选填',
|
||||
`shipper_address2` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人地址2,选填',
|
||||
`shipper_address3` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人地址3,选填',
|
||||
`shipper_city` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人城市,选填',
|
||||
`shipper_state` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人州,选填',
|
||||
`shipper_postcode` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人邮编,选填',
|
||||
`shipper_country` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人国家,选填',
|
||||
`shipper_telephone` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人电话,选填',
|
||||
`shipper_suburb` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人区,选填',
|
||||
`shipper_email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人邮箱,选填',
|
||||
`shipper_passportno` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人护照号,选填',
|
||||
`import_code` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '进口商代码',
|
||||
`import_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '进口商名称',
|
||||
`import_companyname` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '进口商公司名称',
|
||||
`import_address` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '进口商地址',
|
||||
`import_address2` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '进口商地址2',
|
||||
`import_address3` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '进口商地址3',
|
||||
`import_telephone` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '进口商电话',
|
||||
`import_email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '进口商邮箱',
|
||||
`import_postcode` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '进口商邮编',
|
||||
`import_city` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '进口商城市',
|
||||
`import_state` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '进口商州省',
|
||||
`import_country` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '进口商国家',
|
||||
`buyerid` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '买家ID',
|
||||
`create_at` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建人',
|
||||
`pay_type` tinyint(4) DEFAULT NULL COMMENT '付款方式 0-预付 1-到付',
|
||||
`line_code` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '线路产品编号',
|
||||
`line_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '线路产品名称',
|
||||
`product_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '上游产品代码',
|
||||
`product_name` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '上游产品名称',
|
||||
`product_type` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '产品类型(全称产品/全称B2B/尾程产品)',
|
||||
`line_type` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流模式(国际快递/邮政小包)',
|
||||
`cargo_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '货物类型(普货/敏感/特货)',
|
||||
`order_insurance` decimal(12,5) DEFAULT NULL COMMENT '保险金额',
|
||||
`product_sum_price` decimal(12,5) DEFAULT NULL COMMENT '商品总价值',
|
||||
`product_sum` decimal(18,6) DEFAULT NULL COMMENT '商品总件数',
|
||||
`shipper_doorno` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发件人门牌号',
|
||||
`tariff_payment_account` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '关税支付账号',
|
||||
`topayment` decimal(12,5) DEFAULT NULL COMMENT '代收货款',
|
||||
`product_floor` text COLLATE utf8mb4_unicode_ci COMMENT '渠道名称',
|
||||
`latest_trajectory` text COLLATE utf8mb4_unicode_ci COMMENT '订单轨迹',
|
||||
`way_bill` text COLLATE utf8mb4_unicode_ci COMMENT '电子面单',
|
||||
`bl_baging` tinyint(4) DEFAULT NULL COMMENT '是否装箱 0 未装箱 1 已装箱',
|
||||
`bag_date` datetime DEFAULT NULL COMMENT '装箱时间',
|
||||
`org_order_status` tinyint(4) DEFAULT NULL COMMENT '渠道状态 0-未下单 1-获取中 2-获取成功 3-获取失败',
|
||||
`status_description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '状态描述,对当前轨迹状态的详细说明',
|
||||
`zz_date` datetime DEFAULT NULL COMMENT '中转时间',
|
||||
`shipping_date` datetime DEFAULT NULL COMMENT '出货时间',
|
||||
`order_type` decimal(18,6) DEFAULT NULL COMMENT '0-中性面单 1-尾程面单',
|
||||
`receiving_photo` text COLLATE utf8mb4_unicode_ci COMMENT '收货照片',
|
||||
`freight` decimal(10,3) DEFAULT NULL COMMENT '应收总运费',
|
||||
`is_receivable` tinyint(4) DEFAULT NULL COMMENT '是否已经生成应收账单[0.未生成,1.已生成]',
|
||||
`is_meet` tinyint(4) DEFAULT NULL COMMENT '是否已经生成应付账单[0.未生成,1.已生成]',
|
||||
`bill_no_receivable` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '应收账单编号',
|
||||
`bill_no_meet` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '应付账单编号',
|
||||
`country_eingth_name` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收件人英文国家名称',
|
||||
`is_receivable_fee` tinyint(4) DEFAULT NULL COMMENT '是否已计算应收费用0-未计算 1-已计算',
|
||||
`settlement_fee` decimal(10,3) DEFAULT NULL COMMENT '应收运费',
|
||||
`product_id` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '中转产品ID',
|
||||
`service_freight` decimal(10,3) DEFAULT NULL COMMENT '服务商运费',
|
||||
`is_pay_fee` tinyint(4) DEFAULT NULL COMMENT '是否已计算应付费用0-未计算 1-已计算',
|
||||
`has_added_surcharge` tinyint(4) DEFAULT NULL COMMENT '是否已经添加过附加费 0未添加 1 已添加',
|
||||
`yf_fee` decimal(10,3) DEFAULT NULL COMMENT '应付运费',
|
||||
`yf_totail_fee` decimal(10,3) DEFAULT NULL COMMENT '应付总运费',
|
||||
`trajectory_status` tinyint(4) DEFAULT NULL COMMENT '轨迹状态:1.已收货、2.查询失败、3.转运中、4.派送中、5.投递失败、6.退仓、7.异常、8.已签收',
|
||||
`cargo_type_name` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '货物类型中文',
|
||||
`service_code` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '所属服务商编号',
|
||||
`three_code` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '三字码',
|
||||
`volume_height_old` decimal(10,2) DEFAULT NULL COMMENT '高,单位 CM',
|
||||
`volume_length_old` decimal(10,2) DEFAULT NULL COMMENT '长,单位 CM',
|
||||
`volume_width_old` decimal(10,2) DEFAULT NULL COMMENT '宽,单位 CM',
|
||||
`register_man_old` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '收货人',
|
||||
`bag_no_old` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '箱号',
|
||||
`air_no_old` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '航空主单号',
|
||||
`lading_id` bigint(20) DEFAULT NULL COMMENT '应付提单ID',
|
||||
`box_sizi_old` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '箱子规格',
|
||||
`baging_man_old` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '装箱人',
|
||||
`retrieval_man_old` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '出货人',
|
||||
`invoice_amount_old` text COLLATE utf8mb4_unicode_ci COMMENT '申报总价值,必填',
|
||||
`invoice_title_old` text COLLATE utf8mb4_unicode_ci COMMENT '英文品名,必填',
|
||||
`invoice_weight_old` text COLLATE utf8mb4_unicode_ci COMMENT '单件重',
|
||||
`sku_old` text COLLATE utf8mb4_unicode_ci COMMENT '中文品名',
|
||||
`hs_code_old` text COLLATE utf8mb4_unicode_ci COMMENT '海关编码',
|
||||
`register_date_old` datetime DEFAULT NULL COMMENT '收件时间',
|
||||
`invoice_currency_old` text COLLATE utf8mb4_unicode_ci COMMENT '申报币种',
|
||||
`trajectory_sub_state` tinyint(4) DEFAULT NULL COMMENT '轨迹子状态',
|
||||
`sign_in_time` datetime DEFAULT NULL COMMENT '签收时间',
|
||||
`warehouse_time` datetime DEFAULT NULL COMMENT '仓库操作完成,已安排出库时间',
|
||||
`declaration_time` datetime DEFAULT NULL COMMENT '送仓报关时间',
|
||||
`release_time` datetime DEFAULT NULL COMMENT '报关放行时间',
|
||||
`station_time` datetime DEFAULT NULL COMMENT '货站收货时间',
|
||||
`takeoff_time` datetime DEFAULT NULL COMMENT '航班起飞时间',
|
||||
`landing_time` datetime DEFAULT NULL COMMENT '航班落地时间',
|
||||
`clearance_and_delivery_time` datetime DEFAULT NULL COMMENT '已通知清关行提货时间',
|
||||
`supplier_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '生产销售供应商',
|
||||
`credit_code` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '社会信用代码',
|
||||
`other_id` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '其他ID',
|
||||
`platform_code` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '平台代码',
|
||||
`sync_shipment_status` tinyint(4) DEFAULT NULL COMMENT '物流同步状态, 0:未同步, 1: 已同步',
|
||||
`update_weight` decimal(10,3) DEFAULT NULL COMMENT '客户更新重量',
|
||||
`other_bag_no` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '其它箱号',
|
||||
`bag_flag` tinyint(4) DEFAULT NULL COMMENT '装箱标记,1: 已装箱 0:未装箱',
|
||||
`online_time` datetime DEFAULT NULL COMMENT '上网时间',
|
||||
`outbound_time` datetime DEFAULT NULL COMMENT '出库时间',
|
||||
`air_confirm_date` datetime DEFAULT NULL COMMENT '主单号确认时间',
|
||||
`shipment_type` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '订单配送类型',
|
||||
`track_query_time` datetime DEFAULT NULL COMMENT '轨迹抓取时间',
|
||||
`air_confirm_time` datetime DEFAULT NULL COMMENT '航班已配载时间',
|
||||
`package_type` tinyint(4) DEFAULT NULL COMMENT '0:软包;1:硬包',
|
||||
`confirm_weight` decimal(10,3) DEFAULT NULL COMMENT '客户确认重',
|
||||
`update_by` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '更新人',
|
||||
`customer_pickup_site` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '取货地点',
|
||||
`barcode_number` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '面单条形码',
|
||||
`tracking_reflect_status` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '轨迹映射状态',
|
||||
`remote_postcode` tinyint(4) DEFAULT NULL COMMENT '是否偏远邮编',
|
||||
`clearance_time` datetime DEFAULT NULL COMMENT 'CLEARANCE_TIME',
|
||||
`arrive_stock_time` datetime DEFAULT NULL COMMENT 'ARRIVE_STOCK_TIME',
|
||||
`departure_time` datetime DEFAULT NULL COMMENT 'DEPARTURE_TIME',
|
||||
`first_deliver_time` datetime DEFAULT NULL COMMENT 'FIRST_DELIVER_TIME',
|
||||
`hs_code_tax_count` decimal(10,2) DEFAULT NULL COMMENT 'HS_CODE_TAX_COUNT',
|
||||
`hs_code_tax_amount` decimal(10,4) DEFAULT NULL COMMENT 'HS_CODE_TAX_AMOUNT',
|
||||
`hs_code_tax_currency` varchar(8) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'HS_CODE_TAX_CURRENCY',
|
||||
`invoice_url` text COLLATE utf8mb4_unicode_ci COMMENT 'INVOICE_URL',
|
||||
`clearance_no` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'CLEARANCE_NO',
|
||||
`push_weight` decimal(10,3) DEFAULT NULL COMMENT 'PUSH_WEIGHT',
|
||||
`internal_check_time` datetime DEFAULT NULL COMMENT 'INTERNAL_CHECK_TIME',
|
||||
`air_delay_time` datetime DEFAULT NULL COMMENT 'AIR_DELAY_TIME',
|
||||
`first_landing_time` datetime DEFAULT NULL COMMENT 'FIRST_LANDING_TIME',
|
||||
`second_takeoff_time` datetime DEFAULT NULL COMMENT 'SECOND_TAKEOFF_TIME',
|
||||
`des_port_check_time` datetime DEFAULT NULL COMMENT 'DES_PORT_CHECK_TIME',
|
||||
`stay_remark` text COLLATE utf8mb4_unicode_ci COMMENT 'STAY_REMARK',
|
||||
`miss_box_remark` text COLLATE utf8mb4_unicode_ci COMMENT 'MISS_BOX_REMARK',
|
||||
`product_channel_id` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'PRODUCT_CHANNEL_ID',
|
||||
`customer_track_id` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'CUSTOMER_TRACK_ID',
|
||||
`register_site` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'REGISTER_SITE',
|
||||
`package_type_financial` tinyint(4) DEFAULT NULL COMMENT '财务包裹类型,软硬包',
|
||||
`mrn` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'MRN',
|
||||
`product_floor_code` text COLLATE utf8mb4_unicode_ci COMMENT '渠道编码',
|
||||
`order_status` tinyint(4) DEFAULT NULL COMMENT '订单状态',
|
||||
`pickup_date` datetime DEFAULT NULL COMMENT '收件时间',
|
||||
`bl_pickup` tinyint(4) DEFAULT NULL COMMENT '是否收件 0未收件 1已收件',
|
||||
`dimensional_weight_factor` decimal(10,3) DEFAULT NULL COMMENT '计费重',
|
||||
PRIMARY KEY (`bill_id`) USING BTREE,
|
||||
UNIQUE KEY `uk_order_bill_ext_order` (`order_no`) USING BTREE,
|
||||
KEY `idx_order_bill_ext_channel` (`product_channel_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='订单计费扩展表';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `prc_income_bill_new`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prc_income_bill_new` (
|
||||
`income_bill_id` bigint NOT NULL AUTO_INCREMENT COMMENT '应收主表ID',
|
||||
`bill_id` bigint NOT NULL COMMENT '计费订单ID',
|
||||
`currency` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT 'CNY' COMMENT '币种',
|
||||
`product_amount` decimal(18,4) DEFAULT NULL COMMENT '产品价合计',
|
||||
`redline_amount` decimal(18,4) DEFAULT NULL COMMENT '红线价合计',
|
||||
`sales_amount` decimal(18,4) DEFAULT NULL COMMENT '销售价合计(当前计费结果)',
|
||||
`income_total` decimal(18,4) DEFAULT NULL COMMENT '应收合计(当前等于销售价)',
|
||||
`refund_status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'NONE' COMMENT '是否退货:NONE未退货/REFUNDED已退货',
|
||||
`belong_saler` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '业务员/销售员',
|
||||
`belong_saler_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '销售员编码',
|
||||
`settlement_man` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '结算员',
|
||||
`settlement_man_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '结算员编码',
|
||||
`create_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`income_bill_id`) USING BTREE,
|
||||
UNIQUE KEY `uk_income_bill_order_bill` (`bill_id`) USING BTREE,
|
||||
KEY `idx_income_bill_saler` (`belong_saler`) USING BTREE,
|
||||
KEY `idx_income_bill_settlement` (`settlement_man`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='应收主表(订单计费与应收费用中间层,与订单一对一)';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `prc_income_bill_fee_new`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prc_income_bill_fee_new` (
|
||||
`fee_id` bigint NOT NULL AUTO_INCREMENT COMMENT '费用明细ID',
|
||||
`bill_id` bigint NOT NULL COMMENT '计费ID',
|
||||
`income_bill_id` bigint DEFAULT NULL COMMENT '应收主表ID',
|
||||
`fee_type` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '费用类型(字典bms_fee_type)',
|
||||
`fee_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '费用名称',
|
||||
`sc_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '附加费配置ID',
|
||||
`amount` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '金额',
|
||||
`product_amount` decimal(18,4) DEFAULT NULL COMMENT '产品价',
|
||||
`redline_amount` decimal(18,4) DEFAULT NULL COMMENT '红线价',
|
||||
`currency` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'CNY' COMMENT '币种',
|
||||
`round_mode` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT 'HALF_UP' COMMENT '取值方式',
|
||||
`remark` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
|
||||
`ar_bill_status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'UNBILLED' COMMENT '是否生成账单状态:UNBILLED未生成/BILLED已生成',
|
||||
`manual_flag` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '是否手动增加:0否 1是',
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`fee_id`) USING BTREE,
|
||||
UNIQUE KEY `uk_bill_fee_item` (`bill_id`,`fee_type`,`sc_id`) USING BTREE,
|
||||
KEY `idx_bill_fee_type` (`fee_type`) USING BTREE,
|
||||
KEY `idx_income_fee_income_bill` (`income_bill_id`) USING BTREE,
|
||||
KEY `idx_income_fee_ar_status` (`ar_bill_status`) USING BTREE,
|
||||
KEY `idx_income_fee_bill_ar_status` (`bill_id`,`ar_bill_status`,`fee_id`) USING BTREE,
|
||||
KEY `idx_income_fee_bill_status_amount` (`bill_id`,`ar_bill_status`,`amount`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='应收费用明细';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `prc_pay_bill_new`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prc_pay_bill_new` (
|
||||
`pay_bill_id` bigint NOT NULL AUTO_INCREMENT COMMENT '应付主表ID',
|
||||
`bill_id` bigint NOT NULL COMMENT '计费订单ID',
|
||||
`currency` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT 'CNY' COMMENT '币种',
|
||||
`product_amount` decimal(12,4) DEFAULT NULL COMMENT '产品价合计',
|
||||
`redline_amount` decimal(12,4) DEFAULT NULL COMMENT '红线价合计',
|
||||
`cost_amount` decimal(12,4) DEFAULT NULL COMMENT '成本价合计(当前计费结果)',
|
||||
`pay_total` decimal(12,4) DEFAULT NULL COMMENT '应付合计(当前等于成本价)',
|
||||
`amount_a` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT 'A段合计',
|
||||
`amount_b` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT 'B段合计',
|
||||
`amount_c` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT 'C段合计',
|
||||
`amount_d` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT 'D段合计',
|
||||
`belong_saler` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '业务员/销售员',
|
||||
`belong_saler_code` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '销售员编码',
|
||||
`settlement_man` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '结算员',
|
||||
`settlement_man_code` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '结算员编码',
|
||||
`create_by` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_by` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`pay_bill_id`) USING BTREE,
|
||||
UNIQUE KEY `uk_pay_bill_order_bill` (`bill_id`) USING BTREE,
|
||||
KEY `idx_pay_bill_saler` (`belong_saler`) USING BTREE,
|
||||
KEY `idx_pay_bill_settlement` (`settlement_man`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='应付主表(订单计费与应付费用中间层,与订单一对一)';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `prc_pay_bill_fee_new`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prc_pay_bill_fee_new` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
|
||||
`fee_id` bigint NOT NULL COMMENT '费用明细ID',
|
||||
`bill_id` bigint NOT NULL COMMENT '订单主表ID',
|
||||
`pay_bill_id` bigint DEFAULT NULL COMMENT '应付主表ID',
|
||||
`fee_type` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '费用类型(字典bms_fee_type)',
|
||||
`sc_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '附加费配置ID',
|
||||
`fee_level` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '费用所属阶段:1、a段(头程仓储);2、b段(提单运输);3、c段(清关);4、d段(尾程)',
|
||||
`amount` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '金额',
|
||||
`currency` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'CNY' COMMENT '币种',
|
||||
`round_mode` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT 'HALF_UP' COMMENT '取值方式',
|
||||
`remark` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注',
|
||||
`fee_source` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'CALC' COMMENT 'CALC计算 LADING提单分摊 MANUAL人工',
|
||||
`source_id` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '来源数据id',
|
||||
`is_deleted` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '是否删除:0未删除 1已删除',
|
||||
`statement_line_id` bigint(20) DEFAULT NULL COMMENT '已进入的应付账单行ID,空表示未出账',
|
||||
`settle_supplier_id` bigint(20) DEFAULT NULL COMMENT '结算供应商ID,空表示还没标明付款对象',
|
||||
`settle_supplier_name` varchar(32) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '结算供应商名称',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE KEY `uk_pay_bill_fee_item` (`bill_id`,`fee_type`,`sc_id`) USING BTREE,
|
||||
KEY `idx_pay_bill_fee_type` (`fee_type`) USING BTREE,
|
||||
KEY `idx_pay_fee_pay_bill` (`pay_bill_id`) USING BTREE,
|
||||
KEY `idx_pay_fee_settle` (`settle_supplier_id`,`statement_line_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='应付费用明细';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `ar_bill_detail_new`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ar_bill_detail_new` (
|
||||
`detail_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '账单订单明细ID',
|
||||
`ar_bill_id` bigint(20) NOT NULL COMMENT '应收账单ID',
|
||||
`prc_order_bill_id` bigint NOT NULL COMMENT '来源计费订单ID',
|
||||
`detail_no` int(11) NOT NULL COMMENT '账单内顺序号',
|
||||
`order_no` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '订单号快照',
|
||||
`tracking_no` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '运单号快照',
|
||||
`transfer_no` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '转单号快照',
|
||||
`receive_time` datetime DEFAULT NULL COMMENT '收件或入库时间',
|
||||
`product_code` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '产品代码快照',
|
||||
`product_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '产品名称快照',
|
||||
`goods_description` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '货物描述快照',
|
||||
`country_code` char(2) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '目的国家二字码',
|
||||
`country_name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '目的国家名称',
|
||||
`dest_postcode` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '目的邮编',
|
||||
`actual_weight` decimal(12,3) DEFAULT NULL COMMENT '实际重量KG',
|
||||
`receive_weight` decimal(10,3) DEFAULT NULL COMMENT 'prc_order_bill.receive_weight收货重来源快照',
|
||||
`volume_weight` decimal(12,3) DEFAULT NULL COMMENT '材积重量KG',
|
||||
`charge_weight` decimal(12,3) DEFAULT NULL COMMENT '计费重量KG',
|
||||
`freight_rate` decimal(10,4) DEFAULT NULL COMMENT '运费单价快照',
|
||||
`registration_fee` decimal(10,2) DEFAULT NULL COMMENT '处理费快照',
|
||||
`pkg_length` decimal(10,2) DEFAULT NULL COMMENT '长度CM',
|
||||
`pkg_width` decimal(10,2) DEFAULT NULL COMMENT '宽度CM',
|
||||
`pkg_height` decimal(10,2) DEFAULT NULL COMMENT '高度CM',
|
||||
`currency` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '币种快照',
|
||||
`total_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '订单费用合计',
|
||||
`product_amount` decimal(18,4) DEFAULT NULL COMMENT '产品价合计快照',
|
||||
`redline_amount` decimal(18,4) DEFAULT NULL COMMENT '红线价合计快照',
|
||||
`billing_fail_status` tinyint(4) DEFAULT NULL COMMENT '计费失败状态快照:0成功/1未匹配产品/2未匹配国家/3未匹配重量段',
|
||||
`remark` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '订单账单备注',
|
||||
`create_by` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '创建人',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`detail_id`) USING BTREE,
|
||||
UNIQUE KEY `uk_ar_bill_detail_source` (`ar_bill_id`,`prc_order_bill_id`) USING BTREE,
|
||||
UNIQUE KEY `uk_ar_bill_detail_no` (`ar_bill_id`,`detail_no`) USING BTREE,
|
||||
KEY `idx_ar_bill_detail_source` (`prc_order_bill_id`) USING BTREE,
|
||||
KEY `idx_ar_bill_detail_bill_transfer_no` (`ar_bill_id`,`transfer_no`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='应收账单订单快照';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `ar_bill_detail_fee_new`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ar_bill_detail_fee_new` (
|
||||
`detail_fee_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '账单费用明细ID',
|
||||
`detail_id` bigint(20) NOT NULL COMMENT '账单订单明细ID',
|
||||
`prc_income_bill_fee_id` bigint NOT NULL COMMENT '来源收入费用ID',
|
||||
`fee_no` int(11) NOT NULL COMMENT '订单内费用顺序号',
|
||||
`fee_type` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '费用类型快照',
|
||||
`fee_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '费用名称快照',
|
||||
`sc_id` bigint(20) DEFAULT NULL COMMENT '附加费配置ID快照',
|
||||
`quantity` decimal(12,3) DEFAULT NULL COMMENT '计费数量',
|
||||
`unit` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '计费单位',
|
||||
`unit_price` decimal(15,4) DEFAULT NULL COMMENT '费用单价',
|
||||
`amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '费用金额',
|
||||
`product_amount` decimal(18,4) DEFAULT NULL COMMENT '产品价快照',
|
||||
`redline_amount` decimal(18,4) DEFAULT NULL COMMENT '红线价快照',
|
||||
`currency` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '币种',
|
||||
`calculation_formula` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '计算公式或说明',
|
||||
`round_mode` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '取舍规则',
|
||||
`remark` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '费用备注',
|
||||
`create_by` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '创建人',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`detail_fee_id`) USING BTREE,
|
||||
UNIQUE KEY `uk_ar_detail_prc_income_fee` (`detail_id`,`prc_income_bill_fee_id`) USING BTREE,
|
||||
KEY `idx_ar_detail_fee_type` (`fee_type`) USING BTREE,
|
||||
KEY `idx_ar_detail_prc_income_fee` (`prc_income_bill_fee_id`) USING BTREE,
|
||||
KEY `idx_ar_detail_fee_order` (`detail_id`,`fee_no`,`detail_fee_id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='应收账单费用快照';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `pay_bill_line_new`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pay_bill_line_new` (
|
||||
`line_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '账单行ID',
|
||||
`bill_id` bigint(20) NOT NULL COMMENT '应付账单ID',
|
||||
`fee_id` bigint DEFAULT NULL COMMENT '应付费用明细ID',
|
||||
`order_bill_id` bigint DEFAULT NULL COMMENT '订单ID',
|
||||
`order_no` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '订单号',
|
||||
`lading_no` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '提单号',
|
||||
`lading_fee_id` bigint(20) DEFAULT NULL COMMENT '留在主单上的费用',
|
||||
`fee_name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '费用名称',
|
||||
`fee_source` varchar(20) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'CALC计算 LADING提单分摊 MANUAL人工',
|
||||
`fee_level` varchar(8) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '费用阶段 1A 2B 3C 4D',
|
||||
`amount` decimal(12,4) NOT NULL COMMENT '金额快照',
|
||||
`supplier_amount` decimal(12,4) DEFAULT NULL COMMENT '对方金额',
|
||||
`diff_amount` decimal(12,4) DEFAULT NULL COMMENT '差额,对方减我方',
|
||||
`diff_status` varchar(20) CHARACTER SET utf8mb4 NOT NULL DEFAULT 'NONE' COMMENT 'NONE无差异 OPEN待处理 ACCEPT_OURS接受我方 ACCEPT_THEIRS接受对方',
|
||||
`tax_rate` decimal(8,4) NOT NULL DEFAULT '0.0000' COMMENT '税率,0.06 表示 6%',
|
||||
`amount_net` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT '不含税金额',
|
||||
`tax_amount` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT '税额',
|
||||
`base_amount` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT '本位币金额,人民币',
|
||||
`currency` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '币种',
|
||||
`price_date` date DEFAULT NULL COMMENT '取价日',
|
||||
`version_no` int(11) DEFAULT NULL COMMENT '价卡版本',
|
||||
`remote_flag` char(1) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Y偏远 N非偏远',
|
||||
`density_level` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'HIGH MEDIUM LOW',
|
||||
`line_source` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'ORDER订单费用 LADING主单费用',
|
||||
PRIMARY KEY (`line_id`),
|
||||
KEY `idx_pay_bill_line_bill` (`bill_id`),
|
||||
KEY `idx_pay_bill_line_order` (`order_bill_id`),
|
||||
KEY `idx_pay_bill_line_lading_fee` (`lading_fee_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='应付账单费用明细';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `prc_billing_task_new`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prc_billing_task_new` (
|
||||
`task_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务ID',
|
||||
`transfer_no` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '转单号',
|
||||
`tracking_no` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '运单号',
|
||||
`order_no` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '订单号',
|
||||
`customer_code` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户代码',
|
||||
`bill_type` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '计费类型:PENDING待计费 REBILL重计费 REFUND退费',
|
||||
`success_status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'WAITING' COMMENT '是否计费成功:WAITING待处理 SUCCESS成功 FAILED失败',
|
||||
`bill_time` datetime DEFAULT NULL COMMENT '计费时间',
|
||||
`bill_id` bigint DEFAULT NULL COMMENT '计费订单ID',
|
||||
`fail_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '失败码',
|
||||
`error_message` varchar(1000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '失败原因',
|
||||
`create_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`update_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`task_id`) USING BTREE,
|
||||
KEY `idx_billing_task_transfer` (`transfer_no`) USING BTREE,
|
||||
KEY `idx_billing_task_tracking` (`tracking_no`) USING BTREE,
|
||||
KEY `idx_billing_task_order` (`order_no`) USING BTREE,
|
||||
KEY `idx_billing_task_status` (`success_status`,`create_time`) USING BTREE,
|
||||
KEY `idx_billing_task_type` (`bill_type`) USING BTREE,
|
||||
KEY `idx_billing_task_fail_code` (`fail_code`) USING BTREE,
|
||||
KEY `idx_billing_task_customer` (`customer_code`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='计费任务表';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `ar_bill_generate_task_new`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ar_bill_generate_task_new` (
|
||||
`task_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '生成任务ID',
|
||||
`task_no` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '生成任务编号',
|
||||
`ar_bill_id` bigint(20) NOT NULL COMMENT '应收账单ID',
|
||||
`selection_mode` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '选择模式:EXPLICIT=手动选择,ALL_MATCHED=全选查询结果',
|
||||
`request_payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '生成请求快照JSON',
|
||||
`snapshot_create_time` datetime DEFAULT NULL COMMENT '来源订单创建时间快照',
|
||||
`last_source_bill_id` bigint DEFAULT NULL COMMENT '来源订单游标',
|
||||
`total_count` int(11) NOT NULL DEFAULT '-1' COMMENT '待处理订单数,-1表示尚未统计',
|
||||
`processed_count` int(11) NOT NULL DEFAULT '0' COMMENT '已处理订单数',
|
||||
`success_count` int(11) NOT NULL DEFAULT '0' COMMENT '成功订单数',
|
||||
`total_amount` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '当前生成金额',
|
||||
`status` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '任务状态:WAITING=待处理,RUNNING=生成中,SUCCESS=生成成功,FAILED=生成失败,CANCEL_REQUESTED=取消中,CANCELED=已取消',
|
||||
`error_message` varchar(1000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '错误信息',
|
||||
`request_token` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '请求幂等标识',
|
||||
`create_user_id` bigint(20) DEFAULT NULL COMMENT '创建用户ID',
|
||||
`create_by` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '创建人',
|
||||
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||
`started_at` datetime DEFAULT NULL COMMENT '开始时间',
|
||||
`heartbeat_time` datetime DEFAULT NULL COMMENT '最近心跳时间',
|
||||
`finished_at` datetime DEFAULT NULL COMMENT '完成时间',
|
||||
PRIMARY KEY (`task_id`) USING BTREE,
|
||||
UNIQUE KEY `uk_ar_bill_generate_task_no` (`task_no`) USING BTREE,
|
||||
UNIQUE KEY `uk_ar_bill_generate_request_token` (`request_token`) USING BTREE,
|
||||
KEY `idx_ar_bill_generate_status` (`status`,`create_time`) USING BTREE,
|
||||
KEY `idx_ar_bill_generate_bill` (`ar_bill_id`) USING BTREE,
|
||||
KEY `idx_ar_bill_generate_creator` (`create_user_id`,`status`,`create_time`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='应收账单异步生成任务';
|
||||
|
||||
|
||||
-- ========== 监控菜单(系统监控) ==========
|
||||
|
||||
SET @monitorParent := (
|
||||
SELECT menu_id FROM sys_menu
|
||||
WHERE menu_type = 'M' AND (path = 'monitor' OR menu_name = N'系统监控')
|
||||
ORDER BY menu_id LIMIT 1
|
||||
);
|
||||
|
||||
INSERT INTO sys_menu (
|
||||
menu_id, menu_name, parent_id, order_num, path, component, query, route_name,
|
||||
is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark
|
||||
)
|
||||
SELECT 2360, N'UUID阴影同步', IFNULL(@monitorParent, 2), 12,
|
||||
'uuidToNew', 'monitor/uuidToNew/index', '', 'UuidToNew',
|
||||
1, 0, 'C', '0', '0', 'monitor:uuidToNew:list', 'chart',
|
||||
'admin', sysdate(), N'查看 mig_bi_job_log 与同步积压'
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2360 OR perms = 'monitor:uuidToNew:list');
|
||||
|
||||
INSERT INTO sys_menu (
|
||||
menu_id, menu_name, parent_id, order_num, path, component,
|
||||
is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time
|
||||
)
|
||||
SELECT 2361, N'查询', 2360, 1, '', NULL,
|
||||
1, 0, 'F', '0', '0', 'monitor:uuidToNew:list', '#', 'admin', sysdate()
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2361);
|
||||
|
||||
INSERT INTO sys_menu (
|
||||
menu_id, menu_name, parent_id, order_num, path, component,
|
||||
is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark
|
||||
)
|
||||
SELECT 2362, N'开关', 2360, 2, '', NULL,
|
||||
1, 0, 'F', '0', '0', 'monitor:uuidToNew:switch', '#', 'admin', sysdate(), N'打开/关闭连续同步'
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2362 OR perms = 'monitor:uuidToNew:switch');
|
||||
|
||||
INSERT INTO sys_role_menu (role_id, menu_id)
|
||||
SELECT 1, m.menu_id
|
||||
FROM (SELECT 2360 AS menu_id UNION SELECT 2361 UNION SELECT 2362) m
|
||||
WHERE EXISTS (SELECT 1 FROM sys_menu x WHERE x.menu_id = m.menu_id)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM sys_role_menu rm WHERE rm.role_id = 1 AND rm.menu_id = m.menu_id
|
||||
);
|
||||
@@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getUuidToNewProgress() {
|
||||
return request({
|
||||
url: '/monitor/uuidToNew/progress',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function listUuidToNewJobLog(query) {
|
||||
return request({
|
||||
url: '/monitor/uuidToNew/jobLog/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
/** 打开/关闭;开启时可带 threadCount/batchSize */
|
||||
export function setUuidToNewEnabled(payload) {
|
||||
const data = typeof payload === 'boolean'
|
||||
? { enabled: payload }
|
||||
: {
|
||||
enabled: !!payload.enabled,
|
||||
threadCount: payload.threadCount,
|
||||
batchSize: payload.batchSize
|
||||
}
|
||||
return request({
|
||||
url: '/monitor/uuidToNew/enabled',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/** 仅关闭时修改线程/批次 */
|
||||
export function updateUuidToNewConfig(payload) {
|
||||
return request({
|
||||
url: '/monitor/uuidToNew/config',
|
||||
method: 'post',
|
||||
data: {
|
||||
threadCount: payload.threadCount,
|
||||
batchSize: payload.batchSize
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
<template>
|
||||
<div class="app-container uuid-to-new-page">
|
||||
<el-card shadow="never" class="progress-card">
|
||||
<div class="progress-head">
|
||||
<div class="title">UUID 阴影同步进度</div>
|
||||
<div class="actions">
|
||||
<span class="switch-label">线程</span>
|
||||
<el-select
|
||||
v-model="threadCount"
|
||||
size="small"
|
||||
style="width: 88px"
|
||||
:disabled="configLocked || configLoading"
|
||||
v-hasPermi="['monitor:uuidToNew:switch']"
|
||||
@change="onConfigChange"
|
||||
>
|
||||
<el-option v-for="n in threadOptions" :key="n" :label="n + '线程'" :value="n" />
|
||||
</el-select>
|
||||
<span class="switch-label">批次</span>
|
||||
<el-select
|
||||
v-model="batchSize"
|
||||
size="small"
|
||||
style="width: 100px"
|
||||
:disabled="configLocked || configLoading"
|
||||
v-hasPermi="['monitor:uuidToNew:switch']"
|
||||
@change="onConfigChange"
|
||||
>
|
||||
<el-option v-for="n in batchOptions" :key="n" :label="String(n)" :value="n" />
|
||||
</el-select>
|
||||
<span class="switch-label">连续同步</span>
|
||||
<el-switch
|
||||
v-model="switchOn"
|
||||
:loading="switchLoading"
|
||||
:disabled="switchLoading"
|
||||
inline-prompt
|
||||
active-text="开"
|
||||
inactive-text="关"
|
||||
v-hasPermi="['monitor:uuidToNew:switch']"
|
||||
@change="onSwitchChange"
|
||||
/>
|
||||
<el-tag :type="progress.running ? 'success' : (progress.enabled ? 'warning' : 'info')" size="small">
|
||||
{{ statusText }}
|
||||
</el-tag>
|
||||
<el-button size="small" icon="Refresh" :loading="progressLoading" @click="refreshAll">刷新</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-row :gutter="16" class="stat-row">
|
||||
<el-col :xs="12" :sm="8" :md="4">
|
||||
<div class="stat">
|
||||
<div class="num">{{ formatNum(progress.oldCnt) }}</div>
|
||||
<div class="label">旧表订单</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="8" :md="4">
|
||||
<div class="stat">
|
||||
<div class="num ok">{{ formatNum(progress.doneCnt) }}</div>
|
||||
<div class="label">已同步 SUCCESS</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="8" :md="4">
|
||||
<div class="stat">
|
||||
<div class="num warn">{{ formatNum(progress.pendingCnt) }}</div>
|
||||
<div class="label">积压</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="8" :md="4">
|
||||
<div class="stat">
|
||||
<div class="num">{{ formatNum(progress.newCnt) }}</div>
|
||||
<div class="label">阴影订单行</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="8" :md="4">
|
||||
<div class="stat">
|
||||
<div class="num">{{ progress.donePercent }}%</div>
|
||||
<div class="label">完成比例</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="8" :md="4">
|
||||
<div class="stat">
|
||||
<div class="num cfg">{{ progress.threadCount }} / {{ progress.batchSize }}</div>
|
||||
<div class="label">线程 / 批次</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-progress
|
||||
:percentage="Math.min(100, Number(progress.donePercent) || 0)"
|
||||
:stroke-width="14"
|
||||
:text-inside="true"
|
||||
/>
|
||||
<div class="hint-line">关闭开关后可改线程/批次;打开后按当前选项立即连续执行,一批结束立刻下一批。</div>
|
||||
</el-card>
|
||||
|
||||
<basic-table
|
||||
ref="tableRef"
|
||||
class="job-log-table"
|
||||
:columns="columns"
|
||||
:search-columns="searchColumns"
|
||||
:query="queryList"
|
||||
:selection="false"
|
||||
show-index
|
||||
>
|
||||
<template #toolbar>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Refresh" @click="refreshAll">刷新列表</el-button>
|
||||
</el-col>
|
||||
</template>
|
||||
<template #col-fail="{ row }">
|
||||
<span :class="{ 'fail-num': row.fail > 0 }">{{ row.fail }}</span>
|
||||
</template>
|
||||
<template #col-cost="{ row }">
|
||||
{{ formatCost(row.startedAt, row.finishedAt) }}
|
||||
</template>
|
||||
</basic-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="UuidToNewMonitor">
|
||||
import { getUuidToNewProgress, listUuidToNewJobLog, setUuidToNewEnabled, updateUuidToNewConfig } from '@/api/monitor/uuidToNew'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const tableRef = ref()
|
||||
const progressLoading = ref(false)
|
||||
const switchLoading = ref(false)
|
||||
const configLoading = ref(false)
|
||||
const switchOn = ref(false)
|
||||
const threadCount = ref(2)
|
||||
const batchSize = ref(200)
|
||||
const threadOptions = [1, 2, 3, 4]
|
||||
const batchOptions = [50, 100, 200, 300, 500, 1000]
|
||||
|
||||
const progress = reactive({
|
||||
oldCnt: 0,
|
||||
doneCnt: 0,
|
||||
newCnt: 0,
|
||||
pendingCnt: 0,
|
||||
donePercent: 0,
|
||||
enabled: false,
|
||||
running: false,
|
||||
batchSize: 200,
|
||||
threadCount: 2
|
||||
})
|
||||
|
||||
const configLocked = computed(() => !!(switchOn.value || progress.enabled || progress.running))
|
||||
|
||||
const statusText = computed(() => {
|
||||
if (progress.running) return '正在同步'
|
||||
if (progress.enabled) return '开启中(等待启动)'
|
||||
return '已停止'
|
||||
})
|
||||
|
||||
const searchColumns = [
|
||||
{ label: '批次号', prop: 'batchNo', component: 'input', placeholder: '批次号', width: '220px' },
|
||||
{ label: '开始时间', prop: 'dateRange', component: 'datetimerange', width: '360px' }
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{ label: 'ID', prop: 'id', width: 90, align: 'center' },
|
||||
{ label: '批次号', prop: 'batchNo', minWidth: 200, showOverflowTooltip: true },
|
||||
{ label: '抓取', prop: 'fetched', width: 90, align: 'center' },
|
||||
{ label: '成功', prop: 'success', width: 90, align: 'center' },
|
||||
{ label: '失败', prop: 'fail', width: 90, align: 'center', slot: 'fail' },
|
||||
{ label: '跳过', prop: 'skip', width: 90, align: 'center' },
|
||||
{ label: '耗时', prop: 'cost', width: 110, align: 'center', slot: 'cost' },
|
||||
{ label: '开始', prop: 'startedAt', width: 170, align: 'center', parseTime: true },
|
||||
{ label: '结束', prop: 'finishedAt', width: 170, align: 'center', parseTime: true },
|
||||
{ label: '备注', prop: 'remark', minWidth: 140, showOverflowTooltip: true }
|
||||
]
|
||||
|
||||
function formatNum(v) {
|
||||
const n = Number(v || 0)
|
||||
return n.toLocaleString()
|
||||
}
|
||||
|
||||
function formatCost(start, end) {
|
||||
if (!start || !end) return '-'
|
||||
const a = new Date(start).getTime()
|
||||
const b = new Date(end).getTime()
|
||||
if (!a || !b || b < a) return '-'
|
||||
const sec = Math.round((b - a) / 1000)
|
||||
if (sec < 60) return sec + 's'
|
||||
return Math.floor(sec / 60) + 'm' + (sec % 60) + 's'
|
||||
}
|
||||
|
||||
function syncLocalFromProgress() {
|
||||
if (progress.threadCount) threadCount.value = Number(progress.threadCount)
|
||||
if (progress.batchSize) batchSize.value = Number(progress.batchSize)
|
||||
switchOn.value = !!progress.enabled
|
||||
}
|
||||
|
||||
async function loadProgress() {
|
||||
progressLoading.value = true
|
||||
try {
|
||||
const res = await getUuidToNewProgress()
|
||||
Object.assign(progress, res.data || {})
|
||||
syncLocalFromProgress()
|
||||
} finally {
|
||||
progressLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function onConfigChange() {
|
||||
if (configLocked.value) {
|
||||
syncLocalFromProgress()
|
||||
return
|
||||
}
|
||||
configLoading.value = true
|
||||
try {
|
||||
const res = await updateUuidToNewConfig({
|
||||
threadCount: threadCount.value,
|
||||
batchSize: batchSize.value
|
||||
})
|
||||
Object.assign(progress, res.data || {})
|
||||
syncLocalFromProgress()
|
||||
} catch (e) {
|
||||
syncLocalFromProgress()
|
||||
} finally {
|
||||
configLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function onSwitchChange(val) {
|
||||
switchLoading.value = true
|
||||
try {
|
||||
const res = await setUuidToNewEnabled({
|
||||
enabled: val,
|
||||
threadCount: threadCount.value,
|
||||
batchSize: batchSize.value
|
||||
})
|
||||
Object.assign(progress, res.data || {})
|
||||
syncLocalFromProgress()
|
||||
proxy.$modal.msgSuccess(val ? '已开启,按当前线程/批次连续同步' : '已关闭,当前批结束后停止')
|
||||
tableRef.value && tableRef.value.refresh()
|
||||
} catch (e) {
|
||||
switchOn.value = !val
|
||||
} finally {
|
||||
switchLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function queryList(params) {
|
||||
const query = {
|
||||
pageNum: params.pageNum,
|
||||
pageSize: params.pageSize,
|
||||
batchNo: params.batchNo
|
||||
}
|
||||
if (params.dateRange && params.dateRange.length === 2) {
|
||||
query.beginStartedAt = params.dateRange[0]
|
||||
query.endStartedAt = params.dateRange[1]
|
||||
}
|
||||
return listUuidToNewJobLog(query)
|
||||
}
|
||||
|
||||
function refreshAll() {
|
||||
loadProgress()
|
||||
tableRef.value && tableRef.value.refresh()
|
||||
}
|
||||
|
||||
let timer = null
|
||||
onMounted(() => {
|
||||
loadProgress()
|
||||
timer = setInterval(() => {
|
||||
if (progress.enabled || progress.running) {
|
||||
loadProgress()
|
||||
tableRef.value && tableRef.value.refresh()
|
||||
}
|
||||
}, 5000)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.progress-card {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.progress-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.progress-head .title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.progress-head .actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.switch-label {
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
}
|
||||
.stat-row {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.stat {
|
||||
background: #f7f8fa;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.stat .num {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.stat .num.ok { color: #67c23a; }
|
||||
.stat .num.warn { color: #e6a23c; }
|
||||
.stat .num.cfg { font-size: 18px; }
|
||||
.stat .label {
|
||||
margin-top: 4px;
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
}
|
||||
.hint-line {
|
||||
margin-top: 8px;
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
}
|
||||
.fail-num {
|
||||
color: #f56c6c;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user