1124 lines
47 KiB
SQL
1124 lines
47 KiB
SQL
-- ====================
|
||
-- region 日志
|
||
-- ====================
|
||
|
||
-- logs_request
|
||
drop table if exists logs_request cascade;
|
||
create table logs_request (
|
||
id int generated by default as identity primary key,
|
||
ip inet not null,
|
||
ua text not null,
|
||
user_id int,
|
||
client_id int,
|
||
method text not null,
|
||
path text not null,
|
||
status smallint not null,
|
||
error text,
|
||
time timestamptz not null,
|
||
latency text not null
|
||
);
|
||
|
||
-- logs_access表字段注释
|
||
comment on table logs_request is '访问日志表';
|
||
comment on column logs_request.id is '访问日志ID';
|
||
comment on column logs_request.ip is 'IP地址';
|
||
comment on column logs_request.ua is '用户代理';
|
||
comment on column logs_request.user_id is '用户ID';
|
||
comment on column logs_request.client_id is '客户端ID';
|
||
comment on column logs_request.method is '请求方法';
|
||
comment on column logs_request.path is '请求路径';
|
||
comment on column logs_request.status is '响应状态码';
|
||
comment on column logs_request.error is '错误信息';
|
||
comment on column logs_request.time is '请求时间';
|
||
comment on column logs_request.latency is '请求延迟';
|
||
|
||
-- logs_login
|
||
|
||
drop table if exists logs_login cascade;
|
||
create table logs_login (
|
||
id int generated by default as identity primary key,
|
||
ip inet not null,
|
||
ua text not null,
|
||
grant_type text not null,
|
||
password_type text not null,
|
||
success bool not null,
|
||
user_id int,
|
||
time timestamptz not null
|
||
);
|
||
|
||
-- logs_login表字段注释
|
||
comment on table logs_login is '登录日志表';
|
||
comment on column logs_login.id is '登录日志ID';
|
||
comment on column logs_login.user_id is '用户ID';
|
||
comment on column logs_login.ip is 'IP地址';
|
||
comment on column logs_login.ua is '用户代理';
|
||
comment on column logs_login.grant_type is '授权类型:authorization_code-授权码模式,client_credentials-客户端凭证模式,refresh_token-刷新令牌模式,password-密码模式';
|
||
comment on column logs_login.password_type is '密码模式子授权类型:password-账号密码,phone_code-手机验证码,email_code-邮箱验证码';
|
||
comment on column logs_login.success is '登录是否成功';
|
||
comment on column logs_login.time is '登录时间';
|
||
|
||
-- logs_user_usage
|
||
drop table if exists logs_user_usage cascade;
|
||
create table logs_user_usage (
|
||
id int generated by default as identity primary key,
|
||
user_id int not null,
|
||
resource_id int not null,
|
||
batch_no text not null,
|
||
count int not null,
|
||
prov text,
|
||
city text,
|
||
isp text,
|
||
ip inet not null,
|
||
time timestamptz not null
|
||
);
|
||
create index idx_logs_user_usage_user_id on logs_user_usage (user_id);
|
||
create index idx_logs_user_usage_resource_id on logs_user_usage (resource_id);
|
||
create index idx_logs_user_usage_batch_no on logs_user_usage (batch_no);
|
||
|
||
-- logs_user_usage表字段注释
|
||
comment on table logs_user_usage is '用户使用日志表';
|
||
comment on column logs_user_usage.id is '日志ID';
|
||
comment on column logs_user_usage.user_id is '用户ID';
|
||
comment on column logs_user_usage.resource_id is '套餐ID';
|
||
comment on column logs_user_usage.batch_no is '批次编号';
|
||
comment on column logs_user_usage.count is '数量';
|
||
comment on column logs_user_usage.prov is '省份';
|
||
comment on column logs_user_usage.city is '城市';
|
||
comment on column logs_user_usage.isp is '运营商';
|
||
comment on column logs_user_usage.ip is 'IP地址';
|
||
comment on column logs_user_usage.time is '提取时间';
|
||
|
||
-- logs_user_bandwidth
|
||
drop table if exists logs_user_bandwidth cascade;
|
||
create table logs_user_bandwidth (
|
||
id int generated by default as identity primary key,
|
||
user_id int not null,
|
||
bandwidth int not null,
|
||
time timestamptz not null
|
||
);
|
||
create index idx_logs_user_bandwidth_user_id on logs_user_bandwidth (user_id);
|
||
create index idx_logs_user_bandwidth_time on logs_user_bandwidth (time);
|
||
|
||
-- logs_user_bandwidth表字段注释
|
||
comment on table logs_user_bandwidth is '用户带宽日志表';
|
||
comment on column logs_user_bandwidth.id is '日志ID';
|
||
comment on column logs_user_bandwidth.user_id is '用户ID';
|
||
comment on column logs_user_bandwidth.bandwidth is '带宽使用量(KB)';
|
||
comment on column logs_user_bandwidth.time is '记录时间';
|
||
|
||
-- endregion
|
||
|
||
-- ====================
|
||
-- region 系统信息
|
||
-- ====================
|
||
|
||
-- announcement
|
||
drop table if exists announcement cascade;
|
||
create table announcement (
|
||
id int generated by default as identity primary key,
|
||
title text not null,
|
||
content text,
|
||
type int not null default 1,
|
||
pin bool not null default false,
|
||
status int not null default 1,
|
||
sort int not null default 0,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create index idx_announcement_type on announcement (type) where deleted_at is null;
|
||
create index idx_announcement_pin on announcement (pin) where deleted_at is null;
|
||
create index idx_announcement_created_at on announcement (created_at) where deleted_at is null;
|
||
|
||
-- announcement表字段注释
|
||
comment on table announcement is '公告表';
|
||
comment on column announcement.id is '公告ID';
|
||
comment on column announcement.title is '公告标题';
|
||
comment on column announcement.content is '公告内容';
|
||
comment on column announcement.type is '公告类型:1-普通公告';
|
||
comment on column announcement.status is '公告状态:0-禁用,1-正常';
|
||
comment on column announcement.pin is '是否置顶';
|
||
comment on column announcement.sort is '公告排序';
|
||
comment on column announcement.created_at is '创建时间';
|
||
comment on column announcement.updated_at is '更新时间';
|
||
comment on column announcement.deleted_at is '删除时间';
|
||
|
||
-- inquiry
|
||
drop table if exists inquiry cascade;
|
||
create table inquiry (
|
||
id int generated by default as identity primary key,
|
||
company text,
|
||
name text,
|
||
phone text,
|
||
email text,
|
||
content text,
|
||
status int not null default 0,
|
||
remark text,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create index idx_inquiry_phone on inquiry (phone) where deleted_at is null;
|
||
create index idx_inquiry_status on inquiry (status) where deleted_at is null;
|
||
create index idx_inquiry_created_at on inquiry (created_at) where deleted_at is null;
|
||
|
||
-- inquiry表字段注释
|
||
comment on table inquiry is '用户咨询表';
|
||
comment on column inquiry.id is '咨询ID';
|
||
comment on column inquiry.name is '联系人姓名';
|
||
comment on column inquiry.phone is '联系电话';
|
||
comment on column inquiry.email is '联系邮箱';
|
||
comment on column inquiry.company is '公司名称';
|
||
comment on column inquiry.content is '咨询内容';
|
||
comment on column inquiry.status is '处理状态:0-待处理,1-已处理';
|
||
comment on column inquiry.remark is '备注';
|
||
comment on column inquiry.created_at is '创建时间';
|
||
comment on column inquiry.updated_at is '更新时间';
|
||
comment on column inquiry.deleted_at is '删除时间';
|
||
|
||
-- endregion
|
||
|
||
-- ====================
|
||
-- region 管理员信息
|
||
-- ====================
|
||
|
||
-- admin
|
||
drop table if exists admin cascade;
|
||
create table admin (
|
||
id int generated by default as identity primary key,
|
||
username text not null,
|
||
password text not null,
|
||
name text,
|
||
avatar text,
|
||
phone text,
|
||
email text,
|
||
status int not null default 1,
|
||
last_login timestamptz,
|
||
last_login_ip inet,
|
||
last_login_ua text,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create unique index udx_admin_username on admin (username);
|
||
create index idx_admin_status on admin (status) where deleted_at is null;
|
||
create index idx_admin_created_at on admin (created_at) where deleted_at is null;
|
||
|
||
-- admin表字段注释
|
||
comment on table admin is '管理员表';
|
||
comment on column admin.id is '管理员ID';
|
||
comment on column admin.username is '用户名';
|
||
comment on column admin.password is '密码';
|
||
comment on column admin.name is '真实姓名';
|
||
comment on column admin.avatar is '头像URL';
|
||
comment on column admin.phone is '手机号码';
|
||
comment on column admin.email is '邮箱';
|
||
comment on column admin.status is '状态:0-禁用,1-正常';
|
||
comment on column admin.last_login is '最后登录时间';
|
||
comment on column admin.last_login_ip is '最后登录地址';
|
||
comment on column admin.last_login_ua is '最后登录代理';
|
||
comment on column admin.created_at is '创建时间';
|
||
comment on column admin.updated_at is '更新时间';
|
||
comment on column admin.deleted_at is '删除时间';
|
||
|
||
-- admin_role
|
||
drop table if exists admin_role cascade;
|
||
create table admin_role (
|
||
id int generated by default as identity primary key,
|
||
name text not null,
|
||
description text,
|
||
active bool not null default true,
|
||
sort int not null default 0,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create unique index udx_admin_role_name on admin_role (name) where deleted_at is null;
|
||
create index idx_admin_role_created_at on admin_role (created_at) where deleted_at is null;
|
||
|
||
-- admin_role表字段注释
|
||
comment on table admin_role is '管理员角色关联表';
|
||
comment on column admin_role.id is '管理员角色ID';
|
||
comment on column admin_role.name is '角色名称';
|
||
comment on column admin_role.description is '角色描述';
|
||
comment on column admin_role.active is '是否激活';
|
||
comment on column admin_role.sort is '排序';
|
||
comment on column admin_role.created_at is '创建时间';
|
||
comment on column admin_role.updated_at is '更新时间';
|
||
comment on column admin_role.deleted_at is '删除时间';
|
||
|
||
-- endregion
|
||
|
||
-- ====================
|
||
-- region 用户信息
|
||
-- ====================
|
||
|
||
-- user
|
||
drop table if exists "user" cascade;
|
||
create table "user" (
|
||
id int generated by default as identity primary key,
|
||
admin_id int,
|
||
phone text not null unique,
|
||
username text,
|
||
email text,
|
||
password text,
|
||
name text,
|
||
avatar text,
|
||
status int not null default 1,
|
||
balance decimal(12, 2) not null default 0,
|
||
id_type int not null default 0,
|
||
id_no text,
|
||
id_token text,
|
||
contact_qq text,
|
||
contact_wechat text,
|
||
last_login timestamptz,
|
||
last_login_ip inet,
|
||
last_login_ua text,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create index idx_user_admin_id on "user" (admin_id) where deleted_at is null;
|
||
create unique index udx_user_phone on "user" (phone) where deleted_at is null;
|
||
create unique index udx_user_username on "user" (username) where deleted_at is null;
|
||
create unique index udx_user_email on "user" (email) where deleted_at is null;
|
||
create index idx_user_created_at on "user" (created_at) where deleted_at is null;
|
||
|
||
-- user表字段注释
|
||
comment on table "user" is '用户表';
|
||
comment on column "user".id is '用户ID';
|
||
comment on column "user".admin_id is '管理员ID';
|
||
comment on column "user".password is '用户密码';
|
||
comment on column "user".username is '用户名';
|
||
comment on column "user".phone is '手机号码';
|
||
comment on column "user".name is '真实姓名';
|
||
comment on column "user".avatar is '头像URL';
|
||
comment on column "user".status is '用户状态:0-禁用,1-正常';
|
||
comment on column "user".balance is '账户余额';
|
||
comment on column "user".id_type is '认证类型:0-未认证,1-个人认证,2-企业认证';
|
||
comment on column "user".id_no is '身份证号或营业执照号';
|
||
comment on column "user".id_token is '身份验证标识';
|
||
comment on column "user".contact_qq is 'QQ联系方式';
|
||
comment on column "user".contact_wechat is '微信联系方式';
|
||
comment on column "user".last_login is '最后登录时间';
|
||
comment on column "user".last_login_ip is '最后登录地址';
|
||
comment on column "user".last_login_ua is '最后登录代理';
|
||
comment on column "user".created_at is '创建时间';
|
||
comment on column "user".updated_at is '更新时间';
|
||
comment on column "user".deleted_at is '删除时间';
|
||
|
||
-- user_role
|
||
drop table if exists user_role cascade;
|
||
create table user_role (
|
||
id int generated by default as identity primary key,
|
||
name text not null,
|
||
description text,
|
||
active bool default true,
|
||
sort int default 0,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create unique index udx_user_role_name on user_role (name) where deleted_at is null;
|
||
create index idx_user_role_created_at on user_role (created_at) where deleted_at is null;
|
||
|
||
-- user_role表字段注释
|
||
comment on table user_role is '用户角色表';
|
||
comment on column user_role.id is '角色ID';
|
||
comment on column user_role.name is '角色名称';
|
||
comment on column user_role.description is '角色描述';
|
||
comment on column user_role.active is '是否激活';
|
||
comment on column user_role.sort is '排序';
|
||
comment on column user_role.created_at is '创建时间';
|
||
comment on column user_role.updated_at is '更新时间';
|
||
comment on column user_role.deleted_at is '删除时间';
|
||
|
||
-- endregion
|
||
|
||
-- ====================
|
||
-- region 客户端信息
|
||
-- ====================
|
||
|
||
drop table if exists client cascade;
|
||
create table client (
|
||
id int generated by default as identity primary key,
|
||
client_id text not null unique,
|
||
client_secret text not null,
|
||
redirect_uri text,
|
||
spec int not null,
|
||
name text not null,
|
||
icon text,
|
||
status int not null default 1,
|
||
type int not null default 0,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create unique index udx_client_client_id on client (client_id);
|
||
create index idx_client_name on client (name) where deleted_at is null;
|
||
create index idx_client_created_at on client (created_at) where deleted_at is null;
|
||
|
||
-- client表字段注释
|
||
comment on table client is '客户端表';
|
||
comment on column client.id is '客户端ID';
|
||
comment on column client.client_id is 'OAuth2客户端标识符';
|
||
comment on column client.client_secret is 'OAuth2客户端密钥';
|
||
comment on column client.redirect_uri is 'OAuth2 重定向URI';
|
||
comment on column client.spec is '安全规范:1-native,2-browser,3-web,4-api';
|
||
comment on column client.name is '名称';
|
||
comment on column client.icon is '图标URL';
|
||
comment on column client.status is '状态:0-禁用,1-正常';
|
||
comment on column client.type is '类型:0-普通,1-官方';
|
||
comment on column client.created_at is '创建时间';
|
||
comment on column client.updated_at is '更新时间';
|
||
comment on column client.deleted_at is '删除时间';
|
||
|
||
-- endregion
|
||
|
||
-- ====================
|
||
-- region 权限信息
|
||
-- ====================
|
||
|
||
-- session
|
||
drop table if exists session cascade;
|
||
create table session (
|
||
id int generated by default as identity primary key,
|
||
user_id int,
|
||
admin_id int,
|
||
client_id int,
|
||
ip inet,
|
||
ua text,
|
||
access_token text not null,
|
||
access_token_expires timestamptz not null,
|
||
refresh_token text,
|
||
refresh_token_expires timestamptz,
|
||
scopes text,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create unique index udx_session_access_token on session (access_token) where deleted_at is null;
|
||
create unique index udx_session_refresh_token on session (refresh_token) where deleted_at is null;
|
||
create index idx_session_user_id on session (user_id) where deleted_at is null;
|
||
create index idx_session_admin_id on session (admin_id) where deleted_at is null;
|
||
create index idx_session_client_id on session (client_id) where deleted_at is null;
|
||
create index idx_session_created_at on session (created_at) where deleted_at is null;
|
||
|
||
-- session表字段注释
|
||
comment on table session is '会话表';
|
||
comment on column session.id is '会话ID';
|
||
comment on column session.user_id is '用户ID';
|
||
comment on column session.admin_id is '管理员ID';
|
||
comment on column session.client_id is '客户端ID';
|
||
comment on column session.ip is 'IP地址';
|
||
comment on column session.ua is '用户代理';
|
||
comment on column session.access_token is '访问令牌';
|
||
comment on column session.access_token_expires is '访问令牌过期时间';
|
||
comment on column session.refresh_token is '刷新令牌';
|
||
comment on column session.refresh_token_expires is '刷新令牌过期时间';
|
||
comment on column session.scopes is '权限范围';
|
||
comment on column session.created_at is '创建时间';
|
||
comment on column session.updated_at is '更新时间';
|
||
comment on column session.deleted_at is '删除时间';
|
||
|
||
-- permission
|
||
drop table if exists permission cascade;
|
||
create table permission (
|
||
id int generated by default as identity primary key,
|
||
parent_id int,
|
||
name text not null,
|
||
description text,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create unique index udx_permission_name on permission (name) where deleted_at is null;
|
||
create index idx_permission_parent_id on permission (parent_id) where deleted_at is null;
|
||
create index idx_permission_created_at on permission (created_at) where deleted_at is null;
|
||
|
||
-- permission表字段注释
|
||
comment on table permission is '权限表';
|
||
comment on column permission.id is '权限ID';
|
||
comment on column permission.parent_id is '父权限ID';
|
||
comment on column permission.name is '权限名称';
|
||
comment on column permission.description is '权限描述';
|
||
comment on column permission.created_at is '创建时间';
|
||
comment on column permission.updated_at is '更新时间';
|
||
comment on column permission.deleted_at is '删除时间';
|
||
|
||
-- link_user_role
|
||
drop table if exists link_user_role cascade;
|
||
create table link_user_role (
|
||
id int generated by default as identity primary key,
|
||
user_id int not null,
|
||
user_role_id int not null
|
||
);
|
||
create index idx_link_user_role_user_id on link_user_role (user_id);
|
||
create index idx_link_user_role_role_id on link_user_role (user_role_id);
|
||
|
||
-- link_user_role表字段注释
|
||
comment on table link_user_role is '用户角色关联表';
|
||
comment on column link_user_role.id is '关联ID';
|
||
comment on column link_user_role.user_id is '用户ID';
|
||
comment on column link_user_role.user_role_id is '角色ID';
|
||
|
||
-- link_admin_role
|
||
drop table if exists link_admin_role cascade;
|
||
create table link_admin_role (
|
||
id int generated by default as identity primary key,
|
||
admin_id int not null,
|
||
admin_role_id int not null
|
||
);
|
||
create index idx_link_admin_role_admin_id on link_admin_role (admin_id);
|
||
create index idx_link_admin_role_role_id on link_admin_role (admin_role_id);
|
||
|
||
-- link_admin_role表字段注释
|
||
comment on table link_admin_role is '管理员角色关联表';
|
||
comment on column link_admin_role.id is '关联ID';
|
||
comment on column link_admin_role.admin_id is '管理员ID';
|
||
comment on column link_admin_role.admin_role_id is '角色ID';
|
||
|
||
-- link_user_role_permission
|
||
drop table if exists link_user_role_permission cascade;
|
||
create table link_user_role_permission (
|
||
id int generated by default as identity primary key,
|
||
user_role_id int not null,
|
||
permission_id int not null
|
||
);
|
||
create index idx_link_user_role_permission_role_id on link_user_role_permission (user_role_id);
|
||
create index idx_link_user_role_permission_permission_id on link_user_role_permission (permission_id);
|
||
|
||
-- link_user_role_permission表字段注释
|
||
comment on table link_user_role_permission is '用户角色权限关联表';
|
||
comment on column link_user_role_permission.id is '关联ID';
|
||
comment on column link_user_role_permission.user_role_id is '角色ID';
|
||
comment on column link_user_role_permission.permission_id is '权限ID';
|
||
|
||
-- link_admin_role_permission
|
||
drop table if exists link_admin_role_permission cascade;
|
||
create table link_admin_role_permission (
|
||
id int generated by default as identity primary key,
|
||
admin_role_id int not null,
|
||
permission_id int not null
|
||
);
|
||
create index idx_link_admin_role_permission_role_id on link_admin_role_permission (admin_role_id);
|
||
create index idx_link_admin_role_permission_permission_id on link_admin_role_permission (permission_id);
|
||
|
||
-- link_admin_role_permission表字段注释
|
||
comment on table link_admin_role_permission is '管理员角色权限关联表';
|
||
comment on column link_admin_role_permission.id is '关联ID';
|
||
comment on column link_admin_role_permission.admin_role_id is '角色ID';
|
||
comment on column link_admin_role_permission.permission_id is '权限ID';
|
||
|
||
-- link_client_permission
|
||
drop table if exists link_client_permission cascade;
|
||
create table link_client_permission (
|
||
id int generated by default as identity primary key,
|
||
client_id int not null,
|
||
permission_id int not null
|
||
);
|
||
create index idx_link_client_permission_client_id on link_client_permission (client_id);
|
||
create index idx_link_client_permission_permission_id on link_client_permission (permission_id);
|
||
|
||
-- link_client_permission表字段注释
|
||
comment on table link_client_permission is '客户端权限关联表';
|
||
comment on column link_client_permission.id is '关联ID';
|
||
comment on column link_client_permission.client_id is '客户端ID';
|
||
comment on column link_client_permission.permission_id is '权限ID';
|
||
|
||
-- endregion
|
||
|
||
-- ====================
|
||
-- region 节点信息
|
||
-- ====================
|
||
|
||
-- proxy
|
||
drop table if exists proxy cascade;
|
||
create table proxy (
|
||
id int generated by default as identity primary key,
|
||
version int not null,
|
||
mac text not null,
|
||
ip inet not null,
|
||
host text,
|
||
secret text,
|
||
type int not null,
|
||
status int not null,
|
||
meta jsonb,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create unique index udx_proxy_mac on proxy (mac) where deleted_at is null;
|
||
create unique index udx_proxy_ip on proxy (ip) where deleted_at is null;
|
||
create index idx_proxy_created_at on proxy (created_at) where deleted_at is null;
|
||
|
||
-- proxy表字段注释
|
||
comment on table proxy is '代理服务表';
|
||
comment on column proxy.id is '代理服务ID';
|
||
comment on column proxy.version is '代理服务版本';
|
||
comment on column proxy.mac is '代理服务名称';
|
||
comment on column proxy.ip is '代理服务地址';
|
||
comment on column proxy.host is '代理服务域名';
|
||
comment on column proxy.secret is '代理服务密钥';
|
||
comment on column proxy.type is '代理服务类型:1-自有,2-白银';
|
||
comment on column proxy.status is '代理服务状态:0-离线,1-在线';
|
||
comment on column proxy.meta is '代理服务元信息';
|
||
comment on column proxy.created_at is '创建时间';
|
||
comment on column proxy.updated_at is '更新时间';
|
||
comment on column proxy.deleted_at is '删除时间';
|
||
|
||
-- edge
|
||
drop table if exists edge cascade;
|
||
create table edge (
|
||
id int generated by default as identity primary key,
|
||
type int not null,
|
||
version int not null,
|
||
mac text not null,
|
||
ip inet not null,
|
||
isp int not null,
|
||
prov text not null,
|
||
city text not null,
|
||
status int not null default 0,
|
||
rtt int default 0,
|
||
loss int default 0,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create unique index udx_edge_mac on edge (mac) where deleted_at is null;
|
||
create index idx_edge_isp on edge (isp) where deleted_at is null;
|
||
create index idx_edge_prov on edge (prov) where deleted_at is null;
|
||
create index idx_edge_city on edge (city) where deleted_at is null;
|
||
create index idx_edge_created_at on edge (created_at) where deleted_at is null;
|
||
|
||
-- edge表字段注释
|
||
comment on table edge is '节点表';
|
||
comment on column edge.id is '节点ID';
|
||
comment on column edge.type is '节点类型:1-自建';
|
||
comment on column edge.version is '节点版本';
|
||
comment on column edge.mac is '节点 mac 地址';
|
||
comment on column edge.ip is '节点地址';
|
||
comment on column edge.isp is '运营商:1-电信,2-联通,3-移动';
|
||
comment on column edge.prov is '省份';
|
||
comment on column edge.city is '城市';
|
||
comment on column edge.status is '节点状态:0-离线,1-正常';
|
||
comment on column edge.rtt is '最近平均延迟';
|
||
comment on column edge.loss is '最近丢包率';
|
||
comment on column edge.created_at is '创建时间';
|
||
comment on column edge.updated_at is '更新时间';
|
||
comment on column edge.deleted_at is '删除时间';
|
||
|
||
-- whitelist
|
||
drop table if exists whitelist cascade;
|
||
create table whitelist (
|
||
id int generated by default as identity primary key,
|
||
user_id int not null,
|
||
ip inet not null,
|
||
remark text,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create index idx_whitelist_user_id on whitelist (user_id) where deleted_at is null;
|
||
create index idx_whitelist_ip on whitelist (ip) where deleted_at is null;
|
||
create index idx_whitelist_created_at on whitelist (created_at) where deleted_at is null;
|
||
|
||
-- whitelist表字段注释
|
||
comment on table whitelist is '白名单表';
|
||
comment on column whitelist.id is '白名单ID';
|
||
comment on column whitelist.user_id is '用户ID';
|
||
comment on column whitelist.ip is 'IP地址';
|
||
comment on column whitelist.remark is '备注';
|
||
comment on column whitelist.created_at is '创建时间';
|
||
comment on column whitelist.updated_at is '更新时间';
|
||
comment on column whitelist.deleted_at is '删除时间';
|
||
|
||
-- channel
|
||
drop table if exists channel cascade;
|
||
create table channel (
|
||
id int generated by default as identity primary key,
|
||
user_id int not null,
|
||
resource_id int not null,
|
||
batch_no text not null,
|
||
proxy_id int not null,
|
||
host text not null,
|
||
port int not null,
|
||
edge_id int,
|
||
edge_ref text,
|
||
filter_isp int,
|
||
filter_prov text,
|
||
filter_city text,
|
||
ip inet,
|
||
whitelists text,
|
||
username text,
|
||
password text,
|
||
expired_at timestamptz not null,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create index idx_channel_user_resource on channel (user_id, resource_id) where deleted_at is null;
|
||
create index idx_channel_batch_no on channel (batch_no);
|
||
create index idx_channel_proxy_id on channel (proxy_id) where deleted_at is null;
|
||
create index idx_channel_created_at on channel (created_at) where deleted_at is null;
|
||
|
||
-- channel表字段注释
|
||
comment on table channel is '通道表';
|
||
comment on column channel.id is '通道ID';
|
||
comment on column channel.user_id is '用户ID';
|
||
comment on column channel.resource_id is '套餐ID';
|
||
comment on column channel.batch_no is '批次编号';
|
||
comment on column channel.proxy_id is '代理ID';
|
||
comment on column channel.host is '代理主机(快照)';
|
||
comment on column channel.port is '代理端口';
|
||
comment on column channel.edge_id is '节点ID(手动配置)';
|
||
comment on column channel.edge_ref is '外部节点引用,用于索引没有ID的外部非受控节点';
|
||
comment on column channel.filter_isp is '运营商过滤(自动配置):参考 edge.isp';
|
||
comment on column channel.filter_prov is '省份过滤(自动配置)';
|
||
comment on column channel.filter_city is '城市过滤(自动配置)';
|
||
comment on column channel.ip is '节点地址';
|
||
comment on column channel.whitelists is 'IP白名单,逗号分隔';
|
||
comment on column channel.username is '用户名';
|
||
comment on column channel.password is '密码';
|
||
comment on column channel.expired_at is '过期时间';
|
||
comment on column channel.created_at is '创建时间';
|
||
comment on column channel.updated_at is '更新时间';
|
||
comment on column channel.deleted_at is '删除时间';
|
||
|
||
-- endregion
|
||
|
||
-- ====================
|
||
-- region 产品信息
|
||
-- ====================
|
||
|
||
-- product
|
||
drop table if exists product cascade;
|
||
create table product (
|
||
id int generated by default as identity primary key,
|
||
code text not null unique,
|
||
name text not null,
|
||
description text,
|
||
sort int not null default 0,
|
||
status int not null default 1,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create unique index udx_product_code on product (code);
|
||
create index idx_product_name on product (name) where deleted_at is null;
|
||
create index idx_product_created_at on product (created_at) where deleted_at is null;
|
||
|
||
-- product表字段注释
|
||
comment on table product is '产品表';
|
||
comment on column product.id is '产品ID';
|
||
comment on column product.code is '产品代码';
|
||
comment on column product.name is '产品名称';
|
||
comment on column product.description is '产品描述';
|
||
comment on column product.sort is '排序';
|
||
comment on column product.status is '产品状态:0-禁用,1-正常';
|
||
comment on column product.created_at is '创建时间';
|
||
comment on column product.updated_at is '更新时间';
|
||
comment on column product.deleted_at is '删除时间';
|
||
|
||
-- product_sku
|
||
drop table if exists product_sku cascade;
|
||
create table product_sku (
|
||
id int generated by default as identity primary key,
|
||
product_id int not null,
|
||
code text not null,
|
||
name text not null,
|
||
price decimal not null,
|
||
discount float not null,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create index idx_product_sku_product_id on product_sku (product_id) where deleted_at is null;
|
||
create index idx_product_sku_code on product_sku (code) where deleted_at is null;
|
||
|
||
-- product_sku表字段注释
|
||
comment on table product_sku is '产品SKU表';
|
||
comment on column product_sku.id is 'SKU ID';
|
||
comment on column product_sku.product_id is '产品ID';
|
||
comment on column product_sku.code is 'SKU 代码:格式为 key=value,key=value,...,其中,key:value 是 SKU 的属性,多个属性用逗号分隔';
|
||
comment on column product_sku.name is 'SKU 可读名称';
|
||
comment on column product_sku.price is '定价';
|
||
comment on column product_sku.discount is '折扣,0 - 1 的小数,表示 xx 折';
|
||
comment on column product_sku.created_at is '创建时间';
|
||
comment on column product_sku.updated_at is '更新时间';
|
||
comment on column product_sku.deleted_at is '删除时间';
|
||
|
||
-- product_sku_user
|
||
drop table if exists product_sku_user cascade;
|
||
create table product_sku_user (
|
||
id int generated by default as identity primary key,
|
||
user_id int not null,
|
||
product_sku_id int not null,
|
||
price decimal,
|
||
discount float,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp
|
||
);
|
||
create index idx_product_sku_user_user_id on product_sku_user (user_id);
|
||
create index idx_product_sku_user_product_sku_id on product_sku_user (product_sku_id);
|
||
|
||
-- product_sku_user表字段注释
|
||
comment on table product_sku_user is '用户产品SKU表';
|
||
comment on column product_sku_user.id is 'ID';
|
||
comment on column product_sku_user.user_id is '用户ID';
|
||
comment on column product_sku_user.product_sku_id is '产品SKU ID';
|
||
comment on column product_sku_user.price is '定价';
|
||
comment on column product_sku_user.discount is '折扣,0 - 1 的小数,表示 xx 折';
|
||
comment on column product_sku_user.created_at is '创建时间';
|
||
comment on column product_sku_user.updated_at is '更新时间';
|
||
|
||
-- resource
|
||
drop table if exists resource cascade;
|
||
create table resource (
|
||
id int generated by default as identity primary key,
|
||
user_id int not null,
|
||
resource_no text,
|
||
active bool not null default true,
|
||
type int not null,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create unique index udx_resource_resource_no on resource (resource_no);
|
||
create index idx_resource_user_id on resource (user_id) where deleted_at is null;
|
||
create index idx_resource_created_at on resource (created_at) where deleted_at is null;
|
||
|
||
-- resource表字段注释
|
||
comment on table resource is '套餐表';
|
||
comment on column resource.id is '套餐ID';
|
||
comment on column resource.user_id is '用户ID';
|
||
comment on column resource.resource_no is '套餐编号';
|
||
comment on column resource.active is '套餐状态';
|
||
comment on column resource.type is '套餐类型:1-短效动态,2-长效动态';
|
||
comment on column resource.created_at is '创建时间';
|
||
comment on column resource.updated_at is '更新时间';
|
||
comment on column resource.deleted_at is '删除时间';
|
||
|
||
-- resource_short
|
||
drop table if exists resource_short cascade;
|
||
create table resource_short (
|
||
id int generated by default as identity primary key,
|
||
resource_id int not null,
|
||
live int not null,
|
||
type int not null,
|
||
quota int not null,
|
||
expire_at timestamptz,
|
||
used int not null default 0,
|
||
daily int not null default 0,
|
||
last_at timestamptz
|
||
);
|
||
create index idx_resource_short_resource_id on resource_short (resource_id);
|
||
|
||
-- resource_short表字段注释
|
||
comment on table resource_short is '短效动态套餐表';
|
||
comment on column resource_short.id is 'ID';
|
||
comment on column resource_short.resource_id is '套餐ID';
|
||
comment on column resource_short.live is '可用时长(秒)';
|
||
comment on column resource_short.type is '套餐类型:1-包时,2-包量';
|
||
comment on column resource_short.quota is '每日配额(包时)或总配额(包量)';
|
||
comment on column resource_short.expire_at is '套餐过期时间,包时模式可用';
|
||
comment on column resource_short.used is '总用量';
|
||
comment on column resource_short.daily is '当日用量';
|
||
comment on column resource_short.last_at is '最后使用时间';
|
||
|
||
-- resource_long
|
||
drop table if exists resource_long cascade;
|
||
create table resource_long (
|
||
id int generated by default as identity primary key,
|
||
resource_id int not null,
|
||
live int not null,
|
||
type int not null,
|
||
quota int not null,
|
||
expire_at timestamptz,
|
||
used int not null default 0,
|
||
daily int not null default 0,
|
||
last_at timestamptz
|
||
);
|
||
create index idx_resource_long_resource_id on resource_long (resource_id);
|
||
|
||
-- resource_long表字段注释
|
||
comment on table resource_long is '长效动态套餐表';
|
||
comment on column resource_long.id is 'ID';
|
||
comment on column resource_long.resource_id is '套餐ID';
|
||
comment on column resource_long.live is '可用时长(小时)';
|
||
comment on column resource_long.type is '套餐类型:1-包时,2-包量';
|
||
comment on column resource_long.quota is '每日配额(包时)或总配额(包量)';
|
||
comment on column resource_long.expire_at is '套餐过期时间,包时模式可用';
|
||
comment on column resource_long.used is '总用量';
|
||
comment on column resource_long.daily is '当日用量';
|
||
comment on column resource_long.last_at is '最后使用时间';
|
||
|
||
-- endregion
|
||
|
||
-- ====================
|
||
-- region 订单信息
|
||
-- ====================
|
||
|
||
-- trade
|
||
drop table if exists trade cascade;
|
||
create table trade (
|
||
id int generated by default as identity primary key,
|
||
user_id int not null,
|
||
inner_no text not null,
|
||
outer_no text,
|
||
type int not null,
|
||
subject text not null,
|
||
remark text,
|
||
amount decimal(12, 2) not null default 0,
|
||
payment decimal(12, 2) not null default 0,
|
||
method int not null,
|
||
platform int not null,
|
||
acquirer int,
|
||
status int not null default 0,
|
||
refunded bool not null default false,
|
||
payment_url text,
|
||
completed_at timestamptz,
|
||
canceled_at timestamptz,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create unique index udx_trade_inner_no on trade (inner_no);
|
||
create index idx_trade_outer_no on trade (outer_no) where deleted_at is null;
|
||
create index idx_trade_user_id on trade (user_id) where deleted_at is null;
|
||
create index idx_trade_created_at on trade (created_at) where deleted_at is null;
|
||
|
||
-- trade表字段注释
|
||
comment on table trade is '订单表';
|
||
comment on column trade.id is '订单ID';
|
||
comment on column trade.user_id is '用户ID';
|
||
comment on column trade.inner_no is '内部订单号';
|
||
comment on column trade.outer_no is '外部订单号';
|
||
comment on column trade.type is '订单类型:1-购买产品,2-充值余额';
|
||
comment on column trade.subject is '订单主题';
|
||
comment on column trade.remark is '订单备注';
|
||
comment on column trade.amount is '订单总金额';
|
||
comment on column trade.payment is '实际支付金额';
|
||
comment on column trade.method is '支付方式:1-支付宝,2-微信,3-商福通,4-商福通渠道支付宝,5-商福通渠道微信';
|
||
comment on column trade.platform is '支付平台:1-电脑网站,2-手机网站';
|
||
comment on column trade.acquirer is '收单机构:1-支付宝,2-微信,3-银联';
|
||
comment on column trade.status is '订单状态:0-待支付,1-已支付,2-已取消';
|
||
comment on column trade.payment_url is '支付链接';
|
||
comment on column trade.completed_at is '支付时间';
|
||
comment on column trade.canceled_at is '取消时间';
|
||
comment on column trade.created_at is '创建时间';
|
||
comment on column trade.updated_at is '更新时间';
|
||
comment on column trade.deleted_at is '删除时间';
|
||
|
||
-- refund
|
||
drop table if exists refund cascade;
|
||
create table refund (
|
||
id int generated by default as identity primary key,
|
||
trade_id int not null,
|
||
product_id int,
|
||
amount decimal(12, 2) not null default 0,
|
||
reason text,
|
||
status int not null default 0,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create index idx_refund_trade_id on refund (trade_id) where deleted_at is null;
|
||
create index idx_refund_product_id on refund (product_id) where deleted_at is null;
|
||
create index idx_refund_created_at on refund (created_at) where deleted_at is null;
|
||
|
||
-- refund表字段注释
|
||
comment on table refund is '退款记录表';
|
||
comment on column refund.id is '退款ID';
|
||
comment on column refund.trade_id is '订单ID';
|
||
comment on column refund.product_id is '产品ID';
|
||
comment on column refund.amount is '退款金额';
|
||
comment on column refund.reason is '退款原因';
|
||
comment on column refund.status is '退款状态:0-待处理,1-已退款,2-已拒绝';
|
||
comment on column refund.created_at is '创建时间';
|
||
comment on column refund.updated_at is '更新时间';
|
||
comment on column refund.deleted_at is '删除时间';
|
||
|
||
-- bill
|
||
drop table if exists bill cascade;
|
||
create table bill (
|
||
id int generated by default as identity primary key,
|
||
user_id int not null,
|
||
trade_id int,
|
||
resource_id int,
|
||
refund_id int,
|
||
bill_no text not null,
|
||
info text,
|
||
type int not null,
|
||
amount decimal(12, 2) not null default 0,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create unique index udx_bill_bill_no on bill (bill_no);
|
||
create index idx_bill_user_id on bill (user_id) where deleted_at is null;
|
||
create index idx_bill_trade_id on bill (trade_id) where deleted_at is null;
|
||
create index idx_bill_resource_id on bill (resource_id) where deleted_at is null;
|
||
create index idx_bill_refund_id on bill (refund_id) where deleted_at is null;
|
||
create index idx_bill_created_at on bill (created_at) where deleted_at is null;
|
||
|
||
-- bill表字段注释
|
||
comment on table bill is '账单表';
|
||
comment on column bill.id is '账单ID';
|
||
comment on column bill.user_id is '用户ID';
|
||
comment on column bill.trade_id is '订单ID';
|
||
comment on column bill.resource_id is '套餐ID';
|
||
comment on column bill.refund_id is '退款ID';
|
||
comment on column bill.bill_no is '易读账单号';
|
||
comment on column bill.info is '产品可读信息';
|
||
comment on column bill.type is '账单类型:1-消费,2-退款,3-充值';
|
||
comment on column bill.amount is '账单金额';
|
||
comment on column bill.created_at is '创建时间';
|
||
comment on column bill.updated_at is '更新时间';
|
||
comment on column bill.deleted_at is '删除时间';
|
||
|
||
-- coupon 优惠券
|
||
drop table if exists coupon cascade;
|
||
create table coupon (
|
||
id int generated by default as identity primary key,
|
||
user_id int,
|
||
code text not null,
|
||
remark text,
|
||
amount decimal(12, 2) not null default 0,
|
||
min_amount decimal(12, 2) not null default 0,
|
||
status int not null default 0,
|
||
expire_at timestamptz,
|
||
created_at timestamptz default current_timestamp,
|
||
updated_at timestamptz default current_timestamp,
|
||
deleted_at timestamptz
|
||
);
|
||
create index idx_coupon_user_id on coupon (user_id) where deleted_at is null;
|
||
create index idx_coupon_code on coupon (code) where deleted_at is null;
|
||
create index idx_coupon_created_at on coupon (created_at) where deleted_at is null;
|
||
|
||
-- coupon表字段注释
|
||
comment on table coupon is '优惠券表';
|
||
comment on column coupon.id is '优惠券ID';
|
||
comment on column coupon.user_id is '用户ID';
|
||
comment on column coupon.code is '优惠券代码';
|
||
comment on column coupon.remark is '优惠券备注';
|
||
comment on column coupon.amount is '优惠券金额';
|
||
comment on column coupon.min_amount is '最低消费金额';
|
||
comment on column coupon.status is '优惠券状态:0-未使用,1-已使用,2-已过期';
|
||
comment on column coupon.expire_at is '过期时间';
|
||
comment on column coupon.created_at is '创建时间';
|
||
comment on column coupon.updated_at is '更新时间';
|
||
comment on column coupon.deleted_at is '删除时间';
|
||
|
||
-- endregion
|
||
|
||
-- ====================
|
||
-- region 外键约束
|
||
-- ====================
|
||
|
||
-- user表外键
|
||
alter table "user"
|
||
add constraint fk_user_admin_id foreign key (admin_id) references admin (id) on delete set null;
|
||
|
||
-- session表外键
|
||
alter table session
|
||
add constraint fk_session_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||
alter table session
|
||
add constraint fk_session_client_id foreign key (client_id) references client (id) on delete cascade;
|
||
|
||
-- permission表外键
|
||
alter table permission
|
||
add constraint fk_permission_parent_id foreign key (parent_id) references permission (id) on delete set null;
|
||
|
||
-- link_user_role表外键
|
||
alter table link_user_role
|
||
add constraint fk_link_user_role_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||
alter table link_user_role
|
||
add constraint fk_link_user_role_role_id foreign key (user_role_id) references user_role (id) on delete cascade;
|
||
|
||
-- link_admin_role表外键
|
||
alter table link_admin_role
|
||
add constraint fk_link_admin_role_admin_id foreign key (admin_id) references admin (id) on delete cascade;
|
||
alter table link_admin_role
|
||
add constraint fk_link_admin_role_role_id foreign key (admin_role_id) references admin_role (id) on delete cascade;
|
||
|
||
-- link_user_role_permission表外键
|
||
alter table link_user_role_permission
|
||
add constraint fk_link_user_role_permission_role_id foreign key (user_role_id) references user_role (id) on delete cascade;
|
||
alter table link_user_role_permission
|
||
add constraint fk_link_user_role_permission_permission_id foreign key (permission_id) references permission (id) on delete cascade;
|
||
|
||
-- link_admin_role_permission表外键
|
||
alter table link_admin_role_permission
|
||
add constraint fk_link_admin_role_permission_role_id foreign key (admin_role_id) references admin_role (id) on delete cascade;
|
||
alter table link_admin_role_permission
|
||
add constraint fk_link_admin_role_permission_permission_id foreign key (permission_id) references permission (id) on delete cascade;
|
||
|
||
-- link_client_permission表外键
|
||
alter table link_client_permission
|
||
add constraint fk_link_client_permission_client_id foreign key (client_id) references client (id) on delete cascade;
|
||
alter table link_client_permission
|
||
add constraint fk_link_client_permission_permission_id foreign key (permission_id) references permission (id) on delete cascade;
|
||
|
||
-- whitelist表外键
|
||
alter table whitelist
|
||
add constraint fk_whitelist_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||
|
||
-- channel表外键
|
||
alter table channel
|
||
add constraint fk_channel_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||
alter table channel
|
||
add constraint fk_channel_proxy_id foreign key (proxy_id) references proxy (id) on delete set null;
|
||
alter table channel
|
||
add constraint fk_channel_edge_id foreign key (edge_id) references edge (id) on delete set null;
|
||
alter table channel
|
||
add constraint fk_channel_resource_id foreign key (resource_id) references resource (id) on delete set null;
|
||
|
||
-- resource表外键
|
||
alter table resource
|
||
add constraint fk_resource_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||
|
||
-- resource_short表外键
|
||
alter table resource_short
|
||
add constraint fk_resource_short_resource_id foreign key (resource_id) references resource (id) on delete cascade;
|
||
|
||
-- resource_long表外键
|
||
alter table resource_long
|
||
add constraint fk_resource_long_resource_id foreign key (resource_id) references resource (id) on delete cascade;
|
||
|
||
-- trade表外键
|
||
alter table trade
|
||
add constraint fk_trade_user_id foreign key (user_id) references "user" (id) on delete set null;
|
||
|
||
-- refund表外键
|
||
alter table refund
|
||
add constraint fk_refund_trade_id foreign key (trade_id) references trade (id) on delete cascade;
|
||
alter table refund
|
||
add constraint fk_refund_product_id foreign key (product_id) references product (id) on delete set null;
|
||
|
||
-- bill表外键
|
||
alter table bill
|
||
add constraint fk_bill_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||
alter table bill
|
||
add constraint fk_bill_trade_id foreign key (trade_id) references trade (id) on delete set null;
|
||
alter table bill
|
||
add constraint fk_bill_resource_id foreign key (resource_id) references resource (id) on delete set null;
|
||
alter table bill
|
||
add constraint fk_bill_refund_id foreign key (refund_id) references refund (id) on delete set null;
|
||
|
||
-- coupon表外键
|
||
alter table coupon
|
||
add constraint fk_coupon_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||
|
||
-- product_sku表外键
|
||
alter table product_sku
|
||
add constraint fk_product_sku_product_id foreign key (product_id) references product (id) on delete cascade;
|
||
|
||
-- product_sku_user表外键
|
||
alter table product_sku_user
|
||
add constraint fk_product_sku_user_user_id foreign key (user_id) references "user" (id) on delete cascade;
|
||
alter table product_sku_user
|
||
add constraint fk_product_sku_user_product_sku_id foreign key (product_sku_id) references product_sku (id) on delete cascade;
|
||
|
||
-- endregion
|