diff --git a/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/sync/SaleReceivableOrdersSyncEntity.java b/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/sync/SaleReceivableOrdersSyncEntity.java new file mode 100644 index 0000000..fd71157 --- /dev/null +++ b/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/sync/SaleReceivableOrdersSyncEntity.java @@ -0,0 +1,79 @@ +package me.iiv.agent.mcp.sync; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import me.iiv.agent.entity.m0.User; +import me.iiv.iivframework.beans.b1.SaleReceivableOrder; +import me.iiv.iivframework.mapper.m1.SaleReceivableOrderMapper; +import org.springframework.stereotype.Component; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * sale-receivable-orders 同步实体(m1.sale_receivable_order 应收单主表)。 + * 与 repayment-details(回款明细)互补:应收单是整单口径,带收款状态与开票金额/状态。 + * 金额列 legacy BigDecimal(元)→ 分;开票状态 0=未开票 1=全部开票 2=部分开票,原样透传。 + * 行级权限:Token 绑定人时暂按 null 处理(网关同步使用服务身份,不带用户)。 + */ +@Component +public class SaleReceivableOrdersSyncEntity extends AbstractSyncEntity implements SyncEntity { + + public static final String NAME = "sale-receivable-orders"; + + final SaleReceivableOrderMapper saleReceivableOrderMapper; + + public SaleReceivableOrdersSyncEntity(SaleReceivableOrderMapper saleReceivableOrderMapper) { + this.saleReceivableOrderMapper = saleReceivableOrderMapper; + } + + @Override + public String name() { + return NAME; + } + + @Override + public List fetchPage(Long fromTs, long cutoffTs, Long cursorMt, Long cursorId, + int limit, User user) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + applyWindow(wrapper, fromTs, cutoffTs, cursorMt, cursorId); + applyOrderAndLimit(wrapper, limit); + List rows = saleReceivableOrderMapper.selectList(wrapper); + List out = new ArrayList<>(rows.size()); + for (SaleReceivableOrder row : rows) { + long mt = ChangesEngine.effectiveTs(row.getModifyTime(), row.getCreateTime()); + out.add(new SyncRow(toItem(row, mt), mt, row.getId())); + } + return out; + } + + private Map toItem(SaleReceivableOrder row, long mt) { + boolean deleted = row.getSoftDelete() != null && row.getSoftDelete() == 1; + Date effective = row.getModifyTime() != null ? row.getModifyTime() : row.getCreateTime(); + String customerName = row.getCusterName() != null && !row.getCusterName().isBlank() + ? row.getCusterName() : row.getJindieName(); + return SyncChangeSchemas.toMap(new SyncChangeSchemas.ReceivableOrderChange( + stableId(row.getId()), row.getReceivableNo(), row.getOrderNo(), customerName, + stableId(row.getAgentId()), row.getAgentName(), + stableId(row.getPropertyId()), row.getPropertyName(), + row.getSaleCompany(), + ChangesEngine.iso(row.getOrderTime()), ChangesEngine.iso(row.getReceivableTime()), + toMinor(row.getReceivableMoney()), row.getReceivableState(), + toMinor(row.getInvoiceMoney()), toMinor(row.getNotInvoiceMoney()), + toMinor(row.getInvoicingProgressMoney()), row.getInvoiceState(), + row.getInvoiceName(), + ChangesEngine.iso(effective), mt, deleted ? ChangesEngine.iso(effective) : null)); + } + + private static String stableId(Long id) { + return id == null ? null : String.valueOf(id); + } + + static Long toMinor(BigDecimal amount) { + return amount == null ? null + : amount.movePointRight(2).setScale(0, RoundingMode.HALF_UP).longValue(); + } +} diff --git a/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/sync/SyncChangeSchemas.java b/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/sync/SyncChangeSchemas.java index 03d2617..39eb190 100644 --- a/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/sync/SyncChangeSchemas.java +++ b/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/sync/SyncChangeSchemas.java @@ -59,6 +59,30 @@ final class SyncChangeSchemas { @JsonProperty("deleted_at") String deletedAt) { } + record ReceivableOrderChange( + @JsonProperty("receivable_order_id") String receivableOrderId, + @JsonProperty("receivable_no") String receivableNo, + @JsonProperty("order_no") String orderNo, + @JsonProperty("customer_name") String customerName, + @JsonProperty("agent_id") String agentId, + @JsonProperty("agent_name") String agentName, + @JsonProperty("property_id") String propertyId, + @JsonProperty("property_name") String propertyName, + @JsonProperty("sale_company") String saleCompany, + @JsonProperty("order_time") String orderTime, + @JsonProperty("receivable_time") String receivableTime, + @JsonProperty("receivable_money_minor") Long receivableMoneyMinor, + @JsonProperty("receivable_state") Integer receivableState, + @JsonProperty("invoice_money_minor") Long invoiceMoneyMinor, + @JsonProperty("not_invoice_money_minor") Long notInvoiceMoneyMinor, + @JsonProperty("invoicing_progress_money_minor") Long invoicingProgressMoneyMinor, + @JsonProperty("invoice_state") Integer invoiceState, + @JsonProperty("invoice_name") String invoiceName, + @JsonProperty("updated_at") String updatedAt, + long version, + @JsonProperty("deleted_at") String deletedAt) { + } + record ContractChange( @JsonProperty("contract_id") String contractId, @JsonProperty("contract_no") String contractNo, diff --git a/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/tool/ChangesTools.java b/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/tool/ChangesTools.java index cd939a0..5713d55 100644 --- a/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/tool/ChangesTools.java +++ b/xiaoqu-agent-service/src/main/java/me/iiv/agent/mcp/tool/ChangesTools.java @@ -14,6 +14,7 @@ import me.iiv.agent.mcp.sync.MallOrdersSyncEntity; import me.iiv.agent.mcp.sync.PropertiesSyncEntity; import me.iiv.agent.mcp.sync.RelocationOrdersSyncEntity; import me.iiv.agent.mcp.sync.RepaymentDetailsSyncEntity; +import me.iiv.agent.mcp.sync.SaleReceivableOrdersSyncEntity; import me.iiv.agent.mcp.sync.RepaymentTargetsSyncEntity; import me.iiv.agent.mcp.sync.UsersSyncEntity; import me.iiv.agent.mcp.sync.WithdrawOrdersSyncEntity; @@ -141,6 +142,23 @@ public class ChangesTools implements ToolObject { } @XqTool(category = "sync", kind = "read") + @Tool(name = "sale-receivable-orders.changes.list", + description = "增量同步应收单主表(m1.sale_receivable_order,整单口径)。" + PROTOCOL_DESC + + "items 字段:receivable_order_id/receivable_no/order_no/customer_name/" + + "agent_id/agent_name/property_id/property_name/sale_company/" + + "order_time/receivable_time(带时区)/receivable_money_minor(应收金额,分)/" + + "receivable_state(0 未收款 1 全部收款 2 部分收款)/" + + "invoice_money_minor(已开票金额,分)/not_invoice_money_minor(未开票金额,分)/" + + "invoicing_progress_money_minor(开票中金额,分)/" + + "invoice_state(0 未开票 1 全部开票 2 部分开票)/invoice_name/" + + "updated_at/version/deleted_at。") + public Map saleReceivableOrdersChangesList( + @ToolParam(required = false, description = SYNC_TOKEN_DESC) String syncToken, + @ToolParam(required = false, description = CURSOR_DESC) String cursor, + @ToolParam(required = false, description = LIMIT_DESC) Integer limit) { + return changesEngine.execute(SaleReceivableOrdersSyncEntity.NAME, syncToken, cursor, limit); + } + @Tool(name = "repayment-details.changes.list", description = "增量同步客户回款明细(m1.saler_repayment_customer,客户×订单×周期)。" + PROTOCOL_DESC + "items 字段:repayment_detail_id/owner_user_id(销售稳定 user.id)/owner_name/" + "saler_agent_id/saler_agent_name/property_id/property_name/district_id/district_name/customer_name/"