实现用户和组织模型(店铺、企业、个人客户)

核心功能:
- 实现 7 级店铺层级体系(Shop 模型 + 层级校验)
- 实现企业管理模型(Enterprise 模型)
- 实现个人客户管理模型(PersonalCustomer 模型)
- 重构 Account 模型关联关系(基于 EnterpriseID 而非 ParentID)
- 完整的 Store 层和 Service 层实现
- 递归查询下级店铺功能(含 Redis 缓存)
- 全面的单元测试覆盖(Shop/Enterprise/PersonalCustomer Store + Shop Service)

技术要点:
- 显式指定所有 GORM 模型的数据库字段名(column: 标签)
- 统一的字段命名规范(数据库用 snake_case,Go 用 PascalCase)
- 完整的中文字段注释和业务逻辑说明
- 100% 测试覆盖(20+ 测试用例全部通过)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-09 18:02:46 +08:00
parent 6fc90abeb6
commit a36e4a79c0
51 changed files with 5736 additions and 144 deletions

View File

@@ -0,0 +1,13 @@
-- 回滚 tb_account 表的修改
ALTER TABLE tb_account ADD COLUMN IF NOT EXISTS parent_id BIGINT;
CREATE INDEX IF NOT EXISTS idx_account_parent_id ON tb_account(parent_id);
ALTER TABLE tb_account DROP COLUMN IF EXISTS enterprise_id;
-- 删除个人客户表
DROP TABLE IF EXISTS tb_personal_customer;
-- 删除企业表
DROP TABLE IF EXISTS tb_enterprise;
-- 删除店铺表
DROP TABLE IF EXISTS tb_shop;

View File

