Skip to content

携岛 XieDao —— 项目架构全景(按业务功能模块) ​

本文档基于对代码库的全面探索整理而成,覆盖 4 个端 + 后端的 8 大业务域。最后更新:2026-07-06。 探索方法:通过 codegraph 索引(2544 文件 / 36028 节点 / 72840 边)+ 并行 subagent 深入各业务域。


目录 ​


项目总览 ​

携岛 XieDao 是基于 RuoYi-Vue 3.9.1 二次开发的海南旅游生活服务平台,覆盖"平台 + 商户 + 用户"三端 O2O 旅游电商(含酒店/租车/接送/摄影/定制游/笔记社区/商城/钱包/IM/微信支付分账)。域名 api.xiedao888.cn,WSL 工作目录为 /home/ubuntu/projects/xiedao。

端构成 ​

端路径技术栈用途
后端Api/Java 21 + Spring Boot 3.5.8 + MyBatis + 微信支付V3API 中枢
平台后台AdminWeb/Vue3 + Element Plus + Pinia + Vite 6平台运营管理
商家 WebMerchantWeb/同上(RuoYi-Vue)商家 PC 管理
用户小程序App/原生小程序 + glass-easel + tdesignC 端用户
商家小程序MerchantApp/原生小程序 + OpenIM商家移动办公

后端 URL 前缀约定 ​

包URL 前缀消费端
controller/app//api/app/**WeChat 小程序(用户)
controller/merchant//api/merchant/**商家 App
controller/platform//api/admin/**AdminWeb 仪表盘
controller/system/、monitor//system/**、/monitor/**RuoYi 原生系统管理

后端 Maven 模块结构 ​

ruoyi-admin      Web 入口 + 全部 Controller(可执行 jar)
ruoyi-framework  Spring Security/JWT/AOP/数据源路由
ruoyi-system     业务 domain + service + MyBatis mapper(业务核心)
ruoyi-common     通用工具/注解/常量
ruoyi-quartz     定时任务(微信支付查单/关单/退款同步/分账)
ruoyi-generator  代码生成器

Controller 三端分布(共 107+ 个) ​

包数量主要内容
controller/app/33用户端:登录/酒店/租车/摄影/商城/拼团/笔记/钱包/IM/支付/PayScore
controller/merchant/26商家端:登录/商品/订单/调度/核销/财务/提现/司机/IM
controller/platform/48平台端:Admin*(CRUD)+ Xd*(业务实体管理)

模块 1️⃣ 订单 + 支付 + 退款 + 对账(核心交易枢纽) ​

这是整个项目最核心、最复杂的子系统。代码主要分布在:

  • Api/ruoyi-system/src/main/java/com/xiedao/system/domain/ — 实体
  • Api/ruoyi-system/src/main/java/com/xiedao/system/service/{order,payment}/ — 状态机与编排
  • Api/ruoyi-system/src/main/java/com/xiedao/system/service/order/handler/ — 9 种业务类型 Handler
  • Api/ruoyi-admin/src/main/java/com/xiedao/web/controller/{app,merchant,platform}/ — 三端 Controller
  • Api/ruoyi-quartz/ + Api/ruoyi-admin/.../web/task/ — 定时任务

1.1 订单领域 ​

实体表职责
XdOrderxl_order瘦交易头:orderNo/userId/merchantId/activityType/各种分金额/状态字段/parentOrderNo(合单父单号)
XdOrderItemxl_order_item明细:unitPriceFen/paymentFeeFen/merchantIncomeFen/commissionRate/snapshotJson
XdOrderEventxl_order_event状态变更审计日志(fromStatus/toStatus/operator/bizId)
XdOrderVoucherxl_order_voucher券码(12位)+ 状态(0未用/1已核销/4已预约)+validStart/End+verifyTime

状态枚举与状态机 ​

OrderStateMachine(唯一入口,乐观并发条件 UPDATE ... WHERE status=from + 0 行幂等检查):

  • markPaid PENDING_PAY→PAID(写 payTime + 发布 OrderPaidEvent)
  • cancelPendingOrder PENDING_PAY→CANCELLED
  • complete PAID→COMPLETED
  • startRefund PAID|COMPLETED→REFUNDING(多前置)
  • markRefunded REFUNDING→REFUNDED
  • restoreAfterRefundFailed REFUNDING→原状态

OrderSettlementStateMachine:NONE→PENDING_SETTLE→AVAILABLE→DEDUCTED

每次迁移都写一条 xl_order_event 审计日志。

创建编排(解耦多业务类型) ​

OrderOrchestrator.createOrder(OrderCreateContext):

  1. OrderTypeHandlerRegistry.getRequired(activityType) 取对应 Handler
  2. handler.buildOrderDraft(ctx) 产出 OrderDraft(order + items)
  3. 金额汇总由 Orchestrator 自算(不信任请求传入)
  4. 写 xl_order + 批量插 xl_order_item,status=PENDING_PAY

订单号前缀(区分业务类型):

  • PH 房 / CR 车 / IR 物品 / TF 接送 / RM 房型 / PK 套餐 / ML 商城 / OD 团购
  • 预支付用 PAY_ 前缀作微信 out_trade_no(修复了历史 OD_ 前缀的查单 bug)

OrderTypeHandler SPI(9 个实现,service/order/handler/): buildOrderDraft / onPaid / onCompleted / onCancelled / onRefunded / settlementPolicy()。 SettlementPolicy.plusDays(n) 工厂提供 T+N 可提现时效。 OrderPaidEventListener(@TransactionalEventListener AFTER_COMMIT) 异步调 handler.onPaid(ctx)。

