Merge pull request #693 from xerrors/feat/admin-extension-management
feat(auth): 下放扩展管理权限到普通管理员
This commit is contained in:
commit
2e1c729da7
@ -121,3 +121,4 @@ make format # 格式化代码
|
||||
|
||||
1. 参考 [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) 规范编写提交信息。
|
||||
2. 使用中文提交信息,标题简洁明了,描述具体改动内容和原因。
|
||||
3. 创建 PR 需要参考 [CONTRIBUTING.md](CONTRIBUTING.md) 中的 PR 模板[PULL_REQUEST_TEMPLATE.md](.github/PULL_REQUEST_TEMPLATE.md),并在提交前完成其中的检查项。
|
||||
|
||||
@ -121,3 +121,4 @@ make format # 格式化代码
|
||||
|
||||
1. 参考 [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) 规范编写提交信息。
|
||||
2. 使用中文提交信息,标题简洁明了,描述具体改动内容和原因。
|
||||
3. 创建 PR 需要参考 [CONTRIBUTING.md](CONTRIBUTING.md) 中的 PR 模板[PULL_REQUEST_TEMPLATE.md](.github/PULL_REQUEST_TEMPLATE.md),并在提交前完成其中的检查项。
|
||||
|
||||
@ -28,6 +28,7 @@ docker logs api-dev --tail 100
|
||||
2. 在对应目录完成开发与测试
|
||||
3. 提交清晰的 Commit Message
|
||||
4. 发起 Pull Request,并说明修改内容、原因和验证方式
|
||||
5. PR 模板 [PULL_REQUEST_TEMPLATE.md](.github/PULL_REQUEST_TEMPLATE.md) 中的检查项需要在提交前完成
|
||||
|
||||
示例:
|
||||
|
||||
|
||||
@ -12,6 +12,9 @@ PROMPT = f"""
|
||||
专门用来回答用户的问题。请根据用户提供的信息,尽可能详细地回答问题。
|
||||
如果你不确定答案,可以说你不知道,但请尽量提供相关的信息或建议。请保持礼貌和专业。
|
||||
|
||||
<| 内部执行约束 |>
|
||||
以下内容仅用于指导你的内部执行过程,不属于面向用户的基本设定。除非用户明确询问系统如何工作,否则不要主动向用户说明工作区、文件系统、知识库路径、工具调用方式等内部实现细节。
|
||||
|
||||
<| 文件系统约束 |>
|
||||
系统主要工作路径为 {VIRTUAL_PATH_PREFIX},但必须遵守规范:
|
||||
- {VIRTUAL_PATH_WORKSPACE}:用于存放工作文件(用户目录,不要轻易写入)
|
||||
|
||||
@ -9,7 +9,7 @@ from fastapi.responses import FileResponse
|
||||
from pydantic import BaseModel, Field
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from server.utils.auth_middleware import get_admin_user, get_db, get_superadmin_user
|
||||
from server.utils.auth_middleware import get_admin_user, get_db
|
||||
from yuxi.services.remote_skill_install_service import install_remote_skill, list_remote_skills
|
||||
from yuxi.services.skill_service import (
|
||||
BuiltinSkillUpdateConflictError,
|
||||
@ -92,10 +92,10 @@ async def list_skills_route(
|
||||
|
||||
@skills.get("/dependency-options")
|
||||
async def get_skill_dependency_options_route(
|
||||
_current_user: User = Depends(get_superadmin_user),
|
||||
_current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""获取 skill 依赖项可选列表(仅超级管理员)。"""
|
||||
"""获取 skill 依赖项可选列表(管理员)。"""
|
||||
try:
|
||||
return {"success": True, "data": await get_skill_dependency_options(db)}
|
||||
except Exception as e:
|
||||
@ -105,7 +105,7 @@ async def get_skill_dependency_options_route(
|
||||
|
||||
@skills.get("/builtin")
|
||||
async def list_builtin_skills_route(
|
||||
_current_user: User = Depends(get_superadmin_user),
|
||||
_current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
try:
|
||||
@ -141,7 +141,7 @@ async def list_builtin_skills_route(
|
||||
@skills.post("/builtin/{slug}/install")
|
||||
async def install_builtin_skill_route(
|
||||
slug: str,
|
||||
current_user: User = Depends(get_superadmin_user),
|
||||
current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
try:
|
||||
@ -160,7 +160,7 @@ async def install_builtin_skill_route(
|
||||
async def update_builtin_skill_route(
|
||||
slug: str,
|
||||
payload: BuiltinSkillUpdateRequest,
|
||||
current_user: User = Depends(get_superadmin_user),
|
||||
current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
try:
|
||||
@ -188,10 +188,10 @@ async def update_builtin_skill_route(
|
||||
@skills.post("/import")
|
||||
async def import_skill_route(
|
||||
file: UploadFile = File(...),
|
||||
current_user: User = Depends(get_superadmin_user),
|
||||
current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""导入技能包(支持 ZIP 或单个 SKILL.md,仅超级管理员)。"""
|
||||
"""导入技能包(支持 ZIP 或单个 SKILL.md,管理员)。"""
|
||||
try:
|
||||
file_bytes = await file.read()
|
||||
item = await import_skill_zip(
|
||||
@ -213,7 +213,7 @@ async def import_skill_route(
|
||||
@skills.post("/remote/list")
|
||||
async def list_remote_skills_route(
|
||||
payload: RemoteSkillSourceRequest,
|
||||
_current_user: User = Depends(get_superadmin_user),
|
||||
_current_user: User = Depends(get_admin_user),
|
||||
):
|
||||
try:
|
||||
return {"success": True, "data": await list_remote_skills(payload.source)}
|
||||
@ -229,7 +229,7 @@ async def list_remote_skills_route(
|
||||
@skills.post("/remote/install")
|
||||
async def install_remote_skill_route(
|
||||
payload: RemoteSkillInstallRequest,
|
||||
current_user: User = Depends(get_superadmin_user),
|
||||
current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
try:
|
||||
@ -254,10 +254,10 @@ async def install_remote_skill_route(
|
||||
@skills.get("/{slug}/tree")
|
||||
async def get_skill_tree_route(
|
||||
slug: str,
|
||||
_current_user: User = Depends(get_superadmin_user),
|
||||
_current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""获取技能目录树(仅超级管理员)。"""
|
||||
"""获取技能目录树(管理员)。"""
|
||||
try:
|
||||
tree = await get_skill_tree(db, slug)
|
||||
return {"success": True, "data": tree}
|
||||
@ -274,10 +274,10 @@ async def get_skill_tree_route(
|
||||
async def get_skill_file_route(
|
||||
slug: str,
|
||||
path: str = Query(..., description="相对 skill 根目录路径"),
|
||||
_current_user: User = Depends(get_superadmin_user),
|
||||
_current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""读取技能文本文件(仅超级管理员)。"""
|
||||
"""读取技能文本文件(管理员)。"""
|
||||
try:
|
||||
data = await read_skill_file(db, slug, path)
|
||||
return {"success": True, "data": data}
|
||||
@ -294,10 +294,10 @@ async def get_skill_file_route(
|
||||
async def create_skill_file_route(
|
||||
slug: str,
|
||||
payload: SkillNodeCreateRequest,
|
||||
current_user: User = Depends(get_superadmin_user),
|
||||
current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""创建技能文件或目录(仅超级管理员)。"""
|
||||
"""创建技能文件或目录(管理员)。"""
|
||||
try:
|
||||
await create_skill_node(
|
||||
db,
|
||||
@ -321,10 +321,10 @@ async def create_skill_file_route(
|
||||
async def update_skill_file_route(
|
||||
slug: str,
|
||||
payload: SkillFileUpdateRequest,
|
||||
current_user: User = Depends(get_superadmin_user),
|
||||
current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""更新技能文本文件(仅超级管理员)。"""
|
||||
"""更新技能文本文件(管理员)。"""
|
||||
try:
|
||||
await update_skill_file(
|
||||
db,
|
||||
@ -347,10 +347,10 @@ async def update_skill_file_route(
|
||||
async def update_skill_dependencies_route(
|
||||
slug: str,
|
||||
payload: SkillDependenciesUpdateRequest,
|
||||
current_user: User = Depends(get_superadmin_user),
|
||||
current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""更新 skill 依赖(仅超级管理员)。"""
|
||||
"""更新 skill 依赖(管理员)。"""
|
||||
try:
|
||||
item = await update_skill_dependencies(
|
||||
db,
|
||||
@ -374,10 +374,10 @@ async def update_skill_dependencies_route(
|
||||
async def delete_skill_file_route(
|
||||
slug: str,
|
||||
path: str = Query(..., description="相对 skill 根目录路径"),
|
||||
_current_user: User = Depends(get_superadmin_user),
|
||||
_current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""删除技能文件或目录(仅超级管理员)。"""
|
||||
"""删除技能文件或目录(管理员)。"""
|
||||
try:
|
||||
await delete_skill_node(db, slug=slug, relative_path=path)
|
||||
return {"success": True}
|
||||
@ -394,10 +394,10 @@ async def delete_skill_file_route(
|
||||
async def export_skill_route(
|
||||
slug: str,
|
||||
background_tasks: BackgroundTasks,
|
||||
_current_user: User = Depends(get_superadmin_user),
|
||||
_current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""导出技能压缩包(仅超级管理员)。"""
|
||||
"""导出技能压缩包(管理员)。"""
|
||||
try:
|
||||
export_path, download_name = await export_skill_zip(db, slug)
|
||||
background_tasks.add_task(_cleanup_export_file, export_path)
|
||||
@ -418,10 +418,10 @@ async def export_skill_route(
|
||||
@skills.delete("/{slug}")
|
||||
async def delete_skill_route(
|
||||
slug: str,
|
||||
_current_user: User = Depends(get_superadmin_user),
|
||||
_current_user: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""删除技能(目录 + 数据库记录,仅超级管理员)。"""
|
||||
"""删除技能(目录 + 数据库记录,管理员)。"""
|
||||
try:
|
||||
await delete_skill(db, slug=slug)
|
||||
return {"success": True}
|
||||
|
||||
@ -4,11 +4,11 @@ from fastapi import FastAPI, HTTPException
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from server.routers.skill_router import skills
|
||||
from server.utils.auth_middleware import get_admin_user, get_db, get_superadmin_user
|
||||
from server.utils.auth_middleware import get_admin_user, get_db
|
||||
from yuxi.storage.postgres.models_business import Skill, User
|
||||
|
||||
|
||||
def _build_app(*, allow_superadmin: bool) -> FastAPI:
|
||||
def _build_app(*, allow_admin: bool = True) -> FastAPI:
|
||||
app = FastAPI()
|
||||
app.include_router(skills, prefix="/api")
|
||||
|
||||
@ -16,6 +16,8 @@ def _build_app(*, allow_superadmin: bool) -> FastAPI:
|
||||
return None
|
||||
|
||||
async def fake_admin_user():
|
||||
if not allow_admin:
|
||||
raise HTTPException(status_code=403, detail="需要管理员权限")
|
||||
return User(
|
||||
username="admin",
|
||||
user_id="admin",
|
||||
@ -23,19 +25,8 @@ def _build_app(*, allow_superadmin: bool) -> FastAPI:
|
||||
role="admin",
|
||||
)
|
||||
|
||||
async def fake_superadmin_user():
|
||||
if not allow_superadmin:
|
||||
raise HTTPException(status_code=403, detail="需要超级管理员权限")
|
||||
return User(
|
||||
username="root",
|
||||
user_id="root",
|
||||
password_hash="x",
|
||||
role="superadmin",
|
||||
)
|
||||
|
||||
app.dependency_overrides[get_db] = fake_db
|
||||
app.dependency_overrides[get_admin_user] = fake_admin_user
|
||||
app.dependency_overrides[get_superadmin_user] = fake_superadmin_user
|
||||
return app
|
||||
|
||||
|
||||
@ -52,7 +43,7 @@ def test_list_skills_route_returns_data(monkeypatch):
|
||||
|
||||
monkeypatch.setattr("server.routers.skill_router.list_skills", fake_list_skills)
|
||||
|
||||
app = _build_app(allow_superadmin=True)
|
||||
app = _build_app()
|
||||
client = TestClient(app)
|
||||
resp = client.get("/api/system/skills")
|
||||
assert resp.status_code == 200, resp.text
|
||||
@ -61,15 +52,21 @@ def test_list_skills_route_returns_data(monkeypatch):
|
||||
assert payload["data"][0]["slug"] == "demo"
|
||||
|
||||
|
||||
def test_import_skill_requires_superadmin():
|
||||
app = _build_app(allow_superadmin=False)
|
||||
def test_skill_management_requires_admin():
|
||||
app = _build_app(allow_admin=False)
|
||||
client = TestClient(app)
|
||||
|
||||
resp = client.post(
|
||||
dependency_resp = client.get("/api/system/skills/dependency-options")
|
||||
assert dependency_resp.status_code == 403
|
||||
|
||||
import_resp = client.post(
|
||||
"/api/system/skills/import",
|
||||
files={"file": ("demo.zip", b"not zip", "application/zip")},
|
||||
)
|
||||
assert resp.status_code == 403
|
||||
assert import_resp.status_code == 403
|
||||
|
||||
delete_resp = client.delete("/api/system/skills/demo")
|
||||
assert delete_resp.status_code == 403
|
||||
|
||||
|
||||
def test_import_skill_route_accepts_skill_md(monkeypatch):
|
||||
@ -90,7 +87,7 @@ def test_import_skill_route_accepts_skill_md(monkeypatch):
|
||||
|
||||
monkeypatch.setattr("server.routers.skill_router.import_skill_zip", fake_import_skill_zip)
|
||||
|
||||
app = _build_app(allow_superadmin=True)
|
||||
app = _build_app()
|
||||
client = TestClient(app)
|
||||
|
||||
resp = client.post(
|
||||
@ -100,7 +97,7 @@ def test_import_skill_route_accepts_skill_md(monkeypatch):
|
||||
assert resp.status_code == 200, resp.text
|
||||
assert captured["filename"] == "SKILL.md"
|
||||
assert "name: demo" in captured["file_bytes"]
|
||||
assert captured["created_by"] == "root"
|
||||
assert captured["created_by"] == "admin"
|
||||
|
||||
|
||||
def test_update_skill_file_passes_operator(monkeypatch):
|
||||
@ -114,7 +111,7 @@ def test_update_skill_file_passes_operator(monkeypatch):
|
||||
|
||||
monkeypatch.setattr("server.routers.skill_router.update_skill_file", fake_update_skill_file)
|
||||
|
||||
app = _build_app(allow_superadmin=True)
|
||||
app = _build_app()
|
||||
client = TestClient(app)
|
||||
|
||||
resp = client.put(
|
||||
@ -127,7 +124,7 @@ def test_update_skill_file_passes_operator(monkeypatch):
|
||||
assert resp.status_code == 200, resp.text
|
||||
assert captured["slug"] == "demo"
|
||||
assert captured["relative_path"] == "SKILL.md"
|
||||
assert captured["updated_by"] == "root"
|
||||
assert captured["updated_by"] == "admin"
|
||||
|
||||
|
||||
def test_dependency_options_route(monkeypatch):
|
||||
@ -140,7 +137,7 @@ def test_dependency_options_route(monkeypatch):
|
||||
|
||||
monkeypatch.setattr("server.routers.skill_router.get_skill_dependency_options", fake_get_skill_dependency_options)
|
||||
|
||||
app = _build_app(allow_superadmin=True)
|
||||
app = _build_app()
|
||||
client = TestClient(app)
|
||||
resp = client.get("/api/system/skills/dependency-options")
|
||||
assert resp.status_code == 200, resp.text
|
||||
@ -178,7 +175,7 @@ def test_update_skill_dependencies_route(monkeypatch):
|
||||
|
||||
monkeypatch.setattr("server.routers.skill_router.update_skill_dependencies", fake_update_skill_dependencies)
|
||||
|
||||
app = _build_app(allow_superadmin=True)
|
||||
app = _build_app()
|
||||
client = TestClient(app)
|
||||
resp = client.put(
|
||||
"/api/system/skills/demo/dependencies",
|
||||
@ -193,7 +190,7 @@ def test_update_skill_dependencies_route(monkeypatch):
|
||||
assert captured["tool_dependencies"] == ["calculator"]
|
||||
assert captured["mcp_dependencies"] == ["mcp-a"]
|
||||
assert captured["skill_dependencies"] == ["other-skill"]
|
||||
assert captured["updated_by"] == "root"
|
||||
assert captured["updated_by"] == "admin"
|
||||
|
||||
|
||||
def test_list_remote_skills_route(monkeypatch):
|
||||
@ -203,7 +200,7 @@ def test_list_remote_skills_route(monkeypatch):
|
||||
|
||||
monkeypatch.setattr("server.routers.skill_router.list_remote_skills", fake_list_remote_skills)
|
||||
|
||||
app = _build_app(allow_superadmin=True)
|
||||
app = _build_app()
|
||||
client = TestClient(app)
|
||||
resp = client.post("/api/system/skills/remote/list", json={"source": "anthropics/skills"})
|
||||
assert resp.status_code == 200, resp.text
|
||||
@ -230,7 +227,7 @@ def test_install_remote_skill_route(monkeypatch):
|
||||
|
||||
monkeypatch.setattr("server.routers.skill_router.install_remote_skill", fake_install_remote_skill)
|
||||
|
||||
app = _build_app(allow_superadmin=True)
|
||||
app = _build_app()
|
||||
client = TestClient(app)
|
||||
resp = client.post(
|
||||
"/api/system/skills/remote/install",
|
||||
@ -242,4 +239,4 @@ def test_install_remote_skill_route(monkeypatch):
|
||||
assert payload["data"]["slug"] == "frontend-design"
|
||||
assert captured["source"] == "anthropics/skills"
|
||||
assert captured["skill"] == "frontend-design"
|
||||
assert captured["created_by"] == "root"
|
||||
assert captured["created_by"] == "admin"
|
||||
|
||||
@ -18,6 +18,8 @@
|
||||
- 拓宽检索的知识源,统一多知识源(channel),目前已知知识库/知识图谱/网页,可拓展:个人知识库、数据库、历史对话等
|
||||
- 前置任务,多知识库并行检索(扩展 query_kb)
|
||||
- 新增 query_keywords 工具,专门用于基于关键词命中的排序,也结合词频(和 BM25 的区别?)
|
||||
- 调研将当前知识库映射为虚拟文件系统工具的可行性,先明确文件树映射、权限边界、内容读取与 Agent 工具调用形态,再决定是否实现
|
||||
- 参考 AgenticRAG 方案扩展当前 Search 工具:等待虚拟文件系统构建完成后,改进 Search 返回递增文件序列 ID,新增 Find 与 Open 能力;Summary 暂缓
|
||||
- 评估,基于 Agent 的评估,这里应该是结合 Langfuse 实现
|
||||
|
||||
### Bugs
|
||||
@ -36,6 +38,7 @@
|
||||
### 0.6.2 开发记录
|
||||
|
||||
<!-- 0.6.2 的内容请放在这里 -->
|
||||
- 下放扩展管理权限:普通管理员现在可进入扩展管理并完整管理 Tools、MCP、SubAgent、Skills;同步放开 Skill 管理接口权限并补充权限测试。
|
||||
- 调整 Agent 知识库默认选择:未显式配置知识库时默认启用当前用户可访问的全部知识库,显式保存空列表仍表示不启用知识库。
|
||||
- 优化评估基准自动生成:仅支持 commonrag/Milvus 知识库,默认参考 chunks 数量改为 1;多 chunk 场景复用知识库向量检索选择相似 chunks,不再对全量 chunks 重新计算 embedding,并移除前端 Embedding 模型选择。
|
||||
- 修复知识库文档入库状态回退:当已解析文件缺失 `markdown_file` 解析产物时,索引流程会将文件状态恢复为未解析,便于重新解析而不是停留在索引失败。
|
||||
|
||||
@ -1,10 +1,4 @@
|
||||
import {
|
||||
apiAdminGet,
|
||||
apiSuperAdminDelete,
|
||||
apiSuperAdminGet,
|
||||
apiSuperAdminPost,
|
||||
apiSuperAdminPut
|
||||
} from './base'
|
||||
import { apiAdminGet, apiAdminPost, apiAdminPut, apiAdminDelete } from './base'
|
||||
|
||||
const BASE_URL = '/api/system/skills'
|
||||
|
||||
@ -15,67 +9,67 @@ export const listSkills = async () => {
|
||||
export const importSkillZip = async (file) => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
return apiSuperAdminPost(`${BASE_URL}/import`, formData)
|
||||
return apiAdminPost(`${BASE_URL}/import`, formData)
|
||||
}
|
||||
|
||||
export const listRemoteSkills = async (source) => {
|
||||
return apiSuperAdminPost(`${BASE_URL}/remote/list`, { source })
|
||||
return apiAdminPost(`${BASE_URL}/remote/list`, { source })
|
||||
}
|
||||
|
||||
export const installRemoteSkill = async (payload) => {
|
||||
return apiSuperAdminPost(`${BASE_URL}/remote/install`, payload)
|
||||
return apiAdminPost(`${BASE_URL}/remote/install`, payload)
|
||||
}
|
||||
|
||||
export const getSkillDependencyOptions = async () => {
|
||||
return apiSuperAdminGet(`${BASE_URL}/dependency-options`)
|
||||
return apiAdminGet(`${BASE_URL}/dependency-options`)
|
||||
}
|
||||
|
||||
export const listBuiltinSkills = async () => {
|
||||
return apiSuperAdminGet(`${BASE_URL}/builtin`)
|
||||
return apiAdminGet(`${BASE_URL}/builtin`)
|
||||
}
|
||||
|
||||
export const installBuiltinSkill = async (slug) => {
|
||||
return apiSuperAdminPost(`${BASE_URL}/builtin/${encodeURIComponent(slug)}/install`)
|
||||
return apiAdminPost(`${BASE_URL}/builtin/${encodeURIComponent(slug)}/install`)
|
||||
}
|
||||
|
||||
export const updateBuiltinSkill = async (slug, force = false) => {
|
||||
return apiSuperAdminPost(`${BASE_URL}/builtin/${encodeURIComponent(slug)}/update`, { force })
|
||||
return apiAdminPost(`${BASE_URL}/builtin/${encodeURIComponent(slug)}/update`, { force })
|
||||
}
|
||||
|
||||
export const getSkillTree = async (slug) => {
|
||||
return apiSuperAdminGet(`${BASE_URL}/${encodeURIComponent(slug)}/tree`)
|
||||
return apiAdminGet(`${BASE_URL}/${encodeURIComponent(slug)}/tree`)
|
||||
}
|
||||
|
||||
export const getSkillFile = async (slug, path) => {
|
||||
return apiSuperAdminGet(
|
||||
return apiAdminGet(
|
||||
`${BASE_URL}/${encodeURIComponent(slug)}/file?path=${encodeURIComponent(path)}`
|
||||
)
|
||||
}
|
||||
|
||||
export const createSkillFile = async (slug, payload) => {
|
||||
return apiSuperAdminPost(`${BASE_URL}/${encodeURIComponent(slug)}/file`, payload)
|
||||
return apiAdminPost(`${BASE_URL}/${encodeURIComponent(slug)}/file`, payload)
|
||||
}
|
||||
|
||||
export const updateSkillFile = async (slug, payload) => {
|
||||
return apiSuperAdminPut(`${BASE_URL}/${encodeURIComponent(slug)}/file`, payload)
|
||||
return apiAdminPut(`${BASE_URL}/${encodeURIComponent(slug)}/file`, payload)
|
||||
}
|
||||
|
||||
export const updateSkillDependencies = async (slug, payload) => {
|
||||
return apiSuperAdminPut(`${BASE_URL}/${encodeURIComponent(slug)}/dependencies`, payload)
|
||||
return apiAdminPut(`${BASE_URL}/${encodeURIComponent(slug)}/dependencies`, payload)
|
||||
}
|
||||
|
||||
export const deleteSkillFile = async (slug, path) => {
|
||||
return apiSuperAdminDelete(
|
||||
return apiAdminDelete(
|
||||
`${BASE_URL}/${encodeURIComponent(slug)}/file?path=${encodeURIComponent(path)}`
|
||||
)
|
||||
}
|
||||
|
||||
export const exportSkill = async (slug) => {
|
||||
return apiSuperAdminGet(`${BASE_URL}/${encodeURIComponent(slug)}/export`, {}, 'blob')
|
||||
return apiAdminGet(`${BASE_URL}/${encodeURIComponent(slug)}/export`, {}, 'blob')
|
||||
}
|
||||
|
||||
export const deleteSkill = async (slug) => {
|
||||
return apiSuperAdminDelete(`${BASE_URL}/${encodeURIComponent(slug)}`)
|
||||
return apiAdminDelete(`${BASE_URL}/${encodeURIComponent(slug)}`)
|
||||
}
|
||||
|
||||
export const skillApi = {
|
||||
|
||||
@ -152,14 +152,12 @@ const mainList = computed(() => {
|
||||
})
|
||||
}
|
||||
|
||||
if (userStore.isSuperAdmin) {
|
||||
items.push({
|
||||
name: '扩展管理',
|
||||
path: '/extensions',
|
||||
icon: Blocks,
|
||||
activeIcon: Blocks
|
||||
})
|
||||
}
|
||||
items.push({
|
||||
name: '扩展管理',
|
||||
path: '/extensions',
|
||||
icon: Blocks,
|
||||
activeIcon: Blocks
|
||||
})
|
||||
|
||||
items.push({
|
||||
name: '模型配置',
|
||||
|
||||
@ -134,8 +134,7 @@ const router = createRouter({
|
||||
meta: {
|
||||
keepAlive: false,
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
requiresSuperAdmin: true
|
||||
requiresAdmin: true
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -145,8 +144,7 @@ const router = createRouter({
|
||||
meta: {
|
||||
keepAlive: false,
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
requiresSuperAdmin: true
|
||||
requiresAdmin: true
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -156,8 +154,7 @@ const router = createRouter({
|
||||
meta: {
|
||||
keepAlive: false,
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
requiresSuperAdmin: true
|
||||
requiresAdmin: true
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -167,8 +164,7 @@ const router = createRouter({
|
||||
meta: {
|
||||
keepAlive: false,
|
||||
requiresAuth: true,
|
||||
requiresAdmin: true,
|
||||
requiresSuperAdmin: true
|
||||
requiresAdmin: true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user