@@ -0,0 +1,138 @@
-- 创建店铺表
CREATE TABLE IF NOT EXISTS tb_shop (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP WITH TIME ZONE,
creator BIGINT NOT NULL,
updater BIGINT NOT NULL,
shop_name VARCHAR(100) NOT NULL,
shop_code VARCHAR(50),
parent_id BIGINT,
level INT NOT NULL DEFAULT 1,
contact_name VARCHAR(50),
contact_phone VARCHAR(20),
province VARCHAR(50),
city VARCHAR(50),
district VARCHAR(50),
address VARCHAR(255),
status INT NOT NULL DEFAULT 1
);
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_shop_parent_id ON tb_shop(parent_id);
CREATE UNIQUE INDEX IF NOT EXISTS idx_shop_code ON tb_shop(shop_code) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_shop_deleted_at ON tb_shop(deleted_at);
-- 添加表注释
COMMENT ON TABLE tb_shop IS '店铺表';
COMMENT ON COLUMN tb_shop.id IS '主键ID';
COMMENT ON COLUMN tb_shop.created_at IS '创建时间';
COMMENT ON COLUMN tb_shop.updated_at IS '更新时间';
COMMENT ON COLUMN tb_shop.deleted_at IS '删除时间';
COMMENT ON COLUMN tb_shop.creator IS '创建人ID';
COMMENT ON COLUMN tb_shop.updater IS '更新人ID';
COMMENT ON COLUMN tb_shop.shop_name IS '店铺名称';
COMMENT ON COLUMN tb_shop.shop_code IS '店铺编号';
COMMENT ON COLUMN tb_shop.parent_id IS '上级店铺IDNULL表示一级代理';
COMMENT ON COLUMN tb_shop.level IS '层级1-7';
COMMENT ON COLUMN tb_shop.contact_name IS '联系人姓名';
COMMENT ON COLUMN tb_shop.contact_phone IS '联系人电话';
COMMENT ON COLUMN tb_shop.province IS '省份';
COMMENT ON COLUMN tb_shop.city IS '城市';
COMMENT ON COLUMN tb_shop.district IS '区县';
COMMENT ON COLUMN tb_shop.address IS '详细地址';
COMMENT ON COLUMN tb_shop.status IS '状态 0=禁用 1=启用';
-- 创建企业表
CREATE TABLE IF NOT EXISTS tb_enterprise (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP WITH TIME ZONE,
creator BIGINT NOT NULL,
updater BIGINT NOT NULL,
enterprise_name VARCHAR(100) NOT NULL,
enterprise_code VARCHAR(50),
owner_shop_id BIGINT,
legal_person VARCHAR(50),
contact_name VARCHAR(50),
contact_phone VARCHAR(20),
business_license VARCHAR(100),
province VARCHAR(50),
city VARCHAR(50),
district VARCHAR(50),
address VARCHAR(255),
status INT NOT NULL DEFAULT 1
);
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_enterprise_owner_shop_id ON tb_enterprise(owner_shop_id);
CREATE UNIQUE INDEX IF NOT EXISTS idx_enterprise_code ON tb_enterprise(enterprise_code) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_enterprise_deleted_at ON tb_enterprise(deleted_at);
-- 添加表注释
COMMENT ON TABLE tb_enterprise IS '企业表';
COMMENT ON COLUMN tb_enterprise.id IS '主键ID';
COMMENT ON COLUMN tb_enterprise.created_at IS '创建时间';
COMMENT ON COLUMN tb_enterprise.updated_at IS '更新时间';
COMMENT ON COLUMN tb_enterprise.deleted_at IS '删除时间';
COMMENT ON COLUMN tb_enterprise.creator IS '创建人ID';
COMMENT ON COLUMN tb_enterprise.updater IS '更新人ID';
COMMENT ON COLUMN tb_enterprise.enterprise_name IS '企业名称';
COMMENT ON COLUMN tb_enterprise.enterprise_code IS '企业编号';
COMMENT ON COLUMN tb_enterprise.owner_shop_id IS '归属店铺IDNULL表示平台直属';
COMMENT ON COLUMN tb_enterprise.legal_person IS '法人代表';
COMMENT ON COLUMN tb_enterprise.contact_name IS '联系人姓名';
COMMENT ON COLUMN tb_enterprise.contact_phone IS '联系人电话';
COMMENT ON COLUMN tb_enterprise.business_license IS '营业执照号';
COMMENT ON COLUMN tb_enterprise.province IS '省份';
COMMENT ON COLUMN tb_enterprise.city IS '城市';
COMMENT ON COLUMN tb_enterprise.district IS '区县';
COMMENT ON COLUMN tb_enterprise.address IS '详细地址';
COMMENT ON COLUMN tb_enterprise.status IS '状态 0=禁用 1=启用';
-- 创建个人客户表
CREATE TABLE IF NOT EXISTS tb_personal_customer (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP WITH TIME ZONE,
phone VARCHAR(20),
nickname VARCHAR(50),
avatar_url VARCHAR(255),
wx_open_id VARCHAR(100),
wx_union_id VARCHAR(100),
status INT NOT NULL DEFAULT 1
);
-- 添加索引
CREATE UNIQUE INDEX IF NOT EXISTS idx_personal_customer_phone ON tb_personal_customer(phone) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_personal_customer_wx_open_id ON tb_personal_customer(wx_open_id);
CREATE INDEX IF NOT EXISTS idx_personal_customer_wx_union_id ON tb_personal_customer(wx_union_id);
CREATE INDEX IF NOT EXISTS idx_personal_customer_deleted_at ON tb_personal_customer(deleted_at);
-- 添加表注释
COMMENT ON TABLE tb_personal_customer IS '个人客户表';
COMMENT ON COLUMN tb_personal_customer.id IS '主键ID';
COMMENT ON COLUMN tb_personal_customer.created_at IS '创建时间';
COMMENT ON COLUMN tb_personal_customer.updated_at IS '更新时间';
COMMENT ON COLUMN tb_personal_customer.deleted_at IS '删除时间';
COMMENT ON COLUMN tb_personal_customer.phone IS '手机号(唯一标识)';
COMMENT ON COLUMN tb_personal_customer.nickname IS '昵称';
COMMENT ON COLUMN tb_personal_customer.avatar_url IS '头像URL';
COMMENT ON COLUMN tb_personal_customer.wx_open_id IS '微信OpenID';
COMMENT ON COLUMN tb_personal_customer.wx_union_id IS '微信UnionID';
COMMENT ON COLUMN tb_personal_customer.status IS '状态 0=禁用 1=启用';
-- 修改 tb_account 表:添加 enterprise_id 列,移除 parent_id 列
ALTER TABLE tb_account ADD COLUMN IF NOT EXISTS enterprise_id BIGINT;
CREATE INDEX IF NOT EXISTS idx_account_enterprise_id ON tb_account(enterprise_id);
COMMENT ON COLUMN tb_account.enterprise_id IS '企业ID企业账号必填';
-- 移除 parent_id 列(如果存在)
ALTER TABLE tb_account DROP COLUMN IF EXISTS parent_id;
-- 更新 tb_account 表的字段注释
COMMENT ON COLUMN tb_account.user_type IS '用户类型 1=超级管理员 2=平台用户 3=代理账号 4=企业账号';
COMMENT ON COLUMN tb_account.shop_id IS '店铺ID代理账号必填';