合单(伪合单)概念 ​

重要:服务商合单支付模式 + 特约商户号分账已在"阶段八"清理。当前为"伪合单"模型。

  • 「子单 = 一笔 xl_order」,「合单 = 共享同一 parentOrderNo 的多笔订单」
  • XdOrder.parentOrderNo 写入;多笔子单 payAmountFen 汇总发起一笔 JSAPI
  • 支付回调按父单号批量标记子单 PAID;券/钱包/券核销在子单粒度逐笔处理

1.2 支付领域 ​

实体表职责
XdPaymentRecordxl_payment_record支付主单:payNo/totalAmountFen/wechatAmountFen/walletAmountFen/status(PENDING/SUCCESS/CLOSED/REFUNDING/REFUNDED)/expireTime/version
XdPaymentOrderRel—支付主单↔订单 N:N 关系表(含微信/钱包分摊金额)

两套配置(重要澄清) ​

配置类当前状态说明
PlatformWechatPayConfig唯一启用平台直连商户号 V3,构建 RSAPublicKeyConfig/RefundService/NotificationParser 等官方 SDK Bean。@PostConstruct 强校验缺失即抛异常
WechatPayConfig(服务商 SP)已删除"阶段八"清理。无同名 Java 文件残留
WechatPayScoreConfig独立微信支付分押金配置,含 mockMode 开关

PaymentOrchestrator ​

  • createPayment(orderIds, userId, openid) — 合并支付:写 payment_record + order_rel,调 prepayJsapiByPayment
  • applyPaymentSuccess(paymentId, transactionId, paidTime) — 幂等推进支付主单→SUCCESS → 调 OrderStateMachine.markPaid
  • closePayment(paymentId, reason) — 关单;若微信返回 ORDERPAID 转调 applyPaymentSuccess 补偿
  • refundOrder(orderId, reason) — 整单退款:按渠道独立跟踪 wechat_refund_status / wallet_refund_status

IPlatformWechatPayService 关键方法 ​

  • prepayJsapi / prepayTransferOrder / jsapiPrepayDeposit / nativePrepay / prepayJsapiByPayment
  • queryByOutTradeNo / queryByTransactionId / closeOrder
  • refundDeposit / refundByPayNo / queryRefundByOutRefundNo
  • downloadTradeBill / parsePayNotify / parseRefundNotify

dev_ 前缀 openid 走 mock 旁路。

支付相关 Controller ​

  • AppPayController /api/app/pay:prepay / confirm / status / notify / refund-notify
  • PayScoreNotifyController /api/pay-score:⚠️ 未验签、未 AES 解密、TODO 待实现

1.3 退款体系 ​

XdRefundRecord (xl_refund_record) 关键字段:

  • paymentId(新流程关联支付主单)/ sourceOrderStatus(退款前订单快照,用于失败回滚)
  • wechatRefundStatus + walletRefundStatus 双渠道独立跟踪
  • refundType:user_apply / appointment_cancel / pintuan_penalty / user_cancel 等
  • status:PENDING/PROCESSING/SUCCESS/FAILED/PARTIAL_REFUNDED
  • wxRefundId/wxStatus(PROCESSING/SUCCESS/CLOSED/ABNORMAL) + lastErrorCode/Error

关键方法(XdOrderServiceImpl):

  • applyRefund(userId, orderId, reason) — 用户申请
  • auditMerchantRefund(merchantId, ...) — 商户审批入口
  • auditRefund(refundId, status, ...) — 通过→调微信 callWechatRefund;拒绝→restoreAfterRefundFailed
  • handleRefundCallback(RefundCallbackData) — 微信回调:SUCCESS 回填+推进 order→REFUNDED;CLOSED→回滚;ABNORMAL→人工介入
  • 故意不做 Java 短路幂等,让 SQL WHERE wx_status != 'SUCCESS' 兜底并支持自愈

拼团退款三分支:未成团全退(user_cancel) / 免费窗口全退 / 超窗扣手续费(pintuan_penalty 按 XdPintuanCategoryConfig.penaltyRate,含商户钱包扣减)

1.4 个体结算(替代微信分账) ​

散客"分账"概念已物理摘除:不再调用微信分账接口、不再用特约商户号,改用"商家转账到零钱"做个体(司机/摄影师)结算。

XdIndividualSettlement (xl_individual_settlement) 字段:settleDate/orderId/orderType(transfer/photography)/workerId/openid/openidAppid/amountFen/outBatchNo/outDetailNo/wxBatchId/wxDetailId/status(PENDING/PROCESSING/SUCCESS/FAILED/NO_OPENID)/failReason/retryCount。

IndividualSettlementService(走微信 /v3/transfer/batches):

  • runDailySettlement(T-1) 扫已完成 → 幂等去重插入 → submitBatch(按 openidAppid 分组,姓名 PrivacyEncryptor 加密)
  • pollBatchResults 查批次状态
  • manualRetry(settlementId) — retryCount < 3 才重试

ICommissionCalculator 仅剩 SPI 扩展点,无默认实现且无任何调用方(分账逻辑已物理删除,平台佣金以"支付回调写入 XdOrderItem.merchantIncomeFen"方式完成)。

1.5 对账与发货同步 ​

XdBillReconciliation (xl_bill_reconciliation):billDate/orderNo/transactionId/wxAmount/localAmount/diffAmount/status(matched/diff/missing/wx_missing)。 WechatBillReconcileTask(每天 10:30):下载 T-1 账单 → 解析 CSV → 比对 xl_order.payAmountFen → 写对账记录。

