商户入驻审核 — 技术方案
依据: 《商户入驻审核功能需求.md》v1.0.2
关联: 《商户管理技术方案.md》v1.4、《店铺管理技术方案.md》v1.2.1、《商城入驻协议技术方案.md》v1.0、《会员管理技术方案.md》v1.0.1、《关联需求分析.md》v1.2
范围: C 端 商户入驻 申请提交;平台 列表/检索/详情/审核通过/驳回;通过后 落库商户+首家店铺+经营账号;站内消息 通知会员。
原则: 申请状态与商户 cert_status 分离;平台 POST /agri/merchant 不写 申请单;审核通过 单事务 建档。
1. 技术架构
| 项 |
选型 |
| 基础框架 |
RuoYi v3.9.2(springboot2 分支) |
| 数据库 |
MySQL 5.7.39 |
| ORM / 权限 |
MyBatis;@PreAuthorize;AjaxResult / TableDataInfo |
| 申请状态 |
apply_status char(1):0 待审核 1 通过 2 未通过 |
| 表单快照 |
form_json LONGTEXT(详情展示 + 审核落库映射) |
| 日志 |
审核 @Log |
1.1 模块落位
baqing-shop
├── com.ruoyi.web.modules.entry
│ ├── controller.MerchantEntryApplyController # 平台审核
│ ├── controller.MerchantEntryApplyAppController # C 端提交/我的申请
│ ├── domain.BizMerchantEntryApply
│ ├── mapper.BizMerchantEntryApplyMapper
│ ├── service.IMerchantEntryApplyService
│ ├── dto.EntryApplySubmitDTO / EntryApplyRejectDTO
│ ├── vo.EntryApplyListVO / EntryApplyDetailVO
│ ├── constant.MerchantEntryApplyConstants
│ ├── support.EntryApplyFormMapper # JSON ↔ 商户/店铺 DTO
│ └── support.MemberEntryMessageSupport # 站内消息
sql/
├── biz_merchant_entry_apply.sql
└── biz_member_message.sql # 可选:会员站内消息
包名 entry 与 content 下「入驻协议」区分:协议=配置;本模块=申请单。
1.2 业务链
biz_member
└── biz_merchant_entry_apply(apply_status)
├── C 端 POST /api/merchant/entry/apply
│ └── IMerchantEntryAgreementFacade.assertAccepted
│
├── 平台 GET list/detail、PUT approve/reject
│
└── approve(事务)
├── insert biz_merchant(cert_status=0, biz_complete=1)
├── IMerchantAccountBindService(会员路径绑定)
├── IShopService.createShop(首家店)
└── biz_member_message(通知)
| 模块 |
关系 |
| 商城入驻协议 |
C 端提交前 assertAccepted |
| 商户管理 |
通过后 insert 商户;不 经 insertMerchant 平台表单接口 |
| 店铺管理 |
通过后 createShop |
| 会员管理 |
member_id;消息收件人 |
| 商品/订单 |
无直接依赖 |
1.3 跨模块 Facade
| 接口 |
提供方 |
方法 |
用途 |
IMerchantEntryAgreementFacade |
content |
assertAccepted(boolean) |
C 端提交 |
IMerchantAccountBindService |
merchant |
bindMemberOnEntryApprove(...) |
会员→经营账号 |
IShopService |
store |
createShop(ShopCreateDTO) |
首家店 |
IMerchantFacade |
merchant |
唯一性校验可复用 Mapper |
证件/信用代码 |
1.4 状态联动
| 事件 |
biz_merchant_entry_apply |
biz_merchant |
| approve / reject |
更新 apply_status |
approve 时 新增 |
| 改入驻协议 |
不变 |
不变 |
| 平台代录入商户 |
无申请行 |
直接新增 |
2. 数据库设计
2.1 本模块表 biz_merchant_entry_apply
| 字段 |
类型 |
说明 |
| apply_id |
bigint PK |
申请 ID |
| apply_no |
varchar(32) UK |
申请编号,如 EA+日期+序号 |
| apply_status |
char(1) |
0 待审 1 通过 2 未通过 |
| merchant_type |
char(1) |
1 个人 2 企业 |
| member_id |
bigint |
申请人会员 ID |
| member_code |
varchar(64) |
冗余检索:会员名称 |
| subject_label |
varchar(128) |
列表「申请信息」:姓名/企业名 |
| contact_name |
varchar(64) |
联系人 |
| contact_phone |
varchar(20) |
联系人手机 |
| id_card_no |
varchar(32) |
个人证件号(唯一校验) |
| credit_code |
varchar(32) |
企业信用代码(唯一校验) |
| merchant_name |
varchar(128) |
申请中商户名称(唯一校验) |
| shop_name |
varchar(128) |
申请中店铺名称(唯一校验) |
| form_json |
longtext |
完整表单 JSON 快照 |
| reject_reason |
varchar(500) |
驳回原因 |
| merchant_id |
bigint |
通过后回填 |
| shop_id |
bigint |
通过后回填 |
| apply_time |
datetime |
提交时间 |
| audit_by |
varchar(64) |
审核人 |
| audit_time |
datetime |
审核时间 |
| del_flag |
char(1) |
0 存在 2 删 |
| create_by/time, update_by/time |
|
审计 |
索引:
| 索引 |
用途 |
uk_apply_no |
编号 |
idx_status_time (apply_status, apply_time) |
待审列表 |
idx_member_status (member_id, apply_status) |
同会员待审校验 |
idx_member_code (member_code) |
关键词检索 |
idx_id_card (id_card_no) |
个人唯一 |
idx_credit_code (credit_code) |
企业唯一 |
2.2 会员站内消息 biz_member_message(建议)
| 字段 |
类型 |
说明 |
| message_id |
bigint PK |
|
| member_id |
bigint |
收件会员 |
| biz_type |
varchar(32) |
ENTRY_AUDIT |
| biz_id |
bigint |
apply_id |
| title |
varchar(128) |
如「入驻审核通过」 |
| content |
varchar(1000) |
含驳回原因摘要 |
| read_flag |
char(1) |
0 未读 1 已读 |
| create_time |
datetime |
|
若已有统一消息中心,可替换本表;接口契约不变。
2.3 form_json 结构(约定)
{
"subject": { },
"biz": { },
"shop": { "shopName", "shopAvatar", "shopPhone", "shopDesc" },
"agreementAccepted": true
}
subject / biz 字段名与 biz_merchant、商户管理 DTO 一致,便于 EntryApplyFormMapper.toMerchant() / toShopCreateDTO()。
- 详情接口解析 JSON 填
EntryApplyDetailVO 各分区。
2.4 与既有表关系
| 表 |
关系 |
biz_merchant |
approve 后 insert;merchant_id 回写 apply |
biz_shop |
approve 后 insert;shop_id 回写 |
biz_merchant_account |
绑定会员时 insert |
biz_member |
member_id FK 逻辑 |
平台 biz_merchant 无 apply_id 字段:代录入商户 source_type 可选扩展(1 平台 / 2 C 端),非本期必做。
3. 状态机(Service)
| 操作 |
前置 |
结果 |
副作用 |
| submit |
无待审;协议已勾选;唯一性通过 |
apply_status=0 |
— |
| approve |
status=0 |
status=1 |
商户+店+账号+消息 |
| reject |
status=0;rejectReason 非空 |
status=2 |
消息 |
4. 接口设计
4.1 C 端 — 提交申请 POST /api/merchant/entry/apply
| 项 |
说明 |
| 鉴权 |
会员 Token(MemberAuthInterceptor) |
| Body |
EntryApplySubmitDTO:subject + biz + shop + agreementAccepted |
| 校验 |
说明 |
| 协议 |
IMerchantEntryAgreementFacade.assertAccepted |
| 待审 |
同 member_id 无 status=0 |
| 唯一性 |
证件/信用代码/merchant_name/shop_name |
| 会员昵称 |
绑定路径须 nick_name 非空 |
成功: { applyId, applyNo, applyStatus: "0" }
4.2 C 端 — 我的申请 GET /api/merchant/entry/my(可选)
| 项 |
说明 |
| 鉴权 |
会员 Token |
| 响应 |
当前会员最近 N 条申请摘要(状态、时间、驳回原因) |
4.3 平台 — 列表 GET /agri/merchantEntryApply/list
| 项 |
说明 |
| 权限 |
agri:merchantEntryApply:list |
| Query |
keyword(member_code)、applyStatus、pageNum/pageSize |
| 排序 |
status=0 → apply_time ASC;否则 apply_time DESC |
4.4 平台 — 待审数量 GET /agri/merchantEntryApply/pendingCount
| 响应 | { "pendingCount": n } |
4.5 平台 — 详情 GET /agri/merchantEntryApply/{applyId}
| 权限 | agri:merchantEntryApply:query |
| 响应 | EntryApplyDetailVO:基础信息 + 解析 form_json 各分区 + canApprove/canReject |
4.6 平台 — 审核通过 PUT /agri/merchantEntryApply/approve/{applyId}
| 权限 | agri:merchantEntryApply:audit |
| 日志 | title=商户入驻审核通过 |
| Body | 可选 { "confirmed": true } 二次确认 |
成功: { merchantId, shopId };申请 status=1。
4.7 平台 — 审核驳回 PUT /agri/merchantEntryApply/reject
| 权限 | agri:merchantEntryApply:audit |
| Body | { "applyId", "rejectReason" } |
| 校验 | rejectReason 必填 |
4.8 C 端 — 消息 GET /api/member/message/list(可选独立模块)
| 说明 | 读取 biz_member_message;本方案可由 MemberEntryMessageSupport 写入 |
5. Service 要点
5.1 submitApply(memberId, dto)
assertAgreement → assertNoPendingApply(memberId)
→ validateForm → assertUnique(idCard/credit/merchantName/shopName)
→ build BizMerchantEntryApply + form_json
→ insert
5.2 approve(applyId, operator)(@Transactional)
load apply(status=0) → re-validate unique
→ EntryApplyFormMapper → BizMerchant(biz_complete=1, cert_status=0)
→ merchantMapper.insert
→ accountBindService.bindMemberOnEntryApprove(merchantId, memberId)
→ shopService.createShop(shopDto)
→ update apply: status=1, merchant_id, shop_id, audit_*
→ memberMessageSupport.sendPass(memberId, ...)
5.3 reject(dto, operator)
load apply(status=0) → update status=2, reject_reason
→ memberMessageSupport.sendReject(memberId, reason)
5.4 经营账号(会员路径)
| 项 |
规则 |
| 登录名 |
会员 nick_name(商户管理 6.7.2) |
| 管理员姓名 |
member_code + memberId 规则 |
| sys_user |
按 MerchantAccountBindService 现有逻辑创建角色 100 |
6. 业务规则映射(EA)
| 编号 |
实现 |
| EA1 |
仅 C 端 submitApply 写 apply 表 |
| EA2 |
apply_status 独立字段 |
| EA3 |
approve/reject 校验 status=0 |
| EA4 |
reject 校验 rejectReason |
| EA5 |
approve 事务内商户+店+消息 |
| EA6 |
reject 不 insert merchant/shop |
| EA7 |
EntryApplyFormMapper 字段对齐商户/店铺 |
| EA8 |
IMerchantEntryAgreementFacade |
| EA9 |
list 支持 applyStatus 筛选 |
| EA10 |
list keyword → member_code like |
| EA11 |
countPendingByMemberId > 0 阻断 submit |
| EA12 |
唯一:merchant 表 + apply 表 status in (0,1) |
| EA13 |
驳回后可新 apply_id |
| EA14 |
biz_member_message |
| EA15 |
不调用商品/订单 Service |
7. 菜单权限(建议)
| 菜单 |
权限 |
| 商户入驻审核 |
agri:merchantEntryApply:list |
| 查看详情 |
agri:merchantEntryApply:query |
| 审核 |
agri:merchantEntryApply:audit |
8. 非本期实现
申请批量审核、审核 SLA、申请单修改、短信通知、游客免会员提交、申请单导出。
9. 文档索引
| 文档 |
版本 |
| 商户入驻审核功能需求.md |
v1.0.2 |
| 商户管理技术方案.md |
v1.4 |
| 店铺管理技术方案.md |
v1.2.1 |
| 商城入驻协议技术方案.md |
v1.0 |
10. 修订记录
| 版本 |
说明 |
| v1.0 |
首版:申请单表、平台/C 端接口、审核落库 |
| v1.0.1 |
曾用 shopEntryApply / biz_shop_entry_apply 命名 |
| v1.0.2 |
定名 商户入驻审核;/agri/merchantEntryApply、biz_merchant_entry_apply;规则 EA1~EA15 |
文档版本:v1.0.2 · MySQL 5.7.39 · RuoYi v3.9.2-springboot2 · 关联《商户入驻审核功能需求.md》v1.0.2