Files
soul-yongping/scripts/migrate_2026_sections.py
卡若 991e17698c feat: 内容管理第5批优化 - Bug修复 + 分享功能 + 代付功能
1. Bug修复:
   - 修复Markdown星号/下划线在小程序端原样显示问题(markdownToHtml增加__和_支持,contentParser增加Markdown格式剥离)
   - 修复@提及无反应(MentionSuggestion使用ref保持persons最新值,解决闭包捕获空数组问题)
   - 修复#链接标签点击"未找到小程序配置"(增加appId直接跳转降级路径)

2. 分享功能优化:
   - "分享到朋友圈"改为"分享给好友"(open-type从shareTimeline改为share)
   - 90%收益提示移到分享按钮下方
   - 阅读20%后向上滑动弹出分享浮层提示(4秒自动消失)

3. 代付功能:
   - 后端:新增UserBalance/BalanceTransaction/GiftUnlock三个模型
   - 后端:新增8个余额相关API(查询/充值/充值确认/代付/领取/退款/交易记录/礼物信息)
   - 小程序:阅读页新增"代付分享"按钮,支持用余额为好友解锁章节
   - 分享链接携带gift参数,好友打开自动领取解锁

Made-with: Cursor
2026-03-15 09:20:27 +08:00

152 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
将第102场及以后的派对场次迁移到「2026每日派对干货」目录
用法:
python3 scripts/migrate_2026_sections.py # 仅预览,不执行
python3 scripts/migrate_2026_sections.py --execute # 执行迁移
迁移规则:
- 从章节中筛选 section_title 包含「第102场」「第103场」... 的条目
- 按场次号排序,依次赋 id 10.01, 10.02, 10.03, ...
- 更新 part_id=part-2026-daily, part_title=2026每日派对干货
- 更新 chapter_id=chapter-2026-daily, chapter_title=2026每日派对干货
依赖: pip install pymysql
"""
import argparse
import re
import sys
from pathlib import Path
# 项目根目录
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
try:
import pymysql
except ImportError:
print("需要安装 pymysql: pip3 install pymysql")
sys.exit(1)
DB_CONFIG = {
"host": "56b4c23f6853c.gz.cdb.myqcloud.com",
"port": 14413,
"user": "cdb_outerroot",
"password": "Zhiqun1984",
"database": "soul_miniprogram",
"charset": "utf8mb4",
}
PART_2026 = "part-2026-daily"
CHAPTER_2026 = "chapter-2026-daily"
TITLE_2026 = "2026每日派对干货"
def extract_session_num(section_title: str) -> int | None:
"""从 section_title 解析场次号,如 第102场 -> 102"""
m = re.search(r"第(\d+)场", section_title)
return int(m.group(1)) if m else None
def get_connection():
return pymysql.connect(**DB_CONFIG)
def get_max_10_section(cur) -> int:
"""获取当前 10.xx 最大序号"""
cur.execute(
"SELECT id FROM chapters WHERE id REGEXP '^10\\.[0-9]+$' ORDER BY CAST(SUBSTRING_INDEX(id, '.', -1) AS UNSIGNED) DESC LIMIT 1"
)
row = cur.fetchone()
if row:
return int(row[0].split(".")[-1])
return 0
def find_sections_to_migrate(cur) -> list[tuple]:
"""查找需要迁移的章节第102场及以后且不在 part-2026-daily 的"""
cur.execute("""
SELECT id, section_title, part_id, chapter_id, sort_order
FROM chapters
WHERE section_title REGEXP '第[0-9]+场'
ORDER BY sort_order, id
""")
rows = cur.fetchall()
to_migrate = []
for row in rows:
sid, title, part_id, ch_id, order = row
num = extract_session_num(title)
if num is not None and num >= 102 and part_id != PART_2026:
to_migrate.append((sid, title, part_id, ch_id, order, num))
to_migrate.sort(key=lambda x: (x[5], x[4])) # 按场次号、sort_order
return to_migrate
def run(dry_run: bool):
conn = get_connection()
cur = conn.cursor()
rows = find_sections_to_migrate(cur)
max_10 = get_max_10_section(cur)
conn.close()
if not rows:
print("未找到需要迁移的章节第102场及以后、且不在 2026每日派对干货 中)")
return
print(f"当前 10.xx 最大序号: {max_10}")
print(f"找到 {len(rows)} 节待迁移到「2026每日派对干货」\n")
plan = []
for i, (old_id, title, part_id, ch_id, order, num) in enumerate(rows, 1):
new_id = f"10.{max_10 + i:02d}"
plan.append((old_id, new_id, title, part_id))
print(f" {old_id} -> {new_id} {title}")
if dry_run:
print("\n[预览模式] 未执行写入,使用 --execute 执行迁移")
return
print("\n执行迁移...")
conn = get_connection()
cur = conn.cursor()
try:
# 先全部改为临时 id避免与已有 10.xx 冲突)
for i, (old_id, new_id, title, part_id) in enumerate(plan, 1):
tmp_id = f"tmp-migrate-{old_id.replace('.', '-')}"
cur.execute(
"UPDATE chapters SET id = %s WHERE id = %s",
(tmp_id, old_id),
)
conn.commit()
# 再改为最终 id 并更新 part/chapter
for i, (old_id, new_id, title, part_id) in enumerate(plan, 1):
tmp_id = f"tmp-migrate-{old_id.replace('.', '-')}"
cur.execute("""
UPDATE chapters SET
id = %s, part_id = %s, part_title = %s,
chapter_id = %s, chapter_title = %s
WHERE id = %s
""", (new_id, PART_2026, TITLE_2026, CHAPTER_2026, TITLE_2026, tmp_id))
conn.commit()
print(f"已迁移 {len(plan)} 节到 part-2026-dailyid 为 10.01 ~ 10.{len(plan):02d}")
except Exception as e:
conn.rollback()
print(f"迁移失败: {e}")
raise
finally:
conn.close()
def main():
parser = argparse.ArgumentParser(description="将第102场及以后的场次迁移到 2026每日派对干货")
parser.add_argument("--execute", action="store_true", help="执行迁移(默认仅预览)")
args = parser.parse_args()
run(dry_run=not args.execute)
if __name__ == "__main__":
main()