fix(cookieManager): 迁移补齐 Cookie 管理菜单,修复部署后菜单缺失

菜单记录此前只在本地库手工 INSERT,未随迁移分发。
data/ 被 gitignore 排除,部署环境数据库为独立 volume,
导致线上只有代码和空表、看不到菜单。

新增幂等迁移:记录不存在则插入,open_type 为空则补 _iframe。
管理员走 SUPERADMIN 分支加载全部 enable 菜单,无需角色授权即可显示。
This commit is contained in:
bwstudio
2026-09-10 14:14:37 +08:00
parent 1193f7f56a
commit e141e3528e
@@ -0,0 +1,96 @@
"""add cookie manager menus
「Cookie管理」一级菜单 + 二级「登录用户」/「登录网站」及各权限点,
此前只在本地库里手工 INSERT 过,从未随迁移分发。
由于 data/ 目录被 .gitignore 排除、部署环境数据库是独立 volume,
只同步代码无法带上这些菜单行,导致线上后台看不到 Cookie 管理模块。
本迁移以幂等方式补齐:
- 记录不存在 → 插入
- 已存在但 open_type 为空 → 补齐为 _iframe(兼容早期手工插入的数据)
不依赖数据库方言的 UPSERT 语法,SQLite / MySQL 均可执行。
Revision ID: d4e5f6a7b8c9
Revises: b2c3d4e5f6a7
"""
from alembic import op
import sqlalchemy as sa
import datetime
# revision identifiers, used by Alembic.
revision = 'd4e5f6a7b8c9'
down_revision = 'b2c3d4e5f6a7'
branch_labels = None
depends_on = None
# (id, name, type, code, url, open_type, parent_id, icon, sort, enable)
MENUS = [
(76, 'Cookie管理', '0', '', '', '', 0, 'layui-icon layui-icon-ear-phone', 5, 1),
(77, '登录用户', '1', 'system:cookie-user:main', '/system/cookie-user/', '_iframe',
76, 'layui-icon layui-icon-username', 1, 1),
(78, '登录用户新增', '2', 'system:cookie-user:add', '', '', 77, '', 1, 1),
(79, '登录用户编辑', '2', 'system:cookie-user:edit', '', '', 77, '', 2, 1),
(80, '登录用户删除', '2', 'system:cookie-user:remove', '', '', 77, '', 3, 1),
(81, '登录网站', '1', 'system:cookie-site:main', '/system/cookie-site/', '_iframe',
76, 'layui-icon layui-icon-web', 2, 1),
(82, '登录网站新增', '2', 'system:cookie-site:add', '', '', 81, '', 1, 1),
(83, '登录网站编辑', '2', 'system:cookie-site:edit', '', '', 81, '', 2, 1),
(84, '登录网站删除', '2', 'system:cookie-site:remove', '', '', 81, '', 3, 1),
]
def upgrade():
conn = op.get_bind()
now = datetime.datetime.now()
for mid, name, mtype, code, url, open_type, parent_id, icon, sort, enable in MENUS:
row = conn.execute(
sa.text("SELECT id, open_type FROM admin_power WHERE id = :id"),
{"id": mid},
).fetchone()
if row is None:
conn.execute(
sa.text(
"INSERT INTO admin_power "
"(id, name, type, code, url, open_type, parent_id, icon, sort, "
" enable, create_time, update_time) "
"VALUES (:id, :name, :type, :code, :url, :open_type, :parent_id, "
" :icon, :sort, :enable, :ct, :ut)"
),
{
"id": mid, "name": name, "type": mtype, "code": code,
"url": url, "open_type": open_type, "parent_id": parent_id,
"icon": icon, "sort": sort, "enable": enable,
"ct": now, "ut": now,
},
)
elif not row[1] and open_type:
# 历史数据:菜单已存在但打开方式为空,补齐 _iframe
conn.execute(
sa.text("UPDATE admin_power SET open_type = :ot WHERE id = :id"),
{"ot": open_type, "id": mid},
)
def downgrade():
conn = op.get_bind()
ids = [m[0] for m in MENUS]
# 先清角色-权限关联,避免外键/脏数据残留
conn.execute(
sa.text("DELETE FROM admin_role_power WHERE power_id IN :ids").bindparams(
sa.bindparam("ids", expanding=True)
),
{"ids": ids},
)
conn.execute(
sa.text("DELETE FROM admin_power WHERE id IN :ids").bindparams(
sa.bindparam("ids", expanding=True)
),
{"ids": ids},
)