西藏巴青项目

供应商管理技术方案.md 12KB

供应商管理 — 技术方案

依据:同目录 供应商管理功能需求.md。供应商主档 CRUD + 逻辑删除 + 编号自动生成(2 位) + 收费方式联动校验;车辆号牌 JSON 存储。


1. 技术架构

说明
后端 RuoYi v3.9.2springboot2 分支):JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid
数据库 MySQL 5.7.39,InnoDB,utf8mb4
前端 若依 Vue2;字段 小驼峰(本方案不展开页面)

分层ControllerServiceSupplierValidation编号生成、收费字段清洗、分配账号)→ Mapper/XML → domain

代码包com.ruoyi.web.modules.trading

外部依赖:平台 用户/角色ISysUserServiceTradePartnerAccountAssigner

业务摘要

场景 行为
新增 校验通过后 SupplierCodeGenerator 分配 supplier_code0199);del_flag=0
修改 不可改 supplier_code;按 fee_method 清空不适用费率字段
列表/详情 del_flag=0;排序 supplier_code ASC, id ASC
列表筛选 supplier_codesupplier_name 精确匹配
删除 逻辑删除 del_flag=2;存在未结算结算单时 ServiceException已分配账号时联动 deleteUserById
分配账号 account_assigned=0;创建 sys_user 绑定角色 103;登录名=名称拼音首字母+id;成功一次

2. 数据库设计

2.1 表 biz_supplier(供应商)

字段 类型 非空 默认值 说明
id bigint(20) Y 自增 主键
supplier_code char(2) Y 供应商编号,0199全局唯一
supplier_name varchar(64) Y 供应商名称(1~20 字)
supplier_type tinyint(4) Y 1 个体户 2 企业
identity_no varchar(32) Y 身份证号 / 统一社会信用代码(18 位)
contact_phone varchar(20) Y 手机号
business_location varchar(50) N NULL 经营地点(≤50 字)
vehicle_plates varchar(512) N NULL 车辆号牌 JSON 数组,最多 10
fee_method tinyint(4) Y 1 按户 2 按头 3 按额
fee_standard decimal(12,2) N NULL 收费标准(元/头);fee_method=2 时必填
transaction_fee_rate decimal(5,2) N NULL 交易费率(%);fee_method=3 时必填
management_fee_rate decimal(5,2) N NULL 管理费率(%);fee_method=3 时必填
account_assigned tinyint(4) Y 0 0 未分配 1 已分配
sys_user_id bigint(20) N NULL 关联 sys_user.user_id
assigned_login_name varchar(64) N NULL 已分配登录名
del_flag char(1) Y '0' 0 存在 2 删除
create_by / create_time / update_by / update_time 若依惯例 审计
remark varchar(500) N NULL 备注

索引PRIMARY KEY (id)UNIQUE KEY uk_supplier_code (supplier_code)KEY idx_supplier_name (supplier_name)KEY idx_identity_no (identity_no)KEY idx_del_flag (del_flag)

唯一性supplier_nameidentity_no未删除del_flag=0)范围内唯一,由 Service 插入/更新前查询保证(MySQL 5.7 不做部分唯一索引)。

2.2 DDL(MySQL 5.7)

