- 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.
75 lines
3.5 KiB
SQL
75 lines
3.5 KiB
SQL
-- =============================================================================
|
||
-- 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)
|
||
-- ---------------------------------------------------------------------------
|