XdWxShipSync (xl_wx_ship_sync):orderId/orderNo/wxTransactionId/logisticsCompany/logisticsNo/status(PENDING/SUCCESS/FAILED/GIVEUP/SKIPPED)/retryCount/maxRetry。 MallShipSyncTask(每 5min):批量调 WxShippingApiService.uploadShippingInfo,参数错误→GIVEUP 人工介入,否则 markFailed,retryCount >= 5 → GIVEUP。

1.6 定时任务(兜底一致性) ​

Job类型频率职责
PaymentExpireTaskQuartz30 秒支付单过期关单
PayQueryTask@Scheduled2 分钟支付查单兜底,SUCCESS 补偿
RefundSyncTaskQuartz5 分钟退款状态同步
RefundStateSyncTask@Scheduled5 分钟退款状态同步(两份近似实现⚠️)
MallShipSyncTaskQuartz5 分钟微信「发货信息管理」同步
MallAutoConfirmTaskQuartz每天 02:00商城发货超 15 天自动确认收货
WechatBillReconcileTask@Scheduled每天 10:30下载 T-1 账单对账
IndividualSettlementTask@Scheduled02:00 + 03:00个体结算批次生成 + 查询
MerchantWalletSettlementTask@Scheduled每天 01:00商户钱包结算与分成入账(含专车司机/摄影师)
RentalOverdueTaskQuartz—租赁超期处理
XdVoucherExpireTask——券码过期处理

1.7 关键 Controller ​

用户端 AppOrderController /api/app/orders ​

  • POST /groupbuy, /pintuan, /package, /package/preview, /room, /mall —— 各类下单
  • GET /list, /{orderNo} —— 列表/详情
  • POST /{id}/cancel, /{id}/refund —— 取消/退款
  • POST /api/app/hotel/appointments, /api/app/hotel/appointments/{id}/cancel —— 酒店预约
  • POST /{id}/confirm-receive, GET /{orderNo}/logistics —— 商城收货/物流

商户端 MerchantOrderController /api/merchant/orders ​

  • GET /list, /{id}, POST /{id}/verify, /vouchers/lookup, /verify-batch, PUT /{id}/refund(审批)

平台端 AdminOrderController /api/admin/orders ​

  • GET /list, /{id}, /refund/list, PUT /refund/audit, GET /{orderId}/combine-detail, POST /voucher/verify

模块 2️⃣ 商户体系 + 商品/产品/套餐 + 商城 ​

2.1 商户体系 ​

XdMerchant (xl_merchant) 核心字段 ​

  • 标识:id/entryType(personal/merchant)/phone(唯一)/password(BCrypt)/openId
  • 分类:businessType(locallife/hotel/mall/delivery) + categoryId + categoryCode(决定菜单/佣金费率/所需资料严苛度)
  • 状态/审核:status 1待平台审核 / 2平台审核驳回 / 3待支付 / 4正常营业 / 5关店审核中 / 6已关店 / 7禁用(枚举 MerchantStatus)+ rejectReason/orderNo(M 前缀保证金)/paidAt/auditBy
  • 费用/佣金:entryFee/deposit/totalAmount(分) + 3 套 commission(groupbuy/pindan/activity)+ couponRatioMerchant/Platform + promotionCommissionRate + newUserReward
  • 平台直连入驻资料:subjectType(INDIVIDUAL/ENTERPRISE)+全部入驻资料(legalPersonIdCard/Mobile/BankAccountNumber AES 脱敏密文)

入驻与审核流程 ​

apply(status=1 待审) → 平台审核 XdMerchantServiceImpl.auditMerchant
  ├ 通过 + 金额>0 → status=3 待付保证金 → prepay(Native/jsapi) → handlePayCallback
  │     → status=4 营业(同时初始化钱包 + 绑首张银行卡)
  ├ 通过 + 金额=0 → status=4 营业
  └ 驳回 → status=2 → resubmit → 回到 1
cancel(注销)
  ├ 未付 → status=6 已关店
  └ 已付 → status=5 关店审(CAS 抢占)+ 建退款记录 + afterCommit 调微信退款
auditCloseMerchant(approve=true→6 退保证金 / false→回滚 4)

XdMerchantMenu 商家菜单系统 ​

  • 与 RuoYi SysMenu 完全独立的另一套表(xl_merchant_menu)
  • 字段结构对齐 SysMenu(menuId/parentId/menuType(M目录/C菜单)/path/component)
  • 按 merchantTypes 字段(逗号分隔或 all)控制可见商户类型
  • 商户端 GET /api/merchant/getRouters 下发
  • 平台端 AdminMerchantMenuController /api/admin/merchantMenu 维护

商家钱包体系 ​

实体关键字段
XdMerchantWallet (xl_merchant_wallet)merchantId/balanceFen(可用)/frozenFen(冻结)/pendingSettleFen/totalEarnedFen/totalWithdrawnFen
XdMerchantWalletLog (xl_merchant_wallet_log)amountFen/balanceAfterFen/bizType(ORDER_PENDING_SETTLE/ORDER_SETTLE_AVAILABLE/ORDER_COMPLETE/REFUND_DEDUCT/WITHDRAWAL/WITHDRAWAL_REJECT/WITHDRAWAL_PAID)
XdMerchantWithdrawal (xl_merchant_withdrawal)withdrawalNo(W 前缀)/status(PENDING/APPROVED/PAID/REJECTED/FAILED)/bankInfo/version(乐观锁)

钱包闭环:creditForOrder(待结算入账:冻结+pendingSettle 抬升) → unfreezeForOrder(完成时:冻结→可用,写 ORDER_COMPLETE) → deductForRefund(退款扣减,写 REFUND_DEDUCT)。所有操作幂等(by order+bizType)。

