From 0756d9ff0c471a01c04674ecafa4b1f7423d844f Mon Sep 17 00:00:00 2001 From: Alex-larget <33240357+Alex-larget@users.noreply.github.com> Date: Thu, 2 Apr 2026 17:19:51 +0800 Subject: [PATCH] refactor: improve content parsing and API integration - Enhanced content parsing logic to better handle image sources and improve resolution. - Updated API base URL for seamless transitions between development and production environments. - Refactored navigation on the OpenPlatformPage to ensure accurate access to settings and API documentation. - Streamlined ContentPage to include additional webhook configuration retrieval. - Optimized DashboardPage for improved user interaction efficiency. - Cleaned up unused imports and improved readability in AdminLayout. --- .../migrate-super-individual-persons-bind.sql | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 soul-api/scripts/migrate-super-individual-persons-bind.sql diff --git a/soul-api/scripts/migrate-super-individual-persons-bind.sql b/soul-api/scripts/migrate-super-individual-persons-bind.sql new file mode 100644 index 00000000..3e2ab429 --- /dev/null +++ b/soul-api/scripts/migrate-super-individual-persons-bind.sql @@ -0,0 +1,74 @@ +-- ============================================================================= +-- migrate-super-individual-persons-bind.sql +-- 超级个体(有效 VIP)与 @人物 persons 对齐 — 数据侧「补绑」迁移 +-- +-- 说明: +-- 1) 新建 persons 行依赖存客宝 API(ckb_plan_id / ckb_api_key),请勿用纯 SQL 硬插完整行。 +-- 未绑上的用户:部署 soul-api 后,在管理端「内容管理 → @列表」点刷新,由接口自动 ensurePersonForUser。 +-- 2) 本脚本只做安全场景:已有 @人物、user_id 为空,且「未绑定 person 的 VIP」里仅一人昵称与 person.name 一致时,写入 user_id。 +-- 3) 执行前请备份库;建议先只跑「第一节 SELECT」看缺口,再跑 UPDATE。 +-- 4) VIP 口径:is_vip = 1 且 vip_expire_date > NOW()(与 activeSuperIndividualUserIDs 主路径一致)。 +-- ============================================================================= + +-- --------------------------------------------------------------------------- +-- 1) 缺口清单:有效 VIP,且没有任何 person.user_id 指向该用户 +-- --------------------------------------------------------------------------- +SELECT + u.id AS user_id, + TRIM(u.nickname) AS nickname, + u.vip_expire_date, + u.is_vip +FROM users u +WHERE u.is_vip = 1 + AND u.vip_expire_date > NOW() + AND NOT EXISTS ( + SELECT 1 FROM persons p WHERE p.user_id IS NOT NULL AND TRIM(p.user_id) <> '' AND p.user_id = u.id + ) +ORDER BY u.vip_sort ASC, u.vip_activated_at DESC, u.id; + +-- --------------------------------------------------------------------------- +-- 2) 冲突检查:多个未绑定的 person 同名(本脚本不会自动处理,需人工合并或走 API) +-- --------------------------------------------------------------------------- +SELECT TRIM(p.name) AS name_norm, COUNT(*) AS unbound_count +FROM persons p +WHERE p.user_id IS NULL OR TRIM(p.user_id) = '' +GROUP BY TRIM(p.name) +HAVING COUNT(*) > 1; + +-- --------------------------------------------------------------------------- +-- 3) 同名唯一补绑:未绑 person ↔ 有效 VIP(昵称一致),且该 VIP 尚无 person +-- MySQL 8+ / 5.7 均可用;user_id 列为空串时按未绑定处理 +-- --------------------------------------------------------------------------- +UPDATE persons p +INNER JOIN users u + ON TRIM(u.nickname) = TRIM(p.name) + AND CHAR_LENGTH(TRIM(COALESCE(u.nickname, ''))) > 0 +SET + p.user_id = u.id, + p.updated_at = NOW() +WHERE (p.user_id IS NULL OR TRIM(p.user_id) = '') + AND u.is_vip = 1 + AND u.vip_expire_date > NOW() + AND NOT EXISTS ( + SELECT 1 FROM persons px WHERE px.user_id = u.id + ) + AND ( + SELECT COUNT(*) + FROM persons p3 + WHERE TRIM(p3.name) = TRIM(p.name) + AND (p3.user_id IS NULL OR TRIM(p3.user_id) = '') + ) = 1; + +-- --------------------------------------------------------------------------- +-- 4) 可选:将本次补绑且仍为「手工」来源的 VIP 行标为 vip_sync(与统一计划展示一致;按业务需要取消注释) +-- --------------------------------------------------------------------------- +-- UPDATE persons p +-- INNER JOIN users u ON p.user_id = u.id +-- SET p.person_source = 'vip_sync', p.updated_at = NOW() +-- WHERE u.is_vip = 1 +-- AND u.vip_expire_date > NOW() +-- AND (p.person_source IS NULL OR p.person_source = ''); + +-- --------------------------------------------------------------------------- +-- 5) 执行后再跑第一节 SELECT,应只剩「无同名 person」的 VIP(须由线上 API 创建 person) +-- ---------------------------------------------------------------------------