feat(auth): 账号唯一性+清理多余账号 —— 迁移0011加phone/微信openid非空部分唯一索引

- users.phone/wx_openid/wx_mini_openid/wx_unionid 各自唯一(非空部分唯一索引)
- 创建账号必生成ID(create用new_id);find_by_phone/find_by_wx 唯一校验
- cleanup_accounts.py 清理旧accounts已被users接管的重复账号;seed不再重复造账号、迁移后删旧行
This commit is contained in:
Pine
2026-08-25 22:47:27 +08:00
parent 8a00712750
commit c2f4c13ab3
4 changed files with 210 additions and 7 deletions
+10 -7
View File
@@ -24,17 +24,17 @@ log = logging.getLogger("db.seed")
def _seed_training() -> None:
"""培训种子(唯一总库 app.db):超管账号 + 排期 + 在线课程(幂等)。"""
"""培训种子(唯一总库 app.db):排期 + 在线课程(幂等)。
不再向旧 ``accounts`` 表种子账号 —— 平台规范账号已由 platform_seed 写入
``users``(如 u_demo_01/pine),旧 accounts 为「多余账号仓」已被清理
(见 scripts/db/cleanup_accounts.py),此处不再重复造账号。
"""
import sqlite3
import json
from app.training import db as tdb
conn = sqlite3.connect(tdb.DB_PATH)
conn.row_factory = sqlite3.Row
try:
if conn.execute("SELECT COUNT(*) AS c FROM accounts").fetchone()["c"] == 0:
from app.training.auth import hash_password
conn.execute("INSERT INTO accounts (id,username,password,name,identities,created_at) VALUES (?,?,?,?,?,?)",
("U-PINE", "pine", hash_password("123456"), "Pine", json.dumps(["admin"]), tdb.now_iso()))
if conn.execute("SELECT COUNT(*) AS c FROM events").fetchone()["c"] == 0:
for e in tdb.SEED_EVENTS:
conn.execute("INSERT INTO events (id,type,mode,title,subtitle,desc,location,host,image,link,start_at,duration_min,capacity,status) VALUES (:id,:type,:mode,:title,:subtitle,:desc,:location,:host,:image,:link,:start_at,:duration_min,:capacity,:status)", e)
@@ -87,8 +87,11 @@ async def _migrate_accounts_to_users(db) -> None:
)
created += 1
await _ensure_opc_identity(db, user["id"])
# 迁移即接管:删掉旧 accounts 行,避免同一逻辑账号落在两套表(多余账号)。
conn.execute("DELETE FROM accounts WHERE id=?", (row["id"],))
migrated += 1
log.info("accounts→users 迁移完成:共 %s 条,新建 %s", migrated, created)
conn.commit()
log.info("accounts→users 迁移完成:共 %s 条,新建 %s 条(旧 accounts 行已清理)", migrated, created)
finally:
conn.close()