提现流程:

applyWithdrawal(balance 原子扣减 + 写 PENDING + WITHDRAWAL 流水;已有 pending 不可再申请)
  → approve(CAS PENDING→APPROVED)
  → markPaid(APPROVED→PAID + frozen 减 + totalWithdrawn 加 + 写 WITHDRAWAL_PAID)
  → 支付失败 markFailed(余额退回)
  → 驳回 reject(余额退回 + 写 WITHDRAWAL_REJECT)

所有状态变更带 version 乐观锁。

2.2 双套商品体系 ​

A. XdProduct(到店核销类) ​

关联实体作用
XdProduct (xl_product)businessType(locallife/hotel/mall/delivery) + categoryId + roomTypeId(酒店必填) + bookingMode(0团购/1原价预订)
XdProductActivity (xl_product_activity)一商品可挂多个活动,activityType(groupbuy/pintuan/package);priceMode = self(抽成)/floor(平台底价+商户加价);status(0待审/1启用/2下架/3禁用)
XdProductPriceCalendar (xl_product_price_calendar)activityExtraFee(平台)+settlementExtraFee(商户) + stock/sold + auditStatus 嵌主表(0无需/1待/2通过/3驳回)
XdProductNoticeConfig (JSON 结构,非 DB 表)购买须知项:key/label/value/inputType(daterange/timerange/richtext/text/number)/sort

定价双轨:self(抽成比例)vs floor(平台底价 settlementPrice + 商户加价);售价 = 活动基础价 + 日历加价。 日历 auditStatus 单独审核(直接嵌主表)。

B. XdMallProduct(电商履约类) ​

实体关键字段
XdMallProduct (xl_mall_product)productType/SKU/description/brand/unit/weight/auditRemark/salesCount/isFlashSale+flashSale*(秒杀)/isSubsidized+subsidyAmount(补贴)/isLocalSpecialty(海南特产)
XdMallSkuspecData(JSON 规格)+price/originalPrice(分)+stock+skuImage+skuCode
XdMallCartuserId+productId+skuId+quantity+selected
XdMallAddressprovince/city/district/detailAddress+isDefault

XdProduct vs XdMallProduct 边界:

  • XdProduct:服务"到店核销"业态(团购/拼团/套餐/酒店/租车/摄影/接送),绑定 ProductActivity + PriceCalendar,资金进入钱包冻结→完成结算。
  • XdMallProduct:服务"实物电商履约"业态(带物流),独立 SKU/库存/秒杀/补贴/特产标记。
  • 商户要经营商城需 businessType=mall。

2.3 套餐(平台主表+商户报名的众包组合) ​

实体关键字段
XdPackage (xl_package)packageName/city/packagePrice/originalPrice(分)/groupRules/duration/itinerary(行程 JSON)/packageType/sortOrder/delFlag/items(关联)
XdPackageItem (xl_package_item)packageId/productId/activityId/platformPrice+originalPrice/groupName/groupKey(分组)/merchantId/applyStatus(报名状态)/auditBy/auditReason/sortOrder/dayNumber(行程天数)/areaId
XdPackagePriceCalendar (xl_package_price_calendar)packageId/date/extraFee/stock/sold/status

核心校验:saveItemPrices 校验 "各 platformPrice 之和 == packagePrice"。

运营模式:套餐主表+价格日历由平台配置;套餐内每个商品由商户分别通过 MerchantPackageController 报名(applyStatus/audit 字段)并提交 platformPrice,平台审核通过后纳入套餐。

2.4 基础数据三件套 ​

实体表作用前端用法
XdCategoryxl_category统一分类树:businessType+parentId+level+code+entryFee+deposit(入驻费/保证金)+isEnabled商户入驻选分类/菜单推导/商品归类
XdTabGroupxl_tab_groupApp 首页 Tab 分组:sceneType(groupbuy/pintuan/package)+name+icon+sort+isEnabled,关联 categoryIdsApp 按场景拉分组,分组下嵌套分类
XdRegionxl_region区域字典(市县名,如海口、万宁)+sortOrder+status套餐选区/特产地理/+App 区域筛选

模块 3️⃣ 履约服务类商品(酒店/租车/租赁/接送/摄影/定制游) ​

3.1 酒店(双表审核机制) ​

实体关键字段
XdHotelAppointment (xl_hotel_appointment)orderId/orderNo/activityType(room/groupbuy/package)+sourceType(AUTO/MANUAL下单即预约 vs 手工预约)+roomTypeId/checkInDate/checkOutDate/nights/rooms/guestName/Phone/status(0待商户确认/1已确认/2协商中/3已撤销)+cancelSubReason(USER_DISAGREE/USER_TIMEOUT/MERCHANT_TIMEOUT/USER_CANCEL)+surchargeOrderNo(差价单号)
XdRoomType (xl_room_type)merchantId/roomName/roomType(大床/双床/套房)/totalRooms/basePrice(分)/bedInfo/area/maxGuests/facilities(JSON)/commissionRate
XdRoomTypeAudit (xl_room_type_audit)merchantId/roomTypeId/roomName/basePrice/totalRooms + auditStatus(1待审/2通过/3驳回)
XdRoomCalendar (xl_room_calendar)merchantId/roomTypeId/date/price(分)/extraFee/originalPrice/stock/sold/status(0售罄/1可售/2不可约)
XdRoomCalendarAudit (xl_room_calendar_audit)双列对照:old/newPrice、old/newExtraFee、old/newStock、old/newStatus + auditStatus
XdHotelHotArea / XdHotelHotKeywordApp 首页热门区域 / 热门搜索词

