feat: 归档旧迁移文件,创建初始化数据迁移和重置脚本

This commit is contained in:
2026-04-14 11:24:35 +08:00
parent c35542f911
commit 5e9e41db21
231 changed files with 106 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
-- 回滚:删除遗留表(逆序删除,先删关联表)
DROP TABLE IF EXISTS tb_role_permission;
DROP TABLE IF EXISTS tb_role;
DROP TABLE IF EXISTS tb_permission;
DROP TABLE IF EXISTS tb_account;

View File

@@ -0,0 +1,98 @@
-- 创建遗留表(原由 GORM AutoMigrate 自动创建,迁移文件中缺失)
-- 这 4 张表是项目最早期通过 AutoMigrate 创建的,后续迁移 000001-000010 依赖它们的存在
-- 本迁移还原 AutoMigrate 创建时的原始结构(不含后续 ALTER 添加的字段)
-- ============================================================
-- 1. 账号表tb_account
-- 注意:此处包含 parent_id 字段,该字段在 000002 迁移中被 DROP
-- 注意enterprise_id 由 000002 添加is_primary 由 000010 添加,此处不包含
-- ============================================================
CREATE TABLE IF NOT EXISTS tb_account (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE,
updated_at TIMESTAMP WITH TIME ZONE,
deleted_at TIMESTAMP WITH TIME ZONE,
creator BIGINT NOT NULL,
updater BIGINT NOT NULL,
username VARCHAR(50) NOT NULL,
phone VARCHAR(20) NOT NULL,
password VARCHAR(255) NOT NULL,
user_type BIGINT NOT NULL,
shop_id BIGINT,
parent_id BIGINT,
status BIGINT NOT NULL DEFAULT 1
);
-- 索引(与 GORM AutoMigrate 生成的一致)
CREATE UNIQUE INDEX IF NOT EXISTS idx_account_username ON tb_account(username) WHERE deleted_at IS NULL;
CREATE UNIQUE INDEX IF NOT EXISTS idx_account_phone ON tb_account(phone) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_tb_account_user_type ON tb_account(user_type);
CREATE INDEX IF NOT EXISTS idx_tb_account_shop_id ON tb_account(shop_id);
CREATE INDEX IF NOT EXISTS idx_tb_account_deleted_at ON tb_account(deleted_at);
-- ============================================================
-- 2. 权限表tb_permission
-- 注意platform 由 000003 添加available_for_role_types 由 000009 添加,此处不包含
-- ============================================================
CREATE TABLE IF NOT EXISTS tb_permission (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE,
updated_at TIMESTAMP WITH TIME ZONE,
deleted_at TIMESTAMP WITH TIME ZONE,
creator BIGINT NOT NULL,
updater BIGINT NOT NULL,
perm_name VARCHAR(50) NOT NULL,
perm_code VARCHAR(100) NOT NULL,
perm_type BIGINT NOT NULL,
url VARCHAR(255),
parent_id BIGINT,
sort BIGINT NOT NULL DEFAULT 0,
status BIGINT NOT NULL DEFAULT 1
);
-- 索引
CREATE UNIQUE INDEX IF NOT EXISTS idx_permission_code ON tb_permission(perm_code) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_tb_permission_perm_type ON tb_permission(perm_type);
CREATE INDEX IF NOT EXISTS idx_tb_permission_parent_id ON tb_permission(parent_id);
CREATE INDEX IF NOT EXISTS idx_tb_permission_deleted_at ON tb_permission(deleted_at);
-- ============================================================
-- 3. 角色表tb_role
-- ============================================================
CREATE TABLE IF NOT EXISTS tb_role (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE,
updated_at TIMESTAMP WITH TIME ZONE,
deleted_at TIMESTAMP WITH TIME ZONE,
creator BIGINT NOT NULL,
updater BIGINT NOT NULL,
role_name VARCHAR(50) NOT NULL,
role_desc VARCHAR(255),
role_type BIGINT NOT NULL,
status BIGINT NOT NULL DEFAULT 1
);
-- 索引
CREATE INDEX IF NOT EXISTS idx_tb_role_role_type ON tb_role(role_type);
CREATE INDEX IF NOT EXISTS idx_tb_role_deleted_at ON tb_role(deleted_at);
-- ============================================================
-- 4. 角色权限关联表tb_role_permission
-- ============================================================
CREATE TABLE IF NOT EXISTS tb_role_permission (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE,
updated_at TIMESTAMP WITH TIME ZONE,
deleted_at TIMESTAMP WITH TIME ZONE,
creator BIGINT NOT NULL,
updater BIGINT NOT NULL,
role_id BIGINT NOT NULL,
perm_id BIGINT NOT NULL,
status BIGINT NOT NULL DEFAULT 1
);
-- 索引
CREATE INDEX IF NOT EXISTS idx_tb_role_permission_role_id ON tb_role_permission(role_id);
CREATE INDEX IF NOT EXISTS idx_tb_role_permission_perm_id ON tb_role_permission(perm_id);
CREATE UNIQUE INDEX IF NOT EXISTS idx_role_permission_unique ON tb_role_permission(role_id, perm_id) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_tb_role_permission_deleted_at ON tb_role_permission(deleted_at);

View File

@@ -0,0 +1,4 @@
COMMENT ON TABLE tb_account IS null;
COMMENT ON TABLE tb_permission IS null;
COMMENT ON TABLE tb_role IS null;
COMMENT ON TABLE tb_role_permission IS null;

View File

@@ -0,0 +1,4 @@
COMMENT ON TABLE tb_account IS '账号信息表';
COMMENT ON TABLE tb_permission IS '权限表';
COMMENT ON TABLE tb_role IS '角色表';
COMMENT ON TABLE tb_role_permission IS '角色权限表';

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代理账号必填';

View File

@@ -0,0 +1,6 @@
-- 删除 platform 字段
ALTER TABLE tb_permission
DROP COLUMN IF EXISTS platform;
-- 恢复原 role_type 注释
COMMENT ON COLUMN tb_role.role_type IS '角色类型: 1=超级, 2=代理, 3=企业';

View File

@@ -0,0 +1,8 @@
-- 添加 platform 字段到 tb_permission 表
ALTER TABLE tb_permission
ADD COLUMN platform VARCHAR(20) DEFAULT 'all';
COMMENT ON COLUMN tb_permission.platform IS '适用端口: all-全部, web-Web后台, h5-H5端';
-- 更新 tb_role 表的 role_type 字段注释
COMMENT ON COLUMN tb_role.role_type IS '角色类型: 1=平台角色, 2=客户角色';

View File

@@ -0,0 +1,17 @@
-- 删除个人客户设备号绑定表
DROP INDEX IF EXISTS idx_personal_customer_device_deleted_at;
DROP INDEX IF EXISTS idx_personal_customer_device_device_no;
DROP INDEX IF EXISTS idx_personal_customer_device_customer_device;
DROP TABLE IF EXISTS personal_customer_device;
-- 删除个人客户 ICCID 绑定表
DROP INDEX IF EXISTS idx_personal_customer_iccid_deleted_at;
DROP INDEX IF EXISTS idx_personal_customer_iccid_iccid;
DROP INDEX IF EXISTS idx_personal_customer_iccid_customer_iccid;
DROP TABLE IF EXISTS personal_customer_iccid;
-- 删除个人客户手机号绑定表
DROP INDEX IF EXISTS idx_personal_customer_phone_deleted_at;
DROP INDEX IF EXISTS idx_personal_customer_phone_phone;
DROP INDEX IF EXISTS idx_personal_customer_phone_customer_phone;
DROP TABLE IF EXISTS personal_customer_phone;

View File