CREATE TABLE `biz_supplier` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `supplier_code` char(2) NOT NULL COMMENT '供应商编号01-99',
  `supplier_name` varchar(64) NOT NULL COMMENT '供应商名称',
  `supplier_type` tinyint(4) NOT NULL COMMENT '1个体户 2企业',
  `identity_no` varchar(32) NOT NULL COMMENT '身份证号或统一社会信用代码',
  `contact_phone` varchar(20) NOT NULL COMMENT '联系方式',
  `business_location` varchar(50) DEFAULT NULL COMMENT '经营地点',
  `vehicle_plates` varchar(512) DEFAULT NULL COMMENT '车辆号牌JSON数组',
  `fee_method` tinyint(4) NOT NULL COMMENT '1按户 2按头 3按额',
  `fee_standard` decimal(12,2) DEFAULT NULL COMMENT '收费标准元/头',
  `transaction_fee_rate` decimal(5,2) DEFAULT NULL COMMENT '交易费率%',
  `management_fee_rate` decimal(5,2) DEFAULT NULL COMMENT '管理费率%',
  `account_assigned` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0未分配1已分配',
  `sys_user_id` bigint(20) DEFAULT NULL COMMENT '关联用户ID',
  `assigned_login_name` varchar(64) DEFAULT NULL COMMENT '已分配登录名',
  `del_flag` char(1) NOT NULL DEFAULT '0' COMMENT '0存在 2删除',
  `create_by` varchar(64) DEFAULT '' COMMENT '创建者',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(500) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_supplier_code` (`supplier_code`),
  KEY `idx_supplier_name` (`supplier_name`),
  KEY `idx_identity_no` (`identity_no`),
  KEY `idx_del_flag` (`del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='供应商';

2.3 枚举

供应商类型 supplier_type

标签
1 个体户
2 企业

收费方式 fee_method

标签 有效字段
1 按户计费 三项费率/标准均为 NULL
2 按头计费 fee_standard > 0
3 按额计费 transaction_fee_ratemanagement_fee_rate ∈ [0, 100]

删除标记 del_flag

含义
0 正常
2 已逻辑删除

账号分配 account_assigned

含义
0 未分配
1 已分配

