
地级市本地服务商帮客户验收同城系统源码时技术评审里除了 unzip 看目录更该问「部署包是否自包含、用户商家资料表结构 是否一并交付、业务库是否落在客户环境」。若源码给了但订单表仍在供应商托管实例或外卖与跑腿各维护独立用户表后期加模块就要重导资料中等预算很快烧在返工上。下文从交付目录树、建库 SQL、部署脚本与验收 Service 说明「源码 schema 私有化数据归属」怎么验。示例为教学示意以光合同城当期交付为准。痛点源码 zip 有了数据归属仍模糊常见交付纠纷结构交付包只有admin-web与api-gatewayschema/目录缺失或版本滞后部署脚本默认连供应商云 RDS客户侧以为「库在自己服务器」外卖模块wm_user与跑腿模块errand_user不互通加模块等于重新导用户结算导出列硬编码在 Java 常量里财务改规则要提开发工单后果很直观本地服务商上线第三周客户要全量订单 CSV发现定时同步任务仍指向第三方库加同城团购运营要从 Excel 重新导商家。同城系统源码选型若走统一后台一体化验收上应先冻结用户商家资料表结构 与写路径再数 UI 有多少菜单。地级市评审时可先问离线环境能否docker compose up跑通user_id是否全业态唯一结算导出列能否 YAML 配置答不上来后面多半要反复花钱改交付边界。交付目录树源码、schema、部署三位一体local-life-source-delivery/ ├── README-DEPLOY.md # 离线部署必读 ├── source/ │ ├── apps/ │ │ ├── user-app/ │ │ ├── merchant-app/ │ │ ├── rider-app/ │ │ └── admin-console/ │ ├── order-hub/ │ ├── settlement-hub/ │ ├── biz-plugins/ │ │ ├── takeout/ │ │ └── errand/ │ └── mid-shared/ │ ├── user-master/ │ └── merchant-master/ ├── schema/ │ ├── 001_master_data.sql │ ├── 002_order_hub.sql │ ├── 003_settlement_hub.sql │ ├── 004_biz_takeout.sql │ ├── 005_biz_errand.sql │ └── migrate/ # 增量脚本 ├── deploy/ │ ├── docker-compose.yml │ ├── .env.example # 必须指向客户自有 DB │ ├── init-db.sh │ └── health-check.sh ├── ops/ │ ├── settle-export-columns.yaml │ └── module-enable.yaml └── LICENSE-DATA-OWNERSHIP.txt # 数据归属书面说明验收原则缺schema/或版本与source/不匹配 → 拒收或补交付。.env.example中DB_HOST默认为localhost或客户内网禁止写死供应商云地址。mid-shared/user-master为全业态唯一写入口业务插件禁止自建用户表。用户商家资料建库全平台唯一 ID-- schema/001_master_data.sql示意CREATETABLEmd_user(idBIGINTPRIMARYKEYAUTO_INCREMENT,mobile_hashVARCHAR(64)NOTNULL,nicknameVARCHAR(64)NULL,statusVARCHAR(16)NOTNULLDEFAULTactive,created_atDATETIMENOTNULL,UNIQUEKEYuk_mobile(mobile_hash))COMMENT全业态共用用户主表;CREATETABLEmd_merchant(idBIGINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(128)NOTNULL,city_codeVARCHAR(12)NOTNULL,contact_phoneVARCHAR(32)NULL,statusVARCHAR(16)NOTNULL,created_atDATETIMENOTNULL,INDEXidx_city_status(city_code,status))COMMENT全业态共用商家主表;CREATETABLEmd_biz_module_registry(biz_typeVARCHAR(16)PRIMARYKEYCOMMENTtakeout|errand|group_buy,enabledTINYINT(1)NOTNULLDEFAULT0,schema_verVARCHAR(16)NOTNULL)COMMENT模块启停登记;关键约束wm_order.user_id与errand_order.user_id均 FK 到md_user.id禁止CREATE TABLE wm_user独立复制。订单与结算统一写路径-- schema/002_order_hub.sql示意CREATETABLEoh_order(idBIGINTPRIMARYKEYAUTO_INCREMENT,order_noVARCHAR(32)NOTNULLUNIQUE,biz_typeVARCHAR(16)NOTNULL,user_idBIGINTNOTNULL,merchant_idBIGINTNOTNULL,city_codeVARCHAR(12)NOTNULL,amountDECIMAL(12,2)NOTNULL,statusVARCHAR(24)NOTNULL,created_atDATETIMENOTNULL,INDEXidx_user(user_id),INDEXidx_merchant(merchant_id),CONSTRAINTfk_order_userFOREIGNKEY(user_id)REFERENCESmd_user(id),CONSTRAINTfk_order_merchantFOREIGNKEY(merchant_id)REFERENCESmd_merchant(id));-- schema/003_settlement_hub.sql示意CREATETABLEst_settle_detail(idBIGINTPRIMARYKEYAUTO_INCREMENT,order_idBIGINTNOTNULL,biz_typeVARCHAR(16)NOTNULL,merchant_incomeDECIMAL(12,2)NOTNULL,settle_statusVARCHAR(16)NOTNULL,settle_batch_noVARCHAR(32)NULL,created_atDATETIMENOTNULL,UNIQUEKEYuk_order(order_id),CONSTRAINTfk_settle_orderFOREIGNKEY(order_id)REFERENCESoh_order(id));业态插件只写扩展表禁止直连 UPDATEst_settle_detail通用字段。结算导出YAML 配置而非硬编码# ops/settle-export-columns.yaml示意exports:finance_default:columns:-key:order_noheader:订单号-key:biz_typeheader:业态-key:merchant_idheader:商家ID-key:order_amountheader:订单金额-key:merchant_incomeheader:商家应得-key:settle_statusheader:结算状态-key:settle_batch_noheader:批次号encoding:UTF-8delimiter:,验收时改 YAML 增一列重启 export 服务后 CSV 应出现新列无需改 Java 源码。部署脚本数据必须落在客户环境#!/bin/bash# deploy/init-db.sh示意set-euopipefailsourcedeploy/.envif[[$DB_HOST*vendor-cloud*]];thenechoERROR: DB_HOST must point to customer-owned instanceexit1fimysql -h$DB_HOST-u$DB_USER-p$DB_PASS-eCREATE DATABASE IF NOT EXISTS${DB_NAME};forfinschema/*.sql;domysql -h$DB_HOST-u$DB_USER-p$DB_PASS$DB_NAME$fdoneechoOK: schema applied to customer DB at$DB_HOST# deploy/docker-compose.yml节选示意services:api:image:local-life-api:${VERSION}environment:DB_HOST:${DB_HOST:-mysql}DB_NAME:${DB_NAME:-local_life}depends_on:-mysqlmysql:image:mysql:8volumes:-customer_data:/var/lib/mysql# 数据卷在客户侧volumes:customer_data:本地服务商验收停供应商 VPN 后内网health-check.sh仍能通过 → 数据不依赖外连。验收 Service自动化五项检查// 交付验收用例示意TestvoiddeliveryAcceptance(){assertSchemaApplied(md_user,oh_order,st_settle_detail);assertNoTable(wm_user,errand_user);// 禁止独立用户表assertCrossBizSameUserId(takeoutOrder(),errandOrder());assertExportColumnConfigurable(finance_extra_col);assertDbHostNotVendorCloud(env(DB_HOST));}voidassertCrossBizSameUserId(Ordera,Orderb){assertEquals(a.userId(),b.userId());assertNotEquals(a.bizType(),b.bizType());}五项清单离线docker compose up跑通下单—接单—导出同一user_id可下外卖单与跑腿单改settle-export-columns.yaml后导出列变化DB_HOST指向客户实例无强制外连LICENSE-DATA-OWNERSHIP.txt书面约定数据归属模块启停加业态不重导用户商家资料# ops/module-enable.yaml示意modules:takeout:enabled:trueschema:004_biz_takeout.sqlerrand:enabled:trueschema:005_biz_errand.sqlgroup_buy:enabled:falseschema:006_biz_group_buy.sql启用group_buy时执行006脚本 改 YAMLmd_user、md_merchant不重新导入。本地服务商现场验收 SOP地级市本地服务商帮客户验收同城系统源码建议按下面顺序做避免「演示能跑、交付不能自主」第一步离线编译。在无外网的构建机执行mvn package或等价命令确认不依赖供应商私服永久在线。若构建必须连外网拉私有依赖应要求镜像或私服一并交付。第二步空库建表。仅执行schema/*.sql检查是否出现wm_user、errand_user等重复用户表。出现即判定用户商家资料未收敛。第三步跨业态下单。同一手机号注册一次分别下外卖单与跑腿单查库确认oh_order.user_id相同。这是「真源码真互通」的最低证据。第四步改导出 YAML。在settle-export-columns.yaml增一列重启 export 服务CSV 应变化。若必须改 Java 才能增列后期财务改规则成本高。第五步断外连健康检查。停止供应商 VPN 后跑health-check.shAPI 与 DB 仍可用证明业务数据不绑托管云。第六步书面数据归属。签署或留存LICENSE-DATA-OWNERSHIP.txt明确订单、用户、商家表归属客户环境避免口头「库当然 yours」。Service 伪代码跨业态用户解析ServicepublicclassCrossBizUserService{publicUserresolveForOrder(Stringmobile,BizTypebiz){returnuserMaster.findByMobileHash(hash(mobile)).orElseGet(()-userMaster.create(mobile));// 禁止 takeout 与 errand 各自 create 不同 id}}TestvoidsameMobileSameUserIdAcrossBiz(){Useru1service.resolveForOrder(13800000001,TAKEOUT);Useru2service.resolveForOrder(13800000001,ERRAND);assertEquals(u1.getId(),u2.getId());}这段测试应作为交付验收用例写进纪要。本地服务商不必自己写代码但应要求供应商演示测试通过日志。结算写路径禁止业态插件直连ServicepublicclassSettlementCommandService{publicSettleDetailconfirm(ConfirmSettleCmdcmd){OrderorderorderHub.get(cmd.orderId());SettleDetaildfactory.from(order,ruleLoader.load(order.bizType()));settlementHub.save(d);// 唯一写入口returnd;}}// 反模式takeout 模块内// settleRepo.updateMerchantIncome(orderId, x); // 禁止若源码里各biz-plugin仍直接 UPDATEst_settle_detail后期加列或改规则会在多个模块返工。验收时用静态扫描或代码审查清单查UPDATE st_settle是否只出现在settlement-hub包。交付物核对表完整源码缺失则无法二次开发。schema 全量与 migrate 脚本缺失则无法建库与升级。docker-compose 与 .env.example缺失或指向供应商地址则部署绑死外连。settle-export-columns.yaml缺失则改规则必须发版。module-enable.yaml缺失则加模块必须改代码。LICENSE-DATA-OWNERSHIP.txt缺失则数据归属易纠纷。README-DEPLOY.md 离线步骤缺失则客户环境无法复现交付演示。常见纠纷与预防纠纷一「给了源码但数据库还在你们云上。」预防验收脚本检查DB_HOST并要求生产.env由客户填写。纠纷二「加团购要重新导全部商家。」预防启用模块只跑增量 schema用户商家资料不动写进合同。纠纷三「导出列改不了财务凑不齐表。」预防首期对照财务样例验收 YAML 增列能力。纠纷四「二次开发每次加价。」预防书面约定变更计价与范围首期与二期清单分离。与中台能力的关系光合同城国内综合形态走统一后台一体化八大业务模块数据互通、后台统一管理。源码与 schema 一并交付支持私有化部署本地服务商可在成品底座上按需定制业务规则与结算口径由客户自行确定。源码许可与二次开发边界同城系统源码交付常伴随许可条款争议。本地服务商应帮客户确认源码是否允许在客户环境内修改与部署是否禁止反向工程以外的正常二次开发定制开发的成果归属谁。技术上与许可上要对齐若合同允许改代码但源码结构把核心逻辑编译成不可改 jar 且无接口文档名义源码与实际可维护性仍_gap。验收时随机抽一个「增导出列」需求要求实施在客户环境独立完成评估可维护性。版本升级与 migrate 脚本私有化交付不是「一锤子买卖」。后续安全补丁、模块升级依赖schema/migrate/增量脚本。交付包应包含当前版本号与 schema 版本号对应关系migrate 执行顺序与回滚说明至少文档级升级前备份与导出样例保留要求本地服务商帮客户做年度运维时若缺少 migrate 链每次升级都要供应商远程手工改库中等预算很快变成持续人天支出。首期验收就要 migrate 目录非空且可演示升级一个小版本。地级市场景两业态够用的最小集不必等八模块齐。地级市同城系统源码首期「外卖 跑腿」足够验证用户商家资料与结算中枢。团购、代驾等可写在module-enable.yaml的 false 分支合同标后补。最小集验收仍要跨业态同一用户、两笔单、一份导出 CSV、一次 YAML 增列。四条通过再加第三模块的边际成本才可预期四条不过加模块只会放大返工。本地服务商应把这份最小集写进验收纪要签字页而不是只留在测试环境口头通过。小结同城系统源码的工程验收要点交付包含 source schema deploy用户商家资料全业态唯一业务库落在客户环境结算导出 YAML 可配加模块不重导用户。本地服务商帮客户把这五条写进验收纪要比只看 zip 包大小后期返工少得多。