审核模式:酒店采用"双表双列"独立审计——商户新建/修改房型或日历时价不直接落库,写入审计表等待平台审批;通过时回写正式表。其他模块大多把 auditStatus 直接内嵌主表。

关键 Service:

  • IXdHotelAppointmentService:createFromRoomOrder/PackageOrder/PintuanOrder/VoucherRequest + confirm/submitNegotiation/userAgree/userDisagree/userCancel + scanMerchantTimeout/scanUserTimeout/cancelByTimeout
  • IXdRoomCalendarAuditService:insertAudit/batchInsertAudit + approveAudit/rejectAudit/approveBatch/rejectBatch

价格日历:酒店用 XdRoomCalendar.price 直接表达;其他业态(团购/套餐)另用 XdProductPriceCalendar。

3.2 租车与租赁(双链路同骨架) ​

维度租车 car_rental非车租赁 rental
履约单XdCarRentalDispatchXdRentalOrderDispatch
计价/库存关联 XdCarModel + XdMerchantCar(物理车一辆辆登记)关联 rentalItemId(普通租赁商品 xl_product),按 quantity 叠加
计价模式按日(dailyPrice),含里程/油量点检pricingMode + rentalStart/rentalEnd/rentalQuantity,按日/件计
押金XdRentalDeposit(businessType=car_rental)XdRentalDeposit(businessType=rental)
评价共用 XdRentalReview(rentalItemId 双义键)同

车型层级:XdCarType(类目轿/SUV/MPV) → XdCarModel(PaaS标准车型库含 dailyPrice/depositAmount) → XdMerchantCar(商户挂车牌)。

押金 XdRentalDeposit(跨两业务通用):

  • depositMode:wechat_score(微信支付分冻结) / prepaid(预付金)
  • status:0待收取 / 1已冻结 / 2已退还 / 3部分扣除 / 4全额扣除
  • 配套 XdRentalDepositService:freezeDeposit / refundDeposit / deductDeposit(amount, reason)

派单流程(IXdCarRentalDispatchService):

createDispatch → assignMerchant → accept/reject → pickupCar(点检里程/油量/照片)
  → returnCar(还车点检+损伤) → confirmComplete → settle 结算
定时任务 markOverdue 标记逾期并算 overdueFee

3.3 接送机/包车(统一订单+三种计价) ​

计价实体(3 种 serviceType) ​

实体serviceType用法
XdTransferRoute (xl_transfer_route)route固定价路线:routeName/startName/endName/distanceKm/economyPrice+luxuryPrice +对应 platformRatio
XdTransferCharterPrice (xl_transfer_charter_price)chartervehicleType(economy/luxury) × charterType(hour/day) 二维表 + minQuantity
XdTransferTaxiPrice (xl_transfer_taxi_price)taxi分段计费:segmentOrder/basePrice+baseKm 起步/minKm-maxKm 区间/pricePerKm
XdCharterPrice (旧版⚠️)兼容含超出公里+远途分段两段计费,与新 CharterPrice 重叠
XdTransferPriceRule (区间规则⚠️)兼容与 TaxiPrice 分段是两套并存配置

订单与派单 ​

  • XdTransferOrder (xl_transfer_order):核心订单表,serviceType=taxi/charter/route 决定价来源;含起点/终点经纬度、distanceKm(打车用)、charterType+charterQuantity(包车用)、routeId(路线用)、totalAmount/payAmount/platformAmount/driverAmount(分)、司机时间线。专车特例:payAmount = totalAmount(无优惠)
  • XdTransferDispatch (xl_transfer_dispatch):与订单 1:1,dispatchStatus(0待派/1派单/2接单/3进行/4完成/5取消) + dispatchMode(manual/auto)

派单流程(IXdTransferDispatchService):

triggerAutoDispatch(支付成功后) → driverAccept/driverReject(尝试下一位) → startService(位置) → completeService(结算)
复用 XdDriverVehicle(司机端座驾) + XdDriverLocation(位置上行) + DriverController(司机上下线)

计价 Service IXdTransferPriceService(提交订单时调用唯一入口):

  • calcTaxiPrice:按 TaxiPrice 逐段累计,第 1 段起步段;注释明确 pricePerKm 按 "元/km" DB 存,运行时 ×100 → 分/km
  • calcCharterPrice:按 vehicleType+charterType 取规则,校验最小数量
  • calcRoutePrice:按 routeId 取固定价,按 vehicleType 选 economy/luxury

3.4 摄影 + 定制游 ​

旅拍 ​

  • XdPhotographyPackage (xl_photography_package):平台维护的标准套餐(含 shootingDuration/costumeCount/sceneCount/deliveryDays/destination),App 直接下单
  • XdPhotographyDispatch (xl_photography_dispatch):派单流程 assignPhotographer → accept/reject → startShooting → deliverWork(deliverUrl) → confirmComplete → settle

定制游(轻流程) ​

  • XdCustomTour (xl_custom_tour):userId/contactName/destination/startTime/endTime/days/remark + status(0待处理/1已联系)
  • 无订单/派单/结算——用户提交需求 → 后台销售人工联系 → status 0→1

3.5 跨业务共性 ​

  1. 统一的派单状态机骨架:创建 → assign → 接/拒 → 开始 → 完成 → 结算(seettle) + settlementStatus + rejectReason
  2. 平台抽成通用字段:commissionRate / platformRatio / settlementRate
  3. 押金复用:XdRentalDeposit 单表跨两类业务
  4. 评价复用:XdRentalReview 跨两类
  5. 司机抽象:XdDriverVehicle + XdDriverLocation + DriverController 由专车+未来车辆类业务共用

