Ver Fonte

[Mod 0000]系统header增加ai解读按钮

wangkeyi há 3 dias atrás
pai
commit
6f3d47a908

+ 3 - 0
src/assets/images/ventAI/dataPicker/AI-close.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="110.862" height="99.776" viewBox="0 0 110.862 99.776">
+  <path id="路径_58058" data-name="路径 58058" d="M146.307,148.685a11.086,11.086,0,1,0-11.086,0v12.572H104.734a5.543,5.543,0,0,0-5.543,5.543v55.431a5.543,5.543,0,0,0,5.543,5.543h72.06a5.543,5.543,0,0,0,5.543-5.543V166.8a5.543,5.543,0,0,0-5.543-5.543H146.307Zm-22.172,29.2a5.543,5.543,0,1,1-5.543,5.543A5.543,5.543,0,0,1,124.135,177.886Zm33.259,0a5.543,5.543,0,1,1-5.543,5.543A5.543,5.543,0,0,1,157.394,177.886ZM124.135,205.6a5.543,5.543,0,0,1,5.543-5.543h22.172a5.543,5.543,0,1,1,0,11.086H129.678A5.543,5.543,0,0,1,124.135,205.6ZM90.876,177.886a5.543,5.543,0,0,1,5.543,5.543V205.6a5.543,5.543,0,1,1-11.086,0V183.429a5.543,5.543,0,0,1,5.543-5.543Zm99.776,0a5.543,5.543,0,0,1,5.543,5.543V205.6a5.543,5.543,0,1,1-11.086,0V183.429a5.543,5.543,0,0,1,5.543-5.543Z" transform="translate(-85.333 -127.998)" fill="#6a7680"/>
+</svg>

+ 3 - 0
src/assets/images/ventAI/dataPicker/AI-open.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="110.862" height="99.776" viewBox="0 0 110.862 99.776">
+  <path id="路径_58053" data-name="路径 58053" d="M146.307,148.685a11.086,11.086,0,1,0-11.086,0v12.572H104.734a5.543,5.543,0,0,0-5.543,5.543v55.431a5.543,5.543,0,0,0,5.543,5.543h72.06a5.543,5.543,0,0,0,5.543-5.543V166.8a5.543,5.543,0,0,0-5.543-5.543H146.307Zm-22.172,29.2a5.543,5.543,0,1,1-5.543,5.543A5.543,5.543,0,0,1,124.135,177.886Zm33.259,0a5.543,5.543,0,1,1-5.543,5.543A5.543,5.543,0,0,1,157.394,177.886ZM124.135,205.6a5.543,5.543,0,0,1,5.543-5.543h22.172a5.543,5.543,0,1,1,0,11.086H129.678A5.543,5.543,0,0,1,124.135,205.6ZM90.876,177.886a5.543,5.543,0,0,1,5.543,5.543V205.6a5.543,5.543,0,1,1-11.086,0V183.429a5.543,5.543,0,0,1,5.543-5.543Zm99.776,0a5.543,5.543,0,0,1,5.543,5.543V205.6a5.543,5.543,0,1,1-11.086,0V183.429a5.543,5.543,0,0,1,5.543-5.543Z" transform="translate(-85.333 -127.998)" fill="#00baff"/>
+</svg>

+ 11 - 0
src/design/themify/default.less