@@ -0,0 +1,86 @@
-- 创建个人客户手机号绑定表
CREATE TABLE IF NOT EXISTS personal_customer_phone (
id SERIAL PRIMARY KEY,
customer_id INTEGER NOT NULL,
phone VARCHAR(20) NOT NULL,
is_primary BOOLEAN DEFAULT false,
verified_at TIMESTAMP,
status INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
COMMENT ON TABLE personal_customer_phone IS '个人客户手机号绑定表';
COMMENT ON COLUMN personal_customer_phone.id IS '主键ID';
COMMENT ON COLUMN personal_customer_phone.customer_id IS '个人客户ID';
COMMENT ON COLUMN personal_customer_phone.phone IS '手机号';
COMMENT ON COLUMN personal_customer_phone.is_primary IS '是否主手机号';
COMMENT ON COLUMN personal_customer_phone.verified_at IS '验证通过时间';
COMMENT ON COLUMN personal_customer_phone.status IS '状态 0=禁用 1=启用';
COMMENT ON COLUMN personal_customer_phone.created_at IS '创建时间';
COMMENT ON COLUMN personal_customer_phone.updated_at IS '更新时间';
COMMENT ON COLUMN personal_customer_phone.deleted_at IS '删除时间(软删除)';
-- 创建索引
CREATE UNIQUE INDEX idx_personal_customer_phone_customer_phone ON personal_customer_phone(customer_id, phone) WHERE deleted_at IS NULL;
CREATE INDEX idx_personal_customer_phone_phone ON personal_customer_phone(phone);
CREATE INDEX idx_personal_customer_phone_deleted_at ON personal_customer_phone(deleted_at);
-- 创建个人客户 ICCID 绑定表
CREATE TABLE IF NOT EXISTS personal_customer_iccid (
id SERIAL PRIMARY KEY,
customer_id INTEGER NOT NULL,
iccid VARCHAR(20) NOT NULL,
bind_at TIMESTAMP,
last_used_at TIMESTAMP,
status INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
COMMENT ON TABLE personal_customer_iccid IS '个人客户ICCID绑定表';
COMMENT ON COLUMN personal_customer_iccid.id IS '主键ID';
COMMENT ON COLUMN personal_customer_iccid.customer_id IS '个人客户ID';
COMMENT ON COLUMN personal_customer_iccid.iccid IS 'ICCID20位数字';
COMMENT ON COLUMN personal_customer_iccid.bind_at IS '绑定时间';
COMMENT ON COLUMN personal_customer_iccid.last_used_at IS '最后使用时间';
COMMENT ON COLUMN personal_customer_iccid.status IS '状态 0=禁用 1=启用';
COMMENT ON COLUMN personal_customer_iccid.created_at IS '创建时间';
COMMENT ON COLUMN personal_customer_iccid.updated_at IS '更新时间';
COMMENT ON COLUMN personal_customer_iccid.deleted_at IS '删除时间(软删除)';
-- 创建索引
CREATE UNIQUE INDEX idx_personal_customer_iccid_customer_iccid ON personal_customer_iccid(customer_id, iccid) WHERE deleted_at IS NULL;
CREATE INDEX idx_personal_customer_iccid_iccid ON personal_customer_iccid(iccid);
CREATE INDEX idx_personal_customer_iccid_deleted_at ON personal_customer_iccid(deleted_at);
-- 创建个人客户设备号绑定表
CREATE TABLE IF NOT EXISTS personal_customer_device (
id SERIAL PRIMARY KEY,
customer_id INTEGER NOT NULL,
device_no VARCHAR(50) NOT NULL,
bind_at TIMESTAMP,
last_used_at TIMESTAMP,
status INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
COMMENT ON TABLE personal_customer_device IS '个人客户设备号绑定表';
COMMENT ON COLUMN personal_customer_device.id IS '主键ID';
COMMENT ON COLUMN personal_customer_device.customer_id IS '个人客户ID';
COMMENT ON COLUMN personal_customer_device.device_no IS '设备号/IMEI';
COMMENT ON COLUMN personal_customer_device.bind_at IS '绑定时间';
COMMENT ON COLUMN personal_customer_device.last_used_at IS '最后使用时间';
COMMENT ON COLUMN personal_customer_device.status IS '状态 0=禁用 1=启用';
COMMENT ON COLUMN personal_customer_device.created_at IS '创建时间';
COMMENT ON COLUMN personal_customer_device.updated_at IS '更新时间';
COMMENT ON COLUMN personal_customer_device.deleted_at IS '删除时间(软删除)';
-- 创建索引
CREATE UNIQUE INDEX idx_personal_customer_device_customer_device ON personal_customer_device(customer_id, device_no) WHERE deleted_at IS NULL;
CREATE INDEX idx_personal_customer_device_device_no ON personal_customer_device(device_no);
CREATE INDEX idx_personal_customer_device_deleted_at ON personal_customer_device(deleted_at);

View File

@@ -0,0 +1,38 @@
-- IoT SIM 管理系统数据表删除脚本
-- 创建时间: 2026-01-12
-- 说明: 回滚所有 IoT SIM 管理相关表
-- 删除系统管理表
DROP TABLE IF EXISTS card_replacement_requests;
DROP TABLE IF EXISTS dev_capability_configs;
-- 删除财务管理表
DROP TABLE IF EXISTS payment_merchant_settings;
DROP TABLE IF EXISTS commission_withdrawal_settings;
DROP TABLE IF EXISTS commission_withdrawal_requests;
-- 删除分佣相关表
DROP TABLE IF EXISTS carrier_settlements;
DROP TABLE IF EXISTS commission_templates;
DROP TABLE IF EXISTS commission_approvals;
DROP TABLE IF EXISTS commission_records;
DROP TABLE IF EXISTS commission_combined_conditions;
DROP TABLE IF EXISTS commission_ladder;
DROP TABLE IF EXISTS commission_rules;
DROP TABLE IF EXISTS agent_hierarchies;
-- 删除套餐和轮询相关表
DROP TABLE IF EXISTS data_usage_records;
DROP TABLE IF EXISTS polling_configs;
DROP TABLE IF EXISTS package_usages;
-- 删除核心业务表
DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS device_sim_bindings;
DROP TABLE IF EXISTS agent_package_allocations;
DROP TABLE IF EXISTS packages;
DROP TABLE IF EXISTS package_series;
DROP TABLE IF EXISTS number_cards;
DROP TABLE IF EXISTS devices;
DROP TABLE IF EXISTS iot_cards;
DROP TABLE IF EXISTS carriers;

View File

@@ -0,0 +1,841 @@
-- IoT SIM 管理系统数据表创建脚本
-- 创建时间: 2026-01-12
-- 说明: 本脚本创建 IoT 卡、设备、号卡、套餐、订单、分佣等核心业务表
-- ========================================
-- 1. 核心业务表
-- ========================================
-- 1.1 运营商表
CREATE TABLE carriers (
id BIGSERIAL PRIMARY KEY,
carrier_code VARCHAR(50) UNIQUE NOT NULL,
carrier_name VARCHAR(100) NOT NULL,
description VARCHAR(500),
status INT NOT NULL DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE carriers IS '运营商表';
COMMENT ON COLUMN carriers.id IS '主键ID';
COMMENT ON COLUMN carriers.carrier_code IS '运营商编码(CMCC/CUCC/CTCC)';
COMMENT ON COLUMN carriers.carrier_name IS '运营商名称(中国移动/中国联通/中国电信)';
COMMENT ON COLUMN carriers.description IS '运营商描述';
COMMENT ON COLUMN carriers.status IS '状态 1-启用 2-禁用';
COMMENT ON COLUMN carriers.created_at IS '创建时间';
COMMENT ON COLUMN carriers.updated_at IS '更新时间';
-- 插入初始数据
INSERT INTO carriers (carrier_code, carrier_name, status) VALUES
('CMCC', '中国移动', 1),
('CUCC', '中国联通', 1),
('CTCC', '中国电信', 1);
-- 1.2 IoT 卡表
CREATE TABLE iot_cards (
id BIGSERIAL PRIMARY KEY,
iccid VARCHAR(50) UNIQUE NOT NULL,
card_type VARCHAR(50) NOT NULL,
card_category VARCHAR(20) NOT NULL DEFAULT 'normal',
carrier_id BIGINT NOT NULL,
imsi VARCHAR(50),
msisdn VARCHAR(20),
batch_no VARCHAR(100),
supplier VARCHAR(255),
cost_price DECIMAL(10,2) DEFAULT 0,
distribute_price DECIMAL(10,2) DEFAULT 0,
status INT NOT NULL DEFAULT 1,
owner_type VARCHAR(20) NOT NULL DEFAULT 'platform',
owner_id BIGINT NOT NULL DEFAULT 0,
activated_at TIMESTAMP,
activation_status INT NOT NULL DEFAULT 0,
real_name_status INT NOT NULL DEFAULT 0,
network_status INT NOT NULL DEFAULT 0,
data_usage_mb BIGINT DEFAULT 0,
enable_polling BOOLEAN DEFAULT TRUE,
last_data_check_at TIMESTAMP,
last_real_name_check_at TIMESTAMP,
last_sync_time TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE iot_cards IS 'IoT 卡表(物联网卡/流量卡)';
COMMENT ON COLUMN iot_cards.id IS '主键ID';
COMMENT ON COLUMN iot_cards.iccid IS 'ICCID(唯一标识)';
COMMENT ON COLUMN iot_cards.card_type IS '卡类型';
COMMENT ON COLUMN iot_cards.card_category IS '卡业务类型 normal-普通卡 industry-行业卡';
COMMENT ON COLUMN iot_cards.carrier_id IS '运营商ID';
COMMENT ON COLUMN iot_cards.imsi IS 'IMSI';
COMMENT ON COLUMN iot_cards.msisdn IS 'MSISDN(手机号码)';
COMMENT ON COLUMN iot_cards.batch_no IS '批次号';
COMMENT ON COLUMN iot_cards.supplier IS '供应商';
COMMENT ON COLUMN iot_cards.cost_price IS '成本价(元)';
COMMENT ON COLUMN iot_cards.distribute_price IS '分销价(元)';
COMMENT ON COLUMN iot_cards.status IS '状态 1-在库 2-已分销 3-已激活 4-已停用';
COMMENT ON COLUMN iot_cards.owner_type IS '所有者类型 platform-平台 agent-代理 user-用户 device-设备';
COMMENT ON COLUMN iot_cards.owner_id IS '所有者ID';
COMMENT ON COLUMN iot_cards.activated_at IS '激活时间';
COMMENT ON COLUMN iot_cards.activation_status IS '激活状态 0-未激活 1-已激活';
COMMENT ON COLUMN iot_cards.real_name_status IS '实名状态 0-未实名 1-已实名(行业卡可以保持0)';
COMMENT ON COLUMN iot_cards.network_status IS '网络状态 0-停机 1-开机';
COMMENT ON COLUMN iot_cards.data_usage_mb IS '累计流量使用(MB)';
COMMENT ON COLUMN iot_cards.enable_polling IS '是否参与轮询 true-参与 false-不参与';
COMMENT ON COLUMN iot_cards.last_data_check_at IS '最后一次流量检查时间';
COMMENT ON COLUMN iot_cards.last_real_name_check_at IS '最后一次实名检查时间';
COMMENT ON COLUMN iot_cards.last_sync_time IS '最后一次与Gateway同步时间';
COMMENT ON COLUMN iot_cards.created_at IS '创建时间';
COMMENT ON COLUMN iot_cards.updated_at IS '更新时间';
-- IoT 卡表索引
CREATE INDEX idx_iot_cards_carrier ON iot_cards(carrier_id);
CREATE INDEX idx_iot_cards_owner ON iot_cards(owner_type, owner_id, status);
CREATE INDEX idx_iot_cards_batch ON iot_cards(batch_no);
CREATE INDEX idx_iot_cards_activated ON iot_cards(activated_at);
CREATE INDEX idx_iot_cards_category ON iot_cards(card_category);
CREATE INDEX idx_iot_cards_data_check ON iot_cards(enable_polling, activation_status, last_data_check_at);
CREATE INDEX idx_iot_cards_real_name_check ON iot_cards(enable_polling, real_name_status, last_real_name_check_at);
-- 1.3 设备表
CREATE TABLE devices (
id BIGSERIAL PRIMARY KEY,
device_no VARCHAR(100) UNIQUE NOT NULL,
device_name VARCHAR(255),
device_model VARCHAR(100),
device_type VARCHAR(50),
max_sim_slots INT DEFAULT 4,
manufacturer VARCHAR(255),
batch_no VARCHAR(100),
owner_type VARCHAR(20) NOT NULL DEFAULT 'platform',
owner_id BIGINT NOT NULL DEFAULT 0,
status INT NOT NULL DEFAULT 1,
activated_at TIMESTAMP,
device_username VARCHAR(100),
device_password_encrypted VARCHAR(255),
device_api_endpoint VARCHAR(500),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE devices IS '设备表';
COMMENT ON COLUMN devices.id IS '主键ID';
COMMENT ON COLUMN devices.device_no IS '设备编号(唯一标识)';
COMMENT ON COLUMN devices.device_name IS '设备名称';
COMMENT ON COLUMN devices.device_model IS '设备型号';
COMMENT ON COLUMN devices.device_type IS '设备类型';
COMMENT ON COLUMN devices.max_sim_slots IS '最大插槽数量(默认4)';
COMMENT ON COLUMN devices.manufacturer IS '制造商';
COMMENT ON COLUMN devices.batch_no IS '批次号';
COMMENT ON COLUMN devices.owner_type IS '所有者类型 platform-平台 agent-代理 user-用户';
COMMENT ON COLUMN devices.owner_id IS '所有者ID';
COMMENT ON COLUMN devices.status IS '状态 1-在库 2-已分销 3-已激活 4-已停用';
COMMENT ON COLUMN devices.activated_at IS '激活时间';
COMMENT ON COLUMN devices.device_username IS '设备登录用户名';
COMMENT ON COLUMN devices.device_password_encrypted IS '设备登录密码(加密)';
COMMENT ON COLUMN devices.device_api_endpoint IS '设备API端点';
COMMENT ON COLUMN devices.created_at IS '创建时间';
COMMENT ON COLUMN devices.updated_at IS '更新时间';
-- 设备表索引
CREATE INDEX idx_devices_owner ON devices(owner_type, owner_id, status);
-- 1.4 号卡表
CREATE TABLE number_cards (
id BIGSERIAL PRIMARY KEY,
virtual_product_code VARCHAR(100) UNIQUE NOT NULL,
card_name VARCHAR(255) NOT NULL,
card_type VARCHAR(50),
carrier VARCHAR(50),
data_amount_mb BIGINT,
price DECIMAL(10,2),
agent_id BIGINT,
status INT NOT NULL DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE number_cards IS '号卡表';
COMMENT ON COLUMN number_cards.id IS '主键ID';
COMMENT ON COLUMN number_cards.virtual_product_code IS '虚拟商品编码(用于对应运营商订单)';
COMMENT ON COLUMN number_cards.card_name IS '号卡名称';
COMMENT ON COLUMN number_cards.card_type IS '号卡类型';
COMMENT ON COLUMN number_cards.carrier IS '运营商';
COMMENT ON COLUMN number_cards.data_amount_mb IS '流量额度(MB)';
COMMENT ON COLUMN number_cards.price IS '价格(元)';
COMMENT ON COLUMN number_cards.agent_id IS '代理用户ID';
COMMENT ON COLUMN number_cards.status IS '状态 1-在售 2-下架';
COMMENT ON COLUMN number_cards.created_at IS '创建时间';
COMMENT ON COLUMN number_cards.updated_at IS '更新时间';
-- 号卡表索引
CREATE INDEX idx_number_cards_agent ON number_cards(agent_id, status);
-- 1.5 套餐系列表
CREATE TABLE package_series (
id BIGSERIAL PRIMARY KEY,
series_code VARCHAR(100) UNIQUE NOT NULL,
series_name VARCHAR(255) NOT NULL,
description TEXT,
status INT NOT NULL DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE package_series IS '套餐系列表';
COMMENT ON COLUMN package_series.id IS '主键ID';
COMMENT ON COLUMN package_series.series_code IS '系列编码';
COMMENT ON COLUMN package_series.series_name IS '系列名称';
COMMENT ON COLUMN package_series.description IS '描述';
COMMENT ON COLUMN package_series.status IS '状态 1-启用 2-禁用';
COMMENT ON COLUMN package_series.created_at IS '创建时间';
COMMENT ON COLUMN package_series.updated_at IS '更新时间';
-- 1.6 套餐表
CREATE TABLE packages (
id BIGSERIAL PRIMARY KEY,
package_code VARCHAR(100) UNIQUE NOT NULL,
package_name VARCHAR(255) NOT NULL,
series_id BIGINT,
package_type VARCHAR(50) NOT NULL,
duration_months INT NOT NULL,
data_type VARCHAR(20),
real_data_mb BIGINT DEFAULT 0,
virtual_data_mb BIGINT DEFAULT 0,
data_amount_mb BIGINT DEFAULT 0,
price DECIMAL(10,2) NOT NULL,
status INT NOT NULL DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE packages IS '套餐表';
COMMENT ON COLUMN packages.id IS '主键ID';
COMMENT ON COLUMN packages.package_code IS '套餐编码';
COMMENT ON COLUMN packages.package_name IS '套餐名称';
COMMENT ON COLUMN packages.series_id IS '套餐系列ID';
COMMENT ON COLUMN packages.package_type IS '套餐类型 formal-正式套餐 addon-附加套餐';
COMMENT ON COLUMN packages.duration_months IS '套餐时长(月数) 1-月套餐 12-年套餐';
COMMENT ON COLUMN packages.data_type IS '流量类型 real-真流量 virtual-虚流量';
COMMENT ON COLUMN packages.real_data_mb IS '真流量额度(MB)';
COMMENT ON COLUMN packages.virtual_data_mb IS '虚流量额度(MB,用于停机判断)';
COMMENT ON COLUMN packages.data_amount_mb IS '总流量额度(MB)';
COMMENT ON COLUMN packages.price IS '套餐价格(元)';
COMMENT ON COLUMN packages.status IS '状态 1-启用 2-禁用';
COMMENT ON COLUMN packages.created_at IS '创建时间';
COMMENT ON COLUMN packages.updated_at IS '更新时间';
-- 套餐表索引
CREATE INDEX idx_packages_series ON packages(series_id, status);
-- 1.7 代理套餐分配表
CREATE TABLE agent_package_allocations (
id BIGSERIAL PRIMARY KEY,
agent_id BIGINT NOT NULL,
package_id BIGINT NOT NULL,
cost_price DECIMAL(10,2) NOT NULL,
retail_price DECIMAL(10,2) NOT NULL,
status INT NOT NULL DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
CONSTRAINT uk_agent_package UNIQUE (agent_id, package_id)
);
COMMENT ON TABLE agent_package_allocations IS '代理套餐分配表';
COMMENT ON COLUMN agent_package_allocations.id IS '主键ID';
COMMENT ON COLUMN agent_package_allocations.agent_id IS '代理用户ID';
COMMENT ON COLUMN agent_package_allocations.package_id IS '套餐ID';
COMMENT ON COLUMN agent_package_allocations.cost_price IS '成本价(元)';
COMMENT ON COLUMN agent_package_allocations.retail_price IS '零售价(元)';
COMMENT ON COLUMN agent_package_allocations.status IS '状态 1-启用 2-禁用';
COMMENT ON COLUMN agent_package_allocations.created_at IS '创建时间';
COMMENT ON COLUMN agent_package_allocations.updated_at IS '更新时间';
-- 1.8 设备-IoT卡绑定关系表
CREATE TABLE device_sim_bindings (
id BIGSERIAL PRIMARY KEY,
device_id BIGINT NOT NULL,
iot_card_id BIGINT NOT NULL,
slot_position INT,
bind_status INT DEFAULT 1,
bind_time TIMESTAMP,
unbind_time TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE device_sim_bindings IS '设备-IoT卡绑定关系表';
COMMENT ON COLUMN device_sim_bindings.id IS '主键ID';
COMMENT ON COLUMN device_sim_bindings.device_id IS '设备ID';
COMMENT ON COLUMN device_sim_bindings.iot_card_id IS 'IoT卡ID';
COMMENT ON COLUMN device_sim_bindings.slot_position IS '插槽位置(1, 2, 3, 4)';
COMMENT ON COLUMN device_sim_bindings.bind_status IS '绑定状态 1-已绑定 2-已解绑';
COMMENT ON COLUMN device_sim_bindings.bind_time IS '绑定时间';
COMMENT ON COLUMN device_sim_bindings.unbind_time IS '解绑时间';
COMMENT ON COLUMN device_sim_bindings.created_at IS '创建时间';
COMMENT ON COLUMN device_sim_bindings.updated_at IS '更新时间';
-- 设备-IoT卡绑定关系表索引
CREATE INDEX idx_device_sim_bindings_device ON device_sim_bindings(device_id, bind_status);
CREATE INDEX idx_device_sim_bindings_iot_card ON device_sim_bindings(iot_card_id, bind_status);
CREATE UNIQUE INDEX idx_device_sim_bindings_active_card ON device_sim_bindings(iot_card_id) WHERE bind_status = 1;
-- 1.9 订单表
CREATE TABLE orders (
id BIGSERIAL PRIMARY KEY,
order_no VARCHAR(100) UNIQUE NOT NULL,
order_type INT NOT NULL,
iot_card_id BIGINT,
device_id BIGINT,
number_card_id BIGINT,
package_id BIGINT,
user_id BIGINT NOT NULL,
agent_id BIGINT,
amount DECIMAL(10,2) NOT NULL,
payment_method VARCHAR(20),
status INT NOT NULL DEFAULT 1,
carrier_order_id VARCHAR(255),
carrier_order_data JSONB,
paid_at TIMESTAMP,
completed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE orders IS '订单表';
COMMENT ON COLUMN orders.id IS '主键ID';
COMMENT ON COLUMN orders.order_no IS '订单号(唯一标识)';
COMMENT ON COLUMN orders.order_type IS '订单类型 1-套餐订单 2-号卡订单';
COMMENT ON COLUMN orders.iot_card_id IS 'IoT卡ID(单卡套餐订单时有值)';
COMMENT ON COLUMN orders.device_id IS '设备ID(设备级套餐订单时有值)';
COMMENT ON COLUMN orders.number_card_id IS '号卡ID(号卡订单时有值)';
COMMENT ON COLUMN orders.package_id IS '套餐ID(套餐订单时有值)';
COMMENT ON COLUMN orders.user_id IS '用户ID';
COMMENT ON COLUMN orders.agent_id IS '代理用户ID';
COMMENT ON COLUMN orders.amount IS '订单金额(元)';
COMMENT ON COLUMN orders.payment_method IS '支付方式 wallet-钱包 online-在线支付 carrier-运营商支付';
COMMENT ON COLUMN orders.status IS '状态 1-待支付 2-已支付 3-已完成 4-已取消 5-已退款';
COMMENT ON COLUMN orders.carrier_order_id IS '运营商订单ID';
COMMENT ON COLUMN orders.carrier_order_data IS '运营商订单原始数据(JSON)';
COMMENT ON COLUMN orders.paid_at IS '支付时间';
COMMENT ON COLUMN orders.completed_at IS '完成时间';
COMMENT ON COLUMN orders.created_at IS '创建时间';
COMMENT ON COLUMN orders.updated_at IS '更新时间';
-- 订单表索引
CREATE INDEX idx_orders_user ON orders(user_id, status);
CREATE INDEX idx_orders_agent ON orders(agent_id, status);
CREATE INDEX idx_orders_iot_card ON orders(iot_card_id);
CREATE INDEX idx_orders_device ON orders(device_id);
CREATE INDEX idx_orders_number_card ON orders(number_card_id);
-- ========================================
-- 2. 套餐和轮询相关表
-- ========================================
-- 2.1 套餐使用情况表
CREATE TABLE package_usages (
id BIGSERIAL PRIMARY KEY,
order_id BIGINT NOT NULL,
package_id BIGINT NOT NULL,
usage_type VARCHAR(20) NOT NULL,
iot_card_id BIGINT,
device_id BIGINT,
data_limit_mb BIGINT NOT NULL,
data_usage_mb BIGINT DEFAULT 0,
real_data_usage_mb BIGINT DEFAULT 0,
virtual_data_usage_mb BIGINT DEFAULT 0,
activated_at TIMESTAMP NOT NULL,
expires_at TIMESTAMP NOT NULL,
status INT NOT NULL DEFAULT 1,
last_package_check_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE package_usages IS '套餐使用情况表';
COMMENT ON COLUMN package_usages.id IS '主键ID';
COMMENT ON COLUMN package_usages.order_id IS '订单ID';
COMMENT ON COLUMN package_usages.package_id IS '套餐ID';
COMMENT ON COLUMN package_usages.usage_type IS '使用类型 single_card-单卡套餐 device-设备级套餐';
COMMENT ON COLUMN package_usages.iot_card_id IS 'IoT卡ID(单卡套餐时有值)';
COMMENT ON COLUMN package_usages.device_id IS '设备ID(设备级套餐时有值)';
COMMENT ON COLUMN package_usages.data_limit_mb IS '流量限额(MB)';
COMMENT ON COLUMN package_usages.data_usage_mb IS '已使用流量(MB)';
COMMENT ON COLUMN package_usages.real_data_usage_mb IS '真流量使用(MB)';
COMMENT ON COLUMN package_usages.virtual_data_usage_mb IS '虚流量使用(MB)';
COMMENT ON COLUMN package_usages.activated_at IS '套餐生效时间';
COMMENT ON COLUMN package_usages.expires_at IS '套餐过期时间';
COMMENT ON COLUMN package_usages.status IS '状态 1-生效中 2-已用完 3-已过期';
COMMENT ON COLUMN package_usages.last_package_check_at IS '最后一次套餐流量检查时间';
COMMENT ON COLUMN package_usages.created_at IS '创建时间';
COMMENT ON COLUMN package_usages.updated_at IS '更新时间';
-- 套餐使用情况表索引
CREATE INDEX idx_package_usages_order ON package_usages(order_id);
CREATE INDEX idx_package_usages_package ON package_usages(package_id);
CREATE INDEX idx_package_usages_iot_card ON package_usages(iot_card_id);
CREATE INDEX idx_package_usages_device ON package_usages(device_id);
CREATE INDEX idx_package_usages_check ON package_usages(status, expires_at, last_package_check_at);
-- 2.2 轮询配置表
CREATE TABLE polling_configs (
id BIGSERIAL PRIMARY KEY,
config_name VARCHAR(100) UNIQUE NOT NULL,
description VARCHAR(500),
card_condition VARCHAR(50),
carrier_id BIGINT,
real_name_check_enabled BOOLEAN DEFAULT FALSE,
real_name_check_interval INT DEFAULT 60,
card_data_check_enabled BOOLEAN DEFAULT FALSE,
card_data_check_interval INT DEFAULT 60,
package_check_enabled BOOLEAN DEFAULT FALSE,
package_check_interval INT DEFAULT 60,
priority INT NOT NULL DEFAULT 100,
status INT NOT NULL DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE polling_configs IS '轮询配置表';
COMMENT ON COLUMN polling_configs.id IS '主键ID';
COMMENT ON COLUMN polling_configs.config_name IS '配置名称(如 未实名卡、实名卡)';
COMMENT ON COLUMN polling_configs.description IS '配置描述';
COMMENT ON COLUMN polling_configs.card_condition IS '卡状态条件 not_real_name-未实名 real_name-已实名 activated-已激活 suspended-已停用';
COMMENT ON COLUMN polling_configs.carrier_id IS '运营商ID(NULL表示所有运营商)';
COMMENT ON COLUMN polling_configs.real_name_check_enabled IS '是否启用实名检查';
COMMENT ON COLUMN polling_configs.real_name_check_interval IS '实名检查间隔(秒)';
COMMENT ON COLUMN polling_configs.card_data_check_enabled IS '是否启用卡流量检查';
COMMENT ON COLUMN polling_configs.card_data_check_interval IS '卡流量检查间隔(秒)';
COMMENT ON COLUMN polling_configs.package_check_enabled IS '是否启用套餐流量检查';
COMMENT ON COLUMN polling_configs.package_check_interval IS '套餐流量检查间隔(秒)';
COMMENT ON COLUMN polling_configs.priority IS '优先级(数字越小优先级越高)';
COMMENT ON COLUMN polling_configs.status IS '状态 1-启用 2-禁用';
COMMENT ON COLUMN polling_configs.created_at IS '创建时间';
COMMENT ON COLUMN polling_configs.updated_at IS '更新时间';
-- 轮询配置表索引
CREATE INDEX idx_polling_configs_match ON polling_configs(status, card_condition, carrier_id, priority);
-- 2.3 流量使用记录表
CREATE TABLE data_usage_records (
id BIGSERIAL PRIMARY KEY,
iot_card_id BIGINT NOT NULL,
data_usage_mb BIGINT NOT NULL,
data_increase_mb BIGINT DEFAULT 0,
check_time TIMESTAMP NOT NULL,
source VARCHAR(50) DEFAULT 'polling',
created_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE data_usage_records IS '流量使用记录表';
COMMENT ON COLUMN data_usage_records.id IS '主键ID';
COMMENT ON COLUMN data_usage_records.iot_card_id IS 'IoT卡ID';
COMMENT ON COLUMN data_usage_records.data_usage_mb IS '流量使用量(MB)';
COMMENT ON COLUMN data_usage_records.data_increase_mb IS '相比上次的增量(MB)';
COMMENT ON COLUMN data_usage_records.check_time IS '检查时间';
COMMENT ON COLUMN data_usage_records.source IS '数据来源 polling-轮询 manual-手动 gateway-回调';
COMMENT ON COLUMN data_usage_records.created_at IS '创建时间';
-- 流量使用记录表索引
CREATE INDEX idx_data_usage_records_card_time ON data_usage_records(iot_card_id, check_time DESC);
CREATE INDEX idx_data_usage_records_time ON data_usage_records(check_time);
-- ========================================
-- 3. 分佣相关表
-- ========================================
-- 3.1 代理层级关系表
CREATE TABLE agent_hierarchies (
id BIGSERIAL PRIMARY KEY,
agent_id BIGINT NOT NULL UNIQUE,
parent_agent_id BIGINT,
level INT NOT NULL,
path VARCHAR(500),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE agent_hierarchies IS '代理层级关系表';
COMMENT ON COLUMN agent_hierarchies.id IS '主键ID';
COMMENT ON COLUMN agent_hierarchies.agent_id IS '代理用户ID';
COMMENT ON COLUMN agent_hierarchies.parent_agent_id IS '上级代理用户ID(NULL表示顶级代理)';
COMMENT ON COLUMN agent_hierarchies.level IS '代理层级(1, 2, 3...)';
COMMENT ON COLUMN agent_hierarchies.path IS '代理路径(如: "1/5/12")';
COMMENT ON COLUMN agent_hierarchies.created_at IS '创建时间';
COMMENT ON COLUMN agent_hierarchies.updated_at IS '更新时间';
-- 代理层级关系表索引
CREATE INDEX idx_agent_hierarchies_parent ON agent_hierarchies(parent_agent_id);
-- 3.2 分佣规则表
CREATE TABLE commission_rules (
id BIGSERIAL PRIMARY KEY,
agent_id BIGINT NOT NULL,
business_type VARCHAR(50) NOT NULL,
card_type VARCHAR(50) NOT NULL,
series_id BIGINT,
package_id BIGINT,
commission_type VARCHAR(50) NOT NULL,
commission_mode VARCHAR(20) NOT NULL,
commission_value DECIMAL(10,2) NOT NULL,
unfreeze_days INT DEFAULT 0,
min_activation_for_unfreeze INT DEFAULT 0,
approval_type VARCHAR(20) DEFAULT 'auto',
status INT NOT NULL DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE commission_rules IS '分佣规则表';
COMMENT ON COLUMN commission_rules.id IS '主键ID';
COMMENT ON COLUMN commission_rules.agent_id IS '代理用户ID';
COMMENT ON COLUMN commission_rules.business_type IS '业务类型';
COMMENT ON COLUMN commission_rules.card_type IS '卡类型 number_card-号卡 iot_card-IoT卡';
COMMENT ON COLUMN commission_rules.series_id IS '套餐系列ID(一次性分佣时用)';
COMMENT ON COLUMN commission_rules.package_id IS '套餐ID(长期分佣时用)';
COMMENT ON COLUMN commission_rules.commission_type IS '分佣类型 one_time-一次性 long_term-长期 combined-组合';
COMMENT ON COLUMN commission_rules.commission_mode IS '分佣模式 fixed-固定金额 percent-百分比';
COMMENT ON COLUMN commission_rules.commission_value IS '分佣值';
COMMENT ON COLUMN commission_rules.unfreeze_days IS '解冻天数';
COMMENT ON COLUMN commission_rules.min_activation_for_unfreeze IS '解冻最小激活量';
COMMENT ON COLUMN commission_rules.approval_type IS '审批类型 auto-自动 manual-人工';
COMMENT ON COLUMN commission_rules.status IS '状态 1-启用 2-禁用';
COMMENT ON COLUMN commission_rules.created_at IS '创建时间';
COMMENT ON COLUMN commission_rules.updated_at IS '更新时间';
-- 分佣规则表索引
CREATE INDEX idx_commission_rules_agent ON commission_rules(agent_id, business_type, card_type);
-- 3.3 阶梯分佣配置表
CREATE TABLE commission_ladder (
id BIGSERIAL PRIMARY KEY,
rule_id BIGINT NOT NULL,
ladder_type VARCHAR(50) NOT NULL,
threshold_value INT NOT NULL,
commission_mode VARCHAR(20) NOT NULL,
commission_value DECIMAL(10,2) NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE commission_ladder IS '阶梯分佣配置表';
COMMENT ON COLUMN commission_ladder.id IS '主键ID';
COMMENT ON COLUMN commission_ladder.rule_id IS '分佣规则ID';
COMMENT ON COLUMN commission_ladder.ladder_type IS '阶梯类型 activation-激活量 pickup-提货量 deposit-充值量';
COMMENT ON COLUMN commission_ladder.threshold_value IS '阈值';
COMMENT ON COLUMN commission_ladder.commission_mode IS '分佣模式 fixed-固定金额 percent-百分比';
COMMENT ON COLUMN commission_ladder.commission_value IS '分佣值';
COMMENT ON COLUMN commission_ladder.created_at IS '创建时间';
COMMENT ON COLUMN commission_ladder.updated_at IS '更新时间';
-- 阶梯分佣配置表索引
CREATE INDEX idx_commission_ladder_rule ON commission_ladder(rule_id);
-- 3.4 组合分佣条件表
CREATE TABLE commission_combined_conditions (
id BIGSERIAL PRIMARY KEY,
rule_id BIGINT NOT NULL UNIQUE,
one_time_commission_mode VARCHAR(20),
one_time_commission_value DECIMAL(10,2),
long_term_commission_mode VARCHAR(20),
long_term_commission_value DECIMAL(10,2),
long_term_trigger_time_point TIMESTAMP,
long_term_trigger_package_cycles INT,
long_term_trigger_network_months INT,
long_term_unfreeze_days INT DEFAULT 0,
long_term_min_activation INT DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE commission_combined_conditions IS '组合分佣条件表';
COMMENT ON COLUMN commission_combined_conditions.id IS '主键ID';
COMMENT ON COLUMN commission_combined_conditions.rule_id IS '分佣规则ID';
COMMENT ON COLUMN commission_combined_conditions.one_time_commission_mode IS '一次性分佣模式 fixed-固定金额 percent-百分比';
COMMENT ON COLUMN commission_combined_conditions.one_time_commission_value IS '一次性分佣值';
COMMENT ON COLUMN commission_combined_conditions.long_term_commission_mode IS '长期分佣模式 fixed-固定金额 percent-百分比';
COMMENT ON COLUMN commission_combined_conditions.long_term_commission_value IS '长期分佣值';
COMMENT ON COLUMN commission_combined_conditions.long_term_trigger_time_point IS '长期分佣触发时间点(如实名后3个月)';
COMMENT ON COLUMN commission_combined_conditions.long_term_trigger_package_cycles IS '长期分佣触发套餐周期数(如10个套餐周期)';
COMMENT ON COLUMN commission_combined_conditions.long_term_trigger_network_months IS '长期分佣触发在网月数(号卡专用)';
COMMENT ON COLUMN commission_combined_conditions.long_term_unfreeze_days IS '长期分佣解冻天数';
COMMENT ON COLUMN commission_combined_conditions.long_term_min_activation IS '长期分佣解冻最小激活量';
COMMENT ON COLUMN commission_combined_conditions.created_at IS '创建时间';
COMMENT ON COLUMN commission_combined_conditions.updated_at IS '更新时间';
-- 3.5 分佣记录表
CREATE TABLE commission_records (
id BIGSERIAL PRIMARY KEY,
agent_id BIGINT NOT NULL,
order_id BIGINT NOT NULL,
rule_id BIGINT NOT NULL,
commission_type VARCHAR(50) NOT NULL,
amount DECIMAL(10,2) NOT NULL,
status INT NOT NULL DEFAULT 1,
unfrozen_at TIMESTAMP,
released_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE commission_records IS '分佣记录表';
COMMENT ON COLUMN commission_records.id IS '主键ID';
COMMENT ON COLUMN commission_records.agent_id IS '代理用户ID';
COMMENT ON COLUMN commission_records.order_id IS '订单ID';
COMMENT ON COLUMN commission_records.rule_id IS '分佣规则ID';
COMMENT ON COLUMN commission_records.commission_type IS '分佣类型 one_time-一次性 long_term-长期';
COMMENT ON COLUMN commission_records.amount IS '分佣金额(元)';
COMMENT ON COLUMN commission_records.status IS '状态 1-已冻结 2-解冻中 3-已发放 4-已失效';
COMMENT ON COLUMN commission_records.unfrozen_at IS '解冻时间';
COMMENT ON COLUMN commission_records.released_at IS '发放时间';
COMMENT ON COLUMN commission_records.created_at IS '创建时间';
COMMENT ON COLUMN commission_records.updated_at IS '更新时间';
-- 分佣记录表索引
CREATE INDEX idx_commission_records_agent ON commission_records(agent_id, status);
CREATE INDEX idx_commission_records_order ON commission_records(order_id);
CREATE INDEX idx_commission_records_rule ON commission_records(rule_id);
-- 3.6 分佣审批表
CREATE TABLE commission_approvals (
id BIGSERIAL PRIMARY KEY,
commission_record_id BIGINT NOT NULL,
approver_id BIGINT,
status INT NOT NULL DEFAULT 1,
reason TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE commission_approvals IS '分佣审批表';
COMMENT ON COLUMN commission_approvals.id IS '主键ID';
COMMENT ON COLUMN commission_approvals.commission_record_id IS '分佣记录ID';
COMMENT ON COLUMN commission_approvals.approver_id IS '审批人用户ID';
COMMENT ON COLUMN commission_approvals.status IS '状态 1-待审批 2-已通过 3-已拒绝';
COMMENT ON COLUMN commission_approvals.reason IS '原因';
COMMENT ON COLUMN commission_approvals.created_at IS '创建时间';
COMMENT ON COLUMN commission_approvals.updated_at IS '更新时间';
-- 分佣审批表索引
CREATE INDEX idx_commission_approvals_record ON commission_approvals(commission_record_id);
CREATE INDEX idx_commission_approvals_status ON commission_approvals(status);
-- 3.7 分佣模板表
CREATE TABLE commission_templates (
id BIGSERIAL PRIMARY KEY,
template_name VARCHAR(255) UNIQUE NOT NULL,
business_type VARCHAR(50) NOT NULL,
card_type VARCHAR(50) NOT NULL,
commission_type VARCHAR(50) NOT NULL,
commission_mode VARCHAR(20) NOT NULL,
commission_value DECIMAL(10,2) NOT NULL,
unfreeze_days INT DEFAULT 0,
min_activation_for_unfreeze INT DEFAULT 0,
approval_type VARCHAR(20) DEFAULT 'auto',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE commission_templates IS '分佣模板表';
COMMENT ON COLUMN commission_templates.id IS '主键ID';
COMMENT ON COLUMN commission_templates.template_name IS '模板名称';
COMMENT ON COLUMN commission_templates.business_type IS '业务类型';
COMMENT ON COLUMN commission_templates.card_type IS '卡类型 number_card-号卡 iot_card-IoT卡';
COMMENT ON COLUMN commission_templates.commission_type IS '分佣类型 one_time-一次性 long_term-长期 combined-组合';
COMMENT ON COLUMN commission_templates.commission_mode IS '分佣模式 fixed-固定金额 percent-百分比';
COMMENT ON COLUMN commission_templates.commission_value IS '分佣值';
COMMENT ON COLUMN commission_templates.unfreeze_days IS '解冻天数';
COMMENT ON COLUMN commission_templates.min_activation_for_unfreeze IS '解冻最小激活量';
COMMENT ON COLUMN commission_templates.approval_type IS '审批类型 auto-自动 manual-人工';
COMMENT ON COLUMN commission_templates.created_at IS '创建时间';
COMMENT ON COLUMN commission_templates.updated_at IS '更新时间';
-- 3.8 号卡运营商结算表
CREATE TABLE carrier_settlements (
id BIGSERIAL PRIMARY KEY,
commission_record_id BIGINT NOT NULL UNIQUE,
agent_id BIGINT NOT NULL,
settlement_month VARCHAR(20) NOT NULL,
settlement_amount DECIMAL(18,2) NOT NULL,
status INT NOT NULL DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE carrier_settlements IS '号卡运营商结算表';
COMMENT ON COLUMN carrier_settlements.id IS '主键ID';
COMMENT ON COLUMN carrier_settlements.commission_record_id IS '分佣记录ID';
COMMENT ON COLUMN carrier_settlements.agent_id IS '代理用户ID';
COMMENT ON COLUMN carrier_settlements.settlement_month IS '结算月份(如 2026-01)';
COMMENT ON COLUMN carrier_settlements.settlement_amount IS '结算金额(元)';
COMMENT ON COLUMN carrier_settlements.status IS '状态 1-待结算 2-已结算';
COMMENT ON COLUMN carrier_settlements.created_at IS '创建时间';
COMMENT ON COLUMN carrier_settlements.updated_at IS '更新时间';
-- 号卡运营商结算表索引
CREATE INDEX idx_carrier_settlements_agent ON carrier_settlements(agent_id, status);
-- ========================================
-- 4. 财务管理表
-- ========================================
-- 4.1 佣金提现申请表
CREATE TABLE commission_withdrawal_requests (
id BIGSERIAL PRIMARY KEY,
agent_id BIGINT NOT NULL,
amount DECIMAL(18,2) NOT NULL,
fee DECIMAL(18,2) DEFAULT 0,
actual_amount DECIMAL(18,2),
withdrawal_method VARCHAR(20),
account_info JSONB,
status INT DEFAULT 1,
approved_by BIGINT,
approved_at TIMESTAMP,
paid_at TIMESTAMP,
reject_reason TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE commission_withdrawal_requests IS '佣金提现申请表';
COMMENT ON COLUMN commission_withdrawal_requests.id IS '主键ID';
COMMENT ON COLUMN commission_withdrawal_requests.agent_id IS '代理用户ID';
COMMENT ON COLUMN commission_withdrawal_requests.amount IS '提现金额(元)';
COMMENT ON COLUMN commission_withdrawal_requests.fee IS '手续费(元)';
COMMENT ON COLUMN commission_withdrawal_requests.actual_amount IS '实际到账金额(元)';
COMMENT ON COLUMN commission_withdrawal_requests.withdrawal_method IS '提现方式 alipay-支付宝 wechat-微信 bank-银行卡';
COMMENT ON COLUMN commission_withdrawal_requests.account_info IS '收款账户信息(姓名、账号等)';
COMMENT ON COLUMN commission_withdrawal_requests.status IS '状态 1-待审核 2-已通过 3-已拒绝 4-已到账';
COMMENT ON COLUMN commission_withdrawal_requests.approved_by IS '审批人用户ID';
COMMENT ON COLUMN commission_withdrawal_requests.approved_at IS '审批时间';
COMMENT ON COLUMN commission_withdrawal_requests.paid_at IS '到账时间';
COMMENT ON COLUMN commission_withdrawal_requests.reject_reason IS '拒绝原因';
COMMENT ON COLUMN commission_withdrawal_requests.created_at IS '创建时间';
COMMENT ON COLUMN commission_withdrawal_requests.updated_at IS '更新时间';
-- 佣金提现申请表索引
CREATE INDEX idx_commission_withdrawal_requests_agent ON commission_withdrawal_requests(agent_id, status);
CREATE INDEX idx_commission_withdrawal_requests_created ON commission_withdrawal_requests(created_at);
-- 4.2 佣金提现设置表
CREATE TABLE commission_withdrawal_settings (
id BIGSERIAL PRIMARY KEY,
min_withdrawal_amount DECIMAL(10,2),
fee_rate DECIMAL(5,4),
arrival_days INT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE commission_withdrawal_settings IS '佣金提现设置表';
COMMENT ON COLUMN commission_withdrawal_settings.id IS '主键ID';
COMMENT ON COLUMN commission_withdrawal_settings.min_withdrawal_amount IS '最低提现金额(元)';
COMMENT ON COLUMN commission_withdrawal_settings.fee_rate IS '手续费率(如 0.01 表示 1%)';
COMMENT ON COLUMN commission_withdrawal_settings.arrival_days IS '到账天数';
COMMENT ON COLUMN commission_withdrawal_settings.is_active IS '是否生效(最新一条)';
COMMENT ON COLUMN commission_withdrawal_settings.created_at IS '创建时间';
COMMENT ON COLUMN commission_withdrawal_settings.updated_at IS '更新时间';
-- 4.3 收款商户设置表
CREATE TABLE payment_merchant_settings (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
merchant_type VARCHAR(20),
account_name VARCHAR(255),
account_number VARCHAR(255),
bank_name VARCHAR(255),
bank_branch VARCHAR(255),
is_verified BOOLEAN DEFAULT FALSE,
is_default BOOLEAN DEFAULT FALSE,
status INT DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE payment_merchant_settings IS '收款商户设置表';
COMMENT ON COLUMN payment_merchant_settings.id IS '主键ID';
COMMENT ON COLUMN payment_merchant_settings.user_id IS '用户ID';
COMMENT ON COLUMN payment_merchant_settings.merchant_type IS '商户类型 alipay-支付宝 wechat-微信 bank-银行卡';
COMMENT ON COLUMN payment_merchant_settings.account_name IS '账户名称';
COMMENT ON COLUMN payment_merchant_settings.account_number IS '账号';
COMMENT ON COLUMN payment_merchant_settings.bank_name IS '银行名称(仅银行卡)';
COMMENT ON COLUMN payment_merchant_settings.bank_branch IS '开户行(仅银行卡)';
COMMENT ON COLUMN payment_merchant_settings.is_verified IS '是否已验证';
COMMENT ON COLUMN payment_merchant_settings.is_default IS '是否默认账户';
COMMENT ON COLUMN payment_merchant_settings.status IS '状态 1-启用 2-禁用';
COMMENT ON COLUMN payment_merchant_settings.created_at IS '创建时间';
COMMENT ON COLUMN payment_merchant_settings.updated_at IS '更新时间';
-- 收款商户设置表索引
CREATE INDEX idx_payment_merchant_settings_user ON payment_merchant_settings(user_id, is_default);
CREATE INDEX idx_payment_merchant_settings_type ON payment_merchant_settings(merchant_type, status);
-- ========================================
-- 5. 系统管理表
-- ========================================
-- 5.1 开发能力配置表
CREATE TABLE dev_capability_configs (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
app_name VARCHAR(255),
app_id VARCHAR(100) UNIQUE,
app_secret VARCHAR(255),
callback_url VARCHAR(500),
ip_whitelist TEXT,
status INT DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE dev_capability_configs IS '开发能力配置表';
COMMENT ON COLUMN dev_capability_configs.id IS '主键ID';
COMMENT ON COLUMN dev_capability_configs.user_id IS '用户ID(平台或代理)';
COMMENT ON COLUMN dev_capability_configs.app_name IS '应用名称';
COMMENT ON COLUMN dev_capability_configs.app_id IS '应用ID';
COMMENT ON COLUMN dev_capability_configs.app_secret IS '应用密钥';
COMMENT ON COLUMN dev_capability_configs.callback_url IS '回调地址';
COMMENT ON COLUMN dev_capability_configs.ip_whitelist IS 'IP白名单(多个IP用逗号分隔)';
COMMENT ON COLUMN dev_capability_configs.status IS '状态 1-启用 2-禁用';
COMMENT ON COLUMN dev_capability_configs.created_at IS '创建时间';
COMMENT ON COLUMN dev_capability_configs.updated_at IS '更新时间';
-- 开发能力配置表索引
CREATE INDEX idx_dev_capability_configs_user ON dev_capability_configs(user_id, status);
-- 5.2 换卡申请表
CREATE TABLE card_replacement_requests (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
old_iccid VARCHAR(50) NOT NULL,
new_iccid VARCHAR(50),
reason TEXT,
status INT DEFAULT 1,
approved_by BIGINT,
approved_at TIMESTAMP,
completed_at TIMESTAMP,
reject_reason TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE card_replacement_requests IS '换卡申请表';
COMMENT ON COLUMN card_replacement_requests.id IS '主键ID';
COMMENT ON COLUMN card_replacement_requests.user_id IS '申请用户ID';
COMMENT ON COLUMN card_replacement_requests.old_iccid IS '旧卡ICCID';
COMMENT ON COLUMN card_replacement_requests.new_iccid IS '新卡ICCID(审批时填充)';
COMMENT ON COLUMN card_replacement_requests.reason IS '换卡原因';
COMMENT ON COLUMN card_replacement_requests.status IS '状态 1-待处理 2-已通过 3-已拒绝 4-已完成';
COMMENT ON COLUMN card_replacement_requests.approved_by IS '处理人用户ID';
COMMENT ON COLUMN card_replacement_requests.approved_at IS '处理时间';
COMMENT ON COLUMN card_replacement_requests.completed_at IS '完成时间(新卡激活时间)';
COMMENT ON COLUMN card_replacement_requests.reject_reason IS '拒绝原因';
COMMENT ON COLUMN card_replacement_requests.created_at IS '创建时间';
COMMENT ON COLUMN card_replacement_requests.updated_at IS '更新时间';
-- 换卡申请表索引
CREATE INDEX idx_card_replacement_requests_user ON card_replacement_requests(user_id, status);
CREATE INDEX idx_card_replacement_requests_old_iccid ON card_replacement_requests(old_iccid);
CREATE INDEX idx_card_replacement_requests_new_iccid ON card_replacement_requests(new_iccid);

View File

@@ -0,0 +1,251 @@
-- IoT 模型架构重构回滚脚本
-- 创建时间: 2026-01-12
-- 说明: 回滚所有架构重构变更
-- 1. 恢复唯一索引(移除软删除支持)
-- 2. 恢复金额字段为 DECIMAL 类型
-- 3. 删除软删除字段和审计字段
-- 4. 恢复表名为复数形式
-- ========================================
-- 阶段 1: 恢复唯一约束(移除软删除支持)
-- ========================================
-- 1.1 运营商表
DROP INDEX IF EXISTS idx_carrier_code;
ALTER TABLE tb_carrier ADD CONSTRAINT carriers_carrier_code_key UNIQUE (carrier_code);
-- 1.2 IoT 卡表
DROP INDEX IF EXISTS idx_iot_card_iccid;
ALTER TABLE tb_iot_card ADD CONSTRAINT iot_cards_iccid_key UNIQUE (iccid);
-- 1.3 设备表
DROP INDEX IF EXISTS idx_device_no;
ALTER TABLE tb_device ADD CONSTRAINT devices_device_no_key UNIQUE (device_no);
-- 1.4 号卡表
DROP INDEX IF EXISTS idx_number_card_code;
ALTER TABLE tb_number_card ADD CONSTRAINT number_cards_virtual_product_code_key UNIQUE (virtual_product_code);
-- 1.5 套餐系列表
DROP INDEX IF EXISTS idx_package_series_code;
ALTER TABLE tb_package_series ADD CONSTRAINT package_series_series_code_key UNIQUE (series_code);
-- 1.6 套餐表
DROP INDEX IF EXISTS idx_package_code;
ALTER TABLE tb_package ADD CONSTRAINT packages_package_code_key UNIQUE (package_code);
-- 1.7 代理套餐分配表
DROP INDEX IF EXISTS idx_agent_package_allocation_agent_package;
ALTER TABLE tb_agent_package_allocation ADD CONSTRAINT uk_agent_package UNIQUE (agent_id, package_id);
-- 1.8 设备-SIM绑定表跳过保持原样
-- 1.9 订单表
DROP INDEX IF EXISTS idx_order_no;
ALTER TABLE tb_order ADD CONSTRAINT orders_order_no_key UNIQUE (order_no);
-- 1.10 轮询配置表
DROP INDEX IF EXISTS idx_polling_config_name;
ALTER TABLE tb_polling_config ADD CONSTRAINT polling_configs_config_name_key UNIQUE (config_name);
-- 1.11 代理层级表
DROP INDEX IF EXISTS idx_agent_hierarchy_agent;
ALTER TABLE tb_agent_hierarchy ADD CONSTRAINT agent_hierarchies_agent_id_key UNIQUE (agent_id);
-- 1.12 组合分佣条件表
DROP INDEX IF EXISTS idx_commission_combined_rule;
ALTER TABLE tb_commission_combined_condition ADD CONSTRAINT commission_combined_conditions_rule_id_key UNIQUE (rule_id);
-- 1.13 分佣模板表
DROP INDEX IF EXISTS idx_commission_template_name;
ALTER TABLE tb_commission_template ADD CONSTRAINT commission_templates_template_name_key UNIQUE (template_name);
-- 1.14 运营商结算表
DROP INDEX IF EXISTS idx_carrier_settlement_record;
ALTER TABLE tb_carrier_settlement ADD CONSTRAINT carrier_settlements_commission_record_id_key UNIQUE (commission_record_id);
-- 1.15 开发能力配置表
DROP INDEX IF EXISTS idx_dev_capability_app;
ALTER TABLE tb_dev_capability_config ADD CONSTRAINT dev_capability_configs_app_id_key UNIQUE (app_id);
-- ========================================
-- 阶段 2: 恢复金额字段为 DECIMAL 类型(分 / 100 = 元)
-- ========================================
-- 2.1 IoT 卡表
ALTER TABLE tb_iot_card
ALTER COLUMN cost_price TYPE DECIMAL(10,2) USING (cost_price / 100.0)::DECIMAL(10,2),
ALTER COLUMN distribute_price TYPE DECIMAL(10,2) USING (distribute_price / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_iot_card.cost_price IS '成本价(元)';
COMMENT ON COLUMN tb_iot_card.distribute_price IS '分销价(元)';
-- 2.2 号卡表
ALTER TABLE tb_number_card
ALTER COLUMN price TYPE DECIMAL(10,2) USING (price / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_number_card.price IS '价格(元)';
-- 2.3 套餐表
ALTER TABLE tb_package
ALTER COLUMN price TYPE DECIMAL(10,2) USING (price / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_package.price IS '套餐价格(元)';
-- 2.4 代理套餐分配表
ALTER TABLE tb_agent_package_allocation
ALTER COLUMN cost_price TYPE DECIMAL(10,2) USING (cost_price / 100.0)::DECIMAL(10,2),
ALTER COLUMN retail_price TYPE DECIMAL(10,2) USING (retail_price / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_agent_package_allocation.cost_price IS '成本价(元)';
COMMENT ON COLUMN tb_agent_package_allocation.retail_price IS '零售价(元)';
-- 2.5 订单表
ALTER TABLE tb_order
ALTER COLUMN amount TYPE DECIMAL(10,2) USING (amount / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_order.amount IS '订单金额(元)';
-- 2.6 分佣规则表
ALTER TABLE tb_commission_rule
ALTER COLUMN commission_value TYPE DECIMAL(10,2) USING (commission_value / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_commission_rule.commission_value IS '分佣值(元或百分比)';
-- 2.7 阶梯分佣配置表
ALTER TABLE tb_commission_ladder
ALTER COLUMN commission_value TYPE DECIMAL(10,2) USING (commission_value / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_commission_ladder.commission_value IS '分佣值(元或百分比)';
-- 2.8 组合分佣条件表
ALTER TABLE tb_commission_combined_condition
ALTER COLUMN one_time_commission_value TYPE DECIMAL(10,2) USING (one_time_commission_value / 100.0)::DECIMAL(10,2),
ALTER COLUMN long_term_commission_value TYPE DECIMAL(10,2) USING (long_term_commission_value / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_commission_combined_condition.one_time_commission_value IS '一次性分佣值(元或百分比)';
COMMENT ON COLUMN tb_commission_combined_condition.long_term_commission_value IS '长期分佣值(元或百分比)';
-- 2.9 分佣记录表
ALTER TABLE tb_commission_record
ALTER COLUMN amount TYPE DECIMAL(10,2) USING (amount / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_commission_record.amount IS '分佣金额(元)';
-- 2.10 分佣模板表
ALTER TABLE tb_commission_template
ALTER COLUMN commission_value TYPE DECIMAL(10,2) USING (commission_value / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_commission_template.commission_value IS '分佣值(元或百分比)';
-- 2.11 运营商结算表
ALTER TABLE tb_carrier_settlement
ALTER COLUMN settlement_amount TYPE DECIMAL(10,2) USING (settlement_amount / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_carrier_settlement.settlement_amount IS '结算金额(元)';
-- 2.12 佣金提现申请表
ALTER TABLE tb_commission_withdrawal_request
ALTER COLUMN amount TYPE DECIMAL(10,2) USING (amount / 100.0)::DECIMAL(10,2),
ALTER COLUMN fee TYPE DECIMAL(10,2) USING (fee / 100.0)::DECIMAL(10,2),
ALTER COLUMN actual_amount TYPE DECIMAL(10,2) USING (actual_amount / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_commission_withdrawal_request.amount IS '提现金额(元)';
COMMENT ON COLUMN tb_commission_withdrawal_request.fee IS '手续费(元)';
COMMENT ON COLUMN tb_commission_withdrawal_request.actual_amount IS '实际到账金额(元)';
-- 2.13 佣金提现设置表
ALTER TABLE tb_commission_withdrawal_setting
ALTER COLUMN min_withdrawal_amount TYPE DECIMAL(10,2) USING (min_withdrawal_amount / 100.0)::DECIMAL(10,2);
COMMENT ON COLUMN tb_commission_withdrawal_setting.min_withdrawal_amount IS '最低提现金额(元)';
-- ========================================
-- 阶段 3: 删除软删除字段和审计字段
-- ========================================
ALTER TABLE tb_carrier DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_iot_card DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_device DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_number_card DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_package_series DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_package DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_agent_package_allocation DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_device_sim_binding DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_order DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_package_usage DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_polling_config DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
-- 注意: tb_data_usage_record 没有添加这些字段,所以不需要删除
ALTER TABLE tb_agent_hierarchy DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_commission_rule DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_commission_ladder DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_commission_combined_condition DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_commission_record DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_commission_approval DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_commission_template DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_carrier_settlement DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_commission_withdrawal_request DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_commission_withdrawal_setting DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_payment_merchant_setting DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_dev_capability_config DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
ALTER TABLE tb_card_replacement_request DROP COLUMN deleted_at, DROP COLUMN creator, DROP COLUMN updater;
-- ========================================
-- 阶段 4: 恢复表名为复数形式
-- ========================================
ALTER TABLE tb_carrier RENAME TO carriers;
ALTER TABLE tb_iot_card RENAME TO iot_cards;
ALTER TABLE tb_device RENAME TO devices;
ALTER TABLE tb_number_card RENAME TO number_cards;
ALTER TABLE tb_package_series RENAME TO package_series;
ALTER TABLE tb_package RENAME TO packages;
ALTER TABLE tb_agent_package_allocation RENAME TO agent_package_allocations;
ALTER TABLE tb_device_sim_binding RENAME TO device_sim_bindings;
ALTER TABLE tb_order RENAME TO orders;
ALTER TABLE tb_package_usage RENAME TO package_usages;
ALTER TABLE tb_polling_config RENAME TO polling_configs;
ALTER TABLE tb_data_usage_record RENAME TO data_usage_records;
ALTER TABLE tb_agent_hierarchy RENAME TO agent_hierarchies;
ALTER TABLE tb_commission_rule RENAME TO commission_rules;
ALTER TABLE tb_commission_ladder RENAME TO commission_ladder;
ALTER TABLE tb_commission_combined_condition RENAME TO commission_combined_conditions;
ALTER TABLE tb_commission_record RENAME TO commission_records;
ALTER TABLE tb_commission_approval RENAME TO commission_approvals;
ALTER TABLE tb_commission_template RENAME TO commission_templates;
ALTER TABLE tb_carrier_settlement RENAME TO carrier_settlements;
ALTER TABLE tb_commission_withdrawal_request RENAME TO commission_withdrawal_requests;
ALTER TABLE tb_commission_withdrawal_setting RENAME TO commission_withdrawal_settings;
ALTER TABLE tb_payment_merchant_setting RENAME TO payment_merchant_settings;
ALTER TABLE tb_dev_capability_config RENAME TO dev_capability_configs;
ALTER TABLE tb_card_replacement_request RENAME TO card_replacement_requests;
-- ========================================
-- 阶段 5: 恢复表注释
-- ========================================
COMMENT ON TABLE carriers IS '运营商表';
COMMENT ON TABLE iot_cards IS 'IoT 卡表(物联网卡/流量卡)';
COMMENT ON TABLE devices IS '设备表(可容纳1-4张SIM卡)';
COMMENT ON TABLE number_cards IS '号卡表(虚拟商品)';
COMMENT ON TABLE package_series IS '套餐系列表';
COMMENT ON TABLE packages IS '套餐表';
COMMENT ON TABLE agent_package_allocations IS '代理套餐分配表';
COMMENT ON TABLE device_sim_bindings IS '设备-SIM卡绑定表';
COMMENT ON TABLE orders IS '订单表';
COMMENT ON TABLE package_usages IS '套餐使用表';
COMMENT ON TABLE polling_configs IS '轮询配置表';
COMMENT ON TABLE data_usage_records IS '流量使用记录表';
COMMENT ON TABLE agent_hierarchies IS '代理层级关系表';
COMMENT ON TABLE commission_rules IS '分佣规则表';
COMMENT ON TABLE commission_ladder IS '阶梯分佣配置表';
COMMENT ON TABLE commission_combined_conditions IS '组合分佣条件表';
COMMENT ON TABLE commission_records IS '分佣记录表';
COMMENT ON TABLE commission_approvals IS '分佣审批表';
COMMENT ON TABLE commission_templates IS '分佣模板表';
COMMENT ON TABLE carrier_settlements IS '号卡运营商结算表';
COMMENT ON TABLE commission_withdrawal_requests IS '佣金提现申请表';
COMMENT ON TABLE commission_withdrawal_settings IS '佣金提现设置表';
COMMENT ON TABLE payment_merchant_settings IS '收款商户设置表';
COMMENT ON TABLE dev_capability_configs IS '开发能力配置表';
COMMENT ON TABLE card_replacement_requests IS '换卡申请表';

View File

@@ -0,0 +1,349 @@
-- IoT 模型架构重构迁移脚本
-- 创建时间: 2026-01-12
-- 说明: 修改所有 IoT 相关表以符合项目架构规范
-- 1. 表名改为 tb_ 前缀 + 单数形式
-- 2. 添加软删除字段 deleted_at
-- 3. 添加审计字段 creator, updater
-- 4. 金额字段从 DECIMAL 改为 BIGINT分为单位
-- 5. 更新唯一索引以支持软删除
-- ========================================
-- 阶段 1: 重命名表(复数 -> tb_ + 单数)
-- ========================================
ALTER TABLE carriers RENAME TO tb_carrier;
ALTER TABLE iot_cards RENAME TO tb_iot_card;
ALTER TABLE devices RENAME TO tb_device;
ALTER TABLE number_cards RENAME TO tb_number_card;
ALTER TABLE package_series RENAME TO tb_package_series;
ALTER TABLE packages RENAME TO tb_package;
ALTER TABLE agent_package_allocations RENAME TO tb_agent_package_allocation;
ALTER TABLE device_sim_bindings RENAME TO tb_device_sim_binding;
ALTER TABLE orders RENAME TO tb_order;
ALTER TABLE package_usages RENAME TO tb_package_usage;
ALTER TABLE polling_configs RENAME TO tb_polling_config;
ALTER TABLE data_usage_records RENAME TO tb_data_usage_record;
ALTER TABLE agent_hierarchies RENAME TO tb_agent_hierarchy;
ALTER TABLE commission_rules RENAME TO tb_commission_rule;
ALTER TABLE commission_ladder RENAME TO tb_commission_ladder;
ALTER TABLE commission_combined_conditions RENAME TO tb_commission_combined_condition;
ALTER TABLE commission_records RENAME TO tb_commission_record;
ALTER TABLE commission_approvals RENAME TO tb_commission_approval;
ALTER TABLE commission_templates RENAME TO tb_commission_template;
ALTER TABLE carrier_settlements RENAME TO tb_carrier_settlement;
ALTER TABLE commission_withdrawal_requests RENAME TO tb_commission_withdrawal_request;
ALTER TABLE commission_withdrawal_settings RENAME TO tb_commission_withdrawal_setting;
ALTER TABLE payment_merchant_settings RENAME TO tb_payment_merchant_setting;
ALTER TABLE dev_capability_configs RENAME TO tb_dev_capability_config;
ALTER TABLE card_replacement_requests RENAME TO tb_card_replacement_request;
-- ========================================
-- 阶段 2: 添加软删除字段和审计字段
-- ========================================
-- 2.1 运营商表
ALTER TABLE tb_carrier ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_carrier ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_carrier ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.2 IoT 卡表
ALTER TABLE tb_iot_card ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_iot_card ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_iot_card ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.3 设备表
ALTER TABLE tb_device ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_device ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_device ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.4 号卡表
ALTER TABLE tb_number_card ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_number_card ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_number_card ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.5 套餐系列表
ALTER TABLE tb_package_series ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_package_series ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_package_series ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.6 套餐表
ALTER TABLE tb_package ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_package ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_package ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.7 代理套餐分配表
ALTER TABLE tb_agent_package_allocation ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_agent_package_allocation ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_agent_package_allocation ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.8 设备-SIM绑定表
ALTER TABLE tb_device_sim_binding ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_device_sim_binding ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_device_sim_binding ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.9 订单表
ALTER TABLE tb_order ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_order ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_order ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.10 套餐使用表
ALTER TABLE tb_package_usage ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_package_usage ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_package_usage ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.11 轮询配置表
ALTER TABLE tb_polling_config ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_polling_config ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_polling_config ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 注意: tb_data_usage_record 是日志表,不需要软删除和审计字段
-- 2.12 代理层级表
ALTER TABLE tb_agent_hierarchy ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_agent_hierarchy ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_agent_hierarchy ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.13 分佣规则表
ALTER TABLE tb_commission_rule ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_commission_rule ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_commission_rule ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.14 阶梯分佣配置表
ALTER TABLE tb_commission_ladder ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_commission_ladder ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_commission_ladder ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.15 组合分佣条件表
ALTER TABLE tb_commission_combined_condition ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_commission_combined_condition ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_commission_combined_condition ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.16 分佣记录表
ALTER TABLE tb_commission_record ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_commission_record ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_commission_record ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.17 分佣审批表
ALTER TABLE tb_commission_approval ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_commission_approval ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_commission_approval ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.18 分佣模板表
ALTER TABLE tb_commission_template ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_commission_template ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_commission_template ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.19 运营商结算表
ALTER TABLE tb_carrier_settlement ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_carrier_settlement ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_carrier_settlement ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.20 佣金提现申请表
ALTER TABLE tb_commission_withdrawal_request ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_commission_withdrawal_request ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_commission_withdrawal_request ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.21 佣金提现设置表
ALTER TABLE tb_commission_withdrawal_setting ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_commission_withdrawal_setting ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_commission_withdrawal_setting ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.22 收款商户设置表
ALTER TABLE tb_payment_merchant_setting ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_payment_merchant_setting ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_payment_merchant_setting ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.23 开发能力配置表
ALTER TABLE tb_dev_capability_config ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_dev_capability_config ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_dev_capability_config ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- 2.24 换卡申请表
ALTER TABLE tb_card_replacement_request ADD COLUMN deleted_at TIMESTAMP;
ALTER TABLE tb_card_replacement_request ADD COLUMN creator BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_card_replacement_request ADD COLUMN updater BIGINT NOT NULL DEFAULT 0;
-- ========================================
-- 阶段 3: 修改金额字段从 DECIMAL 改为 BIGINT分为单位
-- ========================================
-- 3.1 IoT 卡表:成本价、分销价(元 * 100 = 分)
ALTER TABLE tb_iot_card
ALTER COLUMN cost_price TYPE BIGINT USING (cost_price * 100)::BIGINT,
ALTER COLUMN distribute_price TYPE BIGINT USING (distribute_price * 100)::BIGINT;
COMMENT ON COLUMN tb_iot_card.cost_price IS '成本价(分为单位)';
COMMENT ON COLUMN tb_iot_card.distribute_price IS '分销价(分为单位)';
-- 3.2 号卡表:价格
ALTER TABLE tb_number_card
ALTER COLUMN price TYPE BIGINT USING (price * 100)::BIGINT;
COMMENT ON COLUMN tb_number_card.price IS '价格(分为单位)';
-- 3.3 套餐表:价格
ALTER TABLE tb_package
ALTER COLUMN price TYPE BIGINT USING (price * 100)::BIGINT;
COMMENT ON COLUMN tb_package.price IS '套餐价格(分为单位)';
-- 3.4 代理套餐分配表:成本价和零售价
ALTER TABLE tb_agent_package_allocation
ALTER COLUMN cost_price TYPE BIGINT USING (cost_price * 100)::BIGINT,
ALTER COLUMN retail_price TYPE BIGINT USING (retail_price * 100)::BIGINT;
COMMENT ON COLUMN tb_agent_package_allocation.cost_price IS '成本价(分为单位)';
COMMENT ON COLUMN tb_agent_package_allocation.retail_price IS '零售价(分为单位)';
-- 3.5 订单表:订单金额
ALTER TABLE tb_order
ALTER COLUMN amount TYPE BIGINT USING (amount * 100)::BIGINT;
COMMENT ON COLUMN tb_order.amount IS '订单金额(分为单位)';
-- 3.6 分佣规则表:分佣值
ALTER TABLE tb_commission_rule
ALTER COLUMN commission_value TYPE BIGINT USING (commission_value * 100)::BIGINT;
COMMENT ON COLUMN tb_commission_rule.commission_value IS '分佣值(分为单位,百分比时为千分比如2000表示20%)';
-- 3.7 阶梯分佣配置表:分佣值
ALTER TABLE tb_commission_ladder
ALTER COLUMN commission_value TYPE BIGINT USING (commission_value * 100)::BIGINT;
COMMENT ON COLUMN tb_commission_ladder.commission_value IS '分佣值(分为单位,百分比时为千分比如2000表示20%)';
-- 3.8 组合分佣条件表:一次性分佣值、长期分佣值
ALTER TABLE tb_commission_combined_condition
ALTER COLUMN one_time_commission_value TYPE BIGINT USING (one_time_commission_value * 100)::BIGINT,
ALTER COLUMN long_term_commission_value TYPE BIGINT USING (long_term_commission_value * 100)::BIGINT;
COMMENT ON COLUMN tb_commission_combined_condition.one_time_commission_value IS '一次性分佣值(分为单位,百分比时为千分比如2000表示20%)';
COMMENT ON COLUMN tb_commission_combined_condition.long_term_commission_value IS '长期分佣值(分为单位,百分比时为千分比如2000表示20%)';
-- 3.9 分佣记录表:分佣金额
ALTER TABLE tb_commission_record
ALTER COLUMN amount TYPE BIGINT USING (amount * 100)::BIGINT;
COMMENT ON COLUMN tb_commission_record.amount IS '分佣金额(分为单位)';
-- 3.10 分佣模板表:分佣值
ALTER TABLE tb_commission_template
ALTER COLUMN commission_value TYPE BIGINT USING (commission_value * 100)::BIGINT;
COMMENT ON COLUMN tb_commission_template.commission_value IS '分佣值(分为单位,百分比时为千分比如2000表示20%)';
-- 3.11 运营商结算表:结算金额
ALTER TABLE tb_carrier_settlement
ALTER COLUMN settlement_amount TYPE BIGINT USING (settlement_amount * 100)::BIGINT;
COMMENT ON COLUMN tb_carrier_settlement.settlement_amount IS '结算金额(分为单位)';
-- 3.12 佣金提现申请表:提现金额、手续费、实际到账金额
ALTER TABLE tb_commission_withdrawal_request
ALTER COLUMN amount TYPE BIGINT USING (amount * 100)::BIGINT,
ALTER COLUMN fee TYPE BIGINT USING (fee * 100)::BIGINT,
ALTER COLUMN actual_amount TYPE BIGINT USING (actual_amount * 100)::BIGINT;
COMMENT ON COLUMN tb_commission_withdrawal_request.amount IS '提现金额(分为单位)';
COMMENT ON COLUMN tb_commission_withdrawal_request.fee IS '手续费(分为单位)';
COMMENT ON COLUMN tb_commission_withdrawal_request.actual_amount IS '实际到账金额(分为单位)';
-- 3.13 佣金提现设置表:最低提现金额
ALTER TABLE tb_commission_withdrawal_setting
ALTER COLUMN min_withdrawal_amount TYPE BIGINT USING (min_withdrawal_amount * 100)::BIGINT;
COMMENT ON COLUMN tb_commission_withdrawal_setting.min_withdrawal_amount IS '最低提现金额(分为单位)';
-- ========================================
-- 阶段 4: 更新唯一索引以支持软删除
-- ========================================
-- 4.1 运营商表
ALTER TABLE tb_carrier DROP CONSTRAINT IF EXISTS carriers_carrier_code_key;
CREATE UNIQUE INDEX idx_carrier_code ON tb_carrier(carrier_code) WHERE deleted_at IS NULL;
-- 4.2 IoT 卡表
ALTER TABLE tb_iot_card DROP CONSTRAINT IF EXISTS iot_cards_iccid_key;
CREATE UNIQUE INDEX idx_iot_card_iccid ON tb_iot_card(iccid) WHERE deleted_at IS NULL;
-- 4.3 设备表
ALTER TABLE tb_device DROP CONSTRAINT IF EXISTS devices_device_no_key;
CREATE UNIQUE INDEX idx_device_no ON tb_device(device_no) WHERE deleted_at IS NULL;
-- 4.4 号卡表
ALTER TABLE tb_number_card DROP CONSTRAINT IF EXISTS number_cards_virtual_product_code_key;
CREATE UNIQUE INDEX idx_number_card_code ON tb_number_card(virtual_product_code) WHERE deleted_at IS NULL;
-- 4.5 套餐系列表
ALTER TABLE tb_package_series DROP CONSTRAINT IF EXISTS package_series_series_code_key;
CREATE UNIQUE INDEX idx_package_series_code ON tb_package_series(series_code) WHERE deleted_at IS NULL;
-- 4.6 套餐表
ALTER TABLE tb_package DROP CONSTRAINT IF EXISTS packages_package_code_key;
CREATE UNIQUE INDEX idx_package_code ON tb_package(package_code) WHERE deleted_at IS NULL;
-- 4.7 代理套餐分配表(复合唯一索引)
ALTER TABLE tb_agent_package_allocation DROP CONSTRAINT IF EXISTS uk_agent_package;
CREATE UNIQUE INDEX idx_agent_package_allocation_agent_package ON tb_agent_package_allocation(agent_id, package_id) WHERE deleted_at IS NULL;
-- 4.8 设备-SIM绑定表暂时跳过因为没有约束需要修改
-- 原始表使用条件唯一索引 idx_device_sim_bindings_active_card不需要修改
-- 4.9 订单表
ALTER TABLE tb_order DROP CONSTRAINT IF EXISTS orders_order_no_key;
CREATE UNIQUE INDEX idx_order_no ON tb_order(order_no) WHERE deleted_at IS NULL;
-- 4.10 轮询配置表
ALTER TABLE tb_polling_config DROP CONSTRAINT IF EXISTS polling_configs_config_name_key;
CREATE UNIQUE INDEX idx_polling_config_name ON tb_polling_config(config_name) WHERE deleted_at IS NULL;
-- 4.11 代理层级表
ALTER TABLE tb_agent_hierarchy DROP CONSTRAINT IF EXISTS agent_hierarchies_agent_id_key;
CREATE UNIQUE INDEX idx_agent_hierarchy_agent ON tb_agent_hierarchy(agent_id) WHERE deleted_at IS NULL;
-- 4.12 组合分佣条件表
ALTER TABLE tb_commission_combined_condition DROP CONSTRAINT IF EXISTS commission_combined_conditions_rule_id_key;
CREATE UNIQUE INDEX idx_commission_combined_rule ON tb_commission_combined_condition(rule_id) WHERE deleted_at IS NULL;
-- 4.13 分佣模板表
ALTER TABLE tb_commission_template DROP CONSTRAINT IF EXISTS commission_templates_template_name_key;
CREATE UNIQUE INDEX idx_commission_template_name ON tb_commission_template(template_name) WHERE deleted_at IS NULL;
-- 4.14 运营商结算表
ALTER TABLE tb_carrier_settlement DROP CONSTRAINT IF EXISTS carrier_settlements_commission_record_id_key;
CREATE UNIQUE INDEX idx_carrier_settlement_record ON tb_carrier_settlement(commission_record_id) WHERE deleted_at IS NULL;
-- 4.15 开发能力配置表
ALTER TABLE tb_dev_capability_config DROP CONSTRAINT IF EXISTS dev_capability_configs_app_id_key;
CREATE UNIQUE INDEX idx_dev_capability_app ON tb_dev_capability_config(app_id) WHERE deleted_at IS NULL;
-- ========================================
-- 阶段 5: 更新表注释
-- ========================================
COMMENT ON TABLE tb_carrier IS '运营商表';
COMMENT ON TABLE tb_iot_card IS 'IoT卡表(物联网卡/流量卡)';
COMMENT ON TABLE tb_device IS '设备表(可容纳1-4张SIM卡)';
COMMENT ON TABLE tb_number_card IS '号卡表(虚拟商品)';
COMMENT ON TABLE tb_package_series IS '套餐系列表';
COMMENT ON TABLE tb_package IS '套餐表';
COMMENT ON TABLE tb_agent_package_allocation IS '代理套餐分配表';
COMMENT ON TABLE tb_device_sim_binding IS '设备-SIM卡绑定表';
COMMENT ON TABLE tb_order IS '订单表';
COMMENT ON TABLE tb_package_usage IS '套餐使用表';
COMMENT ON TABLE tb_polling_config IS '轮询配置表';
COMMENT ON TABLE tb_data_usage_record IS '流量使用记录表';
COMMENT ON TABLE tb_agent_hierarchy IS '代理层级关系表';
COMMENT ON TABLE tb_commission_rule IS '分佣规则表';
COMMENT ON TABLE tb_commission_ladder IS '阶梯分佣配置表';
COMMENT ON TABLE tb_commission_combined_condition IS '组合分佣条件表';
COMMENT ON TABLE tb_commission_record IS '分佣记录表';
COMMENT ON TABLE tb_commission_approval IS '分佣审批表';
COMMENT ON TABLE tb_commission_template IS '分佣模板表';
COMMENT ON TABLE tb_carrier_settlement IS '号卡运营商结算表';
COMMENT ON TABLE tb_commission_withdrawal_request IS '佣金提现申请表';
COMMENT ON TABLE tb_commission_withdrawal_setting IS '佣金提现设置表';
COMMENT ON TABLE tb_payment_merchant_setting IS '收款商户设置表';
COMMENT ON TABLE tb_dev_capability_config IS '开发能力配置表';
COMMENT ON TABLE tb_card_replacement_request IS '换卡申请表';

View File

@@ -0,0 +1,50 @@
-- Rollback: Remove wallet, card replacement, tag tables and revert carrier, order changes
-- Created: 2026-01-13
-- Revert order table changes
ALTER TABLE tb_order DROP COLUMN IF EXISTS online_payment_amount;
ALTER TABLE tb_order DROP COLUMN IF EXISTS wallet_payment_amount;
-- Revert carrier table changes
DROP INDEX IF EXISTS idx_carrier_type_channel;
ALTER TABLE tb_carrier DROP COLUMN IF EXISTS channel_code;
ALTER TABLE tb_carrier DROP COLUMN IF EXISTS channel_name;
ALTER TABLE tb_carrier DROP COLUMN IF EXISTS carrier_type;
-- Drop tag tables
DROP INDEX IF EXISTS idx_resource_tag_unique;
DROP INDEX IF EXISTS idx_resource_tag_composite;
DROP INDEX IF EXISTS idx_resource_tag_tag;
DROP INDEX IF EXISTS idx_resource_tag_resource;
DROP TABLE IF EXISTS tb_resource_tag;
DROP INDEX IF EXISTS idx_tag_name;
DROP INDEX IF EXISTS idx_tag_usage;
DROP TABLE IF EXISTS tb_tag;
-- Drop card replacement table
DROP INDEX IF EXISTS idx_card_replacement_no;
DROP INDEX IF EXISTS idx_card_replacement_status;
DROP INDEX IF EXISTS idx_card_replacement_new_owner;
DROP INDEX IF EXISTS idx_card_replacement_old_owner;
DROP INDEX IF EXISTS idx_card_replacement_new_card;
DROP INDEX IF EXISTS idx_card_replacement_old_card;
DROP TABLE IF EXISTS tb_card_replacement_record;
-- Drop recharge record table
DROP INDEX IF EXISTS idx_recharge_no;
DROP INDEX IF EXISTS idx_recharge_status;
DROP INDEX IF EXISTS idx_recharge_user;
DROP TABLE IF EXISTS tb_recharge_record;
-- Drop wallet transaction table
DROP INDEX IF EXISTS idx_wallet_tx_ref;
DROP INDEX IF EXISTS idx_wallet_tx_user;
DROP INDEX IF EXISTS idx_wallet_tx_wallet;
DROP TABLE IF EXISTS tb_wallet_transaction;
-- Drop wallet table
DROP INDEX IF EXISTS idx_wallet_user_type_currency;
DROP INDEX IF EXISTS idx_wallet_status;
DROP INDEX IF EXISTS idx_wallet_user;
DROP TABLE IF EXISTS tb_wallet;

View File

@@ -0,0 +1,285 @@
-- Migration: Add wallet, card replacement, tag tables and modify carrier, order tables
-- Created: 2026-01-13
-- =====================================================
-- 1. 钱包系统3 张表)
-- =====================================================
-- 1.1 钱包表
CREATE TABLE IF NOT EXISTS tb_wallet (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
wallet_type VARCHAR(20) NOT NULL,
balance BIGINT NOT NULL DEFAULT 0,
frozen_balance BIGINT NOT NULL DEFAULT 0,
currency VARCHAR(10) NOT NULL DEFAULT 'CNY',
status INT NOT NULL DEFAULT 1,
version INT NOT NULL DEFAULT 0,
creator BIGINT,
updater BIGINT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
COMMENT ON TABLE tb_wallet IS '钱包表';
COMMENT ON COLUMN tb_wallet.id IS '钱包ID';
COMMENT ON COLUMN tb_wallet.user_id IS '用户ID关联tb_account.id';
COMMENT ON COLUMN tb_wallet.wallet_type IS '钱包类型user-用户钱包, agent-代理钱包';
COMMENT ON COLUMN tb_wallet.balance IS '余额(分)';
COMMENT ON COLUMN tb_wallet.frozen_balance IS '冻结余额(分)';
COMMENT ON COLUMN tb_wallet.currency IS '币种';
COMMENT ON COLUMN tb_wallet.status IS '钱包状态1-正常 2-冻结 3-关闭';
COMMENT ON COLUMN tb_wallet.version IS '版本号(乐观锁)';
COMMENT ON COLUMN tb_wallet.creator IS '创建人ID';
COMMENT ON COLUMN tb_wallet.updater IS '更新人ID';
COMMENT ON COLUMN tb_wallet.created_at IS '创建时间';
COMMENT ON COLUMN tb_wallet.updated_at IS '更新时间';
COMMENT ON COLUMN tb_wallet.deleted_at IS '删除时间(软删除)';
CREATE INDEX idx_wallet_user ON tb_wallet(user_id, deleted_at);
CREATE INDEX idx_wallet_status ON tb_wallet(status, deleted_at);
CREATE UNIQUE INDEX idx_wallet_user_type_currency ON tb_wallet(user_id, wallet_type, currency) WHERE deleted_at IS NULL;
-- 1.2 钱包明细表
CREATE TABLE IF NOT EXISTS tb_wallet_transaction (
id BIGSERIAL PRIMARY KEY,
wallet_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
transaction_type VARCHAR(20) NOT NULL,
amount BIGINT NOT NULL,
balance_before BIGINT NOT NULL,
balance_after BIGINT NOT NULL,
status INT NOT NULL DEFAULT 1,
reference_type VARCHAR(50),
reference_id BIGINT,
remark TEXT,
metadata JSONB,
creator BIGINT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
COMMENT ON TABLE tb_wallet_transaction IS '钱包明细表';
COMMENT ON COLUMN tb_wallet_transaction.id IS '明细ID';
COMMENT ON COLUMN tb_wallet_transaction.wallet_id IS '钱包ID关联tb_wallet.id';
COMMENT ON COLUMN tb_wallet_transaction.user_id IS '用户ID关联tb_account.id';
COMMENT ON COLUMN tb_wallet_transaction.transaction_type IS '交易类型recharge-充值, deduct-扣款, refund-退款, commission-分佣, withdrawal-提现';
COMMENT ON COLUMN tb_wallet_transaction.amount IS '变动金额(分),正数为增加,负数为减少';
COMMENT ON COLUMN tb_wallet_transaction.balance_before IS '变动前余额(分)';
COMMENT ON COLUMN tb_wallet_transaction.balance_after IS '变动后余额(分)';
COMMENT ON COLUMN tb_wallet_transaction.status IS '交易状态1-成功 2-失败 3-处理中';
COMMENT ON COLUMN tb_wallet_transaction.reference_type IS '关联业务类型order, commission, withdrawal, topup';
COMMENT ON COLUMN tb_wallet_transaction.reference_id IS '关联业务ID';
COMMENT ON COLUMN tb_wallet_transaction.remark IS '备注';
COMMENT ON COLUMN tb_wallet_transaction.metadata IS '扩展信息JSON';
COMMENT ON COLUMN tb_wallet_transaction.creator IS '创建人ID';
COMMENT ON COLUMN tb_wallet_transaction.created_at IS '创建时间';
COMMENT ON COLUMN tb_wallet_transaction.updated_at IS '更新时间';
COMMENT ON COLUMN tb_wallet_transaction.deleted_at IS '删除时间(软删除)';
CREATE INDEX idx_wallet_tx_wallet ON tb_wallet_transaction(wallet_id, created_at DESC);
CREATE INDEX idx_wallet_tx_user ON tb_wallet_transaction(user_id, created_at DESC);
CREATE INDEX idx_wallet_tx_ref ON tb_wallet_transaction(reference_type, reference_id);
-- 1.3 充值记录表
CREATE TABLE IF NOT EXISTS tb_recharge_record (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
wallet_id BIGINT NOT NULL,
recharge_no VARCHAR(50) NOT NULL,
amount BIGINT NOT NULL,
payment_method VARCHAR(20) NOT NULL,
payment_channel VARCHAR(50),
payment_transaction_id VARCHAR(100),
status INT NOT NULL DEFAULT 1,
paid_at TIMESTAMP,
completed_at TIMESTAMP,
creator BIGINT,
updater BIGINT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
COMMENT ON TABLE tb_recharge_record IS '充值记录表';
COMMENT ON COLUMN tb_recharge_record.id IS '充值记录ID';
COMMENT ON COLUMN tb_recharge_record.user_id IS '用户ID关联tb_account.id';
COMMENT ON COLUMN tb_recharge_record.wallet_id IS '钱包ID关联tb_wallet.id';
COMMENT ON COLUMN tb_recharge_record.recharge_no IS '充值订单号(唯一)';
COMMENT ON COLUMN tb_recharge_record.amount IS '充值金额(分)';
COMMENT ON COLUMN tb_recharge_record.payment_method IS '支付方式alipay-支付宝, wechat-微信, bank-银行转账, offline-线下';
COMMENT ON COLUMN tb_recharge_record.payment_channel IS '支付渠道';
COMMENT ON COLUMN tb_recharge_record.payment_transaction_id IS '第三方支付交易号';
COMMENT ON COLUMN tb_recharge_record.status IS '充值状态1-待支付 2-已支付 3-已完成 4-已关闭 5-已退款';
COMMENT ON COLUMN tb_recharge_record.paid_at IS '支付时间';
COMMENT ON COLUMN tb_recharge_record.completed_at IS '完成时间';
COMMENT ON COLUMN tb_recharge_record.creator IS '创建人ID';
COMMENT ON COLUMN tb_recharge_record.updater IS '更新人ID';
COMMENT ON COLUMN tb_recharge_record.created_at IS '创建时间';
COMMENT ON COLUMN tb_recharge_record.updated_at IS '更新时间';
COMMENT ON COLUMN tb_recharge_record.deleted_at IS '删除时间(软删除)';
CREATE INDEX idx_recharge_user ON tb_recharge_record(user_id, created_at DESC);
CREATE INDEX idx_recharge_status ON tb_recharge_record(status, created_at DESC);
CREATE UNIQUE INDEX idx_recharge_no ON tb_recharge_record(recharge_no) WHERE deleted_at IS NULL;
-- =====================================================
-- 2. 换卡系统1 张表)
-- =====================================================
CREATE TABLE IF NOT EXISTS tb_card_replacement_record (
id BIGSERIAL PRIMARY KEY,
replacement_no VARCHAR(50) NOT NULL,
old_card_id BIGINT NOT NULL,
old_iccid VARCHAR(50) NOT NULL,
new_card_id BIGINT NOT NULL,
new_iccid VARCHAR(50) NOT NULL,
old_owner_type VARCHAR(20) NOT NULL,
old_owner_id BIGINT NOT NULL,
old_agent_id BIGINT,
new_owner_type VARCHAR(20) NOT NULL,
new_owner_id BIGINT NOT NULL,
new_agent_id BIGINT,
package_snapshot JSONB,
replacement_reason VARCHAR(20) NOT NULL,
remark TEXT,
status INT NOT NULL DEFAULT 1,
approved_by BIGINT,
approved_at TIMESTAMP,
completed_at TIMESTAMP,
creator BIGINT,
updater BIGINT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
COMMENT ON TABLE tb_card_replacement_record IS '换卡记录表';
COMMENT ON COLUMN tb_card_replacement_record.id IS '换卡记录ID';
COMMENT ON COLUMN tb_card_replacement_record.replacement_no IS '换卡单号(唯一)';
COMMENT ON COLUMN tb_card_replacement_record.old_card_id IS '老卡ID关联tb_iot_card.id';
COMMENT ON COLUMN tb_card_replacement_record.old_iccid IS '老卡ICCID冗余存储';
COMMENT ON COLUMN tb_card_replacement_record.new_card_id IS '新卡ID关联tb_iot_card.id';
COMMENT ON COLUMN tb_card_replacement_record.new_iccid IS '新卡ICCID冗余存储';
COMMENT ON COLUMN tb_card_replacement_record.old_owner_type IS '老卡所有者类型';
COMMENT ON COLUMN tb_card_replacement_record.old_owner_id IS '老卡所有者ID';
COMMENT ON COLUMN tb_card_replacement_record.old_agent_id IS '老卡代理ID';
COMMENT ON COLUMN tb_card_replacement_record.new_owner_type IS '新卡所有者类型';
COMMENT ON COLUMN tb_card_replacement_record.new_owner_id IS '新卡所有者ID';
COMMENT ON COLUMN tb_card_replacement_record.new_agent_id IS '新卡代理ID';
COMMENT ON COLUMN tb_card_replacement_record.package_snapshot IS '套餐快照JSON';
COMMENT ON COLUMN tb_card_replacement_record.replacement_reason IS '换卡原因damaged-损坏, lost-丢失, malfunction-故障, upgrade-升级, other-其他';
COMMENT ON COLUMN tb_card_replacement_record.remark IS '备注';
COMMENT ON COLUMN tb_card_replacement_record.status IS '换卡状态1-待审批 2-已通过 3-已拒绝 4-已完成';
COMMENT ON COLUMN tb_card_replacement_record.approved_by IS '审批人ID';
COMMENT ON COLUMN tb_card_replacement_record.approved_at IS '审批时间';
COMMENT ON COLUMN tb_card_replacement_record.completed_at IS '完成时间';
COMMENT ON COLUMN tb_card_replacement_record.creator IS '创建人ID';
COMMENT ON COLUMN tb_card_replacement_record.updater IS '更新人ID';
COMMENT ON COLUMN tb_card_replacement_record.created_at IS '创建时间';
COMMENT ON COLUMN tb_card_replacement_record.updated_at IS '更新时间';
COMMENT ON COLUMN tb_card_replacement_record.deleted_at IS '删除时间(软删除)';
CREATE INDEX idx_card_replacement_old_card ON tb_card_replacement_record(old_card_id, created_at DESC);
CREATE INDEX idx_card_replacement_new_card ON tb_card_replacement_record(new_card_id, created_at DESC);
CREATE INDEX idx_card_replacement_old_owner ON tb_card_replacement_record(old_owner_type, old_owner_id);
CREATE INDEX idx_card_replacement_new_owner ON tb_card_replacement_record(new_owner_type, new_owner_id);
CREATE INDEX idx_card_replacement_status ON tb_card_replacement_record(status, created_at DESC);
CREATE UNIQUE INDEX idx_card_replacement_no ON tb_card_replacement_record(replacement_no) WHERE deleted_at IS NULL;
-- =====================================================
-- 3. 标签系统2 张表)
-- =====================================================
-- 3.1 标签表
CREATE TABLE IF NOT EXISTS tb_tag (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
color VARCHAR(20),
usage_count INT NOT NULL DEFAULT 0,
creator BIGINT,
updater BIGINT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
COMMENT ON TABLE tb_tag IS '标签表';
COMMENT ON COLUMN tb_tag.id IS '标签ID';
COMMENT ON COLUMN tb_tag.name IS '标签名称(唯一)';
COMMENT ON COLUMN tb_tag.color IS '标签颜色(十六进制)';
COMMENT ON COLUMN tb_tag.usage_count IS '使用次数';
COMMENT ON COLUMN tb_tag.creator IS '创建人ID';
COMMENT ON COLUMN tb_tag.updater IS '更新人ID';
COMMENT ON COLUMN tb_tag.created_at IS '创建时间';
COMMENT ON COLUMN tb_tag.updated_at IS '更新时间';
COMMENT ON COLUMN tb_tag.deleted_at IS '删除时间(软删除)';
CREATE INDEX idx_tag_usage ON tb_tag(usage_count DESC, deleted_at);
CREATE UNIQUE INDEX idx_tag_name ON tb_tag(name) WHERE deleted_at IS NULL;
-- 3.2 资源-标签关联表
CREATE TABLE IF NOT EXISTS tb_resource_tag (
id BIGSERIAL PRIMARY KEY,
resource_type VARCHAR(20) NOT NULL,
resource_id BIGINT NOT NULL,
tag_id BIGINT NOT NULL,
creator BIGINT,
updater BIGINT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
COMMENT ON TABLE tb_resource_tag IS '资源-标签关联表';
COMMENT ON COLUMN tb_resource_tag.id IS '关联记录ID';
COMMENT ON COLUMN tb_resource_tag.resource_type IS '资源类型device-设备, iot_card-IoT卡, number_card-号卡';
COMMENT ON COLUMN tb_resource_tag.resource_id IS '资源ID';
COMMENT ON COLUMN tb_resource_tag.tag_id IS '标签ID关联tb_tag.id';
COMMENT ON COLUMN tb_resource_tag.creator IS '创建人ID';
COMMENT ON COLUMN tb_resource_tag.updater IS '更新人ID';
COMMENT ON COLUMN tb_resource_tag.created_at IS '创建时间';
COMMENT ON COLUMN tb_resource_tag.updated_at IS '更新时间';
COMMENT ON COLUMN tb_resource_tag.deleted_at IS '删除时间(软删除)';
CREATE INDEX idx_resource_tag_resource ON tb_resource_tag(resource_type, resource_id, deleted_at);
CREATE INDEX idx_resource_tag_tag ON tb_resource_tag(tag_id, deleted_at);
CREATE INDEX idx_resource_tag_composite ON tb_resource_tag(resource_type, tag_id, deleted_at);
CREATE UNIQUE INDEX idx_resource_tag_unique ON tb_resource_tag(resource_type, resource_id, tag_id) WHERE deleted_at IS NULL;
-- =====================================================
-- 4. 修改运营商表(增加渠道字段)
-- =====================================================
ALTER TABLE tb_carrier ADD COLUMN IF NOT EXISTS carrier_type VARCHAR(20) NOT NULL DEFAULT 'CMCC';
ALTER TABLE tb_carrier ADD COLUMN IF NOT EXISTS channel_name VARCHAR(100);
ALTER TABLE tb_carrier ADD COLUMN IF NOT EXISTS channel_code VARCHAR(50);
COMMENT ON COLUMN tb_carrier.carrier_type IS '运营商类型CMCC-中国移动, CUCC-中国联通, CTCC-中国电信, CBN-广电';
COMMENT ON COLUMN tb_carrier.channel_name IS '渠道名称(可自定义)';
COMMENT ON COLUMN tb_carrier.channel_code IS '渠道编码(可自定义)';
-- 创建新的唯一索引
CREATE UNIQUE INDEX idx_carrier_type_channel ON tb_carrier(carrier_type, channel_code) WHERE deleted_at IS NULL;
-- 初始化现有数据的 carrier_type根据 carrier_code 推断)
UPDATE tb_carrier SET carrier_type = 'CMCC' WHERE carrier_code LIKE '%CMCC%' OR carrier_code LIKE '%移动%';
UPDATE tb_carrier SET carrier_type = 'CUCC' WHERE carrier_code LIKE '%CUCC%' OR carrier_code LIKE '%联通%';
UPDATE tb_carrier SET carrier_type = 'CTCC' WHERE carrier_code LIKE '%CTCC%' OR carrier_code LIKE '%电信%';
UPDATE tb_carrier SET carrier_type = 'CBN' WHERE carrier_code LIKE '%CBN%' OR carrier_code LIKE '%广电%';
-- =====================================================
-- 5. 修改订单表(增加钱包支付字段)
-- =====================================================
ALTER TABLE tb_order ADD COLUMN IF NOT EXISTS wallet_payment_amount BIGINT NOT NULL DEFAULT 0;
ALTER TABLE tb_order ADD COLUMN IF NOT EXISTS online_payment_amount BIGINT NOT NULL DEFAULT 0;
COMMENT ON COLUMN tb_order.wallet_payment_amount IS '钱包支付金额(分)';
COMMENT ON COLUMN tb_order.online_payment_amount IS '在线支付金额(分)';
-- 初始化现有订单的支付金额字段
UPDATE tb_order SET wallet_payment_amount = amount WHERE payment_method = 'wallet';
UPDATE tb_order SET online_payment_amount = amount WHERE payment_method = 'online' OR payment_method = 'carrier';

View File

@@ -0,0 +1,83 @@
-- ========================================
-- 钱包和标签系统多租户改造 - 回滚脚本
-- 变更 ID: fix-wallet-tag-multi-tenant
-- ========================================
-- ========================================
-- 第 1 步:恢复钱包表
-- ========================================
DROP TABLE IF EXISTS tb_wallet CASCADE;
CREATE TABLE tb_wallet AS SELECT * FROM tb_wallet_backup;
-- ========================================
-- 第 2 步:恢复标签表
-- ========================================
ALTER TABLE tb_tag DROP COLUMN IF EXISTS enterprise_id CASCADE;
ALTER TABLE tb_tag DROP COLUMN IF EXISTS shop_id CASCADE;
DROP INDEX IF EXISTS idx_tag_enterprise;
DROP INDEX IF EXISTS idx_tag_shop;
DROP INDEX IF EXISTS idx_tag_enterprise_name;
DROP INDEX IF EXISTS idx_tag_shop_name;
DROP INDEX IF EXISTS idx_tag_global_name;
CREATE UNIQUE INDEX idx_tag_name ON tb_tag (name) WHERE deleted_at IS NULL;
-- ========================================
-- 第 3 步:恢复资源标签表
-- ========================================
ALTER TABLE tb_resource_tag DROP COLUMN IF EXISTS enterprise_id CASCADE;
ALTER TABLE tb_resource_tag DROP COLUMN IF EXISTS shop_id CASCADE;
DROP INDEX IF EXISTS idx_resource_tag_enterprise;
DROP INDEX IF EXISTS idx_resource_tag_shop;
-- ========================================
-- 第 4 步:验证回滚结果
-- ========================================
DO $$
DECLARE
wallet_count INTEGER;
tag_has_enterprise BOOLEAN;
tag_has_shop BOOLEAN;
BEGIN
SELECT COUNT(*) INTO wallet_count FROM tb_wallet;
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'tb_tag' AND column_name = 'enterprise_id'
) INTO tag_has_enterprise;
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'tb_tag' AND column_name = 'shop_id'
) INTO tag_has_shop;
RAISE NOTICE '========================================';
RAISE NOTICE '回滚验证:';
RAISE NOTICE ' 钱包记录数: %', wallet_count;
RAISE NOTICE ' 标签表 enterprise_id 字段存在: %', tag_has_enterprise;
RAISE NOTICE ' 标签表 shop_id 字段存在: %', tag_has_shop;
RAISE NOTICE '========================================';
IF tag_has_enterprise OR tag_has_shop THEN
RAISE WARNING '标签表字段未完全删除,请检查';
END IF;
END $$;
-- ========================================
-- 第 5 步:清理备份表(可选,建议手动执行)
-- ========================================
-- DROP TABLE IF EXISTS tb_wallet_backup;
-- DROP TABLE IF EXISTS tb_tag_backup;
-- DROP TABLE IF EXISTS tb_resource_tag_backup;
-- ========================================
-- 回滚完成
-- ========================================

View File

@@ -0,0 +1,220 @@
-- ========================================
-- 钱包和标签系统多租户改造 - 数据迁移脚本
-- 变更 ID: fix-wallet-tag-multi-tenant
-- ========================================
-- ========================================
-- 第 1 步:备份数据
-- ========================================
-- 删除旧备份表(如果存在)
DROP TABLE IF EXISTS tb_wallet_backup;
DROP TABLE IF EXISTS tb_tag_backup;
DROP TABLE IF EXISTS tb_resource_tag_backup;
-- 备份钱包表
CREATE TABLE tb_wallet_backup AS SELECT * FROM tb_wallet;
-- 备份标签表
CREATE TABLE tb_tag_backup AS SELECT * FROM tb_tag;
-- 备份资源标签表
CREATE TABLE tb_resource_tag_backup AS SELECT * FROM tb_resource_tag;
-- ========================================
-- 第 2 步:钱包表结构变更
-- ========================================
-- 添加新字段(先添加,允许 NULL
ALTER TABLE tb_wallet
ADD COLUMN resource_type VARCHAR(20),
ADD COLUMN resource_id BIGINT;
-- 迁移代理钱包数据
-- 代理钱包从 user_id 迁移到 shop_id
UPDATE tb_wallet w
SET
resource_type = 'shop',
resource_id = a.shop_id
FROM tb_account a
WHERE
w.user_id = a.id
AND w.wallet_type = 'agent'
AND a.shop_id IS NOT NULL;
-- 标记无法迁移的代理钱包shop_id 为 NULL
UPDATE tb_wallet
SET resource_type = 'INVALID_AGENT'
WHERE wallet_type = 'agent' AND resource_type IS NULL;
-- 标记用户钱包为待处理(需要业务人员确认)
UPDATE tb_wallet
SET
resource_type = 'PENDING_USER',
resource_id = 0
WHERE wallet_type = 'user' AND resource_type IS NULL;
-- 检查是否有无法迁移的数据
DO $$
DECLARE
invalid_count INTEGER;
pending_count INTEGER;
BEGIN
SELECT COUNT(*) INTO invalid_count FROM tb_wallet WHERE resource_type = 'INVALID_AGENT';
SELECT COUNT(*) INTO pending_count FROM tb_wallet WHERE resource_type = 'PENDING_USER';
IF invalid_count > 0 THEN
RAISE EXCEPTION '存在 % 个无法迁移的代理钱包shop_id 为 NULL请手动处理', invalid_count;
END IF;
IF pending_count > 0 THEN
RAISE NOTICE '存在 % 个待确认的用户钱包,需要业务人员确认归属', pending_count;
END IF;
END $$;
-- 设置字段为 NOT NULL
ALTER TABLE tb_wallet
ALTER COLUMN resource_type SET NOT NULL,
ALTER COLUMN resource_id SET NOT NULL;
-- 删除旧字段和约束
DROP INDEX IF EXISTS idx_wallet_user_type_currency;
DROP INDEX IF EXISTS idx_wallet_user;
ALTER TABLE tb_wallet DROP COLUMN user_id;
-- 创建新索引和约束
CREATE UNIQUE INDEX idx_wallet_resource_type_currency
ON tb_wallet (resource_type, resource_id, wallet_type, currency)
WHERE deleted_at IS NULL;
CREATE INDEX idx_wallet_resource ON tb_wallet (resource_type, resource_id, deleted_at);
-- 保留状态索引(如果不存在)
CREATE INDEX IF NOT EXISTS idx_wallet_status ON tb_wallet (status, deleted_at);
-- ========================================
-- 第 3 步:标签表结构变更
-- ========================================
-- 添加新字段
ALTER TABLE tb_tag
ADD COLUMN enterprise_id BIGINT,
ADD COLUMN shop_id BIGINT;
-- 迁移企业标签数据(从 creator 推断)
UPDATE tb_tag t
SET enterprise_id = (
SELECT a.enterprise_id
FROM tb_account a
WHERE a.id = t.creator AND a.enterprise_id IS NOT NULL
LIMIT 1
);
-- 迁移店铺标签数据(从 creator 推断)
UPDATE tb_tag t
SET shop_id = (
SELECT a.shop_id
FROM tb_account a
WHERE a.id = t.creator AND a.shop_id IS NOT NULL
LIMIT 1
)
WHERE enterprise_id IS NULL;
-- 其他标签默认为全局标签enterprise_id 和 shop_id 都为 NULL
-- 删除旧约束
DROP INDEX IF EXISTS idx_tag_name;
-- 创建新索引
CREATE INDEX idx_tag_enterprise ON tb_tag (enterprise_id, deleted_at);
CREATE INDEX idx_tag_shop ON tb_tag (shop_id, deleted_at);
-- 创建新唯一约束
CREATE UNIQUE INDEX idx_tag_enterprise_name
ON tb_tag (enterprise_id, name)
WHERE deleted_at IS NULL AND enterprise_id IS NOT NULL;
CREATE UNIQUE INDEX idx_tag_shop_name
ON tb_tag (shop_id, name)
WHERE deleted_at IS NULL AND shop_id IS NOT NULL;
CREATE UNIQUE INDEX idx_tag_global_name
ON tb_tag (name)
WHERE deleted_at IS NULL AND enterprise_id IS NULL AND shop_id IS NULL;
-- ========================================
-- 第 4 步:资源标签表结构变更
-- ========================================
-- 添加新字段
ALTER TABLE tb_resource_tag
ADD COLUMN enterprise_id BIGINT,
ADD COLUMN shop_id BIGINT;
-- 从 creator 推断归属(企业)
UPDATE tb_resource_tag rt
SET enterprise_id = (
SELECT a.enterprise_id
FROM tb_account a
WHERE a.id = rt.creator AND a.enterprise_id IS NOT NULL
LIMIT 1
);
-- 从 creator 推断归属(店铺)
UPDATE tb_resource_tag rt
SET shop_id = (
SELECT a.shop_id
FROM tb_account a
WHERE a.id = rt.creator AND a.shop_id IS NOT NULL
LIMIT 1
)
WHERE enterprise_id IS NULL;
-- 创建索引
CREATE INDEX idx_resource_tag_enterprise ON tb_resource_tag (enterprise_id, deleted_at);
CREATE INDEX idx_resource_tag_shop ON tb_resource_tag (shop_id, deleted_at);
-- ========================================
-- 第 5 步:验证数据一致性
-- ========================================
-- 输出迁移统计信息
DO $$
DECLARE
wallet_total INTEGER;
wallet_shop INTEGER;
wallet_pending INTEGER;
tag_total INTEGER;
tag_enterprise INTEGER;
tag_shop INTEGER;
tag_global INTEGER;
BEGIN
-- 钱包统计
SELECT COUNT(*) INTO wallet_total FROM tb_wallet;
SELECT COUNT(*) INTO wallet_shop FROM tb_wallet WHERE resource_type = 'shop';
SELECT COUNT(*) INTO wallet_pending FROM tb_wallet WHERE resource_type = 'PENDING_USER';
RAISE NOTICE '========================================';
RAISE NOTICE '钱包迁移统计:';
RAISE NOTICE ' 总数: %', wallet_total;
RAISE NOTICE ' 店铺钱包: %', wallet_shop;
RAISE NOTICE ' 待确认用户钱包: %', wallet_pending;
-- 标签统计
SELECT COUNT(*) INTO tag_total FROM tb_tag;
SELECT COUNT(*) INTO tag_enterprise FROM tb_tag WHERE enterprise_id IS NOT NULL;
SELECT COUNT(*) INTO tag_shop FROM tb_tag WHERE shop_id IS NOT NULL;
SELECT COUNT(*) INTO tag_global FROM tb_tag WHERE enterprise_id IS NULL AND shop_id IS NULL;
RAISE NOTICE '========================================';
RAISE NOTICE '标签迁移统计:';
RAISE NOTICE ' 总数: %', tag_total;
RAISE NOTICE ' 企业标签: %', tag_enterprise;
RAISE NOTICE ' 店铺标签: %', tag_shop;
RAISE NOTICE ' 全局标签: %', tag_global;
RAISE NOTICE '========================================';
END $$;
-- ========================================
-- 迁移完成
-- ========================================

View File

@@ -0,0 +1,3 @@
-- 删除权限可用角色类型字段
ALTER TABLE tb_permission
DROP COLUMN IF EXISTS available_for_role_types;

View File

@@ -0,0 +1,8 @@
-- 添加权限可用角色类型字段
ALTER TABLE tb_permission
ADD COLUMN available_for_role_types VARCHAR(20) DEFAULT '1,2' NOT NULL;
COMMENT ON COLUMN tb_permission.available_for_role_types IS '可用角色类型 1=平台 2=客户';
-- 为现有权限设置默认值(兼容所有角色类型)
UPDATE tb_permission SET available_for_role_types = '1,2' WHERE available_for_role_types IS NULL;

View File

@@ -0,0 +1,42 @@
-- 回滚: 账号与佣金管理模块数据模型变更
-- 变更ID: add-commission-model-changes
-- 1. 恢复 owner_type 枚举值 (shop -> agent)
UPDATE tb_iot_card SET owner_type = 'agent' WHERE owner_type = 'shop';
UPDATE tb_device SET owner_type = 'agent' WHERE owner_type = 'shop';
-- 2. 删除新增的表
DROP TABLE IF EXISTS tb_asset_allocation_record;
DROP TABLE IF EXISTS tb_enterprise_card_authorization;
-- 3. 删除 tb_device.shop_id 字段
DROP INDEX IF EXISTS idx_device_shop_id;
ALTER TABLE tb_device DROP COLUMN IF EXISTS shop_id;
-- 4. 删除 tb_iot_card.shop_id 字段
DROP INDEX IF EXISTS idx_iot_card_shop_id;
ALTER TABLE tb_iot_card DROP COLUMN IF EXISTS shop_id;
-- 5. 删除 tb_commission_withdrawal_setting.daily_withdrawal_limit 字段
ALTER TABLE tb_commission_withdrawal_setting DROP COLUMN IF EXISTS daily_withdrawal_limit;
-- 6. 删除 tb_commission_record 新增字段
DROP INDEX IF EXISTS idx_commission_record_shop_id;
ALTER TABLE tb_commission_record
DROP COLUMN IF EXISTS shop_id,
DROP COLUMN IF EXISTS balance_after;
-- 7. 删除 tb_account.is_primary 字段
ALTER TABLE tb_account DROP COLUMN IF EXISTS is_primary;
-- 8. 删除 tb_commission_withdrawal_request 新增字段
DROP INDEX IF EXISTS uk_commission_withdrawal_no;
ALTER TABLE tb_commission_withdrawal_request
DROP COLUMN IF EXISTS withdrawal_no,
DROP COLUMN IF EXISTS applicant_id,
DROP COLUMN IF EXISTS shop_id,
DROP COLUMN IF EXISTS fee_rate,
DROP COLUMN IF EXISTS payment_type,
DROP COLUMN IF EXISTS processor_id,
DROP COLUMN IF EXISTS processed_at,
DROP COLUMN IF EXISTS remark;

View File

@@ -0,0 +1,185 @@
-- 迁移: 账号与佣金管理模块数据模型变更
-- 变更ID: add-commission-model-changes
-- 说明:
-- 1. 扩展现有表字段
-- 2. 创建企业卡授权表和资产分配记录表
-- 3. 统一 owner_type 枚举值 (agent -> shop)
-- ========================================
-- 1. 扩展现有表字段
-- ========================================
-- 1.1 tb_commission_withdrawal_request 佣金提现申请表新增字段
ALTER TABLE tb_commission_withdrawal_request
ADD COLUMN IF NOT EXISTS withdrawal_no VARCHAR(50),
ADD COLUMN IF NOT EXISTS applicant_id BIGINT,
ADD COLUMN IF NOT EXISTS shop_id BIGINT,
ADD COLUMN IF NOT EXISTS fee_rate BIGINT DEFAULT 0,
ADD COLUMN IF NOT EXISTS payment_type VARCHAR(20) DEFAULT 'manual',
ADD COLUMN IF NOT EXISTS processor_id BIGINT,
ADD COLUMN IF NOT EXISTS processed_at TIMESTAMP WITH TIME ZONE,
ADD COLUMN IF NOT EXISTS remark TEXT;
-- 添加唯一索引(提现单号)
CREATE UNIQUE INDEX IF NOT EXISTS uk_commission_withdrawal_no
ON tb_commission_withdrawal_request(withdrawal_no) WHERE deleted_at IS NULL AND withdrawal_no IS NOT NULL;
-- 添加字段注释
COMMENT ON COLUMN tb_commission_withdrawal_request.withdrawal_no IS '提现单号唯一格式W + 时间戳 + 随机数)';
COMMENT ON COLUMN tb_commission_withdrawal_request.applicant_id IS '申请人账号ID';
COMMENT ON COLUMN tb_commission_withdrawal_request.shop_id IS '店铺ID冗余字段';
COMMENT ON COLUMN tb_commission_withdrawal_request.fee_rate IS '手续费比率基点100=1%,快照)';
COMMENT ON COLUMN tb_commission_withdrawal_request.payment_type IS '放款类型manual=人工打款)';
COMMENT ON COLUMN tb_commission_withdrawal_request.processor_id IS '处理人ID';
COMMENT ON COLUMN tb_commission_withdrawal_request.processed_at IS '处理时间';
COMMENT ON COLUMN tb_commission_withdrawal_request.remark IS '备注';
-- 1.2 tb_account 账号表新增字段
ALTER TABLE tb_account
ADD COLUMN IF NOT EXISTS is_primary BOOLEAN DEFAULT FALSE;
COMMENT ON COLUMN tb_account.is_primary IS '是否为店铺主账号(默认 false';
-- 1.3 tb_commission_record 佣金记录表新增字段
ALTER TABLE tb_commission_record
ADD COLUMN IF NOT EXISTS shop_id BIGINT,
ADD COLUMN IF NOT EXISTS balance_after BIGINT DEFAULT 0;
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_commission_record_shop_id ON tb_commission_record(shop_id);
COMMENT ON COLUMN tb_commission_record.shop_id IS '店铺ID佣金主要跟着店铺走';
COMMENT ON COLUMN tb_commission_record.balance_after IS '入账后佣金余额(分)';
-- 1.4 tb_commission_withdrawal_setting 提现设置表新增字段
ALTER TABLE tb_commission_withdrawal_setting
ADD COLUMN IF NOT EXISTS daily_withdrawal_limit INT DEFAULT 3;
COMMENT ON COLUMN tb_commission_withdrawal_setting.daily_withdrawal_limit IS '每日提现次数限制';
-- 1.5 tb_iot_card 物联网卡表新增字段
ALTER TABLE tb_iot_card
ADD COLUMN IF NOT EXISTS shop_id BIGINT;
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_iot_card_shop_id ON tb_iot_card(shop_id);
COMMENT ON COLUMN tb_iot_card.shop_id IS '店铺ID冗余字段方便查询';
-- 1.6 tb_device 设备表新增字段
ALTER TABLE tb_device
ADD COLUMN IF NOT EXISTS shop_id BIGINT;
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_device_shop_id ON tb_device(shop_id);
COMMENT ON COLUMN tb_device.shop_id IS '店铺ID冗余字段方便查询';
-- ========================================
-- 2. 创建新表
-- ========================================
-- 2.1 tb_enterprise_card_authorization 企业卡授权表
CREATE TABLE IF NOT EXISTS tb_enterprise_card_authorization (
id BIGSERIAL PRIMARY KEY,
enterprise_id BIGINT NOT NULL,
iot_card_id BIGINT NOT NULL,
shop_id BIGINT NOT NULL,
authorized_by BIGINT NOT NULL,
authorized_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
status INT DEFAULT 1,
creator BIGINT NOT NULL,
updater BIGINT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
deleted_at TIMESTAMP WITH TIME ZONE
);
-- 添加唯一约束(企业+卡唯一)
CREATE UNIQUE INDEX IF NOT EXISTS uk_enterprise_card
ON tb_enterprise_card_authorization(enterprise_id, iot_card_id) WHERE deleted_at IS NULL;
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_enterprise_card_auth_enterprise_id ON tb_enterprise_card_authorization(enterprise_id);
CREATE INDEX IF NOT EXISTS idx_enterprise_card_auth_iot_card_id ON tb_enterprise_card_authorization(iot_card_id);
CREATE INDEX IF NOT EXISTS idx_enterprise_card_auth_shop_id ON tb_enterprise_card_authorization(shop_id);
CREATE INDEX IF NOT EXISTS idx_enterprise_card_auth_status ON tb_enterprise_card_authorization(status);
-- 添加表注释
COMMENT ON TABLE tb_enterprise_card_authorization IS '企业卡授权表,记录企业被授权可见的卡';
COMMENT ON COLUMN tb_enterprise_card_authorization.enterprise_id IS '企业ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.iot_card_id IS 'IoT卡ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.shop_id IS '店铺ID授权方';
COMMENT ON COLUMN tb_enterprise_card_authorization.authorized_by IS '授权人ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.authorized_at IS '授权时间';
COMMENT ON COLUMN tb_enterprise_card_authorization.status IS '状态 1=有效 0=已回收';
COMMENT ON COLUMN tb_enterprise_card_authorization.creator IS '创建人ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.updater IS '更新人ID';
-- 2.2 tb_asset_allocation_record 资产分配记录表
CREATE TABLE IF NOT EXISTS tb_asset_allocation_record (
id BIGSERIAL PRIMARY KEY,
allocation_no VARCHAR(50) NOT NULL,
allocation_type VARCHAR(20) NOT NULL,
asset_type VARCHAR(20) NOT NULL,
asset_id BIGINT NOT NULL,
asset_identifier VARCHAR(50) NOT NULL,
from_owner_type VARCHAR(20),
from_owner_id BIGINT,
to_owner_type VARCHAR(20) NOT NULL,
to_owner_id BIGINT NOT NULL,
related_device_id BIGINT,
related_card_ids JSONB,
operator_id BIGINT NOT NULL,
remark TEXT,
creator BIGINT NOT NULL,
updater BIGINT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
deleted_at TIMESTAMP WITH TIME ZONE
);
-- 添加唯一约束(分配单号唯一)
CREATE UNIQUE INDEX IF NOT EXISTS uk_asset_allocation_no
ON tb_asset_allocation_record(allocation_no) WHERE deleted_at IS NULL;
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_asset_allocation_type ON tb_asset_allocation_record(allocation_type);
CREATE INDEX IF NOT EXISTS idx_asset_allocation_asset_type ON tb_asset_allocation_record(asset_type);
CREATE INDEX IF NOT EXISTS idx_asset_allocation_asset_id ON tb_asset_allocation_record(asset_id);
CREATE INDEX IF NOT EXISTS idx_asset_allocation_from_owner ON tb_asset_allocation_record(from_owner_type, from_owner_id);
CREATE INDEX IF NOT EXISTS idx_asset_allocation_to_owner ON tb_asset_allocation_record(to_owner_type, to_owner_id);
-- 添加表注释
COMMENT ON TABLE tb_asset_allocation_record IS '资产分配记录表,记录卡/设备在平台和代理商之间的流转历史';
COMMENT ON COLUMN tb_asset_allocation_record.allocation_no IS '分配单号(唯一)';
COMMENT ON COLUMN tb_asset_allocation_record.allocation_type IS '分配类型 allocate=分配 recall=回收';
COMMENT ON COLUMN tb_asset_allocation_record.asset_type IS '资产类型 iot_card=物联网卡 device=设备';
COMMENT ON COLUMN tb_asset_allocation_record.asset_id IS '资产ID';
COMMENT ON COLUMN tb_asset_allocation_record.asset_identifier IS '资产标识符ICCID或设备号';
COMMENT ON COLUMN tb_asset_allocation_record.from_owner_type IS '来源所有者类型';
COMMENT ON COLUMN tb_asset_allocation_record.from_owner_id IS '来源所有者ID';
COMMENT ON COLUMN tb_asset_allocation_record.to_owner_type IS '目标所有者类型';
COMMENT ON COLUMN tb_asset_allocation_record.to_owner_id IS '目标所有者ID';
COMMENT ON COLUMN tb_asset_allocation_record.related_device_id IS '关联设备ID';
COMMENT ON COLUMN tb_asset_allocation_record.related_card_ids IS '关联卡ID列表';
COMMENT ON COLUMN tb_asset_allocation_record.operator_id IS '操作人ID';
COMMENT ON COLUMN tb_asset_allocation_record.remark IS '备注';
COMMENT ON COLUMN tb_asset_allocation_record.creator IS '创建人ID';
COMMENT ON COLUMN tb_asset_allocation_record.updater IS '更新人ID';
-- ========================================
-- 3. 数据迁移 - owner_type 枚举统一
-- ========================================
-- 3.1 更新 tb_iot_card 表 owner_type='agent' 为 'shop'
UPDATE tb_iot_card SET owner_type = 'shop' WHERE owner_type = 'agent';
-- 3.2 更新 tb_device 表 owner_type='agent' 为 'shop'
UPDATE tb_device SET owner_type = 'shop' WHERE owner_type = 'agent';
-- 3.3 填充 tb_iot_card.shop_id 字段owner_type='shop' 时等于 owner_id
UPDATE tb_iot_card SET shop_id = owner_id WHERE owner_type = 'shop' AND shop_id IS NULL;
-- 3.4 填充 tb_device.shop_id 字段owner_type='shop' 时等于 owner_id
UPDATE tb_device SET shop_id = owner_id WHERE owner_type = 'shop' AND shop_id IS NULL;

View File

@@ -0,0 +1,23 @@
-- 回滚:恢复 tb_iot_card 和 tb_device 表中的 owner_type 和 owner_id 字段
-- 恢复 tb_iot_card.iccid 字段长度
ALTER TABLE tb_iot_card ALTER COLUMN iccid TYPE varchar(50);
COMMENT ON COLUMN tb_iot_card.iccid IS 'ICCID(唯一标识)';
-- 恢复 tb_iot_card 的 owner_type 和 owner_id 列
ALTER TABLE tb_iot_card ADD COLUMN IF NOT EXISTS owner_type varchar(20) NOT NULL DEFAULT 'platform';
ALTER TABLE tb_iot_card ADD COLUMN IF NOT EXISTS owner_id bigint NOT NULL DEFAULT 0;
COMMENT ON COLUMN tb_iot_card.owner_type IS '所有者类型 platform-平台 shop-店铺';
COMMENT ON COLUMN tb_iot_card.owner_id IS '所有者ID';
CREATE INDEX IF NOT EXISTS idx_iot_card_owner_id ON tb_iot_card(owner_id);
-- 恢复 tb_device 的 owner_type 和 owner_id 列
ALTER TABLE tb_device ADD COLUMN IF NOT EXISTS owner_type varchar(20) NOT NULL DEFAULT 'platform';
ALTER TABLE tb_device ADD COLUMN IF NOT EXISTS owner_id bigint NOT NULL DEFAULT 0;
COMMENT ON COLUMN tb_device.owner_type IS '所有者类型 platform-平台 shop-店铺';
COMMENT ON COLUMN tb_device.owner_id IS '所有者ID';
CREATE INDEX IF NOT EXISTS idx_device_owner_id ON tb_device(owner_id);
-- 恢复 shop_id 字段的注释
COMMENT ON COLUMN tb_iot_card.shop_id IS '店铺ID冗余字段方便查询';
COMMENT ON COLUMN tb_device.shop_id IS '店铺ID冗余字段方便查询';

View File

@@ -0,0 +1,20 @@
-- 移除 tb_iot_card 和 tb_device 表中的 owner_type 和 owner_id 字段
-- 原因:所有权模型重构,改用 shop_id 字段表示所有权NULL=平台所有,有值=店铺所有)
-- 删除 tb_iot_card 的 owner_type 和 owner_id 列
ALTER TABLE tb_iot_card DROP COLUMN IF EXISTS owner_type;
ALTER TABLE tb_iot_card DROP COLUMN IF EXISTS owner_id;
-- 删除 tb_device 的 owner_type 和 owner_id 列
ALTER TABLE tb_device DROP COLUMN IF EXISTS owner_type;
ALTER TABLE tb_device DROP COLUMN IF EXISTS owner_id;
-- 更新 tb_iot_card 的 shop_id 字段注释
COMMENT ON COLUMN tb_iot_card.shop_id IS '店铺ID(NULL=平台所有,有值=店铺所有)';
-- 更新 tb_device 的 shop_id 字段注释
COMMENT ON COLUMN tb_device.shop_id IS '店铺ID(NULL=平台库存,有值=店铺所有)';
-- 修改 tb_iot_card.iccid 字段长度从 varchar(50) 改为 varchar(20)
ALTER TABLE tb_iot_card ALTER COLUMN iccid TYPE varchar(20);
COMMENT ON COLUMN tb_iot_card.iccid IS 'ICCID(唯一标识,电信19位/其他20位,支持字母数字混合)';

View File

@@ -0,0 +1 @@
DROP TABLE IF EXISTS tb_iot_card_import_task;

View File

@@ -0,0 +1,48 @@
CREATE TABLE IF NOT EXISTS tb_iot_card_import_task (
id BIGSERIAL PRIMARY KEY,
task_no VARCHAR(50) NOT NULL,
status INT NOT NULL DEFAULT 1,
carrier_id BIGINT NOT NULL,
batch_no VARCHAR(100),
file_name VARCHAR(255),
total_count INT NOT NULL DEFAULT 0,
success_count INT NOT NULL DEFAULT 0,
skip_count INT NOT NULL DEFAULT 0,
fail_count INT NOT NULL DEFAULT 0,
skipped_items JSONB DEFAULT '[]',
failed_items JSONB DEFAULT '[]',
started_at TIMESTAMP,
completed_at TIMESTAMP,
error_message TEXT,
shop_id BIGINT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
deleted_at TIMESTAMP,
creator BIGINT NOT NULL DEFAULT 0,
updater BIGINT NOT NULL DEFAULT 0
);
CREATE UNIQUE INDEX idx_import_task_no ON tb_iot_card_import_task(task_no) WHERE deleted_at IS NULL;
CREATE INDEX idx_import_task_carrier_id ON tb_iot_card_import_task(carrier_id);
CREATE INDEX idx_import_task_shop_id ON tb_iot_card_import_task(shop_id);
CREATE INDEX idx_import_task_status ON tb_iot_card_import_task(status);
CREATE INDEX idx_import_task_created_at ON tb_iot_card_import_task(created_at);
COMMENT ON TABLE tb_iot_card_import_task IS 'IoT 卡导入任务表';
COMMENT ON COLUMN tb_iot_card_import_task.task_no IS '任务编号(IMP-YYYYMMDD-XXXXXX)';
COMMENT ON COLUMN tb_iot_card_import_task.status IS '任务状态 1-待处理 2-处理中 3-已完成 4-失败';
COMMENT ON COLUMN tb_iot_card_import_task.carrier_id IS '运营商ID';
COMMENT ON COLUMN tb_iot_card_import_task.batch_no IS '批次号';
COMMENT ON COLUMN tb_iot_card_import_task.file_name IS '原始文件名';
COMMENT ON COLUMN tb_iot_card_import_task.total_count IS '总数';
COMMENT ON COLUMN tb_iot_card_import_task.success_count IS '成功数';
COMMENT ON COLUMN tb_iot_card_import_task.skip_count IS '跳过数';
COMMENT ON COLUMN tb_iot_card_import_task.fail_count IS '失败数';
COMMENT ON COLUMN tb_iot_card_import_task.skipped_items IS '跳过记录详情';
COMMENT ON COLUMN tb_iot_card_import_task.failed_items IS '失败记录详情';
COMMENT ON COLUMN tb_iot_card_import_task.started_at IS '开始处理时间';
COMMENT ON COLUMN tb_iot_card_import_task.completed_at IS '完成时间';
COMMENT ON COLUMN tb_iot_card_import_task.error_message IS '任务级错误信息';
COMMENT ON COLUMN tb_iot_card_import_task.shop_id IS '店铺ID(发起导入的店铺)';
COMMENT ON COLUMN tb_iot_card_import_task.creator IS '创建人ID';
COMMENT ON COLUMN tb_iot_card_import_task.updater IS '更新人ID';

View File

@@ -0,0 +1,2 @@
ALTER TABLE tb_iot_card_import_task DROP COLUMN IF EXISTS carrier_type;
ALTER TABLE tb_iot_card_import_task DROP COLUMN IF EXISTS iccid_list;

View File

@@ -0,0 +1,5 @@
ALTER TABLE tb_iot_card_import_task ADD COLUMN IF NOT EXISTS carrier_type VARCHAR(20) NOT NULL DEFAULT 'CMCC';
ALTER TABLE tb_iot_card_import_task ADD COLUMN IF NOT EXISTS iccid_list JSONB DEFAULT '[]';
COMMENT ON COLUMN tb_iot_card_import_task.carrier_type IS '运营商类型(CMCC/CUCC/CTCC/CBN)';
COMMENT ON COLUMN tb_iot_card_import_task.iccid_list IS '待导入ICCID列表';

View File

@@ -0,0 +1 @@
DROP TABLE IF EXISTS tb_asset_allocation_record;

View File

@@ -0,0 +1,47 @@
-- 创建资产分配记录表
-- 记录卡/设备在平台和代理商之间的流转历史
CREATE TABLE IF NOT EXISTS tb_asset_allocation_record (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMPTZ,
creator BIGINT,
updater BIGINT,
allocation_no VARCHAR(50) NOT NULL,
allocation_type VARCHAR(20) NOT NULL,
asset_type VARCHAR(20) NOT NULL,
asset_id BIGINT NOT NULL,
asset_identifier VARCHAR(50) NOT NULL,
from_owner_type VARCHAR(20),
from_owner_id BIGINT,
to_owner_type VARCHAR(20) NOT NULL,
to_owner_id BIGINT NOT NULL,
related_device_id BIGINT,
related_card_ids JSONB,
operator_id BIGINT NOT NULL,
remark TEXT
);
-- 创建索引(非唯一,同批次多条记录共用相同单号)
CREATE INDEX IF NOT EXISTS idx_asset_allocation_record_allocation_no ON tb_asset_allocation_record(allocation_no);
CREATE INDEX IF NOT EXISTS idx_asset_allocation_record_allocation_type ON tb_asset_allocation_record(allocation_type);
CREATE INDEX IF NOT EXISTS idx_asset_allocation_record_asset_type ON tb_asset_allocation_record(asset_type);
CREATE INDEX IF NOT EXISTS idx_asset_allocation_record_asset_id ON tb_asset_allocation_record(asset_id);
CREATE INDEX IF NOT EXISTS idx_asset_allocation_record_deleted_at ON tb_asset_allocation_record(deleted_at);
-- 添加表注释
COMMENT ON TABLE tb_asset_allocation_record IS '资产分配记录表';
COMMENT ON COLUMN tb_asset_allocation_record.allocation_no IS '分配单号(同批次相同)';
COMMENT ON COLUMN tb_asset_allocation_record.allocation_type IS '分配类型 allocate=分配 recall=回收';
COMMENT ON COLUMN tb_asset_allocation_record.asset_type IS '资产类型 iot_card=物联网卡 device=设备';
COMMENT ON COLUMN tb_asset_allocation_record.asset_id IS '资产ID';
COMMENT ON COLUMN tb_asset_allocation_record.asset_identifier IS '资产标识符ICCID或设备号';
COMMENT ON COLUMN tb_asset_allocation_record.from_owner_type IS '来源所有者类型 platform=平台 shop=店铺';
COMMENT ON COLUMN tb_asset_allocation_record.from_owner_id IS '来源所有者ID';
COMMENT ON COLUMN tb_asset_allocation_record.to_owner_type IS '目标所有者类型 platform=平台 shop=店铺';
COMMENT ON COLUMN tb_asset_allocation_record.to_owner_id IS '目标所有者ID';
COMMENT ON COLUMN tb_asset_allocation_record.related_device_id IS '关联设备ID设备分配时使用';
COMMENT ON COLUMN tb_asset_allocation_record.related_card_ids IS '关联卡ID列表设备分配时使用';
COMMENT ON COLUMN tb_asset_allocation_record.operator_id IS '操作人ID';
COMMENT ON COLUMN tb_asset_allocation_record.remark IS '备注';

View File

@@ -0,0 +1,2 @@
ALTER TABLE tb_iot_card_import_task
DROP COLUMN IF EXISTS card_list;

View File

@@ -0,0 +1,5 @@
-- 添加 card_list 字段存储 ICCID + MSISDN 列表
ALTER TABLE tb_iot_card_import_task
ADD COLUMN card_list JSONB DEFAULT '[]';
COMMENT ON COLUMN tb_iot_card_import_task.card_list IS '待导入卡列表[{iccid, msisdn}]';

View File

@@ -0,0 +1,3 @@
ALTER TABLE tb_iot_card_import_task
DROP COLUMN IF EXISTS storage_bucket,
DROP COLUMN IF EXISTS storage_key;

View File

@@ -0,0 +1,6 @@
ALTER TABLE tb_iot_card_import_task
ADD COLUMN IF NOT EXISTS storage_bucket VARCHAR(100),
ADD COLUMN IF NOT EXISTS storage_key VARCHAR(500);
COMMENT ON COLUMN tb_iot_card_import_task.storage_bucket IS '对象存储桶名';
COMMENT ON COLUMN tb_iot_card_import_task.storage_key IS '对象存储文件路径';

View File

@@ -0,0 +1,8 @@
-- 删除索引
DROP INDEX IF EXISTS idx_eca_authorized_by;
DROP INDEX IF EXISTS idx_eca_deleted_at;
DROP INDEX IF EXISTS idx_card_authorization;
DROP INDEX IF EXISTS idx_enterprise_revoked;
-- 删除表
DROP TABLE IF EXISTS tb_enterprise_card_authorization;

View File

@@ -0,0 +1,54 @@
-- 重建企业卡授权表(替换 000010 中的旧版结构,字段从 iot_card_id 改为 card_id移除 shop_id/status新增 authorizer_type/revoked_by/revoked_at/remark
DROP TABLE IF EXISTS tb_enterprise_card_authorization;
CREATE TABLE tb_enterprise_card_authorization (
-- 基础字段
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP DEFAULT NULL,
-- 授权关系
enterprise_id BIGINT NOT NULL, -- 被授权企业ID
card_id BIGINT NOT NULL, -- 被授权卡ID
-- 授权信息
authorized_by BIGINT NOT NULL, -- 授权人账号ID
authorized_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 授权时间
authorizer_type SMALLINT NOT NULL, -- 授权人类型2=平台用户 3=代理账号
-- 回收信息
revoked_by BIGINT DEFAULT NULL, -- 回收人账号IDNULL表示未回收
revoked_at TIMESTAMP DEFAULT NULL, -- 回收时间NULL表示未回收
-- 备注信息
remark VARCHAR(500) DEFAULT '' -- 授权备注
);
-- 添加表注释
COMMENT ON TABLE tb_enterprise_card_authorization IS '企业卡授权表';
COMMENT ON COLUMN tb_enterprise_card_authorization.id IS '主键ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.created_at IS '创建时间';
COMMENT ON COLUMN tb_enterprise_card_authorization.updated_at IS '更新时间';
COMMENT ON COLUMN tb_enterprise_card_authorization.deleted_at IS '删除时间';
COMMENT ON COLUMN tb_enterprise_card_authorization.enterprise_id IS '被授权企业ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.card_id IS '被授权卡ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.authorized_by IS '授权人账号ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.authorized_at IS '授权时间';
COMMENT ON COLUMN tb_enterprise_card_authorization.authorizer_type IS '授权人类型2=平台用户 3=代理账号';
COMMENT ON COLUMN tb_enterprise_card_authorization.revoked_by IS '回收人账号ID';
COMMENT ON COLUMN tb_enterprise_card_authorization.revoked_at IS '回收时间';
COMMENT ON COLUMN tb_enterprise_card_authorization.remark IS '授权备注';
-- 创建索引
-- 1. 企业ID + 回收时间的联合索引(查询企业的有效授权)
CREATE INDEX idx_enterprise_revoked ON tb_enterprise_card_authorization(enterprise_id, revoked_at);
-- 2. 卡ID索引查询某张卡的授权情况
CREATE INDEX idx_card_authorization ON tb_enterprise_card_authorization(card_id);
-- 3. 软删除索引
CREATE INDEX idx_eca_deleted_at ON tb_enterprise_card_authorization(deleted_at);
-- 4. 授权人索引(查询某人的授权记录)
CREATE INDEX idx_eca_authorized_by ON tb_enterprise_card_authorization(authorized_by);

View File

@@ -0,0 +1,3 @@
-- 回滚:删除设备导入任务表
DROP TABLE IF EXISTS tb_device_import_task;

View File

@@ -0,0 +1,69 @@
-- 创建设备导入任务表
-- 用于记录设备批量导入的任务状态和处理结果
CREATE TABLE IF NOT EXISTS tb_device_import_task (
-- 基础字段
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMP,
creator BIGINT,
updater BIGINT,
-- 任务标识
task_no VARCHAR(50) NOT NULL UNIQUE,
batch_no VARCHAR(100),
-- 文件信息
storage_key VARCHAR(500),
file_name VARCHAR(255),
-- 任务状态: 1-待处理 2-处理中 3-已完成 4-失败
status INT NOT NULL DEFAULT 1,
-- 处理结果统计
total_count INT DEFAULT 0,
success_count INT DEFAULT 0,
skip_count INT DEFAULT 0,
fail_count INT DEFAULT 0,
-- 处理详情JSONB 存储跳过和失败的记录)
skipped_items JSONB,
failed_items JSONB,
-- 错误信息
error_message TEXT,
-- 时间戳
started_at TIMESTAMP,
completed_at TIMESTAMP
);
-- 索引
CREATE INDEX idx_device_import_task_status ON tb_device_import_task(status);
CREATE INDEX idx_device_import_task_batch_no ON tb_device_import_task(batch_no);
CREATE INDEX idx_device_import_task_created_at ON tb_device_import_task(created_at);
CREATE INDEX idx_device_import_task_deleted_at ON tb_device_import_task(deleted_at);
-- 字段注释
COMMENT ON TABLE tb_device_import_task IS '设备导入任务表';
COMMENT ON COLUMN tb_device_import_task.id IS '主键ID';
COMMENT ON COLUMN tb_device_import_task.created_at IS '创建时间';
COMMENT ON COLUMN tb_device_import_task.updated_at IS '更新时间';
COMMENT ON COLUMN tb_device_import_task.deleted_at IS '删除时间(软删除)';
COMMENT ON COLUMN tb_device_import_task.creator IS '创建人ID';
COMMENT ON COLUMN tb_device_import_task.updater IS '更新人ID';
COMMENT ON COLUMN tb_device_import_task.task_no IS '任务编号(唯一)';
COMMENT ON COLUMN tb_device_import_task.batch_no IS '批次号';
COMMENT ON COLUMN tb_device_import_task.storage_key IS '对象存储文件路径';
COMMENT ON COLUMN tb_device_import_task.file_name IS '原始文件名';
COMMENT ON COLUMN tb_device_import_task.status IS '任务状态: 1-待处理 2-处理中 3-已完成 4-失败';
COMMENT ON COLUMN tb_device_import_task.total_count IS '总记录数';
COMMENT ON COLUMN tb_device_import_task.success_count IS '成功数';
COMMENT ON COLUMN tb_device_import_task.skip_count IS '跳过数';
COMMENT ON COLUMN tb_device_import_task.fail_count IS '失败数';
COMMENT ON COLUMN tb_device_import_task.skipped_items IS '跳过记录详情JSON数组';
COMMENT ON COLUMN tb_device_import_task.failed_items IS '失败记录详情JSON数组';
COMMENT ON COLUMN tb_device_import_task.error_message IS '错误信息';
COMMENT ON COLUMN tb_device_import_task.started_at IS '开始处理时间';
COMMENT ON COLUMN tb_device_import_task.completed_at IS '完成时间';

View File

@@ -0,0 +1,9 @@
-- 回滚:修复设备-SIM卡绑定隐患
-- 删除设备插槽唯一索引
DROP INDEX IF EXISTS idx_active_device_slot;
-- 删除导入任务表的警告字段
ALTER TABLE tb_device_import_task
DROP COLUMN IF EXISTS warning_count,
DROP COLUMN IF EXISTS warning_items;

View File

@@ -0,0 +1,18 @@
-- 修复设备-SIM卡绑定隐患
-- 1. 添加设备插槽唯一索引,防止同一插槽绑定多张卡
-- 2. 为导入任务表添加警告字段,支持部分成功反馈
-- 使用 CONCURRENTLY 避免锁表(注意:需要在事务外执行,此处仅作为参考)
-- 生产环境建议手动执行CREATE UNIQUE INDEX CONCURRENTLY idx_active_device_slot ...
CREATE UNIQUE INDEX IF NOT EXISTS idx_active_device_slot
ON tb_device_sim_binding (device_id, slot_position)
WHERE bind_status = 1 AND deleted_at IS NULL;
-- 为导入任务表添加警告字段
ALTER TABLE tb_device_import_task
ADD COLUMN IF NOT EXISTS warning_count INT NOT NULL DEFAULT 0,
ADD COLUMN IF NOT EXISTS warning_items JSONB;
-- 添加字段注释
COMMENT ON COLUMN tb_device_import_task.warning_count IS '警告数量(部分成功的设备)';
COMMENT ON COLUMN tb_device_import_task.warning_items IS '警告记录详情';

View File

@@ -0,0 +1,3 @@
-- 回滚 fee_rate 字段类型变更
ALTER TABLE tb_commission_withdrawal_setting
ALTER COLUMN fee_rate TYPE numeric(5,4) USING (fee_rate::numeric / 10000);

View File

@@ -0,0 +1,8 @@
-- 修复 tb_commission_withdrawal_setting 表的 fee_rate 字段类型
-- 原类型 numeric(5,4) 只能存储 0.0000-9.9999,无法存储万分比值(如 100 表示 1%
-- 改为 bigint 与模型定义一致
ALTER TABLE tb_commission_withdrawal_setting
ALTER COLUMN fee_rate TYPE bigint USING (fee_rate * 10000)::bigint;
COMMENT ON COLUMN tb_commission_withdrawal_setting.fee_rate IS '手续费率(万分比,如100表示1%)';

View File

@@ -0,0 +1,12 @@
-- 回滚:恢复 Carrier 表的 channel_name、channel_code 字段
-- 添加 channel_name 字段
ALTER TABLE tb_carrier ADD COLUMN channel_name VARCHAR(100);
COMMENT ON COLUMN tb_carrier.channel_name IS '渠道名称';
-- 添加 channel_code 字段
ALTER TABLE tb_carrier ADD COLUMN channel_code VARCHAR(50);
COMMENT ON COLUMN tb_carrier.channel_code IS '渠道编码';
-- 重建联合唯一索引carrier_type + channel_code排除已删除记录
CREATE UNIQUE INDEX idx_carrier_type_channel ON tb_carrier(carrier_type, channel_code) WHERE deleted_at IS NULL;

View File

@@ -0,0 +1,11 @@
-- 移除 Carrier 表的 channel_name、channel_code 字段及相关索引
-- 这些字段未被任何地方使用,属于冗余设计
-- 先删除联合唯一索引
DROP INDEX IF EXISTS idx_carrier_type_channel;
-- 删除 channel_name 字段
ALTER TABLE tb_carrier DROP COLUMN IF EXISTS channel_name;
-- 删除 channel_code 字段
ALTER TABLE tb_carrier DROP COLUMN IF EXISTS channel_code;

View File

@@ -0,0 +1,2 @@
ALTER TABLE tb_iot_card DROP COLUMN IF EXISTS carrier_type;
ALTER TABLE tb_iot_card DROP COLUMN IF EXISTS carrier_name;

View File

@@ -0,0 +1,14 @@
-- IotCard 表添加 carrier_type、carrier_name 冗余字段
-- 导入时从 Carrier 表快照,后续查询无需 JOIN
ALTER TABLE tb_iot_card ADD COLUMN carrier_type VARCHAR(20);
ALTER TABLE tb_iot_card ADD COLUMN carrier_name VARCHAR(100);
COMMENT ON COLUMN tb_iot_card.carrier_type IS '运营商类型(CMCC/CUCC/CTCC/CBN),导入时快照';
COMMENT ON COLUMN tb_iot_card.carrier_name IS '运营商名称,导入时快照';
-- 从 Carrier 表填充现有数据
UPDATE tb_iot_card
SET carrier_type = c.carrier_type, carrier_name = c.carrier_name
FROM tb_carrier c
WHERE tb_iot_card.carrier_id = c.id;

View File

@@ -0,0 +1 @@
ALTER TABLE tb_iot_card_import_task DROP COLUMN IF EXISTS carrier_name;

View File

@@ -0,0 +1,11 @@
-- IotCardImportTask 表添加 carrier_name 冗余字段(已有 carrier_type
ALTER TABLE tb_iot_card_import_task ADD COLUMN carrier_name VARCHAR(100);
COMMENT ON COLUMN tb_iot_card_import_task.carrier_name IS '运营商名称,创建任务时快照';
-- 从 Carrier 表填充现有数据
UPDATE tb_iot_card_import_task
SET carrier_name = c.carrier_name
FROM tb_carrier c
WHERE tb_iot_card_import_task.carrier_id = c.id;

View File

@@ -0,0 +1,162 @@
-- 回滚: 删除 tb_package 表的新字段
ALTER TABLE tb_package DROP COLUMN IF EXISTS suggested_cost_price;
ALTER TABLE tb_package DROP COLUMN IF EXISTS suggested_retail_price;
ALTER TABLE tb_package DROP COLUMN IF EXISTS shelf_status;
-- 回滚: 重建废弃表结构(仅结构,不恢复数据)
-- 代理层级关系表
CREATE TABLE IF NOT EXISTS tb_agent_hierarchy (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT DEFAULT 0,
updater BIGINT DEFAULT 0,
agent_id BIGINT NOT NULL,
parent_agent_id BIGINT,
level INT NOT NULL,
path VARCHAR(500)
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_hierarchy_agent ON tb_agent_hierarchy(agent_id) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_agent_hierarchy_parent ON tb_agent_hierarchy(parent_agent_id);
COMMENT ON TABLE tb_agent_hierarchy IS '代理层级关系表';
-- 分佣规则表
CREATE TABLE IF NOT EXISTS tb_commission_rule (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT DEFAULT 0,
updater BIGINT DEFAULT 0,
agent_id BIGINT NOT NULL,
business_type VARCHAR(50) NOT NULL,
card_type VARCHAR(50) NOT NULL,
series_id BIGINT,
package_id BIGINT,
commission_type VARCHAR(50) NOT NULL,
commission_mode VARCHAR(20) NOT NULL,
commission_value BIGINT NOT NULL,
unfreeze_days INT DEFAULT 0,
min_activation_for_unfreeze INT DEFAULT 0,
approval_type VARCHAR(20) DEFAULT 'auto',
status INT DEFAULT 1 NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_commission_rule_agent ON tb_commission_rule(agent_id);
CREATE INDEX IF NOT EXISTS idx_commission_rule_series ON tb_commission_rule(series_id);
CREATE INDEX IF NOT EXISTS idx_commission_rule_package ON tb_commission_rule(package_id);
COMMENT ON TABLE tb_commission_rule IS '分佣规则表';
-- 阶梯分佣配置表
CREATE TABLE IF NOT EXISTS tb_commission_ladder (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT DEFAULT 0,
updater BIGINT DEFAULT 0,
rule_id BIGINT NOT NULL,
ladder_type VARCHAR(50) NOT NULL,
threshold_value INT NOT NULL,
commission_mode VARCHAR(20) NOT NULL,
commission_value BIGINT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_commission_ladder_rule ON tb_commission_ladder(rule_id);
COMMENT ON TABLE tb_commission_ladder IS '阶梯分佣配置表';
-- 组合分佣条件表
CREATE TABLE IF NOT EXISTS tb_commission_combined_condition (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT DEFAULT 0,
updater BIGINT DEFAULT 0,
rule_id BIGINT NOT NULL,
one_time_commission_mode VARCHAR(20),
one_time_commission_value BIGINT,
long_term_commission_mode VARCHAR(20),
long_term_commission_value BIGINT,
long_term_trigger_time_point TIMESTAMPTZ,
long_term_trigger_package_cycles INT,
long_term_trigger_network_months INT,
long_term_unfreeze_days INT DEFAULT 0,
long_term_min_activation INT DEFAULT 0
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_commission_combined_rule ON tb_commission_combined_condition(rule_id) WHERE deleted_at IS NULL;
COMMENT ON TABLE tb_commission_combined_condition IS '组合分佣条件表';
-- 分佣审批表
CREATE TABLE IF NOT EXISTS tb_commission_approval (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT DEFAULT 0,
updater BIGINT DEFAULT 0,
commission_record_id BIGINT NOT NULL,
approver_id BIGINT,
status INT DEFAULT 1 NOT NULL,
reason TEXT
);
CREATE INDEX IF NOT EXISTS idx_commission_approval_record ON tb_commission_approval(commission_record_id);
CREATE INDEX IF NOT EXISTS idx_commission_approval_approver ON tb_commission_approval(approver_id);
COMMENT ON TABLE tb_commission_approval IS '分佣审批表';
-- 分佣模板表
CREATE TABLE IF NOT EXISTS tb_commission_template (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT DEFAULT 0,
updater BIGINT DEFAULT 0,
template_name VARCHAR(255) NOT NULL,
business_type VARCHAR(50) NOT NULL,
card_type VARCHAR(50) NOT NULL,
commission_type VARCHAR(50) NOT NULL,
commission_mode VARCHAR(20) NOT NULL,
commission_value BIGINT NOT NULL,
unfreeze_days INT DEFAULT 0,
min_activation_for_unfreeze INT DEFAULT 0,
approval_type VARCHAR(20) DEFAULT 'auto'
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_commission_template_name ON tb_commission_template(template_name) WHERE deleted_at IS NULL;
COMMENT ON TABLE tb_commission_template IS '分佣模板表';
-- 运营商结算表
CREATE TABLE IF NOT EXISTS tb_carrier_settlement (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT DEFAULT 0,
updater BIGINT DEFAULT 0,
commission_record_id BIGINT NOT NULL,
agent_id BIGINT NOT NULL,
settlement_month VARCHAR(20) NOT NULL,
settlement_amount BIGINT NOT NULL,
status INT DEFAULT 1 NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_carrier_settlement_record ON tb_carrier_settlement(commission_record_id) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_carrier_settlement_agent ON tb_carrier_settlement(agent_id);
COMMENT ON TABLE tb_carrier_settlement IS '运营商结算表';
-- 代理套餐分配表
CREATE TABLE IF NOT EXISTS tb_agent_package_allocation (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT DEFAULT 0,
updater BIGINT DEFAULT 0,
agent_id BIGINT NOT NULL,
package_id BIGINT NOT NULL,
cost_price BIGINT NOT NULL,
retail_price BIGINT NOT NULL,
status INT DEFAULT 1 NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_agent_package_allocation_agent ON tb_agent_package_allocation(agent_id);
CREATE INDEX IF NOT EXISTS idx_agent_package_allocation_package ON tb_agent_package_allocation(package_id);
COMMENT ON TABLE tb_agent_package_allocation IS '代理套餐分配表';

View File

@@ -0,0 +1,21 @@
-- 清理废弃的分佣相关表
-- 这些表从未在生产环境使用,可以直接删除
-- 删除废弃表
DROP TABLE IF EXISTS tb_agent_hierarchy;
DROP TABLE IF EXISTS tb_commission_rule;
DROP TABLE IF EXISTS tb_commission_ladder;
DROP TABLE IF EXISTS tb_commission_combined_condition;
DROP TABLE IF EXISTS tb_commission_approval;
DROP TABLE IF EXISTS tb_commission_template;
DROP TABLE IF EXISTS tb_carrier_settlement;
DROP TABLE IF EXISTS tb_agent_package_allocation;
-- 为 tb_package 表添加新字段
ALTER TABLE tb_package ADD COLUMN IF NOT EXISTS suggested_cost_price BIGINT DEFAULT 0;
ALTER TABLE tb_package ADD COLUMN IF NOT EXISTS suggested_retail_price BIGINT DEFAULT 0;
ALTER TABLE tb_package ADD COLUMN IF NOT EXISTS shelf_status INT DEFAULT 2 NOT NULL;
COMMENT ON COLUMN tb_package.suggested_cost_price IS '建议成本价(分为单位)';
COMMENT ON COLUMN tb_package.suggested_retail_price IS '建议售价(分为单位)';
COMMENT ON COLUMN tb_package.shelf_status IS '上架状态 1-上架 2-下架';

View File

@@ -0,0 +1,8 @@
-- 删除店铺单套餐分配表
DROP TABLE IF EXISTS tb_shop_package_allocation;
-- 删除梯度佣金配置表
DROP TABLE IF EXISTS tb_shop_series_commission_tier;
-- 删除店铺套餐系列分配表
DROP TABLE IF EXISTS tb_shop_series_allocation;

View File

@@ -0,0 +1,89 @@
-- 创建店铺套餐系列分配表
CREATE TABLE IF NOT EXISTS tb_shop_series_allocation (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT DEFAULT 0 NOT NULL,
updater BIGINT DEFAULT 0 NOT NULL,
shop_id BIGINT NOT NULL,
series_id BIGINT NOT NULL,
allocator_shop_id BIGINT NOT NULL,
pricing_mode VARCHAR(20) NOT NULL,
pricing_value BIGINT NOT NULL,
one_time_commission_trigger VARCHAR(30),
one_time_commission_threshold BIGINT DEFAULT 0,
one_time_commission_amount BIGINT DEFAULT 0,
status INT DEFAULT 1 NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_shop_series_allocation_shop_id ON tb_shop_series_allocation(shop_id);
CREATE INDEX IF NOT EXISTS idx_shop_series_allocation_series_id ON tb_shop_series_allocation(series_id);
CREATE INDEX IF NOT EXISTS idx_shop_series_allocation_allocator_shop_id ON tb_shop_series_allocation(allocator_shop_id);
CREATE UNIQUE INDEX IF NOT EXISTS idx_shop_series_allocation_shop_series ON tb_shop_series_allocation(shop_id, series_id) WHERE deleted_at IS NULL;
COMMENT ON TABLE tb_shop_series_allocation IS '店铺套餐系列分配表';
COMMENT ON COLUMN tb_shop_series_allocation.shop_id IS '被分配的店铺ID';
COMMENT ON COLUMN tb_shop_series_allocation.series_id IS '套餐系列ID';
COMMENT ON COLUMN tb_shop_series_allocation.allocator_shop_id IS '分配者店铺ID上级';
COMMENT ON COLUMN tb_shop_series_allocation.pricing_mode IS '加价模式 fixed-固定金额 percent-百分比';
COMMENT ON COLUMN tb_shop_series_allocation.pricing_value IS '加价值(分或千分比)';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_trigger IS '一次性佣金触发类型 one_time_recharge-单次充值 accumulated_recharge-累计充值';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_threshold IS '一次性佣金触发阈值(分)';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_amount IS '一次性佣金金额(分)';
COMMENT ON COLUMN tb_shop_series_allocation.status IS '状态 1-启用 2-禁用';
-- 创建梯度佣金配置表
CREATE TABLE IF NOT EXISTS tb_shop_series_commission_tier (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT DEFAULT 0 NOT NULL,
updater BIGINT DEFAULT 0 NOT NULL,
allocation_id BIGINT NOT NULL,
tier_type VARCHAR(20) NOT NULL,
period_type VARCHAR(20) NOT NULL,
period_start_date TIMESTAMPTZ,
period_end_date TIMESTAMPTZ,
threshold_value BIGINT NOT NULL,
commission_amount BIGINT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_shop_series_commission_tier_allocation_id ON tb_shop_series_commission_tier(allocation_id);
COMMENT ON TABLE tb_shop_series_commission_tier IS '梯度佣金配置表';
COMMENT ON COLUMN tb_shop_series_commission_tier.allocation_id IS '关联的分配ID';
COMMENT ON COLUMN tb_shop_series_commission_tier.tier_type IS '梯度类型 sales_count-销量 sales_amount-销售额';
COMMENT ON COLUMN tb_shop_series_commission_tier.period_type IS '周期类型 monthly-月度 quarterly-季度 yearly-年度 custom-自定义';
COMMENT ON COLUMN tb_shop_series_commission_tier.period_start_date IS '自定义周期开始日期';
COMMENT ON COLUMN tb_shop_series_commission_tier.period_end_date IS '自定义周期结束日期';
COMMENT ON COLUMN tb_shop_series_commission_tier.threshold_value IS '阈值(销量或金额分)';
COMMENT ON COLUMN tb_shop_series_commission_tier.commission_amount IS '佣金金额(分)';
-- 创建店铺单套餐分配表
CREATE TABLE IF NOT EXISTS tb_shop_package_allocation (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT DEFAULT 0 NOT NULL,
updater BIGINT DEFAULT 0 NOT NULL,
shop_id BIGINT NOT NULL,
package_id BIGINT NOT NULL,
allocation_id BIGINT NOT NULL,
cost_price BIGINT NOT NULL,
status INT DEFAULT 1 NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_shop_package_allocation_shop_id ON tb_shop_package_allocation(shop_id);
CREATE INDEX IF NOT EXISTS idx_shop_package_allocation_package_id ON tb_shop_package_allocation(package_id);
CREATE INDEX IF NOT EXISTS idx_shop_package_allocation_allocation_id ON tb_shop_package_allocation(allocation_id);
CREATE UNIQUE INDEX IF NOT EXISTS idx_shop_package_allocation_shop_package ON tb_shop_package_allocation(shop_id, package_id) WHERE deleted_at IS NULL;
COMMENT ON TABLE tb_shop_package_allocation IS '店铺单套餐分配表';
COMMENT ON COLUMN tb_shop_package_allocation.shop_id IS '被分配的店铺ID';
COMMENT ON COLUMN tb_shop_package_allocation.package_id IS '套餐ID';
COMMENT ON COLUMN tb_shop_package_allocation.allocation_id IS '关联的系列分配ID';
COMMENT ON COLUMN tb_shop_package_allocation.cost_price IS '覆盖的成本价(分)';
COMMENT ON COLUMN tb_shop_package_allocation.status IS '状态 1-启用 2-禁用';

View File

@@ -0,0 +1,62 @@
-- 回滚重构套餐分配和佣金系统的迁移
-- ============================================================
-- 6. 删除额外索引
-- ============================================================
DROP INDEX IF EXISTS idx_package_allocation_shop_pkg;
-- ============================================================
-- 5. 删除 tb_shop_series_commission_stats 表
-- ============================================================
DROP TABLE IF EXISTS tb_shop_series_commission_stats;
-- ============================================================
-- 4. 删除 tb_shop_package_allocation_price_history 表
-- ============================================================
DROP TABLE IF EXISTS tb_shop_package_allocation_price_history;
-- ============================================================
-- 3. 删除 tb_shop_series_allocation_config 表
-- ============================================================
DROP TABLE IF EXISTS tb_shop_series_allocation_config;
-- ============================================================
-- 2. 回滚 tb_shop_series_commission_tier 表修改
-- ============================================================
-- 回滚字段重命名
ALTER TABLE tb_shop_series_commission_tier
RENAME COLUMN commission_value TO commission_amount;
-- 删除新增字段
ALTER TABLE tb_shop_series_commission_tier
DROP COLUMN IF EXISTS commission_mode;
-- ============================================================
-- 1. 回滚 tb_shop_series_allocation 表修改
-- ============================================================
-- 删除新增字段
ALTER TABLE tb_shop_series_allocation
DROP COLUMN IF EXISTS base_commission_mode,
DROP COLUMN IF EXISTS base_commission_value,
DROP COLUMN IF EXISTS enable_tier_commission;
-- 恢复旧字段
ALTER TABLE tb_shop_series_allocation
ADD COLUMN pricing_mode VARCHAR(20),
ADD COLUMN pricing_value BIGINT,
ADD COLUMN one_time_commission_trigger VARCHAR(30),
ADD COLUMN one_time_commission_threshold BIGINT DEFAULT 0,
ADD COLUMN one_time_commission_amount BIGINT DEFAULT 0;
-- 恢复字段注释
COMMENT ON COLUMN tb_shop_series_allocation.pricing_mode IS '加价模式 fixed-固定金额 percent-百分比';
COMMENT ON COLUMN tb_shop_series_allocation.pricing_value IS '加价值(分或千分比)';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_trigger IS '一次性佣金触发类型 one_time_recharge-单次充值 accumulated_recharge-累计充值';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_threshold IS '一次性佣金触发阈值(分)';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_amount IS '一次性佣金金额(分)';

View File

@@ -0,0 +1,153 @@
-- 重构套餐分配和佣金系统
-- 1. 删除自动加价机制pricing_mode, pricing_value
-- 2. 重构返佣配置(新增 base_commission_mode, base_commission_value, enable_tier_commission
-- 3. 修正梯度佣金逻辑commission_tier 新增 commission_mode
-- 4. 新增配置版本管理、成本价历史、统计缓存表
-- ============================================================
-- 1. 修改 tb_shop_series_allocation 表
-- ============================================================
-- 删除旧字段
ALTER TABLE tb_shop_series_allocation
DROP COLUMN IF EXISTS pricing_mode,
DROP COLUMN IF EXISTS pricing_value,
DROP COLUMN IF EXISTS one_time_commission_trigger,
DROP COLUMN IF EXISTS one_time_commission_threshold,
DROP COLUMN IF EXISTS one_time_commission_amount;
-- 新增新字段
ALTER TABLE tb_shop_series_allocation
ADD COLUMN base_commission_mode VARCHAR(20) NOT NULL DEFAULT 'percent',
ADD COLUMN base_commission_value BIGINT NOT NULL DEFAULT 0,
ADD COLUMN enable_tier_commission BOOLEAN NOT NULL DEFAULT FALSE;
-- 添加字段注释
COMMENT ON COLUMN tb_shop_series_allocation.base_commission_mode IS '基础返佣模式 fixed-固定金额 percent-百分比';
COMMENT ON COLUMN tb_shop_series_allocation.base_commission_value IS '基础返佣值分或千分比如200=20%';
COMMENT ON COLUMN tb_shop_series_allocation.enable_tier_commission IS '是否启用梯度返佣';
-- ============================================================
-- 2. 修改 tb_shop_series_commission_tier 表
-- ============================================================
-- 新增 commission_mode 字段
ALTER TABLE tb_shop_series_commission_tier
ADD COLUMN commission_mode VARCHAR(20) NOT NULL DEFAULT 'percent';
-- 添加字段注释
COMMENT ON COLUMN tb_shop_series_commission_tier.commission_mode IS '达标后返佣模式 fixed-固定金额 percent-百分比';
-- 删除旧字段 commission_amount重命名为更语义化的 commission_value
ALTER TABLE tb_shop_series_commission_tier
RENAME COLUMN commission_amount TO commission_value;
-- 更新字段注释
COMMENT ON COLUMN tb_shop_series_commission_tier.commission_value IS '达标后返佣值(分或千分比)';
-- ============================================================
-- 3. 创建 tb_shop_series_allocation_config 表(配置版本表)
-- ============================================================
CREATE TABLE IF NOT EXISTS tb_shop_series_allocation_config (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
allocation_id BIGINT NOT NULL,
version INT NOT NULL,
base_commission_mode VARCHAR(20) NOT NULL,
base_commission_value BIGINT NOT NULL,
enable_tier_commission BOOLEAN NOT NULL,
effective_from TIMESTAMPTZ NOT NULL,
effective_to TIMESTAMPTZ
);
-- 创建索引
CREATE INDEX IF NOT EXISTS idx_allocation_config_allocation_id ON tb_shop_series_allocation_config(allocation_id);
CREATE INDEX IF NOT EXISTS idx_allocation_config_effective ON tb_shop_series_allocation_config(allocation_id, effective_to);
-- 添加表和字段注释
COMMENT ON TABLE tb_shop_series_allocation_config IS '套餐系列分配配置版本表';
COMMENT ON COLUMN tb_shop_series_allocation_config.allocation_id IS '关联的分配ID';
COMMENT ON COLUMN tb_shop_series_allocation_config.version IS '配置版本号';
COMMENT ON COLUMN tb_shop_series_allocation_config.base_commission_mode IS '基础返佣模式(配置快照)';
COMMENT ON COLUMN tb_shop_series_allocation_config.base_commission_value IS '基础返佣值(配置快照)';
COMMENT ON COLUMN tb_shop_series_allocation_config.enable_tier_commission IS '是否启用梯度返佣(配置快照)';
COMMENT ON COLUMN tb_shop_series_allocation_config.effective_from IS '生效开始时间';
COMMENT ON COLUMN tb_shop_series_allocation_config.effective_to IS '生效结束时间NULL表示当前生效';
-- ============================================================
-- 4. 创建 tb_shop_package_allocation_price_history 表(成本价历史表)
-- ============================================================
CREATE TABLE IF NOT EXISTS tb_shop_package_allocation_price_history (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
allocation_id BIGINT NOT NULL,
old_cost_price BIGINT NOT NULL,
new_cost_price BIGINT NOT NULL,
change_reason VARCHAR(255),
changed_by BIGINT NOT NULL,
effective_from TIMESTAMPTZ NOT NULL
);
-- 创建索引
CREATE INDEX IF NOT EXISTS idx_price_history_allocation ON tb_shop_package_allocation_price_history(allocation_id, effective_from);
-- 添加表和字段注释
COMMENT ON TABLE tb_shop_package_allocation_price_history IS '套餐成本价变更历史表';
COMMENT ON COLUMN tb_shop_package_allocation_price_history.allocation_id IS '关联的套餐分配IDtb_shop_package_allocation.id';
COMMENT ON COLUMN tb_shop_package_allocation_price_history.old_cost_price IS '原成本价(分)';
COMMENT ON COLUMN tb_shop_package_allocation_price_history.new_cost_price IS '新成本价(分)';
COMMENT ON COLUMN tb_shop_package_allocation_price_history.change_reason IS '变更原因';
COMMENT ON COLUMN tb_shop_package_allocation_price_history.changed_by IS '变更人ID';
COMMENT ON COLUMN tb_shop_package_allocation_price_history.effective_from IS '生效时间';
-- ============================================================
-- 5. 创建 tb_shop_series_commission_stats 表(统计缓存表)
-- ============================================================
CREATE TABLE IF NOT EXISTS tb_shop_series_commission_stats (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
allocation_id BIGINT NOT NULL,
period_type VARCHAR(20) NOT NULL,
period_start TIMESTAMPTZ NOT NULL,
period_end TIMESTAMPTZ NOT NULL,
total_sales_count BIGINT DEFAULT 0 NOT NULL,
total_sales_amount BIGINT DEFAULT 0 NOT NULL,
current_tier_id BIGINT,
last_updated_at TIMESTAMPTZ NOT NULL,
version INT DEFAULT 0 NOT NULL,
status VARCHAR(20) DEFAULT 'active' NOT NULL
);
-- 创建索引
CREATE INDEX IF NOT EXISTS idx_commission_stats_allocation_id ON tb_shop_series_commission_stats(allocation_id);
CREATE INDEX IF NOT EXISTS idx_commission_stats_period ON tb_shop_series_commission_stats(allocation_id, period_start, period_end);
CREATE UNIQUE INDEX IF NOT EXISTS idx_commission_stats_unique ON tb_shop_series_commission_stats(allocation_id, period_type, period_start) WHERE deleted_at IS NULL;
-- 添加表和字段注释
COMMENT ON TABLE tb_shop_series_commission_stats IS '梯度佣金统计缓存表';
COMMENT ON COLUMN tb_shop_series_commission_stats.allocation_id IS '关联的分配ID';
COMMENT ON COLUMN tb_shop_series_commission_stats.period_type IS '周期类型 monthly-月度 quarterly-季度 yearly-年度';
COMMENT ON COLUMN tb_shop_series_commission_stats.period_start IS '周期开始时间';
COMMENT ON COLUMN tb_shop_series_commission_stats.period_end IS '周期结束时间';
COMMENT ON COLUMN tb_shop_series_commission_stats.total_sales_count IS '总销售数量';
COMMENT ON COLUMN tb_shop_series_commission_stats.total_sales_amount IS '总销售金额(分)';
COMMENT ON COLUMN tb_shop_series_commission_stats.current_tier_id IS '当前匹配的梯度ID';
COMMENT ON COLUMN tb_shop_series_commission_stats.last_updated_at IS '最后更新时间';
COMMENT ON COLUMN tb_shop_series_commission_stats.version IS '版本号(乐观锁)';
COMMENT ON COLUMN tb_shop_series_commission_stats.status IS '状态 active-活跃 completed-已完成 cancelled-已取消';
-- ============================================================
-- 6. 创建额外索引(性能优化)
-- ============================================================
-- tb_shop_package_allocation 表新增复合索引(用于代理权限过滤)
CREATE INDEX IF NOT EXISTS idx_package_allocation_shop_pkg ON tb_shop_package_allocation(shop_id, package_id, status);

View File

@@ -0,0 +1,13 @@
-- 删除 tb_device 的索引和字段
DROP INDEX IF EXISTS idx_device_series_allocation;
ALTER TABLE tb_device
DROP COLUMN IF EXISTS series_allocation_id,
DROP COLUMN IF EXISTS first_commission_paid,
DROP COLUMN IF EXISTS accumulated_recharge;
-- 删除 tb_iot_card 的索引和字段
DROP INDEX IF EXISTS idx_iot_card_series_allocation;
ALTER TABLE tb_iot_card
DROP COLUMN IF EXISTS series_allocation_id,
DROP COLUMN IF EXISTS first_commission_paid,
DROP COLUMN IF EXISTS accumulated_recharge;

View File

@@ -0,0 +1,27 @@
-- 为 tb_iot_card 添加套餐系列绑定相关字段
ALTER TABLE tb_iot_card
ADD COLUMN series_allocation_id INTEGER DEFAULT NULL,
ADD COLUMN first_commission_paid BOOLEAN NOT NULL DEFAULT FALSE,
ADD COLUMN accumulated_recharge BIGINT NOT NULL DEFAULT 0;
-- 为 tb_iot_card 的 series_allocation_id 字段添加索引
CREATE INDEX idx_iot_card_series_allocation ON tb_iot_card(series_allocation_id);
-- 为 tb_iot_card 添加注释
COMMENT ON COLUMN tb_iot_card.series_allocation_id IS '套餐系列分配ID(关联ShopSeriesAllocation)';
COMMENT ON COLUMN tb_iot_card.first_commission_paid IS '一次性佣金是否已发放';
COMMENT ON COLUMN tb_iot_card.accumulated_recharge IS '累计充值金额(分)';
-- 为 tb_device 添加套餐系列绑定相关字段
ALTER TABLE tb_device
ADD COLUMN series_allocation_id INTEGER DEFAULT NULL,
ADD COLUMN first_commission_paid BOOLEAN NOT NULL DEFAULT FALSE,
ADD COLUMN accumulated_recharge BIGINT NOT NULL DEFAULT 0;
-- 为 tb_device 的 series_allocation_id 字段添加索引
CREATE INDEX idx_device_series_allocation ON tb_device(series_allocation_id);
-- 为 tb_device 添加注释
COMMENT ON COLUMN tb_device.series_allocation_id IS '套餐系列分配ID(关联ShopSeriesAllocation)';
COMMENT ON COLUMN tb_device.first_commission_paid IS '一次性佣金是否已发放';
COMMENT ON COLUMN tb_device.accumulated_recharge IS '累计充值金额(分)';

View File

@@ -0,0 +1,5 @@
-- 删除订单明细表
DROP TABLE IF EXISTS tb_order_item;
-- 删除订单表
DROP TABLE IF EXISTS tb_order;

View File

@@ -0,0 +1,90 @@
-- 删除旧的订单表(如果存在)
DROP TABLE IF EXISTS tb_order CASCADE;
-- 创建订单表
CREATE TABLE tb_order (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT NOT NULL DEFAULT 0,
updater BIGINT NOT NULL DEFAULT 0,
-- 订单基础信息
order_no VARCHAR(30) NOT NULL,
order_type VARCHAR(20) NOT NULL,
-- 买家信息
buyer_type VARCHAR(20) NOT NULL,
buyer_id BIGINT NOT NULL,
-- 关联资源
iot_card_id BIGINT,
device_id BIGINT,
-- 金额信息
total_amount BIGINT NOT NULL,
-- 支付信息
payment_method VARCHAR(20),
payment_status INT NOT NULL DEFAULT 1,
paid_at TIMESTAMPTZ,
-- 佣金信息
commission_status INT NOT NULL DEFAULT 1,
commission_config_version INT NOT NULL DEFAULT 0
);
-- 添加表注释
COMMENT ON TABLE tb_order IS '订单表';
COMMENT ON COLUMN tb_order.order_no IS '订单号(ORD+时间戳+6位随机数)';
COMMENT ON COLUMN tb_order.order_type IS '订单类型 single_card-单卡购买 device-设备购买';
COMMENT ON COLUMN tb_order.buyer_type IS '买家类型 personal-个人客户 agent-代理商';
COMMENT ON COLUMN tb_order.buyer_id IS '买家ID(个人客户ID或店铺ID)';
COMMENT ON COLUMN tb_order.iot_card_id IS 'IoT卡ID(单卡购买时有值)';
COMMENT ON COLUMN tb_order.device_id IS '设备ID(设备购买时有值)';
COMMENT ON COLUMN tb_order.total_amount IS '订单总金额(分)';
COMMENT ON COLUMN tb_order.payment_method IS '支付方式 wallet-钱包 wechat-微信 alipay-支付宝';
COMMENT ON COLUMN tb_order.payment_status IS '支付状态 1-待支付 2-已支付 3-已取消 4-已退款';
COMMENT ON COLUMN tb_order.paid_at IS '支付时间';
COMMENT ON COLUMN tb_order.commission_status IS '佣金状态 1-待计算 2-已计算';
COMMENT ON COLUMN tb_order.commission_config_version IS '佣金配置版本(订单创建时快照)';
-- 创建索引
CREATE UNIQUE INDEX idx_order_no ON tb_order(order_no) WHERE deleted_at IS NULL;
CREATE INDEX idx_order_buyer ON tb_order(buyer_type, buyer_id);
CREATE INDEX idx_order_payment_status ON tb_order(payment_status);
CREATE INDEX idx_order_iot_card_id ON tb_order(iot_card_id) WHERE iot_card_id IS NOT NULL;
CREATE INDEX idx_order_device_id ON tb_order(device_id) WHERE device_id IS NOT NULL;
CREATE INDEX idx_order_deleted_at ON tb_order(deleted_at);
-- 创建订单明细表
CREATE TABLE tb_order_item (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT NOT NULL DEFAULT 0,
updater BIGINT NOT NULL DEFAULT 0,
order_id BIGINT NOT NULL,
package_id BIGINT NOT NULL,
package_name VARCHAR(100) NOT NULL,
quantity INT NOT NULL DEFAULT 1,
unit_price BIGINT NOT NULL,
amount BIGINT NOT NULL
);
-- 添加表注释
COMMENT ON TABLE tb_order_item IS '订单明细表';
COMMENT ON COLUMN tb_order_item.order_id IS '订单ID';
COMMENT ON COLUMN tb_order_item.package_id IS '套餐ID';
COMMENT ON COLUMN tb_order_item.package_name IS '套餐名称(快照)';
COMMENT ON COLUMN tb_order_item.quantity IS '数量';
COMMENT ON COLUMN tb_order_item.unit_price IS '单价(分)';
COMMENT ON COLUMN tb_order_item.amount IS '小计金额(分)';
-- 创建索引
CREATE INDEX idx_order_item_order_id ON tb_order_item(order_id);
CREATE INDEX idx_order_item_package_id ON tb_order_item(package_id);
CREATE INDEX idx_order_item_deleted_at ON tb_order_item(deleted_at);

View File

@@ -0,0 +1,41 @@
-- 回滚迁移: 一次性佣金功能
-- ========================================
-- 1. 恢复 tb_commission_record 表结构
-- ========================================
-- 1.1 删除新字段
ALTER TABLE tb_commission_record
DROP COLUMN IF EXISTS commission_source,
DROP COLUMN IF EXISTS iot_card_id,
DROP COLUMN IF EXISTS device_id,
DROP COLUMN IF EXISTS remark;
-- 1.2 恢复旧字段
ALTER TABLE tb_commission_record
ADD COLUMN IF NOT EXISTS agent_id BIGINT,
ADD COLUMN IF NOT EXISTS rule_id BIGINT,
ADD COLUMN IF NOT EXISTS commission_type VARCHAR(50),
ADD COLUMN IF NOT EXISTS unfrozen_at TIMESTAMP WITH TIME ZONE;
-- 1.3 恢复索引
CREATE INDEX IF NOT EXISTS idx_commission_record_agent_id ON tb_commission_record(agent_id);
CREATE INDEX IF NOT EXISTS idx_commission_record_rule_id ON tb_commission_record(rule_id);
-- ========================================
-- 2. 删除 tb_shop_series_one_time_commission_tier 表
-- ========================================
DROP TABLE IF EXISTS tb_shop_series_one_time_commission_tier;
-- ========================================
-- 3. 删除 tb_shop_series_allocation 的一次性佣金字段
-- ========================================
ALTER TABLE tb_shop_series_allocation
DROP COLUMN IF EXISTS enable_one_time_commission,
DROP COLUMN IF EXISTS one_time_commission_type,
DROP COLUMN IF EXISTS one_time_commission_trigger,
DROP COLUMN IF EXISTS one_time_commission_threshold,
DROP COLUMN IF EXISTS one_time_commission_mode,
DROP COLUMN IF EXISTS one_time_commission_value;

View File

@@ -0,0 +1,96 @@
-- 迁移: 一次性佣金功能
-- 变更ID: add-one-time-commission
-- 说明:
-- 1. 为 tb_shop_series_allocation 添加一次性佣金配置字段
-- 2. 创建 tb_shop_series_one_time_commission_tier 梯度配置表
-- 3. 简化 tb_commission_record 表结构(删除冻结字段,新增来源字段)
-- ========================================
-- 1. tb_shop_series_allocation 添加一次性佣金配置字段
-- ========================================
ALTER TABLE tb_shop_series_allocation
ADD COLUMN IF NOT EXISTS enable_one_time_commission BOOLEAN NOT NULL DEFAULT FALSE,
ADD COLUMN IF NOT EXISTS one_time_commission_type VARCHAR(20),
ADD COLUMN IF NOT EXISTS one_time_commission_trigger VARCHAR(30),
ADD COLUMN IF NOT EXISTS one_time_commission_threshold BIGINT DEFAULT 0,
ADD COLUMN IF NOT EXISTS one_time_commission_mode VARCHAR(20),
ADD COLUMN IF NOT EXISTS one_time_commission_value BIGINT DEFAULT 0;
-- 添加字段注释
COMMENT ON COLUMN tb_shop_series_allocation.enable_one_time_commission IS '是否启用一次性佣金';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_type IS '一次性佣金类型 fixed-固定 tiered-梯度';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_trigger IS '触发条件 single_recharge-单次充值 accumulated_recharge-累计充值';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_threshold IS '最低阈值(分)';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_mode IS '返佣模式 fixed-固定金额 percent-百分比';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_value IS '佣金金额(分)或比例(千分比)';
-- ========================================
-- 2. 创建 tb_shop_series_one_time_commission_tier 梯度配置表
-- ========================================
CREATE TABLE IF NOT EXISTS tb_shop_series_one_time_commission_tier (
id BIGSERIAL PRIMARY KEY,
allocation_id BIGINT NOT NULL,
tier_type VARCHAR(20) NOT NULL,
threshold_value BIGINT NOT NULL,
commission_mode VARCHAR(20) NOT NULL DEFAULT 'fixed',
commission_value BIGINT NOT NULL,
status INT NOT NULL DEFAULT 1,
creator BIGINT NOT NULL,
updater BIGINT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
deleted_at TIMESTAMP WITH TIME ZONE
);
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_one_time_tier_allocation_id ON tb_shop_series_one_time_commission_tier(allocation_id);
CREATE INDEX IF NOT EXISTS idx_one_time_tier_tier_type ON tb_shop_series_one_time_commission_tier(tier_type);
CREATE INDEX IF NOT EXISTS idx_one_time_tier_threshold ON tb_shop_series_one_time_commission_tier(threshold_value);
-- 添加表注释
COMMENT ON TABLE tb_shop_series_one_time_commission_tier IS '一次性佣金梯度配置表,基于销售业绩的一次性佣金档位';
COMMENT ON COLUMN tb_shop_series_one_time_commission_tier.allocation_id IS '系列分配ID';
COMMENT ON COLUMN tb_shop_series_one_time_commission_tier.tier_type IS '梯度类型 sales_count-销量 sales_amount-销售额';
COMMENT ON COLUMN tb_shop_series_one_time_commission_tier.threshold_value IS '梯度阈值(销量或销售额分)';
COMMENT ON COLUMN tb_shop_series_one_time_commission_tier.commission_mode IS '返佣模式 fixed-固定金额 percent-百分比';
COMMENT ON COLUMN tb_shop_series_one_time_commission_tier.commission_value IS '返佣值(分或千分比)';
COMMENT ON COLUMN tb_shop_series_one_time_commission_tier.status IS '状态 1-启用 2-停用';
COMMENT ON COLUMN tb_shop_series_one_time_commission_tier.creator IS '创建人ID';
COMMENT ON COLUMN tb_shop_series_one_time_commission_tier.updater IS '更新人ID';
-- ========================================
-- 3. 修改 tb_commission_record 表结构
-- ========================================
-- 3.1 删除旧字段
ALTER TABLE tb_commission_record
DROP COLUMN IF EXISTS agent_id,
DROP COLUMN IF EXISTS rule_id,
DROP COLUMN IF EXISTS commission_type,
DROP COLUMN IF EXISTS unfrozen_at;
-- 3.2 添加新字段
ALTER TABLE tb_commission_record
ADD COLUMN IF NOT EXISTS commission_source VARCHAR(20) NOT NULL DEFAULT 'cost_diff',
ADD COLUMN IF NOT EXISTS iot_card_id BIGINT,
ADD COLUMN IF NOT EXISTS device_id BIGINT,
ADD COLUMN IF NOT EXISTS remark VARCHAR(500);
-- 3.3 添加索引
CREATE INDEX IF NOT EXISTS idx_commission_record_commission_source ON tb_commission_record(commission_source);
CREATE INDEX IF NOT EXISTS idx_commission_record_iot_card_id ON tb_commission_record(iot_card_id);
CREATE INDEX IF NOT EXISTS idx_commission_record_device_id ON tb_commission_record(device_id);
-- 3.4 更新字段注释
COMMENT ON COLUMN tb_commission_record.shop_id IS '店铺ID佣金归属';
COMMENT ON COLUMN tb_commission_record.order_id IS '订单ID';
COMMENT ON COLUMN tb_commission_record.commission_source IS '佣金来源 cost_diff-成本价差 one_time-一次性佣金 tier_bonus-梯度奖励';
COMMENT ON COLUMN tb_commission_record.iot_card_id IS '关联卡ID可空';
COMMENT ON COLUMN tb_commission_record.device_id IS '关联设备ID可空';
COMMENT ON COLUMN tb_commission_record.amount IS '佣金金额(分)';
COMMENT ON COLUMN tb_commission_record.balance_after IS '入账后钱包余额(分)';
COMMENT ON COLUMN tb_commission_record.status IS '状态 1-已入账 2-已失效';
COMMENT ON COLUMN tb_commission_record.released_at IS '入账时间';
COMMENT ON COLUMN tb_commission_record.remark IS '备注';

View File

@@ -0,0 +1,6 @@
-- 回滚: 删除 Order 表的佣金计算字段
ALTER TABLE tb_order
DROP COLUMN IF EXISTS seller_shop_id,
DROP COLUMN IF EXISTS seller_cost_price,
DROP COLUMN IF EXISTS series_id;

View File

@@ -0,0 +1,19 @@
-- 迁移: 为 Order 表添加佣金计算所需字段
-- 说明:
-- 1. 添加 seller_shop_id 字段销售店铺ID用于成本价差计算
-- 2. 添加 seller_cost_price 字段(销售成本价,用于计算利润)
-- 3. 添加 series_id 字段系列ID用于查询分配配置
ALTER TABLE tb_order
ADD COLUMN IF NOT EXISTS seller_shop_id BIGINT,
ADD COLUMN IF NOT EXISTS seller_cost_price BIGINT DEFAULT 0,
ADD COLUMN IF NOT EXISTS series_id BIGINT;
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_order_seller_shop_id ON tb_order(seller_shop_id);
CREATE INDEX IF NOT EXISTS idx_order_series_id ON tb_order(series_id);
-- 添加字段注释
COMMENT ON COLUMN tb_order.seller_shop_id IS '销售店铺ID用于成本价差佣金计算';
COMMENT ON COLUMN tb_order.seller_cost_price IS '销售成本价(分,用于计算利润)';
COMMENT ON COLUMN tb_order.series_id IS '系列ID用于查询分配配置';

View File

@@ -0,0 +1,3 @@
-- 回滚: 删除企业设备授权表
DROP TABLE IF EXISTS tb_enterprise_device_authorization;

View File

@@ -0,0 +1,48 @@
-- 迁移: 创建企业设备授权表
-- 说明:
-- 1. 创建 tb_enterprise_device_authorization 表,记录设备与企业的授权关系
-- 2. 添加部分唯一索引保证一个设备同时只能授权给一个企业
-- 3. 添加常规索引优化查询性能
CREATE TABLE IF NOT EXISTS tb_enterprise_device_authorization (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP,
enterprise_id BIGINT NOT NULL,
device_id BIGINT NOT NULL,
authorized_by BIGINT NOT NULL,
authorized_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
authorizer_type SMALLINT NOT NULL,
revoked_by BIGINT,
revoked_at TIMESTAMP,
remark VARCHAR(500) DEFAULT ''
);
-- 添加部分唯一索引:一个设备同时只能授权给一个企业
CREATE UNIQUE INDEX IF NOT EXISTS uq_active_device_auth
ON tb_enterprise_device_authorization(device_id)
WHERE revoked_at IS NULL AND deleted_at IS NULL;
-- 添加常规索引
CREATE INDEX IF NOT EXISTS idx_eda_enterprise ON tb_enterprise_device_authorization(enterprise_id);
CREATE INDEX IF NOT EXISTS idx_eda_device ON tb_enterprise_device_authorization(device_id);
CREATE INDEX IF NOT EXISTS idx_eda_authorized_by ON tb_enterprise_device_authorization(authorized_by);
CREATE INDEX IF NOT EXISTS idx_eda_deleted_at ON tb_enterprise_device_authorization(deleted_at);
-- 添加表注释
COMMENT ON TABLE tb_enterprise_device_authorization IS '企业设备授权表';
-- 添加字段注释
COMMENT ON COLUMN tb_enterprise_device_authorization.id IS '主键ID';
COMMENT ON COLUMN tb_enterprise_device_authorization.created_at IS '创建时间';
COMMENT ON COLUMN tb_enterprise_device_authorization.updated_at IS '更新时间';
COMMENT ON COLUMN tb_enterprise_device_authorization.deleted_at IS '软删除时间';
COMMENT ON COLUMN tb_enterprise_device_authorization.enterprise_id IS '被授权企业ID';
COMMENT ON COLUMN tb_enterprise_device_authorization.device_id IS '被授权设备ID';
COMMENT ON COLUMN tb_enterprise_device_authorization.authorized_by IS '授权人账号ID';
COMMENT ON COLUMN tb_enterprise_device_authorization.authorized_at IS '授权时间';
COMMENT ON COLUMN tb_enterprise_device_authorization.authorizer_type IS '授权人类型2=平台用户 3=代理账号';
COMMENT ON COLUMN tb_enterprise_device_authorization.revoked_by IS '回收人账号ID';
COMMENT ON COLUMN tb_enterprise_device_authorization.revoked_at IS '回收时间';
COMMENT ON COLUMN tb_enterprise_device_authorization.remark IS '授权备注';

View File

@@ -0,0 +1,4 @@
-- 回滚: 删除企业卡授权表的设备授权关联字段
ALTER TABLE tb_enterprise_card_authorization
DROP COLUMN IF EXISTS device_auth_id;

View File

@@ -0,0 +1,14 @@
-- 迁移: 为企业卡授权表添加设备授权关联字段
-- 说明:
-- 1. 添加 device_auth_id 字段,用于关联设备授权记录
-- 2. NULL 表示通过单卡授权创建,有值表示通过设备授权创建
-- 3. 添加索引优化查询性能
ALTER TABLE tb_enterprise_card_authorization
ADD COLUMN IF NOT EXISTS device_auth_id BIGINT DEFAULT NULL;
-- 添加索引
CREATE INDEX IF NOT EXISTS idx_eca_device_auth ON tb_enterprise_card_authorization(device_auth_id);
-- 添加字段注释
COMMENT ON COLUMN tb_enterprise_card_authorization.device_auth_id IS '关联的设备授权IDNULL=单卡授权 有值=设备授权)';

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS idx_package_usage_order_package;

View File

@@ -0,0 +1 @@
CREATE UNIQUE INDEX idx_package_usage_order_package ON tb_package_usage(order_id, package_id) WHERE deleted_at IS NULL;

View File

@@ -0,0 +1,39 @@
-- 回滚: 恢复梯度返佣(TierCommission)相关的表和字段
-- 注意: 此回滚仅恢复表结构,不恢复已删除的数据
-- 1. 重新创建 tb_shop_series_commission_tier 表
CREATE TABLE IF NOT EXISTS tb_shop_series_commission_tier (
id SERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP WITH TIME ZONE,
creator INT NOT NULL DEFAULT 0,
updater INT NOT NULL DEFAULT 0,
allocation_id INT NOT NULL,
tier_type VARCHAR(20) NOT NULL,
period_type VARCHAR(20) NOT NULL,
period_start_date TIMESTAMP WITH TIME ZONE,
period_end_date TIMESTAMP WITH TIME ZONE,
threshold_value BIGINT NOT NULL,
commission_mode VARCHAR(20) NOT NULL DEFAULT 'percent',
commission_value BIGINT NOT NULL
);
COMMENT ON COLUMN tb_shop_series_commission_tier.tier_type IS '梯度类型 sales_count-销量 sales_amount-销售额';
COMMENT ON COLUMN tb_shop_series_commission_tier.period_type IS '周期类型 monthly-月度 quarterly-季度 yearly-年度 custom-自定义';
COMMENT ON COLUMN tb_shop_series_commission_tier.period_start_date IS '自定义周期开始日期';
COMMENT ON COLUMN tb_shop_series_commission_tier.period_end_date IS '自定义周期结束日期';
COMMENT ON COLUMN tb_shop_series_commission_tier.threshold_value IS '阈值(销量或金额分)';
COMMENT ON COLUMN tb_shop_series_commission_tier.commission_mode IS '达标后返佣模式 fixed-固定金额 percent-百分比';
COMMENT ON COLUMN tb_shop_series_commission_tier.commission_value IS '达标后返佣值(分或千分比)';
CREATE INDEX IF NOT EXISTS idx_tier_allocation_id ON tb_shop_series_commission_tier(allocation_id);
CREATE INDEX IF NOT EXISTS idx_tier_deleted_at ON tb_shop_series_commission_tier(deleted_at);
-- 2. 恢复 tb_shop_series_allocation 表的 enable_tier_commission 字段
ALTER TABLE tb_shop_series_allocation ADD COLUMN IF NOT EXISTS enable_tier_commission BOOLEAN NOT NULL DEFAULT FALSE;
COMMENT ON COLUMN tb_shop_series_allocation.enable_tier_commission IS '是否启用梯度返佣';
-- 3. 恢复 tb_shop_series_allocation_config 表的 enable_tier_commission 字段
ALTER TABLE tb_shop_series_allocation_config ADD COLUMN IF NOT EXISTS enable_tier_commission BOOLEAN NOT NULL;
COMMENT ON COLUMN tb_shop_series_allocation_config.enable_tier_commission IS '是否启用梯度返佣(配置快照)';

View File

@@ -0,0 +1,11 @@
-- 删除梯度返佣(TierCommission)相关的表和字段
-- 本次变更将简化佣金配置模型,只保留基础返佣和一次性佣金两种机制
-- 1. 删除 tb_shop_series_allocation 表的 enable_tier_commission 字段
ALTER TABLE tb_shop_series_allocation DROP COLUMN IF EXISTS enable_tier_commission;
-- 2. 删除 tb_shop_series_allocation_config 表的 enable_tier_commission 字段
ALTER TABLE tb_shop_series_allocation_config DROP COLUMN IF EXISTS enable_tier_commission;
-- 3. 删除 tb_shop_series_commission_tier 表
DROP TABLE IF EXISTS tb_shop_series_commission_tier;

View File

@@ -0,0 +1,3 @@
-- 回滚: 删除 tb_order 表的 is_purchase_on_behalf 字段
ALTER TABLE tb_order DROP COLUMN IF EXISTS is_purchase_on_behalf;

View File

@@ -0,0 +1,6 @@
-- 为 tb_order 表添加代购标志字段
-- 用于标识订单是否为代购订单
ALTER TABLE tb_order ADD COLUMN is_purchase_on_behalf BOOLEAN DEFAULT false;
COMMENT ON COLUMN tb_order.is_purchase_on_behalf IS '是否为代购订单';

View File

@@ -0,0 +1,4 @@
-- 回滚: 删除 tb_shop_series_allocation 表的强充配置字段
ALTER TABLE tb_shop_series_allocation DROP COLUMN IF EXISTS enable_force_recharge;
ALTER TABLE tb_shop_series_allocation DROP COLUMN IF EXISTS force_recharge_amount;

View File

@@ -0,0 +1,8 @@
-- 为 tb_shop_series_allocation 表添加强充配置字段
-- 用于支持强制充值功能
ALTER TABLE tb_shop_series_allocation ADD COLUMN enable_force_recharge BOOLEAN DEFAULT false;
ALTER TABLE tb_shop_series_allocation ADD COLUMN force_recharge_amount BIGINT DEFAULT 0;
COMMENT ON COLUMN tb_shop_series_allocation.enable_force_recharge IS '是否启用强制充值';
COMMENT ON COLUMN tb_shop_series_allocation.force_recharge_amount IS '强制充值金额(分)';

View File

@@ -0,0 +1,3 @@
-- 回滚: 删除强充触发类型字段
ALTER TABLE tb_shop_series_allocation DROP COLUMN force_recharge_trigger_type;

View File

@@ -0,0 +1,6 @@
-- 为 tb_shop_series_allocation 表添加强充触发类型字段
-- 补充强充配置完整性
ALTER TABLE tb_shop_series_allocation ADD COLUMN force_recharge_trigger_type INT DEFAULT 2;
COMMENT ON COLUMN tb_shop_series_allocation.force_recharge_trigger_type IS '强充触发类型(1:单次充值, 2:累计充值)';

View File

@@ -0,0 +1,9 @@
-- 回滚: 将 series_id 改回 series_allocation_id
ALTER TABLE tb_iot_card RENAME COLUMN series_id TO series_allocation_id;
COMMENT ON COLUMN tb_iot_card.series_allocation_id IS '套餐系列分配ID(关联ShopSeriesAllocation)';
ALTER TABLE tb_device RENAME COLUMN series_id TO series_allocation_id;
COMMENT ON COLUMN tb_device.series_allocation_id IS '套餐系列分配ID(关联ShopSeriesAllocation)';
-- 删除索引(如果存在)
DROP INDEX IF EXISTS idx_shop_series_allocation_shop_series;

View File

@@ -0,0 +1,13 @@
-- 重构: 将卡/设备的套餐系列绑定从分配ID改为系列ID
-- 重命名 tb_iot_card.series_allocation_id 为 series_id
ALTER TABLE tb_iot_card RENAME COLUMN series_allocation_id TO series_id;
COMMENT ON COLUMN tb_iot_card.series_id IS '套餐系列ID(关联PackageSeries)';
-- 重命名 tb_device.series_allocation_id 为 series_id
ALTER TABLE tb_device RENAME COLUMN series_allocation_id TO series_id;
COMMENT ON COLUMN tb_device.series_id IS '套餐系列ID(关联PackageSeries)';
-- 验证并添加复合索引(如果不存在)
CREATE INDEX IF NOT EXISTS idx_shop_series_allocation_shop_series
ON tb_shop_series_allocation(shop_id, series_id)
WHERE status = 1;

View File

@@ -0,0 +1,7 @@
-- 删除账号操作审计日志表的索引
DROP INDEX IF EXISTS idx_account_log_operator;
DROP INDEX IF EXISTS idx_account_log_target;
DROP INDEX IF EXISTS idx_account_log_created;
-- 删除账号操作审计日志表
DROP TABLE IF EXISTS tb_account_operation_log;

View File

@@ -0,0 +1,49 @@
-- 创建账号操作审计日志表
CREATE TABLE tb_account_operation_log (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- 操作主体
operator_id BIGINT NOT NULL, -- 操作人 ID
operator_type INT NOT NULL, -- 操作人类型 (1=超管 2=平台 3=代理 4=企业)
operator_name VARCHAR(255) NOT NULL, -- 操作人用户名
-- 操作对象
target_account_id BIGINT, -- 目标账号 ID可选删除操作后可能查不到
target_username VARCHAR(255), -- 目标账号用户名
target_user_type INT, -- 目标账号类型
-- 操作内容
operation_type VARCHAR(50) NOT NULL, -- create/update/delete/assign_roles/remove_role
operation_desc TEXT NOT NULL, -- 操作描述(中文)
-- 变更详情JSON 格式)
before_data JSONB, -- 变更前数据update 操作)
after_data JSONB, -- 变更后数据create/update 操作)
-- 请求上下文
request_id VARCHAR(255), -- 请求 ID关联访问日志
ip_address VARCHAR(50), -- 操作 IP
user_agent TEXT -- User-Agent
);
-- 创建索引优化查询性能
CREATE INDEX idx_account_log_operator ON tb_account_operation_log(operator_id, created_at);
CREATE INDEX idx_account_log_target ON tb_account_operation_log(target_account_id, created_at);
CREATE INDEX idx_account_log_created ON tb_account_operation_log(created_at DESC);
-- 添加表注释
COMMENT ON TABLE tb_account_operation_log IS '账号操作审计日志表';
COMMENT ON COLUMN tb_account_operation_log.operator_id IS '操作人ID';
COMMENT ON COLUMN tb_account_operation_log.operator_type IS '操作人类型: 1=超级管理员 2=平台用户 3=代理账号 4=企业账号';
COMMENT ON COLUMN tb_account_operation_log.operator_name IS '操作人用户名';
COMMENT ON COLUMN tb_account_operation_log.target_account_id IS '目标账号ID';
COMMENT ON COLUMN tb_account_operation_log.target_username IS '目标账号用户名';
COMMENT ON COLUMN tb_account_operation_log.target_user_type IS '目标账号类型';
COMMENT ON COLUMN tb_account_operation_log.operation_type IS '操作类型: create/update/delete/assign_roles/remove_role';
COMMENT ON COLUMN tb_account_operation_log.operation_desc IS '操作描述(中文)';
COMMENT ON COLUMN tb_account_operation_log.before_data IS '变更前数据JSONB格式用于update操作';
COMMENT ON COLUMN tb_account_operation_log.after_data IS '变更后数据JSONB格式用于create/update操作';
COMMENT ON COLUMN tb_account_operation_log.request_id IS '请求ID可关联访问日志';
COMMENT ON COLUMN tb_account_operation_log.ip_address IS '操作来源IP地址';
COMMENT ON COLUMN tb_account_operation_log.user_agent IS '用户代理(浏览器信息)';

View File

@@ -0,0 +1,8 @@
-- 删除索引
DROP INDEX IF EXISTS idx_shop_role_deleted_at;
DROP INDEX IF EXISTS idx_shop_role_role_id;
DROP INDEX IF EXISTS idx_shop_role_shop_id;
DROP INDEX IF EXISTS idx_shop_role_shop_id_role_id;
-- 删除表
DROP TABLE IF EXISTS tb_shop_role;

View File

@@ -0,0 +1,31 @@
-- 创建店铺角色关联表
CREATE TABLE tb_shop_role (
id SERIAL PRIMARY KEY,
shop_id INT NOT NULL,
role_id INT NOT NULL,
status INT NOT NULL DEFAULT 1, -- 0=禁用 1=启用
creator INT NOT NULL,
updater INT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP
);
-- 创建唯一索引
CREATE UNIQUE INDEX idx_shop_role_shop_id_role_id ON tb_shop_role(shop_id, role_id) WHERE deleted_at IS NULL;
-- 创建索引
CREATE INDEX idx_shop_role_shop_id ON tb_shop_role(shop_id) WHERE deleted_at IS NULL;
CREATE INDEX idx_shop_role_role_id ON tb_shop_role(role_id) WHERE deleted_at IS NULL;
CREATE INDEX idx_shop_role_deleted_at ON tb_shop_role(deleted_at);
-- 添加注释
COMMENT ON TABLE tb_shop_role IS '店铺角色关联表';
COMMENT ON COLUMN tb_shop_role.shop_id IS '店铺ID';
COMMENT ON COLUMN tb_shop_role.role_id IS '角色ID';
COMMENT ON COLUMN tb_shop_role.status IS '状态 0=禁用 1=启用';
COMMENT ON COLUMN tb_shop_role.creator IS '创建人ID';
COMMENT ON COLUMN tb_shop_role.updater IS '更新人ID';
COMMENT ON COLUMN tb_shop_role.created_at IS '创建时间';
COMMENT ON COLUMN tb_shop_role.updated_at IS '更新时间';
COMMENT ON COLUMN tb_shop_role.deleted_at IS '软删除时间';

View File

@@ -0,0 +1,10 @@
-- 回滚:恢复 card_type 字段
-- 注意:回滚后字段值为空,需要手动填充数据
-- 恢复 IoT 卡表的 card_type 列
ALTER TABLE tb_iot_card ADD COLUMN card_type VARCHAR(50);
COMMENT ON COLUMN tb_iot_card.card_type IS '卡类型(已废弃,仅用于回滚)';
-- 恢复号卡表的 card_type 列
ALTER TABLE tb_number_card ADD COLUMN card_type VARCHAR(50);
COMMENT ON COLUMN tb_number_card.card_type IS '号卡类型(已废弃,仅用于回滚)';

View File

@@ -0,0 +1,9 @@
-- 删除 IoT 卡和号卡表中无用的 card_type 字段
-- 原因:该字段设计为存储技术规格("4G"、"5G"、"NB-IoT"),但实际业务中完全未使用
-- 影响:无业务逻辑依赖该字段,删除不影响现有功能
-- 删除 IoT 卡表的 card_type 列
ALTER TABLE tb_iot_card DROP COLUMN IF EXISTS card_type;
-- 删除号卡表的 card_type 列
ALTER TABLE tb_number_card DROP COLUMN IF EXISTS card_type;

View File

@@ -0,0 +1,95 @@
-- 套餐与佣金模型重构 - 回滚
-- 注意:此回滚会丢失新增字段的数据
-- ============================================
-- 7. ShopSeriesAllocation 表恢复废弃字段
-- ============================================
-- 移除新增的字段
ALTER TABLE tb_shop_series_allocation
DROP COLUMN IF EXISTS one_time_commission_amount;
-- 恢复一次性佣金完整配置字段
ALTER TABLE tb_shop_series_allocation
ADD COLUMN IF NOT EXISTS enable_one_time_commission BOOLEAN DEFAULT false NOT NULL,
ADD COLUMN IF NOT EXISTS one_time_commission_type VARCHAR(20),
ADD COLUMN IF NOT EXISTS one_time_commission_trigger VARCHAR(30),
ADD COLUMN IF NOT EXISTS one_time_commission_threshold BIGINT DEFAULT 0,
ADD COLUMN IF NOT EXISTS one_time_commission_mode VARCHAR(20),
ADD COLUMN IF NOT EXISTS one_time_commission_value BIGINT DEFAULT 0,
ADD COLUMN IF NOT EXISTS enable_force_recharge BOOLEAN DEFAULT false,
ADD COLUMN IF NOT EXISTS force_recharge_amount BIGINT DEFAULT 0,
ADD COLUMN IF NOT EXISTS force_recharge_trigger_type INT DEFAULT 2;
-- ============================================
-- 6. ShopSeriesOneTimeCommissionTier 表移除统计范围
-- ============================================
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_name = 'tb_shop_series_one_time_commission_tier'
) THEN
ALTER TABLE tb_shop_series_one_time_commission_tier
DROP COLUMN IF EXISTS stat_scope;
END IF;
END $$;
-- ============================================
-- 5. PackageSeries 表移除一次性佣金规则配置
-- ============================================
ALTER TABLE tb_package_series
DROP COLUMN IF EXISTS one_time_commission_config;
-- ============================================
-- 4. Device 表移除追踪字段
-- ============================================
ALTER TABLE tb_device
DROP COLUMN IF EXISTS accumulated_recharge_by_series,
DROP COLUMN IF EXISTS first_recharge_triggered_by_series;
-- ============================================
-- 3. IoTCard 表移除追踪字段
-- ============================================
ALTER TABLE tb_iot_card
DROP COLUMN IF EXISTS accumulated_recharge_by_series,
DROP COLUMN IF EXISTS first_recharge_triggered_by_series;
-- ============================================
-- 2. ShopPackageAllocation 表移除字段
-- ============================================
ALTER TABLE tb_shop_package_allocation
DROP COLUMN IF EXISTS one_time_commission_amount;
-- ============================================
-- 1. Package 表恢复废弃字段
-- ============================================
-- 移除虚流量开关字段
ALTER TABLE tb_package
DROP COLUMN IF EXISTS enable_virtual_data;
-- 恢复 cost_price 为 suggested_cost_price
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'tb_package' AND column_name = 'cost_price'
) AND NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'tb_package' AND column_name = 'suggested_cost_price'
) THEN
ALTER TABLE tb_package RENAME COLUMN cost_price TO suggested_cost_price;
END IF;
END $$;
-- 恢复废弃字段
ALTER TABLE tb_package
ADD COLUMN IF NOT EXISTS price BIGINT DEFAULT 0 NOT NULL,
ADD COLUMN IF NOT EXISTS data_type VARCHAR(20),
ADD COLUMN IF NOT EXISTS data_amount_mb BIGINT DEFAULT 0;

View File

@@ -0,0 +1,126 @@
-- 套餐与佣金模型重构
-- 重构说明:
-- 1. Package 表:移除废弃字段,新增虚流量开关
-- 2. ShopPackageAllocation 表:新增一次性佣金金额字段
-- 3. IoTCard/Device 表:新增按系列追踪的累计充值和首充状态字段
-- 4. PackageSeries 表:新增一次性佣金规则配置字段
-- 5. ShopSeriesOneTimeCommissionTier 表:新增统计范围字段
-- 6. ShopSeriesAllocation 表:移除完整一次性佣金配置,改为只存金额
-- ============================================
-- 1. Package 表调整
-- ============================================
-- 移除废弃字段
ALTER TABLE tb_package
DROP COLUMN IF EXISTS price,
DROP COLUMN IF EXISTS data_type,
DROP COLUMN IF EXISTS data_amount_mb;
-- 新增虚流量开关字段
ALTER TABLE tb_package
ADD COLUMN IF NOT EXISTS enable_virtual_data BOOLEAN DEFAULT false NOT NULL;
COMMENT ON COLUMN tb_package.enable_virtual_data IS '是否启用虚流量';
-- 重命名 suggested_cost_price 为 cost_price如果存在的话通过 RENAME 实现)
-- 注意PostgreSQL 不支持条件性重命名,此处直接重命名
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'tb_package' AND column_name = 'suggested_cost_price'
) THEN
ALTER TABLE tb_package RENAME COLUMN suggested_cost_price TO cost_price;
END IF;
END $$;
COMMENT ON COLUMN tb_package.cost_price IS '成本价(分为单位)';
-- ============================================
-- 2. ShopPackageAllocation 表新增字段
-- ============================================
ALTER TABLE tb_shop_package_allocation
ADD COLUMN IF NOT EXISTS one_time_commission_amount BIGINT DEFAULT 0 NOT NULL;
COMMENT ON COLUMN tb_shop_package_allocation.one_time_commission_amount IS '该代理能拿到的一次性佣金(分)';
-- ============================================
-- 3. IoTCard 表新增追踪字段
-- ============================================
-- 新增按系列追踪的累计充值字段JSON Map: series_id -> amount
ALTER TABLE tb_iot_card
ADD COLUMN IF NOT EXISTS accumulated_recharge_by_series JSONB DEFAULT '{}';
-- 新增按系列追踪的首充触发状态JSON Map: series_id -> bool
ALTER TABLE tb_iot_card
ADD COLUMN IF NOT EXISTS first_recharge_triggered_by_series JSONB DEFAULT '{}';
COMMENT ON COLUMN tb_iot_card.accumulated_recharge_by_series IS '按套餐系列追踪的累计充值金额JSON Map: series_id -> amount 分)';
COMMENT ON COLUMN tb_iot_card.first_recharge_triggered_by_series IS '按套餐系列追踪的首充触发状态JSON Map: series_id -> bool';
-- ============================================
-- 4. Device 表新增追踪字段
-- ============================================
-- 新增按系列追踪的累计充值字段
ALTER TABLE tb_device
ADD COLUMN IF NOT EXISTS accumulated_recharge_by_series JSONB DEFAULT '{}';
-- 新增按系列追踪的首充触发状态
ALTER TABLE tb_device
ADD COLUMN IF NOT EXISTS first_recharge_triggered_by_series JSONB DEFAULT '{}';
COMMENT ON COLUMN tb_device.accumulated_recharge_by_series IS '按套餐系列追踪的累计充值金额JSON Map: series_id -> amount 分)';
COMMENT ON COLUMN tb_device.first_recharge_triggered_by_series IS '按套餐系列追踪的首充触发状态JSON Map: series_id -> bool';
-- ============================================
-- 5. PackageSeries 表新增一次性佣金规则配置
-- ============================================
ALTER TABLE tb_package_series
ADD COLUMN IF NOT EXISTS one_time_commission_config JSONB;
COMMENT ON COLUMN tb_package_series.one_time_commission_config IS '一次性佣金规则配置JSONenable, trigger_type, threshold, commission_type, commission_amount, validity_type 等)';
-- ============================================
-- 6. ShopSeriesOneTimeCommissionTier 表新增统计范围
-- ============================================
-- 检查表是否存在,存在则添加字段
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_name = 'tb_shop_series_one_time_commission_tier'
) THEN
ALTER TABLE tb_shop_series_one_time_commission_tier
ADD COLUMN IF NOT EXISTS stat_scope VARCHAR(20) DEFAULT 'self' NOT NULL;
COMMENT ON COLUMN tb_shop_series_one_time_commission_tier.stat_scope IS '统计范围 self-仅自己 self_and_sub-自己+下级';
END IF;
END $$;
-- ============================================
-- 7. ShopSeriesAllocation 表移除废弃字段,新增新字段
-- ============================================
-- 移除一次性佣金完整配置字段
ALTER TABLE tb_shop_series_allocation
DROP COLUMN IF EXISTS enable_one_time_commission,
DROP COLUMN IF EXISTS one_time_commission_type,
DROP COLUMN IF EXISTS one_time_commission_trigger,
DROP COLUMN IF EXISTS one_time_commission_threshold,
DROP COLUMN IF EXISTS one_time_commission_mode,
DROP COLUMN IF EXISTS one_time_commission_value,
DROP COLUMN IF EXISTS enable_force_recharge,
DROP COLUMN IF EXISTS force_recharge_amount,
DROP COLUMN IF EXISTS force_recharge_trigger_type;
-- 新增一次性佣金金额字段
ALTER TABLE tb_shop_series_allocation
ADD COLUMN IF NOT EXISTS one_time_commission_amount BIGINT DEFAULT 0 NOT NULL;
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_amount IS '给被分配店铺的一次性佣金金额(分)';

View File

@@ -0,0 +1,68 @@
-- 回滚:恢复 ShopSeriesAllocation 层
-- ============================================
-- 1. 重建 ShopSeriesAllocation 表
-- ============================================
CREATE TABLE IF NOT EXISTS tb_shop_series_allocation (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT NOT NULL DEFAULT 0,
updater BIGINT NOT NULL DEFAULT 0,
shop_id BIGINT NOT NULL,
series_id BIGINT NOT NULL,
allocator_shop_id BIGINT NOT NULL DEFAULT 0,
cost_price_markup BIGINT NOT NULL DEFAULT 0,
one_time_commission_amount BIGINT NOT NULL DEFAULT 0,
status INTEGER NOT NULL DEFAULT 1
);
COMMENT ON TABLE tb_shop_series_allocation IS '店铺系列分配表';
COMMENT ON COLUMN tb_shop_series_allocation.shop_id IS '被分配店铺ID';
COMMENT ON COLUMN tb_shop_series_allocation.series_id IS '套餐系列ID';
COMMENT ON COLUMN tb_shop_series_allocation.allocator_shop_id IS '分配者店铺ID0表示平台分配';
COMMENT ON COLUMN tb_shop_series_allocation.cost_price_markup IS '成本价加价(分)';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_amount IS '一次性佣金金额(分)';
CREATE INDEX IF NOT EXISTS idx_shop_series_allocation_shop_id ON tb_shop_series_allocation(shop_id);
CREATE INDEX IF NOT EXISTS idx_shop_series_allocation_series_id ON tb_shop_series_allocation(series_id);
-- ============================================
-- 2. 重建 ShopSeriesAllocationConfig 表
-- ============================================
CREATE TABLE IF NOT EXISTS tb_shop_series_allocation_config (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT NOT NULL DEFAULT 0,
updater BIGINT NOT NULL DEFAULT 0,
allocation_id BIGINT NOT NULL,
config_type VARCHAR(50) NOT NULL,
config_value JSONB
);
COMMENT ON TABLE tb_shop_series_allocation_config IS '店铺系列分配配置表';
-- ============================================
-- 3. 恢复 allocation_id 字段
-- ============================================
ALTER TABLE tb_shop_package_allocation
ADD COLUMN IF NOT EXISTS allocation_id BIGINT NOT NULL DEFAULT 0;
-- ============================================
-- 4. 删除新增的字段
-- ============================================
DROP INDEX IF EXISTS idx_shop_package_allocation_series_id;
DROP INDEX IF EXISTS idx_shop_package_allocation_allocator_shop_id;
ALTER TABLE tb_shop_package_allocation
DROP COLUMN IF EXISTS series_id;
ALTER TABLE tb_shop_package_allocation
DROP COLUMN IF EXISTS allocator_shop_id;

View File

@@ -0,0 +1,61 @@
-- 简化佣金分配模型:删除 ShopSeriesAllocation 层,使用 ShopPackageAllocation 直接管理
-- 重构原因:业务模型只需要套餐级别的分配,不需要系列级别的中间层
-- ============================================
-- 1. 为 ShopPackageAllocation 添加新字段
-- ============================================
-- 添加 series_id 字段(记录套餐所属系列,便于查询)
ALTER TABLE tb_shop_package_allocation
ADD COLUMN IF NOT EXISTS series_id BIGINT DEFAULT 0 NOT NULL;
COMMENT ON COLUMN tb_shop_package_allocation.series_id IS '套餐系列ID冗余字段便于查询';
-- 添加 allocator_shop_id 字段记录是谁分配的0表示平台分配
ALTER TABLE tb_shop_package_allocation
ADD COLUMN IF NOT EXISTS allocator_shop_id BIGINT DEFAULT 0 NOT NULL;
COMMENT ON COLUMN tb_shop_package_allocation.allocator_shop_id IS '分配者店铺ID0表示平台分配';
-- ============================================
-- 2. 从现有数据迁移 series_id 和 allocator_shop_id
-- ============================================
-- 通过 package 表获取 series_id
UPDATE tb_shop_package_allocation spa
SET series_id = p.series_id
FROM tb_package p
WHERE spa.package_id = p.id AND spa.series_id = 0;
-- 通过 shop_series_allocation 获取 allocator_shop_id
UPDATE tb_shop_package_allocation spa
SET allocator_shop_id = ssa.allocator_shop_id
FROM tb_shop_series_allocation ssa
WHERE spa.allocation_id = ssa.id AND spa.allocator_shop_id = 0;
-- ============================================
-- 3. 删除废弃的 allocation_id 字段
-- ============================================
ALTER TABLE tb_shop_package_allocation
DROP COLUMN IF EXISTS allocation_id;
-- ============================================
-- 4. 添加索引优化查询性能
-- ============================================
CREATE INDEX IF NOT EXISTS idx_shop_package_allocation_series_id
ON tb_shop_package_allocation(series_id);
CREATE INDEX IF NOT EXISTS idx_shop_package_allocation_allocator_shop_id
ON tb_shop_package_allocation(allocator_shop_id);
-- ============================================
-- 5. 删除废弃的表
-- ============================================
-- 删除系列分配配置表
DROP TABLE IF EXISTS tb_shop_series_allocation_config;
-- 删除系列分配表
DROP TABLE IF EXISTS tb_shop_series_allocation;

View File

@@ -0,0 +1,54 @@
-- 回滚:恢复原有结构
-- ============================================
-- 1. 恢复 tb_shop_package_allocation 字段
-- ============================================
-- 恢复 series_id 字段
ALTER TABLE tb_shop_package_allocation
ADD COLUMN IF NOT EXISTS series_id BIGINT NOT NULL DEFAULT 0;
COMMENT ON COLUMN tb_shop_package_allocation.series_id IS '套餐系列ID冗余字段便于查询';
-- 恢复 one_time_commission_amount 字段
ALTER TABLE tb_shop_package_allocation
ADD COLUMN IF NOT EXISTS one_time_commission_amount BIGINT NOT NULL DEFAULT 0;
COMMENT ON COLUMN tb_shop_package_allocation.one_time_commission_amount IS '该代理能拿到的一次性佣金(分)';
-- 删除 series_allocation_id 字段
DROP INDEX IF EXISTS idx_shop_package_allocation_series_allocation_id;
ALTER TABLE tb_shop_package_allocation
DROP COLUMN IF EXISTS series_allocation_id;
-- ============================================
-- 2. 恢复 tb_shop_series_one_time_commission_tier 表
-- ============================================
CREATE TABLE IF NOT EXISTS tb_shop_series_one_time_commission_tier (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT NOT NULL DEFAULT 0,
updater BIGINT NOT NULL DEFAULT 0,
allocation_id BIGINT NOT NULL,
tier_type VARCHAR(50) NOT NULL,
threshold_value BIGINT NOT NULL DEFAULT 0,
commission_mode VARCHAR(20) NOT NULL DEFAULT 'fixed',
commission_value BIGINT NOT NULL DEFAULT 0,
stat_scope VARCHAR(50) NOT NULL DEFAULT 'self',
status INT NOT NULL DEFAULT 1
);
CREATE INDEX IF NOT EXISTS idx_shop_series_otc_tier_allocation_id
ON tb_shop_series_one_time_commission_tier(allocation_id);
COMMENT ON TABLE tb_shop_series_one_time_commission_tier IS '一次性佣金梯度配置表';
-- ============================================
-- 3. 删除 tb_shop_series_allocation 表
-- ============================================
DROP TABLE IF EXISTS tb_shop_series_allocation;

View File

@@ -0,0 +1,77 @@
-- 重构一次性佣金分配:恢复系列分配表,移除套餐分配中的佣金字段
-- 原因:一次性佣金是系列级概念,不应存储在套餐分配中
-- ============================================
-- 1. 创建 tb_shop_series_allocation 表
-- ============================================
CREATE TABLE IF NOT EXISTS tb_shop_series_allocation (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
deleted_at TIMESTAMPTZ,
creator BIGINT NOT NULL DEFAULT 0,
updater BIGINT NOT NULL DEFAULT 0,
shop_id BIGINT NOT NULL,
series_id BIGINT NOT NULL,
allocator_shop_id BIGINT NOT NULL DEFAULT 0,
one_time_commission_amount BIGINT NOT NULL DEFAULT 0,
enable_one_time_commission BOOLEAN NOT NULL DEFAULT false,
one_time_commission_trigger VARCHAR(50),
one_time_commission_threshold BIGINT NOT NULL DEFAULT 0,
enable_force_recharge BOOLEAN NOT NULL DEFAULT false,
force_recharge_amount BIGINT NOT NULL DEFAULT 0,
force_recharge_trigger_type INT NOT NULL DEFAULT 2,
status INT NOT NULL DEFAULT 1
);
-- 索引
CREATE INDEX IF NOT EXISTS idx_shop_series_allocation_shop_id
ON tb_shop_series_allocation(shop_id);
CREATE INDEX IF NOT EXISTS idx_shop_series_allocation_series_id
ON tb_shop_series_allocation(series_id);
CREATE INDEX IF NOT EXISTS idx_shop_series_allocation_allocator_shop_id
ON tb_shop_series_allocation(allocator_shop_id);
CREATE UNIQUE INDEX IF NOT EXISTS idx_shop_series_allocation_shop_series
ON tb_shop_series_allocation(shop_id, series_id) WHERE deleted_at IS NULL;
-- 注释
COMMENT ON TABLE tb_shop_series_allocation IS '店铺系列分配表 - 管理系列级一次性佣金配置';
COMMENT ON COLUMN tb_shop_series_allocation.shop_id IS '被分配店铺ID';
COMMENT ON COLUMN tb_shop_series_allocation.series_id IS '套餐系列ID';
COMMENT ON COLUMN tb_shop_series_allocation.allocator_shop_id IS '分配者店铺ID0表示平台分配';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_amount IS '该代理能拿的一次性佣金金额上限(分)';
COMMENT ON COLUMN tb_shop_series_allocation.enable_one_time_commission IS '是否启用一次性佣金';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_trigger IS '一次性佣金触发类型 first_recharge-首次充值 accumulated_recharge-累计充值';
COMMENT ON COLUMN tb_shop_series_allocation.one_time_commission_threshold IS '一次性佣金触发阈值(分)';
COMMENT ON COLUMN tb_shop_series_allocation.enable_force_recharge IS '是否启用强制充值';
COMMENT ON COLUMN tb_shop_series_allocation.force_recharge_amount IS '强制充值金额(分)';
COMMENT ON COLUMN tb_shop_series_allocation.force_recharge_trigger_type IS '强充触发类型 1-单次充值 2-累计充值';
COMMENT ON COLUMN tb_shop_series_allocation.status IS '状态 1-启用 2-禁用';
-- ============================================
-- 2. 修改 tb_shop_package_allocation 表
-- ============================================
-- 添加 series_allocation_id 字段(如果不存在)
ALTER TABLE tb_shop_package_allocation
ADD COLUMN IF NOT EXISTS series_allocation_id BIGINT;
COMMENT ON COLUMN tb_shop_package_allocation.series_allocation_id IS '关联的系列分配ID';
CREATE INDEX IF NOT EXISTS idx_shop_package_allocation_series_allocation_id
ON tb_shop_package_allocation(series_allocation_id);
-- 删除 one_time_commission_amount 字段(佣金配置移到系列分配)
ALTER TABLE tb_shop_package_allocation
DROP COLUMN IF EXISTS one_time_commission_amount;
-- 删除 series_id 字段(通过 series_allocation_id 关联)
ALTER TABLE tb_shop_package_allocation
DROP COLUMN IF EXISTS series_id;
-- ============================================
-- 3. 删除 tb_shop_series_one_time_commission_tier 表(未使用)
-- ============================================
DROP TABLE IF EXISTS tb_shop_series_one_time_commission_tier;

View File

@@ -0,0 +1,4 @@
DROP INDEX IF EXISTS idx_package_series_enable_one_time_commission;
ALTER TABLE tb_package_series
DROP COLUMN IF EXISTS enable_one_time_commission;

View File

@@ -0,0 +1,10 @@
-- 修复tb_package_series 表添加 enable_one_time_commission 字段
-- 该字段在 000042 迁移中被删除,但按新设计需要在系列级启用/禁用一次性佣金
ALTER TABLE tb_package_series
ADD COLUMN IF NOT EXISTS enable_one_time_commission BOOLEAN NOT NULL DEFAULT false;
COMMENT ON COLUMN tb_package_series.enable_one_time_commission IS '是否启用一次性佣金顶层字段支持SQL索引';
CREATE INDEX IF NOT EXISTS idx_package_series_enable_one_time_commission
ON tb_package_series(enable_one_time_commission);

View File

@@ -0,0 +1,2 @@
-- 删除轮询配置表
DROP TABLE IF EXISTS tb_polling_config;

View File

@@ -0,0 +1,44 @@
-- 轮询配置表
-- 先删除旧表(如果存在)
DROP TABLE IF EXISTS tb_polling_config CASCADE;
CREATE TABLE tb_polling_config (
id BIGSERIAL PRIMARY KEY,
config_name VARCHAR(100) NOT NULL,
card_condition VARCHAR(50),
card_category VARCHAR(50),
carrier_id BIGINT,
priority INT NOT NULL DEFAULT 100,
realname_check_interval INT,
carddata_check_interval INT,
package_check_interval INT,
status SMALLINT NOT NULL DEFAULT 1,
description TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_by BIGINT,
updated_by BIGINT
);
-- 索引
CREATE INDEX idx_polling_config_status_priority ON tb_polling_config(status, priority);
CREATE INDEX idx_polling_config_carrier_id ON tb_polling_config(carrier_id);
-- 表注释
COMMENT ON TABLE tb_polling_config IS '轮询配置表 - 定义不同条件下的卡轮询策略';
-- 列注释
COMMENT ON COLUMN tb_polling_config.config_name IS '配置名称';
COMMENT ON COLUMN tb_polling_config.card_condition IS '卡状态条件not_real_name/real_name/activated/suspended';
COMMENT ON COLUMN tb_polling_config.card_category IS '卡业务类型normal/industry';
COMMENT ON COLUMN tb_polling_config.carrier_id IS '运营商ID可选精确匹配';
COMMENT ON COLUMN tb_polling_config.priority IS '优先级(数字越小优先级越高)';
COMMENT ON COLUMN tb_polling_config.realname_check_interval IS '实名检查间隔NULL表示不检查';
COMMENT ON COLUMN tb_polling_config.carddata_check_interval IS '流量检查间隔NULL表示不检查';
COMMENT ON COLUMN tb_polling_config.package_check_interval IS '套餐检查间隔NULL表示不检查';
COMMENT ON COLUMN tb_polling_config.status IS '状态0-禁用1-启用';
COMMENT ON COLUMN tb_polling_config.description IS '配置说明';
COMMENT ON COLUMN tb_polling_config.created_at IS '创建时间';
COMMENT ON COLUMN tb_polling_config.updated_at IS '更新时间';
COMMENT ON COLUMN tb_polling_config.created_by IS '创建人ID';
COMMENT ON COLUMN tb_polling_config.updated_by IS '更新人ID';

View File

@@ -0,0 +1,2 @@
-- 删除并发控制配置表
DROP TABLE IF EXISTS tb_polling_concurrency_config;

View File

@@ -0,0 +1,24 @@
-- 并发控制配置表
CREATE TABLE IF NOT EXISTS tb_polling_concurrency_config (
id BIGSERIAL PRIMARY KEY,
task_type VARCHAR(50) NOT NULL UNIQUE,
max_concurrency INT NOT NULL DEFAULT 50,
description TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_by BIGINT
);
-- 索引
CREATE INDEX idx_polling_concurrency_task_type ON tb_polling_concurrency_config(task_type);
-- 表注释
COMMENT ON TABLE tb_polling_concurrency_config IS '并发控制配置表 - 控制不同类型任务的最大并发数';
-- 列注释
COMMENT ON COLUMN tb_polling_concurrency_config.task_type IS '任务类型realname/carddata/package/stop_start';
COMMENT ON COLUMN tb_polling_concurrency_config.max_concurrency IS '最大并发数';
COMMENT ON COLUMN tb_polling_concurrency_config.description IS '配置说明';
COMMENT ON COLUMN tb_polling_concurrency_config.created_at IS '创建时间';
COMMENT ON COLUMN tb_polling_concurrency_config.updated_at IS '更新时间';
COMMENT ON COLUMN tb_polling_concurrency_config.updated_by IS '更新人ID';

View File

@@ -0,0 +1,2 @@
-- 删除告警规则表
DROP TABLE IF EXISTS tb_polling_alert_rule;

View File

@@ -0,0 +1,45 @@
-- 告警规则表
CREATE TABLE IF NOT EXISTS tb_polling_alert_rule (
id BIGSERIAL PRIMARY KEY,
rule_name VARCHAR(100) NOT NULL,
task_type VARCHAR(50) NOT NULL,
metric_type VARCHAR(50) NOT NULL,
operator VARCHAR(20) NOT NULL,
threshold DECIMAL(10, 2) NOT NULL,
duration_minutes INT NOT NULL DEFAULT 5,
alert_level VARCHAR(20) NOT NULL DEFAULT 'warning',
notification_channels TEXT,
notification_config TEXT,
status SMALLINT NOT NULL DEFAULT 1,
cooldown_minutes INT NOT NULL DEFAULT 5,
description TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_by BIGINT,
updated_by BIGINT
);
-- 索引
CREATE INDEX idx_polling_alert_rule_status ON tb_polling_alert_rule(status);
CREATE INDEX idx_polling_alert_rule_task_type ON tb_polling_alert_rule(task_type);
-- 表注释
COMMENT ON TABLE tb_polling_alert_rule IS '告警规则表 - 定义轮询系统的告警条件和通知方式';
-- 列注释
COMMENT ON COLUMN tb_polling_alert_rule.rule_name IS '规则名称';
COMMENT ON COLUMN tb_polling_alert_rule.task_type IS '任务类型realname/carddata/package';
COMMENT ON COLUMN tb_polling_alert_rule.metric_type IS '指标类型queue_size/success_rate/avg_duration/concurrency';
COMMENT ON COLUMN tb_polling_alert_rule.operator IS '比较运算符gt/lt/gte/lte/eq';
COMMENT ON COLUMN tb_polling_alert_rule.threshold IS '阈值';
COMMENT ON COLUMN tb_polling_alert_rule.duration_minutes IS '持续时长(分钟),避免短暂波动';
COMMENT ON COLUMN tb_polling_alert_rule.alert_level IS '告警级别info/warning/error/critical';
COMMENT ON COLUMN tb_polling_alert_rule.notification_channels IS '通知渠道JSON数组["email","sms","webhook"]';
COMMENT ON COLUMN tb_polling_alert_rule.notification_config IS '通知配置JSON';
COMMENT ON COLUMN tb_polling_alert_rule.status IS '状态0-禁用1-启用';
COMMENT ON COLUMN tb_polling_alert_rule.cooldown_minutes IS '冷却期(分钟),避免重复告警';
COMMENT ON COLUMN tb_polling_alert_rule.description IS '规则说明';
COMMENT ON COLUMN tb_polling_alert_rule.created_at IS '创建时间';
COMMENT ON COLUMN tb_polling_alert_rule.updated_at IS '更新时间';
COMMENT ON COLUMN tb_polling_alert_rule.created_by IS '创建人ID';
COMMENT ON COLUMN tb_polling_alert_rule.updated_by IS '更新人ID';

View File

@@ -0,0 +1,2 @@
-- 删除告警历史表
DROP TABLE IF EXISTS tb_polling_alert_history;

View File

@@ -0,0 +1,36 @@
-- 告警历史表
CREATE TABLE IF NOT EXISTS tb_polling_alert_history (
id BIGSERIAL PRIMARY KEY,
rule_id BIGINT NOT NULL,
task_type VARCHAR(50) NOT NULL,
metric_type VARCHAR(50) NOT NULL,
alert_level VARCHAR(20) NOT NULL,
current_value DECIMAL(10, 2) NOT NULL,
threshold DECIMAL(10, 2) NOT NULL,
alert_message TEXT NOT NULL,
notification_channels TEXT,
notification_status VARCHAR(20),
notification_result TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- 索引
CREATE INDEX idx_polling_alert_history_rule_id ON tb_polling_alert_history(rule_id);
CREATE INDEX idx_polling_alert_history_created_at ON tb_polling_alert_history(created_at);
CREATE INDEX idx_polling_alert_history_task_type ON tb_polling_alert_history(task_type);
-- 表注释
COMMENT ON TABLE tb_polling_alert_history IS '告警历史表 - 记录所有触发的告警';
-- 列注释
COMMENT ON COLUMN tb_polling_alert_history.rule_id IS '告警规则ID';
COMMENT ON COLUMN tb_polling_alert_history.task_type IS '任务类型';
COMMENT ON COLUMN tb_polling_alert_history.metric_type IS '指标类型';
COMMENT ON COLUMN tb_polling_alert_history.alert_level IS '告警级别';
COMMENT ON COLUMN tb_polling_alert_history.current_value IS '当前值';
COMMENT ON COLUMN tb_polling_alert_history.threshold IS '阈值';
COMMENT ON COLUMN tb_polling_alert_history.alert_message IS '告警消息';
COMMENT ON COLUMN tb_polling_alert_history.notification_channels IS '通知渠道JSON数组';
COMMENT ON COLUMN tb_polling_alert_history.notification_status IS '通知状态pending/sent/failed';
COMMENT ON COLUMN tb_polling_alert_history.notification_result IS '通知结果JSON';
COMMENT ON COLUMN tb_polling_alert_history.created_at IS '告警时间';

Some files were not shown because too many files have changed in this diff Show More