提示信息
# 同伴 App 数据库设计规范
> 本文档由系统根据 `database/schema/*.sql` 自动生成。请勿手动修改本项目文件。
## 表结构概览
| 数据表 | 中文说明 |
| :--- | :--- |
| [`users`](#表users) | 用户核心信息 |
| [`user_devices`](#表user_devices) | 用户设备绑定 |
| [`user_blocks`](#表user_blocks) | 黑名单 |
| [`user_login_logs`](#表user_login_logs) | 登录流水 |
| [`user_risk_logs`](#表user_risk_logs) | 风控/风险日志 |
| [`user_forbidden`](#表user_forbidden) | 封禁记录 |
| [`user_sign_stats`](#表user_sign_stats) | 用户签到统计 |
| [`user_sign_logs`](#表user_sign_logs) | 用户签到流水 |
| [`user_module_cursors`](#表user_module_cursors) | 用户模块游标 |
| [`user_verifications`](#表user_verifications) | 用户实人认证流水 |
| [`user_cancellations`](#表user_cancellations) | 用户注销记录 |
| [`reports`](#表reports) | 举报 |
| [`signals`](#表signals) | 信号 |
| [`signal_receives`](#表signal_receives) | 信号收取记录 |
| [`signal_replies`](#表signal_replies) | 信号回复 |
| [`signal_low_quality_feedbacks`](#表signal_low_quality_feedbacks) | 信号低质量反馈 |
| [`im_stranger_limit`](#表im_stranger_limit) | IM陌生人聊天限制 |
| [`im_daily_greet`](#表im_daily_greet) | IM每日打招呼记录 |
| [`im_day_stats`](#表im_day_stats) | IM每日统计 |
| [`im_upload_logs`](#表im_upload_logs) | IM附件上传日志 |
| [`im_violation_logs`](#表im_violation_logs) | IM违规拦截日志 |
| [`app_versions`](#表app_versions) | 版本检查与更新配置表 |
| [`orders`](#表orders) | 交易订单与充值流水表 |
| [`sms_logs`](#表sms_logs) | |
| [`app_documents`](#表app_documents) | 法律文档 |
| [`system_notifications`](#表system_notifications) | 系统通知广播 |
| [`user_system_notification_reads`](#表user_system_notification_reads) | 用户已读记录 |
## 详细字段设计
<a name="表users"></a>
### 表:`users`
> **说明**:用户核心信息表:存储账号、资料、统计数据及隐私设置
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 用户唯一标识 |
| `nickname` | `VARCHAR(255)` | 昵称 |
| `bio` | `VARCHAR(500)` | 个人简介 |
| `phone` | `VARCHAR(30)` | 手机号 |
| `password_hash` | `VARCHAR(255)` | 密码哈希 |
| `avatar` | `TEXT` | 头像地址 |
| `gender` | `SMALLINT` | 性别 ([`Gender`](/docs/dictionary#Gender)) |
| `orientation` | `SMALLINT` | 性取向 |
| `attribute` | `SMALLINT` | 属性 |
| `birth_date` | `DATE` | 出生日期 |
| `residence` | `JSONB` | 常住地 (结构化数据: 省/市/区) |
| `mbti` | `VARCHAR(10)` | MBTI 人格类型 |
| `is_hot` | `INTEGER` | 推荐权重/热度分 |
| `is_verified` | `BOOLEAN` | 是否通过认证 |
| `is_vip` | `BOOLEAN` | 是否是 VIP |
| `force_auth` | `BOOLEAN` | 是否强制认证 |
| `forbidden_type` | `SMALLINT` | 当前封禁原因 ([`ForbiddenType`](/docs/dictionary#ForbiddenType)),null=正常 |
| `canceled_at` | `TIMESTAMPTZ` | 注销时间 |
| `rating_updated_at` | `TIMESTAMPTZ` | 评级/分值更新时间 |
| `location` | `POINT` | 经纬度位置 |
| `accepted_privacy_version` | `SMALLINT` | 已同意的隐私政策版本 |
| `is_profile_hidden` | `BOOLEAN` | 是否隐藏资料页 |
| `is_visit_hidden` | `BOOLEAN` | 是否隐藏访问记录 |
| `is_distance_hidden` | `BOOLEAN` | 是否隐藏距离 |
| `is_active_hidden` | `BOOLEAN` | 是否隐藏活跃时间 |
| `is_vip_hidden` | `BOOLEAN` | 是否隐藏 VIP 标志 |
| `is_personalized` | `BOOLEAN` | 是否开启个性化推荐 |
| `young_pass` | `VARCHAR(100)` | 青少年模式密码 (空表示未开启) |
| `device_id` | `VARCHAR(255)` | 注册时的设备 ID |
| `last_ip` | `INET` | 最后访问 IP 地址 |
| `last_active_at` | `TIMESTAMPTZ` | 最后活跃时间 |
| `created_at` | `TIMESTAMPTZ` | 注册时间 |
---
<a name="表user_devices"></a>
### 表:`user_devices`
> **说明**:用户设备绑定表:记录用户登录过的设备信息及封禁状态
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 主键 |
| `user_id` | `BIGINT` | 用户 ID |
| `device_id` | `TEXT` | 设备唯一标识 (UUID/IDFA等) |
| `model` | `TEXT` | 设备型号 (例: iPhone 16 Pro) |
| `platform` | `TEXT` | 平台 (ios/android) |
| `os_version` | `TEXT` | 操作系统版本 |
| `app_version` | `TEXT` | App 版本 |
| `is_banned` | `BOOLEAN` | 该设备是否被封禁 |
| `ban_reason` | `TEXT` | 封禁原因 |
| `risk_flags` | `TEXT[]` | 设备风险标志数组,来自 IOSSecuritySuite (例: ["safe"] / ["jailbreak","hook"]) |
| `risk_updated_at` | `TIMESTAMPTZ` | 风险标志最后更新时间 |
| `first_seen_at` | `TIMESTAMPTZ` | 首次在该设备登录时间 |
| `last_seen_at` | `TIMESTAMPTZ` | 最后在该设备登录时间 |
---
<a name="表user_blocks"></a>
### 表:`user_blocks`
> **说明**:黑名单表:记录用户屏蔽关系
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 主键 |
| `user_id` | `BIGINT` | 发起屏蔽的用户 ID |
| `target_user_id` | `BIGINT` | 被屏蔽的用户 ID |
| `created_at` | `TIMESTAMPTZ` | 屏蔽时间 |
| `deleted_at` | `TIMESTAMPTZ` | 解除屏蔽时间 (逻辑删除) |
---
<a name="表user_login_logs"></a>
### 表:`user_login_logs`
> **说明**:登录流水表:记录用户所有登录尝试及环境信息
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 主键 |
| `user_id` | `BIGINT` | 用户 ID |
| `device_id` | `TEXT` | 设备 ID |
| `model` | `TEXT` | 设备型号 |
| `platform` | `TEXT` | 平台 (ios/android) |
| `os_version` | `TEXT` | 系统版本 |
| `app_version` | `TEXT` | App 版本 |
| `ip` | `INET` | 登录 IP 地址 |
| `ip_country` | `TEXT` | 国家 (由 ip2region 解析) |
| `ip_city` | `TEXT` | 城市 (由 ip2region 解析) |
| `user_agent` | `TEXT` | 浏览器/客户端 UA |
| `client_type` | `TEXT` | 客户端类型 (app/web) |
| `network_type` | `TEXT` | 网络类型 (wifi/5g等) |
| `locale` | `TEXT` | 语言/时区设置 |
| `login_type` | `SMALLINT` | 登录方式 ([`LoginType`](/docs/dictionary#LoginType)) |
| `is_success` | `BOOLEAN` | 是否成功 |
| `fail_reason` | `TEXT` | 失败原因 |
| `extra_info` | `JSONB` | 扩展信息 (风控、埋点等) |
| `request_id` | `TEXT` | 请求追踪 ID |
| `is_emulator` | `BOOLEAN` | 是否模拟器 |
| `is_root` | `BOOLEAN` | 是否 Root/越狱 |
| `is_debugger` | `BOOLEAN` | 是否开启调试 |
| `is_hook` | `BOOLEAN` | 是否有 Hook 框架 |
| `created_at` | `TIMESTAMPTZ` | 记录时间 |
---
<a name="表user_risk_logs"></a>
### 表:`user_risk_logs`
> **说明**:风控/风险日志表:记录系统检测到的疑似异常或风险行为
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 主键 |
| `user_id` | `BIGINT` | 用户 ID |
| `device_id` | `TEXT` | 触发风险的设备 ID |
| `risk_type` | `SMALLINT` | 风险类型 (1-异地登录 2-模拟器 3-Root 4-Hook 5-调试 6-多账号 7-频繁失败 8-录屏 9-VPN 10-Token异常) |
| `risk_level` | `SMALLINT` | 风险等级 (1-低 2-中 3-高) |
| `detail` | `JSONB` | 详细风险上下文 |
| `ip` | `INET` | 触发风险的 IP |
| `created_at` | `TIMESTAMPTZ` | 记录时间 |
---
<a name="表user_forbidden"></a>
### 表:`user_forbidden`
> **说明**:封禁记录表:记录用户或设备的处罚详情及期限
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 主键 |
| `user_id` | `BIGINT` | 被封禁的用户 ID |
| `device_id` | `TEXT` | 被封禁的设备 ID (可选) |
| `forbidden_type` | `SMALLINT` | 封禁类型 ([`ForbiddenType`](/docs/dictionary#ForbiddenType)) |
| `reason` | `TEXT` | 封禁原因 |
| `start_at` | `TIMESTAMPTZ` | 封禁开始时间 |
| `end_at` | `TIMESTAMPTZ` | 封禁结束时间 (NULL 表示永久) |
| `operator_user_id` | `BIGINT` | 操作员 ID (NULL 表示系统自动执行) |
| `is_active` | `BOOLEAN` | 是否当前生效 |
| `created_at` | `TIMESTAMPTZ` | 记录创建时间 |
---
<a name="表user_sign_stats"></a>
### 表:`user_sign_stats`
> **说明**:用户签到统计表:维护用户的连续签到与累计签到数据
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `user_id` | `BIGINT` | 用户 ID (主键,1对1关系) |
| `continuous_days` | `INTEGER` | 连续签到天数 |
| `total_days` | `INTEGER` | 累计签到总数 |
| `last_sign_at` | `TIMESTAMPTZ` | 最近一次签到时间 |
| `created_at` | `TIMESTAMPTZ` | 创建时间 |
| `updated_at` | `TIMESTAMPTZ` | 更新时间 |
---
<a name="表user_sign_logs"></a>
### 表:`user_sign_logs`
> **说明**:用户签到流水表:记录用户每一天的具体签到历史
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 主键 |
| `user_id` | `BIGINT` | 用户 ID |
| `sign_date` | `DATE` | 签到所属日期 |
| `experience_reward` | `INTEGER` | 该次签到获得的奖励 (金币/经验) |
| `created_at` | `TIMESTAMPTZ` | 签到动作的具体时间 |
---
<a name="表user_module_cursors"></a>
### 表:`user_module_cursors`
> **说明**:用户模块游标表:记录用户在不同模块(粉丝、访客等)的最后查看时间,用于红点提示
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `user_id` | `BIGINT` | 用户 ID |
| `last_fans_view_at` | `TIMESTAMPTZ` | 最后查看粉丝列表时间 |
| `last_visitors_view_at` | `TIMESTAMPTZ` | 最后查看访客列表时间 |
| `last_signals_view_at` | `TIMESTAMPTZ` | 最后查看动态/信号时间 |
| `updated_at` | `TIMESTAMPTZ` | 记录更新时间 |
---
<a name="表user_verifications"></a>
### 表:`user_verifications`
> **说明**:用户实人认证流水表:对接三方服务(如阿里云、腾讯云)进行的三要素认证以及人工认证
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 主键 |
| `user_id` | `BIGINT` | 用户 ID |
| `outer_order_no` | `VARCHAR(64)` | 业务流水号 |
| `verify_type` | `VARCHAR(32)` | 认证类型 (three_elements-三要素, manual-人工) |
| `real_name` | `VARCHAR(255)` | 真实姓名 (加密存储) |
| `id_card` | `VARCHAR(255)` | 身份证号 (加密存储) |
| `mobile` | `VARCHAR(32)` | 认证手机号 |
| `photo_url` | `VARCHAR(255)` | 人工认证照片URL |
| `request_payload` | `JSONB` | 原始请求信息(可选) |
| `provider_response` | `JSONB` | 三方接口的原始完整响应 |
| `fail_reason` | `VARCHAR(255)` | 认证失败的原因说明 |
| `status` | `SMALLINT` | 认证状态: 0=pending, 1=approved, 2=rejected, 3=cancelled |
| `created_at` | `TIMESTAMPTZ` | 创建时间 |
| `updated_at` | `TIMESTAMPTZ` | 更新时间 |
---
<a name="表user_cancellations"></a>
### 表:`user_cancellations`
> **说明**:用户注销记录表:记录已注销用户的轨迹
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 主键 |
| `user_id` | `BIGINT` | 注销的用户 ID |
| `ip` | `INET` | 注销时的 IP 地址 |
| `device_id` | `VARCHAR(255)` | 设备 ID |
| `platform` | `VARCHAR(50)` | 平台 (ios/android/web) |
| `reason` | `VARCHAR(500)` | 注销原因 |
| `created_at` | `TIMESTAMPTZ` | 注销执行时间 |
---
<a name="表reports"></a>
### 表:`reports`
> **说明**:举报表:记录用户对其他用户、信号或私聊的举报
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 主键 |
| `reporter_uid` | `BIGINT` | 举报人 ID |
| `relation_type` | `SMALLINT` | 1=用户主页 2=信号 3=私聊 |
| `relation_id` | `VARCHAR(255)` | 用户ID/信号ID/会话ID |
| `reported_uid` | `BIGINT` | 被举报的用户 ID |
| `reason_code` | `INT` | 违规理由代码 (枚举) |
| `message` | `VARCHAR(1000)` | 补充说明 |
| `images` | `JSONB` | 图片 JSON 数组 |
| `status` | `SMALLINT` | 0=待处理 1=违规成立 2=举报无效 |
| `handle_result` | `SMALLINT` | 处理措施:1=封禁账号 2=警告提醒 3=仅记录违规 NULL(status=2时)=举报无效 |
| `handle_note` | `VARCHAR(500)` | 处理备注,内部可见 |
| `handled_at` | `TIMESTAMPTZ` | 管理员处理时间 |
| `dismiss_reason` | `VARCHAR(50)` | 驳回原因:incomplete=举报材料不完整 no_violation=未发现任何违规 |
| `reporter_violated` | `BOOLEAN` | 举报人是否同时存在违规行为 |
| `created_at` | `TIMESTAMPTZ` | 举报创建时间 |
| `updated_at` | `TIMESTAMPTZ` | 状态最后流转时间 |
---
<a name="表signals"></a>
### 表:`signals`
> **说明**:信号表:存储用户发布的信号(匹配请求)
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 信号唯一 ID |
| `uid` | `BIGINT` | 发布者用户 ID |
| `category` | `SMALLINT` | 信号分类 ([`SignalCategory`](/docs/dictionary#SignalCategory)) |
| `content` | `TEXT` | 信号文本内容 |
| `type` | `SMALLINT` | 信号类型 ([`SignalType`](/docs/dictionary#SignalType)) |
| `attachment` | `JSONB` | 附件信息 {object_key, width, height, duration} |
| `is_archived` | `BOOLEAN` | 是否归档(表示软删除,作者还可见) |
| `status` | `SMALLINT` | 信号状态 ([`SignalStatus`](/docs/dictionary#SignalStatus)) |
| `reply_count` | `INT` | 累计被回复次数 |
| `collect_count` | `INT` | 累计被收取的次数 |
| `created_at` | `TIMESTAMPTZ` | 创建时间 |
| `updated_at` | `TIMESTAMPTZ` | 最后热度或内容更新时间 |
| `deleted_at` | `TIMESTAMPTZ` | 删除时间 |
---
<a name="表signal_receives"></a>
### 表:`signal_receives`
> **说明**:信号收取记录表:记录用户收取了哪些信号或回复
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 收取记录唯一 ID |
| `uid` | `BIGINT` | 收取者用户 ID |
| `type` | `SMALLINT` | 收取类型 ([`SignalReceiveType`](/docs/dictionary#SignalReceiveType)) |
| `source_id` | `BIGINT` | 来源 ID (对应 signals.id 或 signal_replies.id) |
| `source_uid` | `BIGINT` | 发送者用户 ID |
| `status` | `SMALLINT` | 互动状态 ([`SignalReceiveStatus`](/docs/dictionary#SignalReceiveStatus)) |
| `is_read` | `BOOLEAN` | 是否已读 |
| `created_at` | `TIMESTAMPTZ` | 收取时间 |
| `deleted_at` | `TIMESTAMPTZ` | 删除时间 |
---
<a name="表signal_replies"></a>
### 表:`signal_replies`
> **说明**:信号回复表:存储用户针对某个信号的回复内容
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 回复唯一 ID |
| `signal_id` | `BIGINT` | 所属信号 ID |
| `from_uid` | `BIGINT` | 回复者(收取了信号的人) |
| `to_uid` | `BIGINT` | 被回复者(信号发布者) |
| `content` | `TEXT` | 回复文本内容 |
| `received_at` | `TIMESTAMPTZ` | 被收取时间 (NULL 表示信号主尚未收取此回复) |
| `is_im_opened` | `BOOLEAN` | 是否已直接开启 IM 对话 |
| `created_at` | `TIMESTAMPTZ` | 回复时间 |
| `deleted_at` | `TIMESTAMPTZ` | 删除时间 |
---
<a name="表signal_low_quality_feedbacks"></a>
### 表:`signal_low_quality_feedbacks`
> **说明**:信号低质量反馈表:记录用户对信号或回复的低质量反馈
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 主键 |
| `reporter_uid` | `BIGINT` | 反馈人 ID |
| `reported_uid` | `BIGINT` | 被反馈的用户 ID |
| `target_type` | `SMALLINT` | 反馈对象类型 (1:信号 2:回复) |
| `target_id` | `BIGINT` | 目标 ID (信号 ID 或回复 ID) |
| `created_at` | `TIMESTAMPTZ` | |
---
<a name="表im_stranger_limit"></a>
### 表:`im_stranger_limit`
> **说明**:IM陌生人聊天限制表:记录陌生人之间的消息发送次数及解锁状态
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | |
| `sender_user_id` | `BIGINT` | 发送者用户 ID |
| `receiver_user_id` | `BIGINT` | 接收者用户 ID |
| `msg_count` | `SMALLINT` | 已发送条数 |
| `is_unlocked` | `BOOLEAN` | 是否已解锁 |
| `updated_at` | `TIMESTAMPTZ` | |
---
<a name="表im_daily_greet"></a>
### 表:`im_daily_greet`
> **说明**:IM每日打招呼记录表:记录用户每天向哪些人发送了打招呼,用于限频控制
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | |
| `user_id` | `BIGINT` | 打招呼的用户 ID |
| `greet_date` | `DATE` | 统计日期 |
| `target_user_id` | `BIGINT` | 被打招呼的用户 ID |
| `created_at` | `TIMESTAMPTZ` | |
---
<a name="表im_day_stats"></a>
### 表:`im_day_stats`
> **说明**:IM每日统计表:按天汇总 IM 消息量、活跃用户等核心运营指标
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | |
| `stat_date` | `DATE` | 统计日期 |
| `active_users` | `INTEGER` | 活跃人数 |
| `new_registrations` | `INTEGER` | 新增注册 |
| `msg_text_count` | `INTEGER` | 文本消息数 |
| `msg_pic_count` | `INTEGER` | 图片消息数 |
| `msg_voice_count` | `INTEGER` | 语音消息数 |
| `msg_video_count` | `INTEGER` | 视频消息数 |
| `msg_total_count` | `INTEGER` | 总消息数 |
| `updated_at` | `TIMESTAMPTZ` | |
---
<a name="表im_upload_logs"></a>
### 表:`im_upload_logs`
> **说明**:IM附件上传日志表:记录每次上传的文件信息及内容安全检测结果
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | |
| `user_id` | `BIGINT` | 上传者用户 ID |
| `file_type` | `VARCHAR(16)` | image/video/audio |
| `file_path` | `VARCHAR(255)` | OSS 路径或 URL |
| `risk_score` | `INTEGER` | 第三方检测评分 |
| `is_blocked` | `BOOLEAN` | 是否被阻断 |
| `is_skip_check` | `BOOLEAN` | 是否免审(特殊用户/场景) |
| `created_at` | `TIMESTAMPTZ` | |
---
<a name="表im_violation_logs"></a>
### 表:`im_violation_logs`
> **说明**:IM违规拦截日志表:记录被内容安全系统拦截的消息及人工审核状态
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | |
| `sender_user_id` | `BIGINT` | 发送者用户 ID |
| `receiver_user_id` | `BIGINT` | 接收者用户 ID |
| `content_type` | `SMALLINT` | 1:文本 2:图片 3:语音 4:视频 |
| `content` | `TEXT` | 违规内容(文本或文件 URL) |
| `risk_type` | `VARCHAR(32)` | 违规类型(涉黄/广告/政治) |
| `risk_score` | `INTEGER` | 机器评分(0-100) |
| `status` | `SMALLINT` | 0:拦截待审 1:确认违规 2:误判放行 |
| `created_at` | `TIMESTAMPTZ` | |
---
<a name="表app_versions"></a>
### 表:`app_versions`
> **说明**:版本检查与更新配置表
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | |
| `platform` | `TEXT` | 平台 (ios / android) |
| `version_code` | `INTEGER` | 版本号(整型,用于比较大小) |
| `version_name` | `VARCHAR(20)` | 版本名 (例: 1.0.1) |
| `is_force` | `BOOLEAN` | 是否强制更新 |
| `min_version_code` | `INTEGER` | 强制升级临界点:当前版本 < 此值时必强更 |
| `update_content` | `TEXT` | 更新日志内容 |
| `download_url` | `TEXT` | 下载地址 (Android APK 直链或 H5 下载页) |
| `status` | `SMALLINT` | 状态: 1=正常 0=下线 |
| `created_at` | `TIMESTAMPTZ` | 创建时间 |
---
<a name="表orders"></a>
### 表:`orders`
> **说明**:交易订单与充值流水表
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | 订单唯一标识 |
| `user_id` | `BIGINT` | 用户ID (关联 users.id) |
| `trade_no` | `VARCHAR(64)` | 内部订单号 (年+月+日+雪花算法流水号) |
| `transaction_id` | `VARCHAR(128)` | 第三方通道真实交易流水号 (Apple IAP / 微信 / 支付宝) |
| `pay_platform` | `SMALLINT` | 支付渠道 (1:微信, 2:支付宝, 3:Apple原生) |
| `relation_type` | `SMALLINT` | 关联类型 (1:VIP, 2:SVIP, 3:派币/虚拟币, 9:购买商品) |
| `relation_id` | `INTEGER` | 关联套餐ID 或 商品ID |
| `product_name` | `VARCHAR(128)` | 商品名称 (快照) |
| `currency` | `VARCHAR(16)` | 币种 (CNY, USD等) |
| `pay_amount` | `NUMERIC(11,2)` | 实付金额 |
| `status` | `SMALLINT` | 交易状态 (0:待支付, 1:支付成功, 2:支付失败/关闭, 3:已退款) |
| `refund_status` | `SMALLINT` | 退款状态 (0:无, 1:已退款) |
| `source` | `VARCHAR(64)` | 购买来源/渠道归因 (譬如 visitor_list, daily_limit) |
| `refund_time` | `TIMESTAMPTZ` | 退款时间 |
| `pay_time` | `TIMESTAMPTZ` | 付款成功时间 |
| `created_at` | `TIMESTAMPTZ` | 订单创建时间 |
---
<a name="表sms_logs"></a>
### 表:`sms_logs`
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
---
<a name="表app_documents"></a>
### 表:`app_documents`
> **说明**:法律文档表:存储隐私政策、用户协议、个人信息收集清单、第三方共享清单 支持版本管理,is_current=true 表示当前生效版本
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | |
| `type` | `VARCHAR(50)` | privacy / terms / info_collection / third_party |
| `version_code` | `SMALLINT` | 数字版本号,与 users.accepted_privacy_version 对应 |
| `version` | `VARCHAR(20)` | 展示版本号,如 2025-03-28 或 1.0 |
| `title` | `VARCHAR(200)` | 文档标题 |
| `content` | `TEXT` | HTML 正文(仅 <body> 内容片段) |
| `is_current` | `BOOLEAN` | 是否为当前生效版本 |
| `published_at` | `TIMESTAMPTZ` | 生效时间 |
| `created_at` | `TIMESTAMPTZ` | |
---
<a name="表system_notifications"></a>
### 表:`system_notifications`
> **说明**:系统通知广播表:管理员创建,面向全体用户展示
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | `BIGINT` | |
| `title` | `TEXT` | 通知标题 |
| `body` | `TEXT` | 通知正文 |
| `extra` | `JSONB` | 扩展数据(跳转链接等) |
| `push_sent` | `BOOLEAN` | 是否已触发群推 |
| `created_by` | `BIGINT` | 操作管理员 uid |
| `created_at` | `TIMESTAMPTZ` | |
---
<a name="表user_system_notification_reads"></a>
### 表:`user_system_notification_reads`
> **说明**:用户已读记录表:记录哪些用户已读了哪条系统通知
| 字段名 | 类型 | 说明 |
| :--- | :--- | :--- |
| `uid` | `BIGINT` | |
| `notification_id` | `BIGINT` | |
| `created_at` | `TIMESTAMPTZ` | |
---