@@ -108,4 +108,15 @@ html {
   --img-chat-download-icon-btn: url('/src/assets/images/ventAI/chatModalBlue/4-5.svg');
   --img-chat-preview-icon: url('/src/assets/images/ventAI/chatModalBlue/4-6.svg');
   --img-chat-welcome-img: url('/src/assets/images/ventAI/chatModalBlue/5-1.png');
+
+  // 全屏模式图片
+  --img-chat-fs-header-bg: url('/src/assets/images/ventAI/chatModalBlue/fullscreen/1-1.png');
+  --img-chat-fs-modal-bg: url('/src/assets/images/ventAI/chatModalBlue/fullscreen/1-2.png');
+  --img-chat-fs-task-panel-bg: url('/src/assets/images/ventAI/chatModalBlue/fullscreen/1-3.png');
+  --img-chat-fs-panel-bg: url('/src/assets/images/ventAI/chatModalBlue/fullscreen/1-4.png');
+  --img-chat-fs-collapse-btn-bg: url('/src/assets/images/ventAI/chatModalBlue/fullscreen/1-5.png');
+  --img-chat-fs-options-item-bg: url('/src/assets/images/ventAI/chatModalBlue/fullscreen/1-6.png');
+  --img-chat-fs-options-item-active-bg: url('/src/assets/images/ventAI/chatModalBlue/fullscreen/1-7.png');
+  --img-chat-fs-header-title-bg: url('/src/assets/images/ventAI/chatModalBlue/fullscreen/1-8.png');
+  --img-chat-fs-header-title-icon: url('/src/assets/images/ventAI/chatModalBlue/fullscreen/1-9.svg');
 }

+ 20 - 0
src/layouts/default/header/index.vue

@@ -62,6 +62,7 @@
         <a-radio :value="true">快速模式</a-radio>
         <a-radio :value="false">特效模式</a-radio>
       </a-radio-group> -->
+
       <div v-if="hasPermission('show:modalChange')" @click="changeModalType" style="width: 92px; color: #fff; cursor: pointer">
         <div v-if="programModalType == true"> <span class="icon">⚡</span>快速模式</div>
         <div v-if="programModalType == false"> <span class="icon">✨</span>特效模式</div>
@@ -69,6 +70,13 @@
       <WeatherBroadcast v-if="sysOrgCode != 'sdmtjtgsd' && isShowQy && portValue != '8062' && hasPermission('show:weather')" />
       <VoiceBroadcast v-if="sysOrgCode != 'sdmtjtgsd' && portValue != '8062'" />
       <AIChat v-if="hasPermission('show:AIChat')" />
+      <div style="width: 24px; height: 24px; cursor: pointer; user-select: none; margin: 0 3px">
+        <img
+          :src="dataPickerHoverEnabled ? AIOpenIcon : AICloseIcon"
+          :title="dataPickerHoverEnabled ? '关闭AI解读' : '开启AI解读'"
+          @click="toggleDataPickerHover"
+        />
+      </div>
       <VoiceBroadcastGsd v-if="sysOrgCode == 'sdmtjtgsd'" />
       <UserDropDown v-if="showUserDropdown" :theme="getHeaderTheme" />
       <LoginSelect ref="loginSelectRef" @success="loginSelectOk" />
@@ -116,6 +124,9 @@
   import { usePermission } from '/@/hooks/web/usePermission';
   import { useAppStore } from '/@/store/modules/app';
   import { router } from '/@/router';
+  import { dataPickerHoverEnabled, setDataPickerHoverEnabled } from '/@/views/ventAI/dataPicker';
+  import AIOpenIcon from '/@/assets/images/ventAI/dataPicker/AI-open.svg';
+  import AICloseIcon from '/@/assets/images/ventAI/dataPicker/AI-close.svg';
 
   export default defineComponent({
     name: 'LayoutHeader',
@@ -252,6 +263,10 @@
         window.location.reload();
       };
 
+      const toggleDataPickerHover = () => {
+        setDataPickerHoverEnabled(!dataPickerHoverEnabled.value);
+      };
+
       onMounted(() => {
         showLoginSelect();
       });
@@ -294,6 +309,10 @@
         isShowQy,
         programModalType,
         changeModalType,
+        dataPickerHoverEnabled,
+        toggleDataPickerHover,
+        AIOpenIcon,
+        AICloseIcon,
       };
     },
   });
@@ -371,5 +390,6 @@
     display: flex;
     align-items: center;
     height: 48px;
