diff --git a/.gitignore b/.gitignore index e355020..344333d 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,7 @@ bin/ *.http */playground/ -scripts/ \ No newline at end of file + +scripts/* +!scripts/dev/ +!scripts/sql/ diff --git a/README.md b/README.md index 6a6f161..902961c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ - 微信支付 - 错误处理类型转换失败问题 -- 用对称加密处理密钥 - 检查数据库枚举字段,0 值只作为空值使用 - 移动端适配 - channel 接口 diff --git a/scripts/dev/docker-compose.yaml b/scripts/dev/docker-compose.yaml new file mode 100644 index 0000000..add8574 --- /dev/null +++ b/scripts/dev/docker-compose.yaml @@ -0,0 +1,24 @@ +name: platform-dev + +services: + + postgres: + image: postgres:17 + restart: always + environment: + POSTGRES_USER: ${DB_USERNAME} + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_DB: ${DB_NAME} + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + + redis: + image: redis:7.4 + restart: always + ports: + - "6379:6379" + +volumes: + postgres_data: diff --git a/scripts/sql/init.sql b/scripts/sql/init.sql new file mode 100644 index 0000000..a5726c0 --- /dev/null +++ b/scripts/sql/init.sql @@ -0,0 +1,861 @@ +-- 清空数据表 +do +$$ + declare + r record; + begin + for r in ( + select + tablename + from + pg_tables + where + schemaname = 'public' + ) loop + execute 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE'; + end loop; + end +$$; + +-- ==================== +-- region 管理员信息 +-- ==================== + +-- admin +drop table if exists admin cascade; +create table admin ( + id serial primary key, + username varchar(255) not null unique, + password varchar(255) not null, + name varchar(255), + avatar varchar(255), + phone varchar(255), + email varchar(255), + status int not null default 1, + last_login timestamp, + last_login_host varchar(45), + last_login_agent varchar(255), + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index admin_status_index on admin (status); +create index admin_deleted_at_index on admin (deleted_at); + +-- 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 '状态:1-正常,0-禁用'; +comment on column admin.last_login is '最后登录时间'; +comment on column admin.last_login_host is '最后登录地址'; +comment on column admin.last_login_agent 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 serial primary key, + name varchar(255) not null unique, + description varchar(255), + active bool default true, + sort int default 0, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index admin_role_deleted_at_index on admin_role (deleted_at); + +-- 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 serial primary key, + admin_id int references admin (id) -- + on update cascade -- + on delete set null, + phone varchar(255) not null unique, + username varchar(255), + email varchar(255), + password varchar(255), + name varchar(255), + avatar varchar(255), + status int not null default 1, + balance decimal(12, 2) not null default 0, + id_type int not null default 0, + id_no varchar(255), + id_token varchar(255), + contact_qq varchar(255), + contact_wechat varchar(255), + last_login timestamp, + last_login_host varchar(45), + last_login_agent varchar(255), + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index user_admin_id_index on "user" (admin_id); +create index user_username_index on "user" (username); +create index user_email_index on "user" (email); +create index user_status_index on "user" (status); +create index user_deleted_at_index on "user" (deleted_at); + +-- 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 '用户状态:1-正常,0-禁用'; +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_host is '最后登录地址'; +comment on column "user".last_login_agent 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 serial primary key, + name varchar(255) not null unique, + description varchar(255), + active bool default true, + sort int default 0, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index user_role_deleted_at_index on user_role (deleted_at); + +-- 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 serial primary key, + client_id varchar(255) not null unique, + client_secret varchar(255) not null, + redirect_uri varchar(255), + grant_code bool not null default false, + grant_client bool not null default false, + grant_refresh bool not null default false, + grant_password bool not null default false, + spec int not null, + name varchar(255) not null, + icon varchar(255), + status int not null default 1, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); + +create index client_client_id_index on client (client_id); +create index client_name_index on client (name); +create index client_status_index on client (status); +create index client_deleted_at_index on client (deleted_at); + +-- 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.grant_code is '允许授权码授予'; +comment on column client.grant_client is '允许客户端凭证授予'; +comment on column client.grant_refresh is '允许刷新令牌授予'; +comment on column client.grant_password is '允许密码授予'; +comment on column client.spec is '安全规范:0-web,1-native,2-browser'; +comment on column client.name is '名称'; +comment on column client.icon is '图标URL'; +comment on column client.status is '状态:1-正常,0-禁用'; +comment on column client.created_at is '创建时间'; +comment on column client.updated_at is '更新时间'; +comment on column client.deleted_at is '删除时间'; + +-- endregion + +-- ==================== +-- region 权限信息 +-- ==================== + +-- permission +drop table if exists permission cascade; +create table permission ( + id serial primary key, + parent_id int references permission (id) + on update cascade + on delete cascade, + name varchar(255) not null unique, + description varchar(255), + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index permission_parent_id_index on permission (parent_id); +create index permission_name_index on permission (name); +create index permission_deleted_at_index on permission (deleted_at); + +-- 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 '删除时间'; + +-- user_role_link +drop table if exists user_role_link cascade; +create table user_role_link ( + id serial primary key, + user_id int not null references "user" (id) + on update cascade + on delete cascade, + role_id int not null references user_role (id) + on update cascade + on delete cascade, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index user_role_link_user_id_index on user_role_link (user_id); +create index user_role_link_role_id_index on user_role_link (role_id); +create index user_role_link_deleted_at_index on user_role_link (deleted_at); + +-- user_role_link表字段注释 +comment on table user_role_link is '用户角色关联表'; +comment on column user_role_link.id is '关联ID'; +comment on column user_role_link.user_id is '用户ID'; +comment on column user_role_link.role_id is '角色ID'; +comment on column user_role_link.created_at is '创建时间'; +comment on column user_role_link.updated_at is '更新时间'; +comment on column user_role_link.deleted_at is '删除时间'; + +-- admin_role_link +drop table if exists admin_role_link cascade; +create table admin_role_link ( + id serial primary key, + admin_id int not null references admin (id) + on update cascade + on delete cascade, + role_id int not null references admin_role (id) + on update cascade + on delete cascade, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index admin_role_link_admin_id_index on admin_role_link (admin_id); +create index admin_role_link_role_id_index on admin_role_link (role_id); +create index admin_role_link_deleted_at_index on admin_role_link (deleted_at); + +-- admin_role_link表字段注释 +comment on table admin_role_link is '管理员角色关联表'; +comment on column admin_role_link.id is '关联ID'; +comment on column admin_role_link.admin_id is '管理员ID'; +comment on column admin_role_link.role_id is '角色ID'; +comment on column admin_role_link.created_at is '创建时间'; +comment on column admin_role_link.updated_at is '更新时间'; +comment on column admin_role_link.deleted_at is '删除时间'; + +-- user_role_permission_link +drop table if exists user_role_permission_link cascade; +create table user_role_permission_link ( + id serial primary key, + role_id int not null references user_role (id) + on update cascade + on delete cascade, + permission_id int not null references permission (id) + on update cascade + on delete cascade, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index user_role_permission_link_role_id_index on user_role_permission_link (role_id); +create index user_role_permission_link_permission_id_index on user_role_permission_link (permission_id); +create index user_role_permission_link_deleted_at_index on user_role_permission_link (deleted_at); + +-- user_role_permission_link表字段注释 +comment on table user_role_permission_link is '用户角色权限关联表'; +comment on column user_role_permission_link.id is '关联ID'; +comment on column user_role_permission_link.role_id is '角色ID'; +comment on column user_role_permission_link.permission_id is '权限ID'; +comment on column user_role_permission_link.created_at is '创建时间'; +comment on column user_role_permission_link.updated_at is '更新时间'; +comment on column user_role_permission_link.deleted_at is '删除时间'; + +-- admin_role_permission_link +drop table if exists admin_role_permission_link cascade; +create table admin_role_permission_link ( + id serial primary key, + role_id int not null references admin_role (id) + on update cascade + on delete cascade, + permission_id int not null references permission (id) + on update cascade + on delete cascade, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index admin_role_permission_link_role_id_index on admin_role_permission_link (role_id); +create index admin_role_permission_link_permission_id_index on admin_role_permission_link (permission_id); +create index admin_role_permission_link_deleted_at_index on admin_role_permission_link (deleted_at); + +-- admin_role_permission_link表字段注释 +comment on table admin_role_permission_link is '管理员角色权限关联表'; +comment on column admin_role_permission_link.id is '关联ID'; +comment on column admin_role_permission_link.role_id is '角色ID'; +comment on column admin_role_permission_link.permission_id is '权限ID'; +comment on column admin_role_permission_link.created_at is '创建时间'; +comment on column admin_role_permission_link.updated_at is '更新时间'; +comment on column admin_role_permission_link.deleted_at is '删除时间'; + +-- client_permission_link +drop table if exists client_permission_link cascade; +create table client_permission_link ( + id serial primary key, + client_id int not null references client (id) + on update cascade + on delete cascade, + permission_id int not null references permission (id) + on update cascade + on delete cascade, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index client_permission_link_client_id_index on client_permission_link (client_id); +create index client_permission_link_permission_id_index on client_permission_link (permission_id); +create index client_permission_link_deleted_at_index on client_permission_link (deleted_at); + +-- client_permission_link表字段注释 +comment on table client_permission_link is '客户端权限关联表'; +comment on column client_permission_link.id is '关联ID'; +comment on column client_permission_link.client_id is '客户端ID'; +comment on column client_permission_link.permission_id is '权限ID'; +comment on column client_permission_link.created_at is '创建时间'; +comment on column client_permission_link.updated_at is '更新时间'; +comment on column client_permission_link.deleted_at is '删除时间'; + +-- endregion + +-- ==================== +-- region 节点信息 +-- ==================== + +-- proxy +drop table if exists proxy cascade; +create table proxy ( + id serial primary key, + version int not null, + name varchar(255) not null unique, + host varchar(255) not null, + type int not null default 0, + secret varchar(255), + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index proxy_name_index on proxy (name); +create index proxy_host_index on proxy (host); +create index proxy_deleted_at_index on proxy (deleted_at); + +-- proxy表字段注释 +comment on table proxy is '代理服务表'; +comment on column proxy.id is '代理服务ID'; +comment on column proxy.version is '代理服务版本'; +comment on column proxy.name is '代理服务名称'; +comment on column proxy.host is '代理服务地址'; +comment on column proxy.type is '代理服务类型:0-自有,1-三方'; +comment on column proxy.secret is '代理服务密钥'; +comment on column proxy.created_at is '创建时间'; +comment on column proxy.updated_at is '更新时间'; +comment on column proxy.deleted_at is '删除时间'; + +-- node +drop table if exists node cascade; +create table node ( + id serial primary key, + proxy_id int references proxy (id) + on update cascade + on delete cascade, + version int not null, + name varchar(255) not null unique, + host varchar(255) not null, + isp int not null, + prov varchar(255) not null, + city varchar(255) not null, + proxy_port int, + status int not null default 0, + rtt int default 0, + loss int default 0, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index node_isp_index on node (isp); +create index node_prov_index on node (prov); +create index node_city_index on node (city); +create index node_proxy_id_index on node (proxy_id); +create index node_deleted_at_index on node (deleted_at); + +-- node表字段注释 +comment on table node is '节点表'; +comment on column node.id is '节点ID'; +comment on column node.version is '节点版本'; +comment on column node.name is '节点名称'; +comment on column node.host is '节点地址'; +comment on column node.isp is '运营商:0-其他,1-电信,2-联通,3-移动'; +comment on column node.prov is '省份'; +comment on column node.city is '城市'; +comment on column node.proxy_id is '代理ID'; +comment on column node.proxy_port is '代理端口'; +comment on column node.status is '节点状态:0-离线,1-正常'; +comment on column node.rtt is '延迟'; +comment on column node.loss is '丢包率'; +comment on column node.created_at is '创建时间'; +comment on column node.updated_at is '更新时间'; +comment on column node.deleted_at is '删除时间'; + +-- whitelist +drop table if exists whitelist cascade; +create table whitelist ( + id serial primary key, + user_id int not null references "user" (id) + on update cascade + on delete cascade, + host varchar(45) not null, + remark varchar(255), + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index whitelist_user_id_index on whitelist (user_id); +create index whitelist_host_index on whitelist (host); +create index whitelist_deleted_at_index on whitelist (deleted_at); + +-- 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.host 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 serial primary key, + user_id int not null references "user" (id) + on update cascade + on delete cascade, + proxy_id int not null references proxy (id) -- + on update cascade -- + on delete set null, + node_id int references node (id) -- + on update cascade -- + on delete set null, + proxy_host varchar(255) not null default '', + proxy_port int not null, + node_host varchar(255), + protocol int, + auth_ip bool not null default false, + user_host varchar(255), + auth_pass bool not null default false, + username varchar(255), + password varchar(255), + expiration timestamp not null, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index channel_user_id_index on channel (user_id); +create index channel_proxy_id_index on channel (proxy_id); +create index channel_node_id_index on channel (node_id); +create index channel_proxy_host_index on channel (proxy_host); +create index channel_proxy_port_index on channel (proxy_port); +create index channel_node_host_index on channel (node_host); +create index channel_auth_ip_index on channel (auth_ip); +create index channel_user_host_index on channel (user_host); +create index channel_auth_pass_index on channel (auth_pass); +create index channel_username_index on channel (username); +create index channel_expiration_index on channel (expiration); +create index channel_deleted_at_index on channel (deleted_at); + +-- 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.proxy_id is '代理ID'; +comment on column channel.node_id is '节点ID'; +comment on column channel.proxy_host is '代理地址'; +comment on column channel.proxy_port is '转发端口'; +comment on column channel.node_host is '节点地址'; +comment on column channel.protocol is '协议类型:1-http,2-https,3-socks5'; +comment on column channel.auth_ip is 'IP认证'; +comment on column channel.user_host is '用户地址'; +comment on column channel.auth_pass is '密码认证'; +comment on column channel.username is '用户名'; +comment on column channel.password is '密码'; +comment on column channel.expiration 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 serial primary key, + code varchar(255) not null unique, + name varchar(255) not null, + description varchar(255), + sort int not null default 0, + status int not null default 1, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index product_deleted_at_index on product (deleted_at); + +-- 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 '产品状态:1-正常,0-禁用'; +comment on column product.created_at is '创建时间'; +comment on column product.updated_at is '更新时间'; +comment on column product.deleted_at is '删除时间'; + +-- resource +drop table if exists resource cascade; +create table resource ( + id serial primary key, + user_id int not null references "user" (id) + on update cascade + on delete cascade, + resource_no varchar(255) unique, + active bool not null default true, + type int not null, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index resource_user_id_index on resource (user_id); +create index resource_resource_no_index on resource (resource_no); +create index resource_active_index on resource (active); +create index resource_type_index on resource (type); +create index resource_deleted_at_index on resource (deleted_at); + +-- 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-隧道,3-独享'; +comment on column resource.created_at is '创建时间'; +comment on column resource.updated_at is '更新时间'; +comment on column resource.deleted_at is '删除时间'; + +-- resource_pss +drop table if exists resource_pss cascade; +create table resource_pss ( + id serial primary key, + resource_id int not null references resource (id) + on update cascade + on delete cascade, + type int, + live int, + expire timestamp, + quota int, + used int not null default 0, + daily_limit int not null default 0, + daily_used int not null default 0, + daily_last timestamp +); +create index resource_pss_resource_id_index on resource_pss (resource_id); + +-- resource_pss表字段注释 +comment on table resource_pss is '动态代理套餐表'; +comment on column resource_pss.id is 'ID'; +comment on column resource_pss.resource_id is '套餐ID'; +comment on column resource_pss.type is '套餐类型:1-包时,2-包量'; +comment on column resource_pss.live is '可用时长(秒)'; +comment on column resource_pss.quota is '配额数量'; +comment on column resource_pss.used is '已用数量'; +comment on column resource_pss.expire is '过期时间'; +comment on column resource_pss.daily_limit is '每日限制'; +comment on column resource_pss.daily_used is '今日已用数量'; +comment on column resource_pss.daily_last is '今日最后使用时间'; + +-- resource_psr +drop table if exists resource_psr cascade; +create table resource_psr ( + id serial primary key, + resource_id int not null references resource (id) + on update cascade + on delete cascade, + live int, + conn int, + expire timestamp, + used bool +); +create index resource_psr_resource_id_index on resource_psr (resource_id); + +-- resource_psr表字段注释 +comment on table resource_psr is '隧道代理套餐表'; +comment on column resource_psr.id is 'ID'; +comment on column resource_psr.resource_id is '套餐ID'; +comment on column resource_psr.live is '轮换周期(秒)'; +comment on column resource_psr.conn is '最大连接数'; +comment on column resource_psr.expire is '过期时间'; +comment on column resource_psr.used is '是否已使用'; + +-- resource_pps +drop table if exists resource_pps cascade; +create table resource_pps ( + id serial primary key, + resource_id int not null references resource (id) + on update cascade + on delete cascade +); +create index resource_pps_resource_id_index on resource_pps (resource_id); + +-- resource_pps表字段注释 +comment on table resource_pps is '独享代理套餐表'; +comment on column resource_pps.id is 'ID'; +comment on column resource_pps.resource_id is '套餐ID'; + +-- endregion + +-- ==================== +-- region 订单信息 +-- ==================== + +-- trade +drop table if exists trade cascade; +create table trade ( + id serial primary key, + user_id int not null references "user" (id) + on update cascade + on delete cascade, + inner_no varchar(255) not null unique, + outer_no varchar(255), + type int not null, + subject varchar(255) not null, + remark varchar(255), + amount decimal(12, 2) not null default 0, + payment decimal(12, 2) not null default 0, + method int not null, + status int not null default 0, + pay_url text, + paid_at timestamp, + cancel_at timestamp, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index trade_user_id_index on trade (user_id); +create index trade_outer_no_index on trade (outer_no); +create index trade_type_index on trade (type); +create index trade_status_index on trade (status); +create index trade_deleted_at_index on trade (deleted_at); + +-- 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 '订单类型:0-充值余额,1-购买产品'; +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-微信'; +comment on column trade.status is '订单状态:0-待支付,1-已支付,2-已取消,3-已退款'; +comment on column trade.pay_url is '支付链接'; +comment on column trade.paid_at is '支付时间'; +comment on column trade.cancel_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 serial primary key, + trade_id int not null references trade (id) + on update cascade + on delete cascade, + product_id int references product (id) -- + on update cascade -- + on delete set null, + amount decimal(12, 2) not null default 0, + reason varchar(255), + status int not null default 0, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index refund_trade_id_index on refund (trade_id); +create index refund_product_id_index on refund (product_id); +create index refund_deleted_at_index on refund (deleted_at); + +-- 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 serial primary key, + user_id int not null references "user" (id) + on update cascade + on delete cascade, + trade_id int references trade (id) -- + on update cascade -- + on delete set null, + resource_id int references resource (id) -- + on update cascade -- + on delete set null, + refund_id int references refund (id) -- + on update cascade -- + on delete set null, + bill_no varchar(255) not null unique, + info varchar(255), + type int not null, + amount decimal(12, 2) not null default 0, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index bill_user_id_index on bill (user_id); +create index bill_trade_id_index on bill (trade_id); +create index bill_resource_id_index on bill (resource_id); +create index bill_refund_id_index on bill (refund_id); +create index bill_bill_no_index on bill (bill_no); +create index bill_type_index on bill (type); +create index bill_deleted_at_index on bill (deleted_at); + +-- 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 '账单类型:0-充值,1-消费,2-退款'; +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 serial primary key, + user_id int references "user" (id) + on update cascade + on delete cascade, + code varchar(255) not null unique, + remark varchar(255), + 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 timestamp, + created_at timestamp default current_timestamp, + updated_at timestamp default current_timestamp, + deleted_at timestamp +); +create index coupon_user_id_index on coupon (user_id); +create index coupon_code_index on coupon (code); +create index coupon_status_index on coupon (status); +create index coupon_deleted_at_index on coupon (deleted_at); + +-- 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 \ No newline at end of file