模块 4️⃣ 用户 + 社交 + 钱包 ​

4.1 用户与社交 ​

实体字段要点
XdAppUser (xl_app_user)openid/unionid/phone/nickname/avatar/bio/gender/status(0正常/1禁用)/newcomerGiftReceived/lastLoginTime+IP + 推广体系:referCode(6位注册自动生成)+referrerId(扫码绑定)
XdUserFollow (xl_user_follow)followerId/followingId + isMutual(互关校验,IM 私信用)
XdUserGuest (xl_user_guest)userId+name+phone+isDefault —— 常用入住人,下单复用
XdWallet (xl_wallet)balance/frozenAmount/totalRecharge/totalConsume/totalRefund/totalReward(分)+version(乐观锁)
XdWalletTransaction (xl_wallet_transaction)transactionNo/type/direction(收/支)/balanceBefore/balanceAfter/relatedOrderNo/remark

4.2 登录与 JWT ​

AppLoginController.login 步骤:

  1. WechatMiniAppService.jscode2session(code) 拿 openid/unionid;本地无 secret 走 mock(dev_ 前缀 openid + 占位手机号)
  2. selectByOpenid —— 不存在则 registerUser(isNewUser=true),存在则 updateLoginInfo,禁用抛错
  3. tokenService.createAppToken(XdAppUser):fastUUID 作 appKey → Redis(TTL expireTime×24 min)+ JWT 含 LOGIN_USER_KEY/userId/USER_TYPE_APP
  4. 返回 token+user+isNewUser+grantNewcomerGift 自动发券并返回 giftCoupons
  5. 滑动续期:剩余 < 2h 自动续;delAppToken 删 Redis

模块 5️⃣ 笔记社区 + 旅游攻略 + IM ​

5.1 笔记核心实体链 ​

实体要点
XdNote (xl_note)authorType("user"/"merchant")/authorId/title/content/coverImage/images(列表)/videoUrl/location/lat/lng/viewCount/likeCount/collectCount/commentCount/status/rejectReason/isTop/isRecommend
XdNoteDraft草稿(含 topicIds JSON 字符串)
XdNoteCommentparentId(树形 self-ref)+replyToUserId+likeCount+status,children 子评论
XdNoteInteractiontype 字段记录点赞/收藏
XdNoteProductRel笔记→商品挂载(productTitle/productCover 快照)
XdNoteViewLoguserId+noteId+duration(停留时长,喂个性化)

话题系统:XdNoteTopic(话题) + XdNoteTopicRel(多对多),有 source(官方/用户)区分。

5.2 个性化推荐 ​

XdNoteRecommendServiceImpl:

  • recordView(userId, noteId, duration):写 ViewLog + 增浏览数
  • refreshUserInterest(userId):SQL selectInterestScoresByUser 按近一周浏览计算话题兴趣分 → 写 Redis Hash note:interest:{userId} (TTL 7 天)
  • getUserInterestTopicIds(userId):从 Redis Hash 按分降序取 Top10 topicIds
  • 定时 NoteRecommendTask.refreshActiveUserInterests(建议 cron 0 0 3 * * ?)
  • App list 用法:有登录且兴趣非空 → selectRecommendedNoteList(interestTopicIds, topicId);否则 selectHotNoteList(热门兜底)

5.3 三端入口 ​

  • 用户 AppNoteController /api/app/notes:list(个性化推荐,支持 seed)/ topics / 详情(带 liked/collected) / 发布 / 编辑(校验属主) / 我的 / 收藏 / 点赞 / 评论 / 上报浏览 / 按用户页+stats + AppNoteDraftController 草稿 CRUD
  • 商家 MerchantNoteController /api/merchant/notes:商家发笔记(authorType="merchant") + 回复评论
  • 平台 AdminNoteController /api/admin/notes:approve/reject/offline/top/recommend + user-stats + AdminNoteTopicController 话题 CRUD + AdminNoteCommentController 评论删除

5.4 旅游攻略 ​

  • XdTravelGuide (xl_travel_guide):title/summary/content/coverImage/viewCount/sortOrder/status
  • XdTravelGuideProductRel:guideId/itemType/itemId(攻略挂多种业务商品:团/酒店等)
  • 用户 AppTravelGuideController 列表/详情;平台 AdminTravelGuideController 发布/下线/CRUD

5.5 IM 客服 ​

集成自建 OpenIM,业务后端不维护消息表,消息由 OpenIM 服务存储。

  • OpenIMConfig 配置服务端 API、客户端 API、WebSocket、共享密钥和客服管理员账号
  • OpenIMService 负责幂等注册账号、签发用户 Token;三端统一通过 /im/credentials 获取凭证
  • 账号命名:user_{userId} / merchant_{id} / admin_{userId}(客服)
  • C 端 canChat/{targetUserId} 校验 isMutual 互关;公开 customer-service 客服号

模块 6️⃣ 拼团 + 团购 + 营销活动 ​

6.1 拼团机制 ​

实体字段
XdGroup (xl_group)productId/activityId/activityProductId/status(0等待中/1成团成功/2失败/3取消)/requiredCount/expireTime(成团截止)/creatorName/members/currentCount
XdGroupMemberuserId/orderId/isLeader(0普通/1团长)/joinTime

状态流转(PintuanOrderHandler.onPaid 触发):

  1. 团长支付成功 → createGroup 建 status=0;expireTime = now + pintuan.timeout.hours(默认 24h)
  2. 团员加入:createPintuanGroup/joinPintuanGroup 下单,支付回调按 orderId 幂等插 Member(防重)
  3. 成团:paidCount >= requiredCount → setGroupSuccess(status=1) → 批量发券(券 valid_end 由 PintuanCategoryConfig.verifyHours 决定)
  4. 超时:handleTimeoutGroups 扫过期 → setGroupFailed(2) → 未支付取消返还券 / 已支付 createAutoRefundForPintuanFailed 自动退款
  5. 取消:cancelGroup status=3

