<template>
|
<div ref="screenRef" class="ai-brain-screen">
|
<section class="brain-stage">
|
<header class="brain-head">
|
<div class="head-date">
|
<p>{{ weekLabel }}</p>
|
<p>{{ dateLabel }}</p>
|
</div>
|
|
<div class="head-title">
|
<span>AI工业大脑</span>
|
</div>
|
|
<div class="head-actions">
|
<button type="button" class="head-back-btn" @click="goBack">
|
<el-icon><ArrowLeftBold /></el-icon>
|
<span>返回</span>
|
</button>
|
</div>
|
</header>
|
|
<section class="brain-intro">
|
<h2>工业AI数字员工,赋能智造新纪元</h2>
|
<p>六大AI助手协同企业管理、销售、采购、生产、财务及数据全链路</p>
|
<div class="intro-sign">阿里云 × 千问大模型 × 智能体AI</div>
|
</section>
|
|
<section class="carousel-area">
|
<button type="button" class="nav-btn nav-btn--left" @click="prevCard">
|
<el-icon><ArrowLeftBold /></el-icon>
|
</button>
|
|
<div class="carousel-track">
|
<article
|
v-for="card in visibleCards"
|
:key="card.agent.key"
|
class="agent-card"
|
:class="{ 'agent-card--active': card.offset === 0 }"
|
:style="getCardStyle(card.offset)"
|
@click="openAssistant(card.realIndex)"
|
>
|
<div class="agent-card__head" :class="{ 'agent-card__head--active': card.offset === 0 }">
|
{{ card.agent.name }}
|
</div>
|
|
<div class="agent-card__body" :class="{ 'agent-card__body--active': card.offset === 0 }">
|
<div class="avatar-shell" :class="{ 'avatar-shell--active': card.offset === 0 }">
|
<div class="avatar-base"></div>
|
<div class="avatar-cut">
|
<img v-if="card.agent.avatar" class="avatar-cut__img" :src="card.agent.avatar" :alt="card.agent.name" />
|
</div>
|
</div>
|
<div v-if="card.offset === 0" class="highlight-list">
|
<div
|
v-for="highlight in card.agent.highlights"
|
:key="highlight"
|
class="highlight-item"
|
>
|
{{ highlight }}
|
</div>
|
</div>
|
</div>
|
</article>
|
</div>
|
|
<button type="button" class="nav-btn nav-btn--right" @click="nextCard">
|
<el-icon><ArrowRightBold /></el-icon>
|
</button>
|
</section>
|
|
<section class="brain-footer">
|
<div class="footer-grid-overlay"></div>
|
|
<div class="footer-metrics">
|
<article class="footer-metric">
|
<span class="footer-metric__label">在线智能体</span>
|
<strong class="footer-metric__value">{{ agents.length }}个</strong>
|
<small class="footer-metric__hint">全链路协同运行</small>
|
</article>
|
|
<article class="footer-metric footer-metric--focus">
|
<span class="footer-metric__label">当前焦点</span>
|
<strong class="footer-metric__value">{{ getFooterAgentName(focusAgent.name) }}</strong>
|
<small class="footer-metric__hint">{{ focusAgent.highlights?.[0] || "智能分析联动" }}</small>
|
</article>
|
|
<article class="footer-metric footer-metric--period">
|
<span class="footer-metric__label">轮播周期</span>
|
<strong class="footer-metric__value">{{ carouselSecondsText }}</strong>
|
<div class="footer-period-control">
|
<button type="button" class="period-btn" @click="adjustCarouselSeconds(-0.5)">-</button>
|
<input
|
v-model.number="carouselSeconds"
|
class="period-input"
|
type="number"
|
min="2"
|
max="12"
|
step="0.5"
|
/>
|
<span class="period-unit">s</span>
|
<button type="button" class="period-btn" @click="adjustCarouselSeconds(0.5)">+</button>
|
</div>
|
<input
|
v-model.number="carouselSeconds"
|
class="footer-period-slider"
|
type="range"
|
min="2"
|
max="12"
|
step="0.5"
|
/>
|
<small class="footer-metric__hint">可手动设置 2.0s - 12.0s</small>
|
</article>
|
</div>
|
|
<div class="footer-rail">
|
<div class="footer-rail__line">
|
<span class="footer-rail__flow"></span>
|
</div>
|
<div class="footer-rail__nodes">
|
<button
|
v-for="node in footerNodes"
|
:key="node.key"
|
type="button"
|
class="footer-node"
|
:class="{ 'footer-node--active': node.index === carouselIndex }"
|
@click="openAssistant(node.index)"
|
>
|
<span class="footer-node__dot"></span>
|
<span class="footer-node__name">{{ getFooterAgentName(node.name) }}</span>
|
</button>
|
</div>
|
</div>
|
</section>
|
</section>
|
|
<AiAssistantWorkspace
|
:visible="fullscreenVisible"
|
:agent="currentAgent"
|
@close="closeFullscreen"
|
/>
|
</div>
|
</template>
|
|
<script setup>
|
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
import { useRouter } from "vue-router";
|
import { ArrowLeftBold, ArrowRightBold } from "@element-plus/icons-vue";
|
import AiAssistantWorkspace from "./components/AiAssistantWorkspace.vue";
|
import todoAvatar from "@/assets/AI/待办助手.png";
|
import salesAvatar from "@/assets/AI/销售助手.png";
|
import purchaseAvatar from "@/assets/AI/采购助手.png";
|
import productionAvatar from "@/assets/AI/生产助手.png";
|
import financeAvatar from "@/assets/AI/财务助手.png";
|
|
const router = useRouter();
|
|
const agents = [
|
{
|
key: "general",
|
name: "AI待办助手",
|
highlights: ["跨模块流程诊断", "经营风险智能提醒"],
|
},
|
{
|
key: "sales",
|
name: "AI销售助手",
|
highlights: ["客户流失风险分析", "回款与报价策略建议"],
|
},
|
{
|
key: "purchase",
|
name: "AI采购助手",
|
highlights: ["供应链指标分析", "采购订单智能生成"],
|
},
|
{
|
key: "production",
|
name: "AI生产助手",
|
highlights: ["工序瓶颈定位", "产能与报废智能预警"],
|
},
|
{
|
key: "finance",
|
name: "AI财务助手",
|
highlights: ["现金流压力预判", "费用结构智能分析"],
|
},
|
];
|
|
const avatarByAgentKey = {
|
general: todoAvatar,
|
sales: salesAvatar,
|
purchase: purchaseAvatar,
|
production: productionAvatar,
|
finance: financeAvatar,
|
};
|
|
for (let i = agents.length - 1; i >= 0; i -= 1) {
|
const agent = agents[i];
|
const avatar = avatarByAgentKey[agent.key];
|
if (!avatar) {
|
agents.splice(i, 1);
|
continue;
|
}
|
agent.avatar = avatar;
|
}
|
|
const carouselIndex = ref(Math.min(2, Math.max(agents.length - 1, 0)));
|
const fullscreenVisible = ref(false);
|
const screenRef = ref(null);
|
const carouselIntervalMs = ref(4500);
|
|
let carouselTimer = null;
|
|
const fallbackAgent = {
|
key: "fallback",
|
name: "AI助手",
|
avatar: "",
|
highlights: [],
|
};
|
|
const currentAgent = computed(() => agents[carouselIndex.value] || agents[0] || fallbackAgent);
|
const focusAgent = computed(() => currentAgent.value || fallbackAgent);
|
const footerNodes = computed(() =>
|
agents.map((agent, index) => ({
|
key: agent.key,
|
name: agent.name,
|
index,
|
}))
|
);
|
const carouselSeconds = computed({
|
get: () => Number((carouselIntervalMs.value / 1000).toFixed(1)),
|
set: (value) => {
|
const next = Number(value);
|
if (!Number.isFinite(next)) return;
|
const clamped = Math.max(2, Math.min(12, Math.round(next * 2) / 2));
|
carouselIntervalMs.value = Math.round(clamped * 1000);
|
},
|
});
|
const carouselSecondsText = computed(() => `${carouselSeconds.value.toFixed(1)}s`);
|
|
const weekLabel = computed(() => {
|
const weekMap = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
|
return weekMap[new Date().getDay()];
|
});
|
|
const dateLabel = computed(() => {
|
const now = new Date();
|
const year = now.getFullYear();
|
const month = String(now.getMonth() + 1).padStart(2, "0");
|
const day = String(now.getDate()).padStart(2, "0");
|
return `${year}年${month}月${day}日`;
|
});
|
|
const visibleCards = computed(() => {
|
const total = agents.length;
|
return agents
|
.map((agent, index) => {
|
let offset = index - carouselIndex.value;
|
if (offset > total / 2) offset -= total;
|
if (offset < -total / 2) offset += total;
|
return { agent, offset, realIndex: index };
|
})
|
.filter((item) => Math.abs(item.offset) <= 2)
|
.sort((a, b) => a.offset - b.offset);
|
});
|
|
function getCardStyle(offset) {
|
const distance = Math.abs(offset);
|
const scale = distance === 0 ? 1 : distance === 1 ? 0.88 : 0.78;
|
const opacity = distance === 0 ? 1 : distance === 1 ? 0.92 : 0.76;
|
return {
|
transform: `translateX(${offset * 340}px) scale(${scale})`,
|
zIndex: String(50 - distance),
|
opacity,
|
};
|
}
|
|
function getFooterAgentName(name) {
|
return String(name || "AI助手").replace(/^AI/, "");
|
}
|
|
function adjustCarouselSeconds(delta) {
|
carouselSeconds.value = carouselSeconds.value + delta;
|
}
|
|
function prevCard() {
|
const total = agents.length;
|
if (!total) return;
|
carouselIndex.value = (carouselIndex.value - 1 + total) % total;
|
}
|
|
function nextCard() {
|
const total = agents.length;
|
if (!total) return;
|
carouselIndex.value = (carouselIndex.value + 1) % total;
|
}
|
|
async function enterBrowserFullscreen() {
|
if (document.fullscreenElement) return;
|
const target = screenRef.value || document.documentElement;
|
if (!target || typeof target.requestFullscreen !== "function") return;
|
try {
|
await target.requestFullscreen();
|
} catch (error) {
|
// Ignore: browser may block fullscreen when there is no direct user activation.
|
}
|
}
|
|
async function exitBrowserFullscreen() {
|
if (!document.fullscreenElement || typeof document.exitFullscreen !== "function") return;
|
try {
|
await document.exitFullscreen();
|
} catch (error) {
|
// Ignore fullscreen exit failures.
|
}
|
}
|
|
function goBack() {
|
closeFullscreen();
|
exitBrowserFullscreen();
|
if (window.history.length > 1) {
|
router.back();
|
return;
|
}
|
router.push("/index");
|
}
|
|
function openAssistant(index) {
|
if (!agents.length) return;
|
carouselIndex.value = index;
|
fullscreenVisible.value = true;
|
}
|
|
function closeFullscreen() {
|
fullscreenVisible.value = false;
|
}
|
|
function startCarousel() {
|
stopCarousel();
|
if (fullscreenVisible.value) return;
|
carouselTimer = window.setInterval(() => {
|
nextCard();
|
}, carouselIntervalMs.value);
|
}
|
|
function stopCarousel() {
|
if (carouselTimer) {
|
window.clearInterval(carouselTimer);
|
carouselTimer = null;
|
}
|
}
|
|
function handleEscClose(event) {
|
if (event.key === "Escape" && fullscreenVisible.value) {
|
closeFullscreen();
|
}
|
}
|
|
watch(
|
() => fullscreenVisible.value,
|
(opened) => {
|
if (opened) {
|
stopCarousel();
|
} else {
|
startCarousel();
|
}
|
}
|
);
|
|
watch(
|
() => carouselIntervalMs.value,
|
() => {
|
if (!fullscreenVisible.value) {
|
startCarousel();
|
}
|
}
|
);
|
|
onMounted(() => {
|
startCarousel();
|
window.addEventListener("keydown", handleEscClose);
|
window.requestAnimationFrame(() => {
|
enterBrowserFullscreen();
|
});
|
});
|
|
onBeforeUnmount(() => {
|
stopCarousel();
|
window.removeEventListener("keydown", handleEscClose);
|
exitBrowserFullscreen();
|
});
|
</script>
|
|
<style scoped>
|
.ai-brain-screen {
|
position: fixed;
|
inset: 0;
|
z-index: 1900;
|
padding: 10px;
|
overflow: hidden;
|
background: var(--app-bg);
|
}
|
|
.brain-stage {
|
position: relative;
|
height: 100%;
|
min-height: 100%;
|
border-radius: 22px;
|
border: 1px solid var(--surface-border);
|
background:
|
radial-gradient(circle at 14% 8%, rgba(31, 122, 114, 0.14), transparent 40%),
|
radial-gradient(circle at 86% 12%, rgba(30, 91, 255, 0.1), transparent 42%),
|
linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(245, 249, 247, 0.94)),
|
repeating-linear-gradient(
|
135deg,
|
rgba(255, 255, 255, 0.05) 0,
|
rgba(255, 255, 255, 0.05) 14px,
|
rgba(31, 122, 114, 0.03) 14px,
|
rgba(31, 122, 114, 0.03) 28px
|
);
|
box-shadow: var(--shadow-sm);
|
}
|
|
.brain-head {
|
display: grid;
|
grid-template-columns: 220px minmax(0, 1fr) 180px;
|
align-items: center;
|
padding: 12px 18px 0;
|
}
|
|
.head-date {
|
color: var(--text-secondary);
|
font-size: 24px;
|
font-weight: 600;
|
}
|
|
.head-date p {
|
margin: 0;
|
line-height: 1.2;
|
}
|
|
.head-title {
|
justify-self: center;
|
width: min(760px, 95%);
|
height: 68px;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
border-radius: 0 0 46px 46px;
|
color: #fff;
|
font-size: 42px;
|
font-style: italic;
|
font-weight: 700;
|
letter-spacing: 1px;
|
background: linear-gradient(135deg, #1f7a72 0%, #1e5bff 100%);
|
box-shadow: 0 16px 30px rgba(31, 122, 114, 0.24);
|
}
|
|
.head-actions {
|
justify-self: end;
|
}
|
|
.head-back-btn {
|
height: 40px;
|
padding: 0 14px;
|
display: inline-flex;
|
align-items: center;
|
gap: 4px;
|
border: none;
|
border-radius: 999px;
|
font-size: 16px;
|
font-weight: 600;
|
color: var(--colorPrimary);
|
background: var(--surface-base);
|
box-shadow: 0 8px 18px rgba(31, 49, 38, 0.12);
|
cursor: pointer;
|
}
|
|
.brain-intro {
|
text-align: center;
|
margin-top: 34px;
|
}
|
|
.brain-intro h2 {
|
margin: 0;
|
font-size: 44px;
|
font-style: italic;
|
font-weight: 700;
|
color: var(--text-primary);
|
}
|
|
.brain-intro p {
|
margin: 12px 0 10px;
|
font-size: 28px;
|
color: var(--text-secondary);
|
}
|
|
.intro-sign {
|
display: inline-block;
|
padding: 6px 18px;
|
border-radius: 999px;
|
font-size: 24px;
|
font-weight: 700;
|
color: #1e5bff;
|
background: rgba(255, 255, 255, 0.82);
|
border: 1px solid rgba(30, 91, 255, 0.18);
|
}
|
|
.carousel-area {
|
position: relative;
|
margin-top: 34px;
|
padding: 0 72px 12px;
|
}
|
|
.carousel-track {
|
position: relative;
|
height: 500px;
|
overflow: hidden;
|
}
|
|
.brain-footer {
|
position: relative;
|
margin: 0 72px;
|
height: clamp(226px, 25vh,0);
|
border-radius: 18px;
|
border: 1px solid rgba(31, 122, 114, 0.28);
|
background:
|
linear-gradient(120deg, rgba(31, 122, 114, 0.14), rgba(30, 91, 255, 0.14)),
|
linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(236, 244, 249, 0.9));
|
box-shadow:
|
0 16px 34px rgba(31, 81, 131, 0.12),
|
inset 0 1px 0 rgba(255, 255, 255, 0.72);
|
overflow: hidden;
|
}
|
|
.brain-footer::before {
|
content: "";
|
position: absolute;
|
left: -22%;
|
bottom: -120%;
|
width: 52%;
|
height: 260%;
|
background: radial-gradient(ellipse at center, rgba(30, 91, 255, 0.2) 0%, rgba(30, 91, 255, 0) 72%);
|
pointer-events: none;
|
}
|
|
.brain-footer::after {
|
content: "";
|
position: absolute;
|
inset: 0;
|
background: linear-gradient(110deg, transparent 12%, rgba(255, 255, 255, 0.24) 38%, transparent 64%);
|
transform: translateX(-120%);
|
animation: footerSweep 5.8s linear infinite;
|
pointer-events: none;
|
}
|
|
.footer-grid-overlay {
|
position: absolute;
|
inset: 0;
|
background:
|
repeating-linear-gradient(
|
90deg,
|
rgba(31, 122, 114, 0.07) 0,
|
rgba(31, 122, 114, 0.07) 1px,
|
transparent 1px,
|
transparent 36px
|
),
|
repeating-linear-gradient(
|
0deg,
|
rgba(30, 91, 255, 0.06) 0,
|
rgba(30, 91, 255, 0.06) 1px,
|
transparent 1px,
|
transparent 28px
|
);
|
opacity: 0.72;
|
pointer-events: none;
|
}
|
|
.footer-metrics {
|
position: relative;
|
z-index: 2;
|
padding: 14px 20px 72px;
|
display: grid;
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
gap: 12px;
|
}
|
|
.footer-metric {
|
min-height: 76px;
|
border-radius: 12px;
|
padding: 10px 14px;
|
border: 1px solid rgba(37, 124, 188, 0.2);
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(245, 250, 255, 0.82));
|
box-shadow: 0 10px 18px rgba(29, 83, 134, 0.08);
|
display: grid;
|
grid-template-rows: auto auto 1fr;
|
gap: 4px;
|
}
|
|
.footer-metric--focus {
|
border-color: rgba(38, 122, 194, 0.34);
|
box-shadow:
|
0 12px 22px rgba(30, 91, 255, 0.12),
|
inset 0 0 0 1px rgba(85, 148, 232, 0.2);
|
}
|
|
.footer-metric__label {
|
font-size: 14px;
|
color: rgba(38, 72, 108, 0.88);
|
font-weight: 600;
|
}
|
|
.footer-metric__value {
|
font-size: 30px;
|
line-height: 1;
|
font-style: italic;
|
font-weight: 700;
|
color: #1f5ddf;
|
text-shadow: 0 3px 10px rgba(30, 91, 255, 0.18);
|
}
|
|
.footer-metric__hint {
|
margin-top: auto;
|
font-size: 13px;
|
color: rgba(52, 89, 128, 0.82);
|
}
|
|
.footer-metric--period .footer-metric__hint {
|
margin-top: 0;
|
line-height: 1.25;
|
}
|
|
.footer-metric--period {
|
min-height: 122px;
|
grid-template-rows: auto auto auto auto auto;
|
gap: 6px;
|
}
|
|
.footer-period-control {
|
display: inline-flex;
|
align-items: center;
|
gap: 8px;
|
}
|
|
.period-btn {
|
width: 22px;
|
height: 22px;
|
border-radius: 50%;
|
border: 1px solid rgba(38, 112, 183, 0.28);
|
background: rgba(255, 255, 255, 0.9);
|
color: #2054c9;
|
font-size: 14px;
|
font-weight: 700;
|
line-height: 1;
|
cursor: pointer;
|
}
|
|
.period-input {
|
width: 56px;
|
height: 24px;
|
border-radius: 8px;
|
border: 1px solid rgba(38, 112, 183, 0.24);
|
background: rgba(255, 255, 255, 0.94);
|
color: #1f5ddf;
|
font-size: 13px;
|
font-weight: 600;
|
text-align: center;
|
padding: 0 4px;
|
}
|
|
.period-unit {
|
font-size: 12px;
|
font-weight: 600;
|
color: rgba(40, 80, 117, 0.86);
|
}
|
|
.footer-period-slider {
|
width: min(250px, 100%);
|
height: 3px;
|
accent-color: #2a6ded;
|
cursor: pointer;
|
}
|
|
.footer-rail {
|
position: absolute;
|
left: 20px;
|
right: 20px;
|
bottom: 18px;
|
z-index: 2;
|
}
|
|
.footer-rail__line {
|
position: relative;
|
height: 2px;
|
border-radius: 999px;
|
background: linear-gradient(90deg, rgba(31, 122, 114, 0.12), rgba(30, 91, 255, 0.6), rgba(31, 122, 114, 0.12));
|
overflow: hidden;
|
}
|
|
.footer-rail__flow {
|
position: absolute;
|
top: -1px;
|
left: -18%;
|
width: 22%;
|
height: 4px;
|
border-radius: 999px;
|
background: linear-gradient(90deg, rgba(31, 122, 114, 0), rgba(59, 146, 244, 0.92), rgba(30, 91, 255, 0));
|
filter: blur(0.2px);
|
animation: railFlow 3.1s ease-in-out infinite;
|
}
|
|
.footer-rail__nodes {
|
margin-top: 12px;
|
display: grid;
|
grid-template-columns: repeat(5, minmax(0, 1fr));
|
gap: 8px;
|
}
|
|
.footer-node {
|
height: 34px;
|
border: 1px solid rgba(38, 112, 183, 0.18);
|
border-radius: 999px;
|
background: rgba(255, 255, 255, 0.76);
|
display: inline-flex;
|
align-items: center;
|
justify-content: center;
|
gap: 8px;
|
color: rgba(40, 80, 117, 0.92);
|
font-size: 14px;
|
font-weight: 600;
|
cursor: pointer;
|
transition: all 0.26s ease;
|
}
|
|
.footer-node:hover {
|
transform: translateY(-1px);
|
border-color: rgba(31, 122, 114, 0.34);
|
box-shadow: 0 8px 14px rgba(31, 122, 114, 0.14);
|
}
|
|
.footer-node--active {
|
color: #fff;
|
border-color: transparent;
|
background: linear-gradient(135deg, rgba(31, 122, 114, 0.94), rgba(30, 91, 255, 0.94));
|
box-shadow: 0 10px 18px rgba(30, 91, 255, 0.28);
|
}
|
|
.footer-node__dot {
|
width: 8px;
|
height: 8px;
|
border-radius: 50%;
|
background: rgba(30, 91, 255, 0.72);
|
box-shadow: 0 0 10px rgba(30, 91, 255, 0.52);
|
}
|
|
.footer-node--active .footer-node__dot {
|
background: #fff;
|
box-shadow: 0 0 12px rgba(255, 255, 255, 0.72);
|
animation: nodePulse 1.4s ease-in-out infinite;
|
}
|
|
.agent-card {
|
position: absolute;
|
left: 50%;
|
top: 0;
|
width: 460px;
|
margin-left: -230px;
|
cursor: pointer;
|
transform-origin: center bottom;
|
transition: transform 0.35s ease, opacity 0.35s ease;
|
}
|
|
.agent-card__head {
|
height: 56px;
|
border-radius: 12px 12px 0 0;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
font-size: 28px;
|
color: #fff;
|
font-weight: 700;
|
background: linear-gradient(135deg, #1f7a72 0%, #1e5bff 100%);
|
}
|
|
.agent-card__head--active {
|
box-shadow:
|
0 12px 22px rgba(30, 91, 255, 0.26),
|
inset 0 0 0 1px rgba(255, 255, 255, 0.28);
|
position: relative;
|
}
|
|
.agent-card__head--active::after {
|
content: "";
|
position: absolute;
|
left: 12px;
|
right: 12px;
|
bottom: 6px;
|
height: 3px;
|
border-radius: 999px;
|
background: linear-gradient(90deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0.96), rgba(255, 255, 255, 0.22));
|
}
|
|
.agent-card__body {
|
position: relative;
|
height: 430px;
|
border: 1px solid var(--surface-border-strong);
|
border-top: none;
|
border-radius: 0 0 20px 20px;
|
background: rgba(255, 255, 255, 0.96);
|
overflow: hidden;
|
display: flex;
|
justify-content: center;
|
align-items: flex-end;
|
isolation: isolate;
|
box-shadow: 0 12px 24px rgba(31, 49, 38, 0.1);
|
}
|
|
.agent-card__body--active {
|
background: linear-gradient(180deg, rgba(248, 252, 251, 0.96), rgba(225, 241, 250, 0.9));
|
border-color: rgba(31, 122, 114, 0.35);
|
}
|
|
.agent-card__body--active::after {
|
content: "";
|
position: absolute;
|
inset: 0;
|
background: linear-gradient(108deg, transparent 28%, rgba(255, 255, 255, 0.34) 50%, transparent 72%);
|
transform: translateX(-125%);
|
animation: bodySweep 3.6s linear infinite;
|
pointer-events: none;
|
z-index: 1;
|
}
|
|
.avatar-shell {
|
position: relative;
|
width: 248px;
|
height: 430px;
|
display: flex;
|
align-items: flex-end;
|
justify-content: center;
|
--base-core: rgba(53, 143, 222, 0.4);
|
--base-ring: rgba(39, 122, 201, 0.62);
|
--base-glow: rgba(46, 133, 214, 0.28);
|
}
|
|
.avatar-shell::before {
|
content: "";
|
position: absolute;
|
left: 50%;
|
bottom: -10px;
|
width: 268px;
|
height: 58px;
|
transform: translateX(-50%);
|
border-radius: 50%;
|
background: radial-gradient(
|
ellipse at center,
|
rgba(55, 140, 219, 0.22) 0%,
|
rgba(55, 140, 219, 0.11) 46%,
|
rgba(55, 140, 219, 0) 74%
|
);
|
filter: blur(2.4px);
|
animation: baseGlow 4.6s ease-in-out infinite;
|
z-index: 1;
|
pointer-events: none;
|
}
|
|
.avatar-shell::after {
|
content: "";
|
position: absolute;
|
left: 50%;
|
bottom: 0;
|
width: 248px;
|
height: 46px;
|
transform: translateX(-50%);
|
border-radius: 50%;
|
border: 2px solid var(--base-ring);
|
box-shadow:
|
inset 0 0 0 1px rgba(255, 255, 255, 0.64),
|
0 0 24px var(--base-glow);
|
animation: basePulse 3.1s ease-in-out infinite;
|
z-index: 4;
|
}
|
|
.avatar-base {
|
position: absolute;
|
left: 50%;
|
bottom: 2px;
|
width: 224px;
|
height: 38px;
|
transform: translateX(-50%);
|
z-index: 2;
|
pointer-events: none;
|
}
|
|
.avatar-base::before {
|
content: "";
|
position: absolute;
|
inset: 0;
|
border-radius: 50%;
|
background:
|
radial-gradient(
|
ellipse at center,
|
rgba(255, 255, 255, 0.96) 0%,
|
rgba(255, 255, 255, 0.92) 36%,
|
var(--base-core) 68%,
|
rgba(38, 118, 195, 0.08) 100%
|
);
|
box-shadow:
|
0 0 30px var(--base-core),
|
0 0 10px rgba(255, 255, 255, 0.34) inset;
|
z-index: 3;
|
}
|
|
.avatar-base::after {
|
content: "";
|
position: absolute;
|
left: 50%;
|
top: 50%;
|
width: 194px;
|
height: 194px;
|
transform: translate(-50%, -50%);
|
border-radius: 50%;
|
background:
|
conic-gradient(
|
from 180deg,
|
transparent 0deg,
|
var(--base-ring) 48deg,
|
transparent 112deg,
|
var(--base-ring) 208deg,
|
transparent 284deg,
|
rgba(33, 114, 191, 0.48) 332deg,
|
transparent 360deg
|
);
|
-webkit-mask: radial-gradient(circle, transparent 61%, #000 62%, #000 68%, transparent 70%);
|
mask: radial-gradient(circle, transparent 61%, #000 62%, #000 68%, transparent 70%);
|
opacity: 0.62;
|
animation: baseRotate 10.5s linear infinite;
|
z-index: 2;
|
}
|
|
.avatar-shell--active {
|
--base-core: rgba(50, 141, 217, 0.52);
|
--base-ring: rgba(42, 127, 205, 0.76);
|
--base-glow: rgba(38, 130, 211, 0.38);
|
}
|
|
.avatar-cut {
|
position: relative;
|
width: 220px;
|
height: 430px;
|
z-index: 6;
|
display: flex;
|
align-items: flex-end;
|
justify-content: center;
|
filter: saturate(1.04) drop-shadow(0 14px 18px rgba(24, 44, 66, 0.14));
|
transform-origin: center 82%;
|
animation: avatarFloat 3.2s ease-in-out infinite;
|
}
|
|
.avatar-cut__img {
|
width: 100%;
|
height: 100%;
|
object-fit: contain;
|
object-position: center bottom;
|
display: block;
|
}
|
|
.agent-card--active .avatar-cut {
|
animation-duration: 2.6s;
|
}
|
|
.highlight-list {
|
position: absolute;
|
right: 10px;
|
top: 14px;
|
display: grid;
|
gap: 8px;
|
width: 220px;
|
z-index: 16;
|
}
|
|
.highlight-item {
|
border-radius: 10px;
|
padding: 8px 10px;
|
font-size: 18px;
|
line-height: 1.4;
|
color: #fff;
|
background: rgba(33, 49, 63, 0.92);
|
box-shadow: 0 8px 16px rgba(21, 30, 40, 0.22);
|
}
|
|
.agent-card--active .highlight-item {
|
background: rgba(31, 122, 114, 0.9);
|
}
|
|
.nav-btn {
|
position: absolute;
|
top: 212px;
|
z-index: 80;
|
width: 50px;
|
height: 50px;
|
border-radius: 50%;
|
border: none;
|
font-size: 30px;
|
color: var(--colorPrimary);
|
background: var(--surface-base);
|
box-shadow: 0 10px 20px rgba(31, 49, 38, 0.16);
|
cursor: pointer;
|
}
|
|
.nav-btn--left {
|
left: 14px;
|
}
|
|
.nav-btn--right {
|
right: 14px;
|
}
|
|
.ai-fullscreen {
|
position: fixed;
|
inset: 0;
|
z-index: 2100;
|
padding: 12px;
|
background: rgba(33, 49, 63, 0.24);
|
backdrop-filter: blur(2px);
|
}
|
|
.ai-panel {
|
height: 100%;
|
border-radius: 22px;
|
border: 1px solid var(--surface-border);
|
background: linear-gradient(180deg, #f9fcfb 0%, #f0f5f2 100%);
|
display: grid;
|
grid-template-rows: 62px minmax(0, 1fr) 110px;
|
box-shadow: var(--shadow-md);
|
}
|
|
.ai-panel__top {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 0 24px;
|
}
|
|
.ai-brand {
|
font-size: 34px;
|
color: var(--text-primary);
|
font-weight: 700;
|
}
|
|
.ai-close {
|
width: 40px;
|
height: 40px;
|
border: none;
|
border-radius: 50%;
|
background: transparent;
|
font-size: 30px;
|
color: var(--text-secondary);
|
cursor: pointer;
|
}
|
|
.ai-panel__center {
|
padding: 8px 20px 10px;
|
display: grid;
|
grid-template-rows: 120px 290px minmax(0, 1fr);
|
gap: 10px;
|
min-height: 0;
|
}
|
|
.welcome-card {
|
border-radius: 14px;
|
background: linear-gradient(135deg, rgba(232, 244, 242, 0.95), rgba(230, 237, 250, 0.9));
|
padding: 16px 18px;
|
display: flex;
|
justify-content: space-between;
|
gap: 12px;
|
border: 1px solid var(--surface-border);
|
}
|
|
.welcome-card__text h3 {
|
margin: 0;
|
font-size: 28px;
|
color: var(--text-primary);
|
}
|
|
.welcome-card__text p {
|
margin: 8px 0 0;
|
font-size: 20px;
|
color: var(--text-secondary);
|
}
|
|
.mini-avatar {
|
width: 120px;
|
height: 120px;
|
border-radius: 14px;
|
border: 1px solid var(--surface-border);
|
background-color: #fff;
|
background-clip: border-box;
|
overflow: hidden;
|
}
|
|
.mini-avatar__img {
|
width: 100%;
|
height: 100%;
|
object-fit: contain;
|
object-position: center bottom;
|
display: block;
|
}
|
|
.recommend-card {
|
border-radius: 14px;
|
border: 1px solid var(--surface-border);
|
background: rgba(255, 255, 255, 0.86);
|
padding: 12px 14px;
|
}
|
|
.recommend-card__head {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
margin-bottom: 10px;
|
color: var(--text-primary);
|
font-size: 24px;
|
font-weight: 700;
|
}
|
|
.refresh-btn {
|
border: none;
|
background: transparent;
|
color: var(--text-secondary);
|
font-size: 18px;
|
display: inline-flex;
|
align-items: center;
|
gap: 4px;
|
cursor: pointer;
|
}
|
|
.recommend-grid {
|
display: grid;
|
grid-template-columns: 1fr 1fr;
|
gap: 8px 18px;
|
}
|
|
.recommend-item {
|
border: 1px solid var(--surface-border);
|
border-radius: 8px;
|
text-align: left;
|
padding: 8px 10px;
|
font-size: 18px;
|
color: var(--text-secondary);
|
background: #fff;
|
cursor: pointer;
|
}
|
|
.recommend-item:hover {
|
background: rgba(31, 122, 114, 0.08);
|
color: var(--colorPrimary);
|
}
|
|
.chat-card {
|
border-radius: 14px;
|
border: 1px solid var(--surface-border);
|
background: #fff;
|
min-height: 0;
|
overflow: hidden;
|
}
|
|
.chat-empty {
|
height: 100%;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
color: var(--text-tertiary);
|
font-size: 18px;
|
}
|
|
.chat-messages {
|
height: 100%;
|
overflow-y: auto;
|
padding: 14px;
|
display: grid;
|
gap: 10px;
|
}
|
|
.chat-row {
|
display: flex;
|
}
|
|
.chat-row--assistant {
|
justify-content: flex-start;
|
}
|
|
.chat-row--user {
|
justify-content: flex-end;
|
}
|
|
.chat-bubble {
|
max-width: 72%;
|
border-radius: 12px;
|
padding: 10px 12px;
|
font-size: 18px;
|
line-height: 1.5;
|
white-space: pre-wrap;
|
color: var(--text-primary);
|
background: var(--surface-soft);
|
border: 1px solid var(--surface-border);
|
}
|
|
.chat-row--user .chat-bubble {
|
color: #fff;
|
background: linear-gradient(135deg, #1f7a72 0%, #1e5bff 100%);
|
border: none;
|
}
|
|
.ai-panel__input {
|
display: grid;
|
grid-template-columns: minmax(0, 1fr) 130px;
|
gap: 12px;
|
padding: 14px 20px 18px;
|
}
|
|
.ask-input :deep(.el-input__wrapper) {
|
height: 74px;
|
border-radius: 18px;
|
box-shadow: 0 0 0 1px var(--surface-border) inset;
|
background: #fff;
|
}
|
|
.ask-input :deep(.el-input__inner) {
|
font-size: 20px;
|
}
|
|
.send-btn {
|
align-self: center;
|
height: 56px;
|
font-size: 20px;
|
min-width: 98px;
|
}
|
|
.fade-enter-active,
|
.fade-leave-active {
|
transition: opacity 0.2s ease;
|
}
|
|
.fade-enter-from,
|
.fade-leave-to {
|
opacity: 0;
|
}
|
|
@keyframes avatarFloat {
|
0%,
|
100% {
|
transform: translateY(0);
|
}
|
50% {
|
transform: translateY(-8px);
|
}
|
}
|
|
@keyframes basePulse {
|
0%,
|
100% {
|
transform: translateX(-50%) scale(1);
|
opacity: 0.88;
|
}
|
50% {
|
transform: translateX(-50%) scale(1.045);
|
opacity: 0.95;
|
}
|
}
|
|
@keyframes baseRotate {
|
from {
|
transform: translate(-50%, -50%) rotate(0deg);
|
}
|
to {
|
transform: translate(-50%, -50%) rotate(360deg);
|
}
|
}
|
|
@keyframes baseGlow {
|
0%,
|
100% {
|
transform: translateX(-50%) scaleX(1);
|
opacity: 0.84;
|
}
|
50% {
|
transform: translateX(-50%) scaleX(1.06);
|
opacity: 0.96;
|
}
|
}
|
|
@keyframes bodySweep {
|
0% {
|
transform: translateX(-125%);
|
}
|
100% {
|
transform: translateX(135%);
|
}
|
}
|
|
@keyframes footerSweep {
|
0% {
|
transform: translateX(-120%);
|
}
|
100% {
|
transform: translateX(140%);
|
}
|
}
|
|
@keyframes railFlow {
|
0% {
|
transform: translateX(0);
|
opacity: 0;
|
}
|
20% {
|
opacity: 1;
|
}
|
80% {
|
opacity: 1;
|
}
|
100% {
|
transform: translateX(520%);
|
opacity: 0;
|
}
|
}
|
|
@keyframes nodePulse {
|
0%,
|
100% {
|
transform: scale(1);
|
}
|
50% {
|
transform: scale(1.25);
|
}
|
}
|
|
@media (max-width: 1600px) {
|
.head-title {
|
font-size: 34px;
|
height: 60px;
|
}
|
|
.brain-intro h2 {
|
font-size: 36px;
|
}
|
|
.brain-intro p {
|
font-size: 22px;
|
}
|
|
.intro-sign {
|
font-size: 20px;
|
}
|
|
.agent-card {
|
width: 380px;
|
margin-left: -190px;
|
}
|
|
.agent-card__head {
|
font-size: 24px;
|
height: 54px;
|
}
|
|
.agent-card__body {
|
height: 390px;
|
}
|
|
.highlight-list {
|
width: 184px;
|
}
|
|
.highlight-item {
|
font-size: 15px;
|
}
|
|
.avatar-shell {
|
width: 220px;
|
height: 390px;
|
}
|
|
.avatar-cut {
|
width: 202px;
|
height: 390px;
|
}
|
|
.avatar-base {
|
width: 194px;
|
height: 34px;
|
}
|
|
.avatar-base::after {
|
width: 164px;
|
height: 164px;
|
}
|
|
.avatar-shell::before {
|
width: 236px;
|
height: 48px;
|
bottom: -9px;
|
}
|
|
.avatar-shell::after {
|
width: 220px;
|
height: 40px;
|
bottom: 0;
|
}
|
|
.brain-footer {
|
margin: 0 52px;
|
height: clamp(210px, 23vh, 264px);
|
}
|
|
.footer-metrics {
|
padding: 12px 14px 66px;
|
gap: 8px;
|
}
|
|
.footer-metric {
|
min-height: 66px;
|
padding: 8px 10px;
|
}
|
|
.footer-metric--period {
|
min-height: 108px;
|
gap: 4px;
|
}
|
|
.footer-metric__label {
|
font-size: 12px;
|
}
|
|
.footer-metric__value {
|
font-size: 24px;
|
}
|
|
.footer-metric__hint {
|
font-size: 11px;
|
}
|
|
.footer-period-control {
|
gap: 6px;
|
}
|
|
.period-btn {
|
width: 20px;
|
height: 20px;
|
font-size: 12px;
|
}
|
|
.period-input {
|
width: 50px;
|
height: 22px;
|
font-size: 12px;
|
}
|
|
.footer-period-slider {
|
width: 100%;
|
}
|
|
.footer-rail {
|
left: 14px;
|
right: 14px;
|
bottom: 14px;
|
}
|
|
.footer-rail__nodes {
|
margin-top: 10px;
|
gap: 6px;
|
}
|
|
.footer-node {
|
height: 30px;
|
font-size: 12px;
|
gap: 6px;
|
}
|
|
.footer-node__dot {
|
width: 7px;
|
height: 7px;
|
}
|
|
.ai-brand {
|
font-size: 28px;
|
}
|
|
.welcome-card__text h3,
|
.recommend-card__head {
|
font-size: 22px;
|
}
|
|
.welcome-card__text p,
|
.recommend-item,
|
.chat-bubble,
|
.refresh-btn,
|
.chat-empty,
|
.ask-input :deep(.el-input__inner),
|
.send-btn {
|
font-size: 16px;
|
}
|
}
|
</style>
|