分配账号默认角色(sys_role.role_id

主体 role_id
供应商 103

已有库升级:执行 sql/alter_biz_supplier_distributor_assign_account.sql(供应商、承销商字段一并追加)。

2.4 编号生成(SupplierCodeGenerator

  1. 查询 del_flag 任意状态下 MAX(supplier_code)(或维护 sys_seq 表,本期可用 MAX + 事务)。
  2. 无记录 → 01;有记录 → 数值 +1,格式 %02d
  3. 下一号 > 99 → 抛 ServiceException「供应商编号已达上限,请联系管理员」。
  4. 与插入同事务,避免并发重复(SELECT … FOR UPDATE 或表级锁)。

2.5 车辆号牌存储

  • 库内:vehicle_plates 存 JSON,如 ["藏A12345","藏B67890"]
  • API:vehiclePlatesstring[];空数组或 null 表示未登记。
  • 单条长度建议 ≤16;数组长度 ≤10;非法车牌格式由 SupplierValidation 拒绝。

2.6 分配账号登录名(TradingPartnerLoginNameGenerator

  • supplier_name 逐字取汉语拼音首字母(小写);ASCII 字母数字原样小写拼接。
  • 结果 + id 作为 user_name(如 扎西供应商、id=12 → zxgys12)。
  • 无有效字符时回退 user + id
  • TradePartnerAccountAssigner.createAccountISysUserService.insertUser,初始密码 sys.user.initPassword

3. 接口设计

统一响应AjaxResult / TableDataInfocodemsgdata / rowstotal)。

权限标识tradeMarket:supplier:list|query|add|edit|remove|assignAccount

Base Path/tradeMarket/supplier

# 说明 Method URI 权限
3.1 分页列表 GET /tradeMarket/supplier/list list
3.2 详情 GET /tradeMarket/supplier/{id} query
3.3 新增 POST /tradeMarket/supplier add
3.4 修改 PUT /tradeMarket/supplier edit
3.5 删除 DELETE /tradeMarket/supplier/{ids} remove

3.1.1 列表 Query

参数 类型 必填 说明
pageNum / pageSize int N 默认 1 / 20
supplierCode string N 供应商编号精确匹配
supplierName string N 供应商名称精确匹配

列表行(驼峰):表字段 + supplierTypeNamefeeMethodName + accountAssignedsysUserIdassignedLoginName

排序supplier_code ASC, id ASC

3.2.1 详情 data

全业务字段(驼峰)+ supplierTypeNamefeeMethodName + vehiclePlates(数组)+ 审计字段。

3.3.1 新增 / 修改 Body(驼峰)

字段 新增 修改 说明
id Y 主键
supplierCode 禁止传入;仅响应带回
supplierName Y Y 1~20 字,trim
supplierType Y Y 1 / 2
identityNo Y Y 个体户身份证 / 企业 USCC
contactPhone Y Y 手机号
businessLocation N N ≤50 字
vehiclePlates N N 字符串数组,≤10
feeMethod Y Y 1 / 2 / 3
feeStandard 条件 条件 feeMethod=2 必填,>0
transactionFeeRate 条件 条件 feeMethod=3 必填,0~100
managementFeeRate 条件 条件 feeMethod=3 必填,0~100
remark N N ≤500 字

3.4 服务端校验(SupplierValidation

规则
名称 trim 后 1~20 字;del_flag=0名称唯一
类型 + 身份号 supplier_type=1 → 身份证校验;=2 → 18 位 USCC;身份号唯一(未删除)
手机 项目统一手机号规则
收费联动 fee_method=1 → 三费率字段置 NULL;=2 → 仅 fee_standard=3 → 两费率 0~100
车辆 每条格式合法;数量 ≤10
修改 禁止改 supplier_code;记录存在且未删
删除 未删;SupplierReferenceChecker.hasUnsettledSettlement(id) 为 false(biz_supplier_settlement 待结算且未删)
分配账号 SupplierValidation.validateForAssignAccountaccount_assigned≠1

3.5 删除

  • DELETE /tradeMarket/supplier/{ids},本期前端单条传一个 id。
  • del_flag='2';存在未结算结算单时失败,msg「存在未结算的结算单,无法删除」。
  • account_assigned=1sys_user_id 非空:TradePartnerAccountAssigner.deleteLinkedAccountdeleteUserById

3.6 分配账号

说明
Method / URI POST /tradeMarket/supplier/assignAccount/{id}
权限 tradeMarket:supplier:assignAccount
前置 account_assigned=0del_flag=0
结果 创建 sys_user,绑定角色 103;写 sys_user_idassigned_login_nameaccount_assigned=1
失败 登录名冲突等返回明确 msgaccount_assigned=1

3.7 Mapper 约定

  • 查询/更新条件带 del_flag='0'
  • 列表筛选:supplier_code = #{supplierCode}supplier_name = #{supplierName}(非空时)。
  • 逻辑删除:按 id 更新 del_flag='2'

4. 菜单与权限(示例)

类型 名称 权限标识
菜单 供应商管理 tradeMarket:supplier:list
按钮 查询 tradeMarket:supplier:query
按钮 新增 tradeMarket:supplier:add
按钮 修改 tradeMarket:supplier:edit
按钮 删除 tradeMarket:supplier:remove
按钮 分配账号 tradeMarket:supplier:assignAccount

组件路径:tradeMarket/supplier/index(「交易市场平台」目录下)。


5. 交付清单

  • sql/biz_supplier.sqlsql/alter_biz_supplier_distributor_assign_account.sql、菜单权限 SQL
  • BizSupplier、Mapper/XML、Service、Controller
  • SupplierValidationSupplierCodeGeneratorSupplierRules
  • TradingPartnerLoginNameGeneratorTradePartnerAccountAssignerTradePartnerAccountRules
  • 单元测试(编号、收费联动、唯一性、分配账号、删除联动)
  • MockMvc(list、CRUD、assignAccount

6. 修订记录

版本 说明
1.0 初稿:biz_supplier;CRUD+逻辑删除;2 位编号;收费方式三档;车辆 JSON;tradeMarket/supplier
1.1 分配账号:account_assigned/sys_user_id/assigned_login_namePOST assignAccount;角色 103;拼音首字母+id
1.3 删除约束:SupplierReferenceChecker.hasUnsettledSettlementbiz_supplier_settlement 待结算拦截