XdPintuanCategoryConfig (xl_pintuan_category_config):categoryId + verifyHours(核销时长)+cancelMinutes+penaltyRate(超窗费率)。退款扣手续费按此配置,由商户钱包 deductForRefund 扣减。

6.2 营销活动 ​

XdProductActivity 字段:productId/merchantId/city/activityType/priceMode(amountPrice+commissionRate+settlementPrice+originalPrice)/limitPerUser/refundType/useRules/purchaseNotice/noticeConfigList(JSON)/validType(1天数/2日期)/validStart+End/sort/status(0待审/1启用/2下架/3禁用)+auditReason/auditBy/auditTime/platformMargin。

Service IXdProductActivityService:

  • insertActivity(校验同类型不可重复)
  • auditActivity(id, status, reason, auditor) 平台审核
  • setActivityPrice(id, price) 平台定价
  • onlineByProductId/offlineByProductId 批量上下架所有活动

模块 7️⃣ 优惠券 + 新人礼包 + 推广分销 ​

7.1 优惠券 ​

实体要点
XdCouponTemplate + XdCouponVersion模板保存稳定业务身份,已发布版本固化满减/直减规则、默认商户承担金额、xd_category 适用分类和有效期
XdCouponClaimCampaign领券中心投放窗口、总量与已发数量;同一用户对同一模板只能主动领取一次
XdUserCoupon发放时固化规则、分类、承担金额和来源;状态按 AVAILABLE/LOCKED/USED/EXPIRED/VOID 流转
XdOrderCouponUsage + XdOrderCouponAllocation下单时固化实际优惠、商户/平台承担、结算和订单明细分摊,支付、钱包、详情及退款只读快照

7.2 新人礼包 ​

XdCouponBundle/XdCouponBundleItem 组成通用礼包。新人礼包在 AppLoginController.login 首次登录时幂等发放全部优惠券;普通礼包支持 N 选 K,每个礼包每位用户只能领取一次。

7.3 推广分销 ​

  • XdAppUser.referCode(6位注册自动生成)+ referrerId(扫码绑定,防自绑+仅首次绑定)
  • IXdAppUserService.getReferralStats/getReferralDetail:推广统计
  • 平台 AdminReferralController 查看

模块 8️⃣ 基础数据 + 通知 + 监控 ​

8.1 区域 / Tab / 短信 / 通知 ​

  • XdRegion + XdTabGroup(见 §2.4)
  • XdSmsLog (xl_sms_log):phone/code/templateCode/scene/sendDate/bizId(阿里云)/aliyunStatus/Code/errorMsg
  • SmsService(阿里云 dysmsapi 20170525.Client):
    • SMS_CODE_KEY="sms_code:" 缓存验证码 5min;SMS_VERIFIED_KEY 已校验状态 30min;发送间隔 60s
    • sendCode(phone) 生成 6 位 + 调阿里云 + 写 XdSmsLog
    • verifyCode(phone, code) + isVerified(phone)
  • XdNoticeTemplate (xl_notice_template):key/label/inputType/defaultContent/sort/isEnabled —— 购买须知可配置项

8.2 三端短信/通知接口 ​

  • 用户/商户 SmsController /api/merchant/sms:send/verify(无需登录)
  • 平台 AdminSmsLogController /api/admin/sms-log:list/detail/syncStatus(回查阿里云)

8.3 RuoYi 原生(系统/监控) ​

保留原版系统管理、监控、代码生成模块(sys/monitor/tool),与业务并行使用。


模块间核心数据流 ​

┌────────────────────────────────────────────────────────────┐
│  ④ 用户登录(app) → XdAppUser + NewcomerGift +              │
│                     Wallet(getOrCreate)                    │
└──────────────┬─────────────────────────────────────────────┘
              ↓
┌──── App:选 TabGroup/Region/Category → AppProduct 查商品 ────┐
│                                                              │
│  下单(9 种 OrderTypeHandler.buildOrderDraft)               │
│            └─ 汇总金额 + XdOrderItem + parentOrderNo(PAY_)   │
│                                                              │
└──────────────────┬─────────────────────────────────┬─────────┘
                  ↓                                 ↓
          ① PaymentOrchestrator.createPayment   ⑤ 笔记社区
                  ↓                                 (关联 ProductRel)
          ① PlatformWechatPayService.prepayJsapi
                  ↓
          wx.requestPayment
                  ↓
          notify → applyPaymentSuccess → OrderStateMachine.markPaid
                  ↓ OrderPaidEvent(AFTER_COMMIT)
        ┌─────────┴──────────┬───────────┬───────────────┐
        ↓                    ↓           ↓               ↓
  扣库存/发券(券码)    Handler.onPaid    记套餐占位     ⑤ 触发派单 Dispatch
                       (per-activityType)              (auto-trigger)
        │
┌───────┴─── 履约流程 ─────────────────────────────────┐
│ ③ 酒店:XdHotelAppointment 商户协商/确认→发券→核销     │
│ ③ 租车/租赁:Dispatch.assign→pickup→return→settle      │
│ ③ 接送:TransferDispatch.autoAssign→接→起→完→settle    │
│ ③ 摄影:PhotographyDispatch.assignPhotographer→交付     │
└──────────────────┬───────────────────────────────────┘
                  ↓
            OrderCompletionService.complete
                  ↓ (SettlementPolicy T+N)
            ② MerchantWalletLedger.pendingSettle
                  ↓
          MerchantWalletSettlementTask(每天 01:00) → 可提现
                  ↓
            ② MerchantWithdrawal → 提现审批 → 转账