+    width: max-content;
   }
 </style>

+ 1 - 1
src/views/ventAI/dataPicker/index.ts

@@ -1,4 +1,4 @@
-export { useDataPicker } from './useDataPicker';
+export { useDataPicker, dataPickerHoverEnabled, setDataPickerHoverEnabled } from './useDataPicker';
 export type { DataPickerOptions } from './useDataPicker';
 export { fetchTunnelInterpretation, fetchDeviceInterpretation } from './api';
 export type { SSERawEvent, SSEEventType, TodoItem, ToolCallRecord } from './types';

+ 34 - 0
src/views/ventAI/dataPicker/useDataPicker.ts

@@ -5,6 +5,34 @@ import type { TodoItem, ToolCallRecord, SSERawEvent } from './types';
 import DataPickerModal from './components/DataPickerModal.vue';
 import aiIcon from '@/assets/images/ventAI/dataPicker/AI-icon.svg';
 
+// ─── 全局开关:控制悬停模式浮动按钮是否启用 ─────────────────────────────────
+const STORAGE_KEY = 'dataPickerHoverEnabled';
+
+export const dataPickerHoverEnabled = ref(localStorage.getItem(STORAGE_KEY) !== 'false');
+
+/** 记录所有活跃的悬停实例,以便全局开关关闭时立即隐藏按钮 */
+const allHoverInstances = new Set<HoverInstance>();
+
+export function setDataPickerHoverEnabled(val: boolean) {
+  dataPickerHoverEnabled.value = val;
+  localStorage.setItem(STORAGE_KEY, String(val));
+  if (!val) {
+    // 关闭时立即隐藏所有浮动按钮并清除定时器
+    allHoverInstances.forEach((inst) => {
+      inst.cancelLeave();
+      inst.clearHideTimer();
+      const btn = (inst as any)._btn as HTMLElement;
+      if (btn) {
+        btn.style.display = 'none';
+        btn.style.transform = 'scale(0.9)';
+        btn.style.opacity = '0';
+      }
+      // 重新挂载 mousemove 监听,以便开启后能正常触发
+      inst.attachMove();
+    });
+  }
+}
+
 // ─── 按钮 DOM 构建(悬停模式专用)──────────────────────────────────────────
 const BUTTON_CLASS = 'di-floating-btn';
 
@@ -116,6 +144,7 @@ function createHoverInstance(btn: HTMLElement) {
       hostEl = el;
     },
     onEnter(e: MouseEvent) {
+      if (!dataPickerHoverEnabled.value) return;
       clearHideTimer();
       if (!visible) {
         setPosition(e.clientX - 36, e.clientY - 34);
@@ -126,6 +155,7 @@ function createHoverInstance(btn: HTMLElement) {
       }
     },
     onMove(e: MouseEvent) {
+      if (!dataPickerHoverEnabled.value) return;
       setPosition(e.clientX - 36, e.clientY - 34);
       clearPauseTimer();
       pauseTimer = setTimeout(show, PAUSE_DELAY);
@@ -146,6 +176,7 @@ function createHoverInstance(btn: HTMLElement) {
     },
     clearHideTimer,
     startHideTimer,
+    attachMove,
     destroy() {
       clearPauseTimer();
       clearHideTimer();
@@ -327,6 +358,8 @@ export function useDataPicker(
     btnContainer!.appendChild(btn);
     const inst = createHoverInstance(btn);
     (btn as any).__di_owner = inst;
+    (inst as any)._btn = btn;
+    allHoverInstances.add(inst);
     btn.addEventListener('click', (e) => {
       e.stopPropagation();
       const item = (inst as any).raw;
@@ -373,6 +406,7 @@ export function useDataPicker(
       if (mode === 'hover') {
         const inst = hoverMap.get(el);
         if (inst) {
+          allHoverInstances.delete(inst);
           inst.destroy();
           hoverMap.delete(el);
         }