gaoluyang
4 天以前 6e173210a874ff7601aa68eab56e912f5619c79c
src/views/aiIndustrialBrain/components/AiAssistantWorkspace.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,198 @@
<template>
  <transition name="fade">
    <section v-if="visible" class="assistant-workspace">
      <div class="assistant-workspace__panel">
        <button
          v-if="assistantMode === 'pending'"
          type="button"
          class="workspace-back-btn"
          @click="$emit('close')"
        >
          <el-icon><ArrowLeftBold /></el-icon>
          <span>返回工业大屏</span>
        </button>
        <div class="assistant-workspace__body">
          <AIChatSidebar
            v-if="assistantMode !== 'pending'"
            :key="assistantMode"
            class="workspace-chat"
            :assistants="resolvedAssistants"
            :default-assistant="assistantMode"
            :hide-trigger="true"
            :auto-open="true"
            drawer-size="100%"
            drawer-direction="ttb"
            header-extra-action-text="返回工业大屏"
            @header-extra-action="$emit('close')"
          />
          <div v-else class="workspace-pending">
            <div class="workspace-pending__content">
              <h3>{{ agentTitle }}</h3>
              <p>正在开发,敬请期待......</p>
            </div>
          </div>
        </div>
      </div>
    </section>
  </transition>
</template>
<script setup>
import { computed } from "vue";
import { ArrowLeftBold } from "@element-plus/icons-vue";
import AIChatSidebar from "@/components/AIChatSidebar/index.vue";
import { assistantRegistry } from "@/components/AIChatSidebar/assistants";
const props = defineProps({
  visible: {
    type: Boolean,
    default: false,
  },
  agent: {
    type: Object,
    default: () => ({}),
  },
});
defineEmits(["close"]);
const agentKey = computed(() => String(props.agent?.key || ""));
const agentTitle = computed(() => String(props.agent?.name || "AI助手"));
/**
 * ç»´æŠ¤è§„则:
 * AI工业大脑新增智能体时,若希望右侧弹窗可用,需保证智能体 key åœ¨ assistantRegistry ä¸­æœ‰åŒåé…ç½®ã€‚
 * æœªé…ç½®æ—¶ä¼šè¿›å…¥ pending(开发中)态,作为显式提醒。
 */
const resolvedAssistant = computed(() => assistantRegistry[agentKey.value] || null);
const assistantMode = computed(() => {
  return resolvedAssistant.value ? agentKey.value : "pending";
});
const resolvedAssistants = computed(() => (resolvedAssistant.value ? [resolvedAssistant.value] : []));
</script>
<style scoped>
.assistant-workspace {
  position: fixed;
  inset: 0;
  z-index: 2100;
  padding: 12px;
  background: rgba(33, 49, 63, 0.24);
  backdrop-filter: blur(2px);
}
.assistant-workspace__panel {
  position: relative;
  height: 100%;
  border-radius: 22px;
  border: 1px solid var(--surface-border);
  background: linear-gradient(180deg, #f9fcfb 0%, #f0f5f2 100%);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
.assistant-workspace__body {
  height: 100%;
  min-height: 100%;
}
.workspace-back-btn {
  position: absolute;
  top: 16px;
  right: 20px;
  z-index: 5;
  height: 36px;
  padding: 0 14px;
  border: 1px solid rgba(38, 112, 183, 0.3);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.92);
  color: #25528f;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease;
}
.workspace-back-btn:hover {
  border-color: rgba(31, 122, 114, 0.45);
  color: #1f5ddf;
  box-shadow: 0 8px 16px rgba(31, 122, 114, 0.14);
  transform: translateY(-1px);
}
.workspace-chat {
  width: 100%;
  height: 100%;
}
.workspace-chat :deep(.ai-chat-sidebar-wrapper) {
  height: 100%;
}
.workspace-chat :deep(.ai-chat-drawer) {
  height: 100%;
}
.workspace-chat :deep(.el-drawer) {
  height: 100% !important;
  width: 100% !important;
}
.workspace-pending {
  height: 100%;
  display: grid;
  place-items: center;
  padding: 20px;
  color: var(--text-secondary);
}
.workspace-pending__content {
  display: grid;
  gap: 12px;
  text-align: center;
}
.workspace-pending__content h3 {
  margin: 0;
  font-size: 36px;
  color: var(--text-primary);
}
.workspace-pending__content p {
  margin: 0;
  font-size: 24px;
}
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s ease;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
@media (max-width: 1600px) {
  .workspace-back-btn {
    top: 12px;
    right: 14px;
    height: 32px;
    padding: 0 12px;
    font-size: 13px;
  }
  .workspace-pending__content h3 {
    font-size: 30px;
  }
  .workspace-pending__content p {
    font-size: 20px;
  }
}
</style>