Browse Source

feat(ventAI): 非管理员隐藏技能/子智能体/思考级别等全局变更入口 (M3)

lizuo 5 ngày trước cách đây
mục cha
commit
aef76ebbbd

+ 12 - 0
src/views/ventAI/manageAssistent/api.ts

@@ -4,6 +4,7 @@ import type { SseEvent } from './components/chatModal/types';
 
 enum Api {
   usageToday = '/ventAI/api/usage/today',
+  me = '/ventAI/api/me',
   unified = '/ventAI/api/chat',
   getHistoryList = '/ventAI/api/sessions',
   getDetail = '/ventAI/api/chat/history/',
@@ -90,6 +91,17 @@ export const throwStreamHttpError = async (response: Response): Promise<never> =
  */
 export const getTodayUsage = () => defHttp.get({ url: Api.usageToday }, { isTransformResponse: false });
 
+export interface MeInfo {
+  username: string;
+  is_admin: boolean;
+  admin_configured: boolean;
+}
+
+/**
+ * 当前登录用户信息(is_admin:是否管理员,用于前端隐藏全局管理入口)
+ */
+export const getMe = () => defHttp.get<MeInfo>({ url: Api.me }, { isTransformResponse: false, errorMessageMode: 'none' });
+
 /**
  * 历史会话接口
  */

+ 21 - 0
src/views/ventAI/manageAssistent/components/AiAssistantModal.vue

@@ -26,6 +26,7 @@
         <TaskListPanel
           :taskList="taskList"
           :currentTaskId="currentTaskId"
+          :isAdmin="isAdmin"
           @switch-task="switchTask"
           @create-task="createNewTask"
           @delete-task="handleDeleteTask"
@@ -90,6 +91,7 @@
             :usageRemaining="usageToday?.remaining_tokens ?? 0"
             :usageByModel="usageToday?.by_model ?? []"
             :initialThinkLevel="thinkLevel"
+            :isAdmin="isAdmin"
             :initialEditMode="editMode"
             :taskList="taskList"
             :currentTaskId="currentTaskId"
@@ -166,6 +168,7 @@
     getSessionMode,
     putSessionMode,
     getTodayUsage,
+    getMe,
     StreamError,
   } from '../api';
   import { message, Modal } from 'ant-design-vue';
@@ -307,6 +310,10 @@
   const contextMax = ref(1000000);
   const contextPercent = ref(0);
   const thinkLevel = ref('off');
+  // 是否具备“全局变更”管理权限(TfAgents 的 is_admin);取不到一律按非管理员处理(保守)
+  const isAdmin = ref(false);
+  // 管理员白名单是否已在服务端配置;false 时可提示管理员未配置
+  const adminConfigured = ref(true);
   const editMode = ref('full');
   const contextBreakdown = ref({ messages: 0, mcp: 0, skills: 0, system_prompt: 0, other: 0 });
 
@@ -1342,6 +1349,19 @@
     }
   };
 
+  const fetchMe = async () => {
+    try {
+      const me = await getMe();
+      isAdmin.value = !!me?.is_admin;
+      adminConfigured.value = me?.admin_configured !== false;
+    } catch (e) {
+      // 取不到(未登录/接口未上线/令牌失效)→ 按非管理员处理,隐藏管理入口
+      isAdmin.value = false;
+      adminConfigured.value = true;
+      console.warn('获取当前用户权限失败,管理入口将隐藏:', e);
+    }
+  };
+
   const fetchSessionMode = async (sessionId: string) => {
     try {
       const res = await getSessionMode(sessionId);
@@ -1911,6 +1931,7 @@
       } else {
         await fetchSessionList();
         fetchModelMsg();
+        fetchMe();
         fetchScheduleListForDetail();
         fetchTodayUsage();
 

+ 3 - 1
src/views/ventAI/manageAssistent/components/chatModal/ChatInputArea.vue

@@ -237,7 +237,7 @@
           </div>
         </div> -->
         <div class="action-divider"></div>
-        <div class="btn-think-wrapper" ref="thinkPopupRef">
+        <div v-if="isAdmin" class="btn-think-wrapper" ref="thinkPopupRef">
           <a-tooltip title="思考级别">
             <div class="btn-think" @click="toggleThinkPopup">
               <div class="btn-icon think-icon"></div>
@@ -357,6 +357,7 @@
       initialEditMode?: string;
       taskList?: Task[];
       currentTaskId?: string;
+      isAdmin?: boolean;
     }>(),
     {
       contextUsed: 0,
@@ -372,6 +373,7 @@
       initialEditMode: 'full',
       taskList: () => [],
       currentTaskId: '',
+      isAdmin: false,
     }
   );
 

+ 11 - 7
src/views/ventAI/manageAssistent/components/chatModal/TaskListPanel.vue

@@ -60,6 +60,7 @@
   const props = defineProps<{
     taskList: Task[];
     currentTaskId: string;
+    isAdmin?: boolean;
   }>();
 
   const emit = defineEmits<{
@@ -99,13 +100,16 @@
     emit('pin-task', task);
   };
 
-  const optionItems = [
-    { type: 'add' as OptionType, label: '新建任务' },
-    // { type: 'search' as OptionType, label: '搜索' },
-    { type: 'skill' as OptionType, label: '技能' },
-    { type: 'sub-agents' as OptionType, label: '子智能体' },
-    { type: 'schedules' as OptionType, label: '定时任务' },
-  ];
+  const optionItems = computed(() => {
+    const items = [
+      { type: 'add' as OptionType, label: '新建任务' },
+      // { type: 'search' as OptionType, label: '搜索' },
+      { type: 'skill' as OptionType, label: '技能' },
+      { type: 'sub-agents' as OptionType, label: '子智能体' },
+      { type: 'schedules' as OptionType, label: '定时任务' },
+    ];
+    return props.isAdmin ? items : items.filter((item) => item.type !== 'skill' && item.type !== 'sub-agents');
+  });
 
   const formatRelativeTime = (dateStr?: string) => {
     if (!dateStr) return '刚刚';