── 对账 & 兜底:① 8 个 Quartz/Scheduled Task 保证最终一致
── 发货同步:① MallShipSyncTask → XdWxShipSync
── 个体结算:① IndividualSettlementTask → 微信 V3 转账零钱

关键技术债与风险清单 ​

  1. PayScoreNotifyController 未验签未 AES 解密,有 TODO 标注 —— 上线前必须补
  2. ICommissionCalculator 是 SPI 残留:无实现、无调用方,建议清理或重新接入
  3. XdOrder 大量 @Deprecated 桩方法(标 "remove in Phase 8")待清理
  4. RefundSyncTask(Quartz) 与 RefundStateSyncTask(@Scheduled) 两份近似实现并存 —— 应统一
  5. XdCharterPrice 与 XdTransferCharterPrice、XdTransferPriceRule 与 XdTransferTaxiPrice 都是新旧两套并存 —— 建议收敛
  6. WechatPayConfig(服务商合单模式)已物理删除 —— 历史代码层注释残留,新人易误解
  7. 金额单位全系统统一为"分"(Long) —— 存在历史迁移脚本 money-to-fen.sql,前端须保持一致
  8. Druid 监控默认口令 ruoyi/123456 —— 上线前替换
  9. PAY_ 前缀修复了 OD_ 前缀的查单 bug —— 历史坑已规避但需明确文档
  10. 平台抽佣已退化为支付回调时直写 XdOrderItem.merchantIncomeFen —— 无微信分账接口调用,分账体系已简化

关键技术栈速查 ​

后端 ​

类别技术版本
框架Spring Boot (BOM)3.5.8
Java—17
骨架RuoYi-Vue3.9.1
数据层MyBatis Spring Boot3.0.5
分页PageHelper2.1.1
连接池Druid1.2.27
数据库MySQL服务器实例(通过 SSH 隧道映射到本地 3306,库 xiedao_dev)
缓存Redis(Lettuce 连接池)+ embedded-redis 1.4.3 兜底
认证JWT (jjwt 0.9.1) + kaptcha 2.3.3
文档springdoc-openapi2.8.14
微信支付wechatpay-java0.2.14 (V3)
OpenIM Server APIHTTP/WebSocket3.8.3-patch.12
阿里云 OSSaliyun-sdk-oss3.18.1
富文本/Excel/Velocityfastjson2 2.0.60 / POI 4.1.2 / Velocity 2.3

前端 AdminWeb ​

类别依赖版本
框架vue3.5.26
UIelement-plus + icons2.13.1 / 2.3.2
状态pinia3.0.4
路由vue-router4.6.4
构建vite + @vitejs/plugin-vue6.4.1 / 5.2.4
HTTPaxios1.13.2
富文本/图表/IM@vueup/vue-quill / echarts / @openim/wasm-client-sdk

开发端口约定 ​

  • 后端 dev 8082
  • AdminWeb dev 8081
  • MerchantWeb dev 8083
  • MySQL 3306(SSH 隧道)
  • Redis 6379(SSH 隧道)

生产配置要点 ​

  • API 域名 api.xiedao888.cn
  • 阿里云 OSS bucket xielioss(深圳)
  • OpenIM Server 3.8.3-patch.12,Web SDK 3.8.3-patch.14
  • 微信小程序:用户端 appId wx0335c014637515d7 + 商家端 wx6642b9109973617a

数据库演进体系速查 ​

目录风格用途
Api/db/migration/Flyway 式 V{date}__name.sql正式增量迁移
Api/sql/基础 SQL仅保留 RuoYi 系统表和 Quartz 调度表;业务库结构及数据由数据库备份维护
Docs/sql/跨主题迁移db-migrate-xiedao.sql、money-to-fen(-migrate).sql
Docs/superpowers/ddl/工作流产物phase1-baseline.sql

代码组织速查 ​

Api/
├─ ruoyi-admin/.../web/controller/
│   ├─ app/         用户端 33 个 Controller(/api/app/**)
│   ├─ merchant/    商户端 26 个(/api/merchant/**)
│   ├─ platform/    平台端 48 个(/api/admin/**)
│   ├─ system/      RuoYi 系统管理(/system/**)
│   ├─ monitor/     监控(/monitor/**)
│   └─ task/        Spring @Scheduled 定时任务
├─ ruoyi-system/.../system/
│   ├─ domain/      全部业务实体(Xd* 前缀)
│   ├─ mapper/      MyBatis Mapper 接口
│   └─ service/
│       ├─ order/   OrderStateMachine + Orchestration + 9 个 Handler
│       ├─ payment/ PaymentOrchestrator + 微信支付服务
│       └─ impl/    Service 实现
├─ ruoyi-framework/  Spring Security/JWT/AOP
├─ ruoyi-common/     共享工具/注解/常量
├─ ruoyi-quartz/    Quartz 定时任务(sys_job 配置)
└─ ruoyi-generator/ 代码生成器

业务命名约定:

  • 实体前缀 Xd* 区分 RuoYi 原生 Sys*
  • 数据库表前缀(旧)xl_ —— 已迁移,保留兼容
  • 金额字段统一后缀 Fen 或存 Long(分单位)
  • 状态变更均写 *_event 或 *_log 审计表

本文档由代码探索自动整理,可能与最新实现略有出入,建议结合代码与 git history 阅读。如发现偏差,欢迎补充修订。

携岛 XieDao · 内部文档