Files
xuanzhi-service/web/.ai-transition/book-admin-menu-scripts/02-assign-book-admin-menus-to-roles.browser-console.js
wdh-home 392fbea7eb
Some checks failed
CI / init (pull_request) Has been cancelled
CI / Frontend node 18.16.0 (pull_request) Has been cancelled
CI / Backend go (1.22) (pull_request) Has been cancelled
CI / release-pr (pull_request) Has been cancelled
CI / devops-test (1.22, 18.16.0) (pull_request) Has been cancelled
CI / release-please (pull_request) Has been cancelled
CI / devops-prod (1.22, 18.x) (pull_request) Has been cancelled
CI / docker (pull_request) Has been cancelled
基础项目
2026-04-26 15:32:46 +08:00

158 lines
4.7 KiB
JavaScript
Raw Permalink 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.
/**
* 书籍后台管理菜单角色授权脚本
*
* 使用方式:
* 1. 先执行 01-create-book-admin-menus.browser-console.js。
* 2. 登录后台管理前端,打开浏览器控制台。
* 3. 如需给多个角色授权,先设置角色 ID
* window.__XUANZHI_BOOK_AUTHORITY_IDS__ = [888, 8881]
* 4. 如前端接口代理不是 /api先执行
* window.__XUANZHI_BASE_API__ = 'http://127.0.0.1:8888'
* 5. 粘贴本文件全部内容并执行。
*
* 说明:
* - /menu/addMenuAuthority 是全量覆盖角色菜单。
* - 本脚本会先读取角色已有菜单,再合并书籍菜单,避免覆盖原有权限。
*/
(async () => {
const BASE_API = window.__XUANZHI_BASE_API__ || '/api'
const TOKEN = window.__XUANZHI_TOKEN__ || localStorage.getItem('token') || getCookie('x-token')
const AUTHORITY_IDS = window.__XUANZHI_BOOK_AUTHORITY_IDS__ || [888]
const TARGET_MENU_NAMES = [
'book',
'bookManage',
'bookChapterManage',
'bookAuthorManage',
'bookSeriesManage',
'bookCommentManage',
'bookReadRecordManage',
'bookFavoriteRecordManage',
'bookCommentLikeRecordManage'
]
let userId = window.__XUANZHI_USER_ID__ || localStorage.getItem('userId') || ''
if (!TOKEN) {
throw new Error('未找到 token请先登录后台或手动设置 window.__XUANZHI_TOKEN__')
}
if (!Array.isArray(AUTHORITY_IDS) || AUTHORITY_IDS.length === 0) {
throw new Error('请设置 window.__XUANZHI_BOOK_AUTHORITY_IDS__例如[888, 8881]')
}
userId = userId || await getCurrentUserId()
const allMenus = flattenMenus(await getBaseMenuTree())
const targetMenus = TARGET_MENU_NAMES.map((name) => {
const menu = allMenus.find((item) => item.name === name)
if (!menu) throw new Error(`未找到菜单 ${name},请先执行创建菜单脚本。`)
return menu
})
for (const authorityId of AUTHORITY_IDS) {
const currentMenus = await getMenuAuthority(authorityId)
const merged = mergeMenusById(currentMenus, targetMenus)
await apiPost('/menu/addMenuAuthority', {
authorityId,
menus: merged
})
console.log(`[authority] ${authorityId} 已授权书籍后台菜单,合并后菜单数量:${merged.length}`)
}
console.log('书籍后台菜单角色授权完成。刷新页面或重新登录后可查看菜单。')
async function getBaseMenuTree() {
const res = await apiPost('/menu/getBaseMenuTree', {})
return res.data?.menus || []
}
async function getMenuAuthority(authorityId) {
const res = await apiPost('/menu/getMenuAuthority', { authorityId })
return res.data?.menus || []
}
function mergeMenusById(currentMenus, targetMenus) {
const map = new Map()
;[...(currentMenus || []), ...(targetMenus || [])].forEach((item) => {
const id = getMenuId(item)
if (!id) return
map.set(Number(id), normalizeMenu(item))
})
return [...map.values()]
}
function normalizeMenu(item) {
return {
ID: getMenuId(item),
path: item.path,
name: item.name,
hidden: item.hidden,
parentId: item.parentId,
component: item.component,
sort: item.sort,
meta: item.meta,
parameters: item.parameters || [],
menuBtn: item.menuBtn || []
}
}
async function getCurrentUserId() {
try {
const res = await apiGet('/user/getUserInfo')
return res.data?.userInfo?.ID || res.data?.userInfo?.id || ''
} catch (error) {
console.warn('读取当前用户 ID 失败,将不带 x-user-id 调用菜单接口。必要时可手动设置 window.__XUANZHI_USER_ID__。', error)
return ''
}
}
async function apiGet(path) {
return apiRequest(path, { method: 'GET' })
}
async function apiPost(path, data) {
return apiRequest(path, {
method: 'POST',
body: JSON.stringify(data)
})
}
async function apiRequest(path, options = {}) {
const res = await fetch(`${BASE_API}${path}`, {
...options,
headers: {
'Content-Type': 'application/json',
'x-token': TOKEN,
'x-user-id': String(userId || ''),
...(options.headers || {})
}
})
const json = await res.json().catch(() => ({}))
if (!res.ok || json.code !== 0) {
throw new Error(`${path} 调用失败:${json.msg || res.statusText}`)
}
return json
}
function flattenMenus(list) {
const result = []
const walk = (items) => {
;(items || []).forEach((item) => {
result.push(item)
walk(item.children)
})
}
walk(list)
return result
}
function getMenuId(menu) {
return menu?.ID || menu?.id || menu?.menuId
}
function getCookie(name) {
return document.cookie
.split('; ')
.find((row) => row.startsWith(`${name}=`))
?.split('=')[1] || ''
}
})()