Files
Situation-Awareness-Platfor…/src/views/Jyh/Home/index.vue
2025-11-28 14:48:13 +08:00

982 lines
26 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="home-container">
<div class="home-content">
<div class="home-title animate-fade-in-up">
<img src="@/assets/imgs/logo.png" alt="logo"/>
<h1>可信开源代码库</h1>
</div>
<div class="home-search animate-fade-in-up delay-100" ref="homeSearch" :class="{ 'glow-border': inputGlow }">
<d-input
ref="searchInput"
placeholder="请输入搜索关键字"
@focus="inputFocus"
@blur="inputBlur"
@keyup.enter="search"
:autocomplete="'off'"
v-model="searchStr"
>
<template #prepend>
<d-dropdown @toggle="onCateToggle($event)">
<div class="flex items-center gap-1 cursor-pointer dropdown-trigger">
{{ searchType }}
<d-icon :rotate="cateRotate" name="icon-chevron-down-2" class="transition-transform"></d-icon>
</div>
<template #menu>
<ul class="list-menu">
<li class="menu-item" @click="onCategoryChange('软件')">软件</li>
<d-dropdown :position="position" :offset="0">
<li class="menu-item">
行业
<i class="icon icon-chevron-right"></i>
</li>
<template #menu>
<ul class="list-menu">
<li class="menu-item" v-for="option in industryList" @click="onCategoryChange(option)">
{{ option.name }}
</li>
</ul>
</template>
</d-dropdown>
</ul>
</template>
</d-dropdown>
</template>
<template #append>
<div id="advancedSearch close-isopen" class="advanced-search" @click="openAdvancedSearch">
<span class="close-isopen">高级筛选</span>
<d-icon class="close-isopen transition-transform" :rotate="rotate" name="icon-chevron-down-2"></d-icon>
</div>
</template>
</d-input>
<d-dropdown-menu v-model="isOpen" :origin="searchInput?.$el" :offset="offset" :clickOutside="closeOutside">
<div class="advanced-search-menu" :style="{ width: dropdownWidth + 'px' }">
<AdvanceSearch @submit="submit($event)" @cancel="isOpen = false" class="p-20" :layout="'vertical'">
<template #title>
<span class="title">高级筛选</span>
</template>
</AdvanceSearch>
</div>
</d-dropdown-menu>
<d-button icon="search" shape="circle" @click="search"></d-button>
</div>
<div style="width: 70%" class="from-blue-50 to-white animate-fade-in-up delay-200">
<d-row :gutter="16" class="mb-8 top-btn">
<div
style="cursor: pointer"
v-for="(item, index) in topButtons"
:key="item.name"
@click="handleButtonClick(item)"
class="hover-lift"
:style="{ animationDelay: `${index * 100}ms` }"
>
<div style="width: 84px;height: 84px;flex-direction: column;padding: 12px;margin: 0 12px"
class="bg-white rounded-lg shadow-md flex items-center justify-center mb-2">
<div>
<img style="width: 32px;height: 32px;margin-bottom: 4px" :src="item.icon"
class="text-blue-600 text-xl func-icon transition-transform"></img>
</div>
<div class="text-sm font-medium">{{ item.name }}</div>
</div>
</div>
</d-row>
<div class="dashboard-page">
<d-row :gutter="16" class="main-row">
<d-col :span="14">
<div class="bg-white rounded-xl shadow-md p-4 hover-shadow">
<div class="section-title">全球威胁态势实时监控
<a href="#" class="text-blue-600 text-sm">更多 ></a></div>
<d-row :gutter="24" class="threat-row">
<d-col :span="10">
<d-chart :option="lineOption" style="width: 400px; height: 240px"></d-chart>
</d-col>
<d-col :span="8">
<d-chart :option="pieOption" style="width: 240px; height: 240px"></d-chart>
</d-col>
<d-col :span="6">
<div class="data-card">
<div class="data-item hover-scale">
<span class="data-label">今日检测量</span>
<span class="data-value count-up">128万次</span>
</div>
<div class="data-item hover-scale">
<span class="data-label">高危威胁</span>
<span class="data-value danger count-up">327</span>
</div>
</div>
</d-col>
</d-row>
</div>
</d-col>
<d-col style="height: 320px" :span="10">
<div style="height: 100%" class="bg-white rounded-xl shadow-md p-4 hover-shadow">
<div class="section-title">AI+安全核心能力
<router-link :to="{ name: 'aihome' }" style="cursor: pointer;" class="text-blue-600 text-sm">更多 >
</router-link>
</div>
<d-row :gutter="16" class="ai-capability-row">
<d-col :span="8" v-for="(item, index) in aiCapabilities" :key="index">
<div class="capability-card hover-lift" :style="{ animationDelay: `${index * 150}ms` }">
<div class="capability-icon">
<img :src="item.icon" class="text-blue-600 text-2xl transition-transform"></img>
</div>
<h2 class="capability-title">{{ item.title }}</h2>
<h4>{{ item.rate }}</h4>
<p class="capability-desc">{{ item.desc }}</p>
</div>
</d-col>
</d-row>
</div>
</d-col>
</d-row>
</div>
<d-row style="height: 237px" :gutter="16" class="mb-8">
<d-col style="height: 100%" :span="8">
<div style="height: 100%" class="bg-white rounded-xl shadow-md p-4 mb-4 hover-shadow">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-bold">团队与成果</h3>
<router-link :to="{ name: 'OurTeam' }" style="cursor: pointer;" class="text-blue-600 text-sm">更多 >
</router-link>
</div>
<div class="flex flex-col items-center">
<h4 class="font-medium mb-2">顶尖安全团队</h4>
<div class="flex gap-4 mb-3">
<div class="flex flex-col items-center member-item hover-bob" v-for="(member, index) in teamMembers" :key="member.name" :style="{ animationDelay: `${index * 100}ms` }">
<img src="https://picsum.photos/id/1001/60/60" alt="团队成员" class="w-14 h-14 rounded-full mb-1 member-avatar transition-transform">
<span class="text-sm font-medium">{{ member.name }}</span>
<span class="text-xs text-gray-500">{{ member.title }}</span>
</div>
</div>
<div class="flex gap-2">
<button class="bg-blue-600 text-white text-xs px-3 py-1 rounded hover-scale">国家级安全认证团队</button>
<button class="bg-blue-100 text-blue-600 text-xs px-3 py-1 rounded hover-scale">200+专利技术</button>
<button class="bg-blue-100 text-blue-600 text-xs px-3 py-1 rounded hover-scale">200+专利技术</button>
</div>
</div>
</div>
</d-col>
<d-col style="height: 100%" :span="16">
<div style="height: 100%" class="bg-white rounded-xl shadow-md p-4 hover-shadow">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-bold">最新动态</h3>
<router-link :to="{ name: 'Insights' }" style="cursor: pointer;" class="text-blue-600 text-sm">更多 >
</router-link>
</div>
<div style="overflow: auto; height: calc(100% - 46px);">
<d-timeline direction="vertical" center>
<d-timeline-item
v-for="(news, index) in latestNews"
:key="index"
:time="news.year"
dot-color="#ff6384"
line-color="#e5e7eb"
class="timeline-item animate-fade-in-left"
:style="{ animationDelay: `${index * 150}ms` }"
>
<div class="timeline-content hover-translate-x">
<p class="font-medium transition-color">{{ news.title }}</p>
<p class="text-xs text-gray-500">{{ news.desc }}</p>
</div>
</d-timeline-item>
</d-timeline>
</div>
</div>
</d-col>
</d-row>
</div>
</div>
</div>
<d-modal class="warning-modal" v-model="warningModalVisable" title="" style="width: 600px">
<EarlyWarningDetail :warningData="currentWarning" :type="'user'"></EarlyWarningDetail>
</d-modal>
</template>
<script setup lang="ts">
// 保持原有的逻辑和数据定义
import {ref, onMounted, onBeforeUnmount, computed} from 'vue';
import {useRoute, useRouter} from 'vue-router';
import {useAccount} from '@/utils/hooks/useAccount';
import AdvanceSearch from '@/components/AdvanceSearch/index.vue';
import {getHomeNoticeList} from '@/api/jyh';
import EarlyWarningDetail from '@/views/Jyh/PersonalCenter/Detail/EarlyWarningDetail.vue';
import {useGlobalInfoStore} from '@/stores/Global';
import {useDiscussGetUserInfo} from '@/api/discussion/hook';
import {DChart} from 'vue-devui/echarts';
import {reactive} from 'vue';
// --- Echarts Options (保持不变) ---
const lineOption = reactive({
tooltip: {show: true, trigger: 'axis'},
grid: {
left: '0%',
right: '3%',
bottom: '3%',
containLabel: true,
},
xAxis: {
type: 'category',
data: ['0', '30', '60', '90', '120', '150', '180', '210', '240'],
axisLine: {lineStyle: {color: '#909399'}},
axisTick: {show: false},
},
yAxis: {
type: 'value',
max: 550,
axisLine: {show: false},
axisTick: {show: false},
splitLine: {lineStyle: {color: '#eee'}},
},
series: [
{
name: '实时威胁A',
data: [0, 150, 250, 200, 350, 400, 450, 500, 550],
type: 'line',
itemStyle: {color: '#ff9f40'},
lineStyle: {color: '#ff9f40'},
symbol: 'circle',
symbolSize: 6,
},
{
name: '实时威胁B',
data: [0, 100, 200, 150, 300, 350, 400, 450, 500],
type: 'line',
itemStyle: {color: '#36a2eb'},
lineStyle: {color: '#36a2eb'},
symbol: 'circle',
symbolSize: 6,
},
],
});
const pieOption = reactive({
tooltip: {show: true, trigger: 'item'},
legend: {
icon: "rect",
itemHeight: 13,
itemWidth: 13,
itemGap: 10,
top: '0%',
left: '0%',
right: '0%',
},
series: [
{
title: '态势感知',
type: 'pie',
radius: ['40%', '70%'],
data: [
{name: '态势感知', value: 34, itemStyle: {color: '#ff6384'}},
{name: '实时威胁', value: 33, itemStyle: {color: '#36a2eb'}},
{name: '其他', value: 33, itemStyle: {color: '#ffce56'}},
],
label: {
show: true,
formatter: '{b}: {d}%',
position: 'center',
},
labelLine: {show: true},
},
],
});
// --- Data & State (保持不变) ---
const route = useRoute();
const router = useRouter();
const inputGlow = ref(false);
const searchStr = ref('');
const position = ref(['right-start', 'right-end']);
const searchType = ref('软件');
const offset = ref({mainAxis: 7, crossAxis: -10});
const isOpen = ref(false);
const cateRotate = ref(0);
const warningModalVisable = ref(false);
const currentWarning = ref();
const {isLogin} = useDiscussGetUserInfo();
const homeSearch = ref(null);
const dropdownWidth = ref(0);
import aqts from '@/assets/imgs/jyh/menu/风险预警.png'
import aqqb from '@/assets/imgs/jyh/menu/许可证检测.png'
import aqjc from '@/assets/imgs/jyh/menu/已知漏洞检测.png'
import aqzk from '@/assets/imgs/jyh/menu/可信治理.png'
import kxrj from '@/assets/imgs/jyh/menu/可信软件.png'
// 顶部功能按钮数据 (保持不变)
const topButtons = ref([
{name: '安全智库', icon: aqzk},
{name: '安全检测', icon: aqjc},
{name: '安全情报', icon: aqqb},
{name: '安全态势', icon: aqts},
{name: '智能引擎', icon: kxrj},
]);
// 按钮点击事件处理 (保持不变)
const handleButtonClick = (item) => {
const routeMap = {
'安全智库': 'Search',
'安全检测': 'TestingCenter',
'安全情报': 'Insights',
'智能引擎': 'aihome',
'安全态势': 'https://example.com/security-situation'
};
const target = routeMap[item.name];
if (!target) return;
if (item.name === '安全态势') {
window.open(target, '_blank');
} else {
router.push({name: target});
}
};
import znjc from '@/assets/imgs/jyh/menu/AI大模型能力.png'
import aiLogo1 from '@/assets/imgs/jyh/ai/aiLogo1.png'
import vulnerabilityForewarning from '@/assets/imgs/jyh/menu/vulnerabilityForewarning.png'
// AI+安全核心能力数据 (保持不变)
const aiCapabilities = ref([
{
title: '智能检测引擎',
rate: '覆盖99.9%样本率)',
desc: '智能检测引擎具备对各类文件、恶意软件的高精度识别能力。',
icon: znjc
},
{
title: '行为分析模型',
rate: '(实时响应<1秒',
desc: '深度行为分析模型可实时识别异常行为,精准定位威胁根源。',
icon: aiLogo1
},
{
title: '自动溯源系统',
rate: '覆盖99.9%',
desc: '自动溯源系统可快速定位威胁来源,助力威胁事件全链路分析。',
icon: vulnerabilityForewarning
},
]);
// 团队成员数据 (保持不变)
const teamMembers = ref([
{name: '主理', title: '安全专家/负责人'},
{name: '顾问', title: '企业安全专家'},
{name: '架构', title: '技术架构专家'},
]);
// 最新动态数据 (保持不变)
const latestNews = ref([
{year: '2024', title: '中国头安全实验室等合作的智能决策模型授奖', desc: '智能决策模型在多领域安全决策中表现卓越,获行业权威奖项。', more: true},
{year: '2023', title: '智能检测引擎从一定论到再超越的与证明', desc: '2024年深度优化检测在极端场景中达99.9%准确率,性能、智能、召回率再升级。', more: false},
{year: '2023', title: '新闻网常务委员:邻区区委交换稿与证明', desc: '网络空间安全会议上,邻区、外防负责人、专家会首席等共论,包含新成果实证。', more: false},
]);
const rotate = computed(() => {
return isOpen.value ? 180 : 0;
});
// --- Methods (保持不变) ---
const searchInput = ref(null);
const openAdvancedSearch = () => {
isOpen.value = !isOpen.value;
inputGlow.value = isOpen.value;
};
const closeOutside = () => {
return false;
};
const submit = (formData) => {
isOpen.value = false;
router.push({
name: 'Search',
query: {
softwareName: searchStr.value ? searchStr.value : '',
searchType: getIndustryValue(searchType.value),
softwareVersion: formData.softwareVersion || '',
programmingLanguage: formData.programmingLanguage || '',
interestTag: formData.interestTag || '',
industry: formData.industry || '',
licenseName: formData.licenseName || '',
dependentSoftware: formData.dependentSoftware || '',
releaseDateStart: formData.dateRange && formData.dateRange.length > 0 ? formData.dateRange[0] : '',
releaseDateEnd: formData.dateRange && formData.dateRange.length > 0 ? formData.dateRange[1] : ''
}
});
};
const inputFocus = () => {
inputGlow.value = true;
};
const inputBlur = () => {
inputGlow.value = false;
};
const updateDropdownWidth = () => {
if (homeSearch.value) {
dropdownWidth.value = homeSearch.value.offsetWidth * 0.85;
}
};
const globalInfo = useGlobalInfoStore();
const industryList = globalInfo.industryList;
const getIndustryValue = (name) => {
const industry = industryList.find((item) => item.name === name);
return industry ? industry.value : '';
};
const search = () => {
router.push({
name: 'Search',
query: {
softwareName: searchStr.value ? searchStr.value : '',
searchType: getIndustryValue(searchType.value)
}
});
};
const onCategoryChange = (event) => {
searchType.value = event?.name || '软件';
globalInfo.updateHeaderSearch({softwareName: searchStr.value, searchType: event.value});
};
const onCateToggle = (event) => {
cateRotate.value = event ? 180 : 0;
};
let resizeObserver: ResizeObserver | null = null;
onMounted(() => {
resizeObserver = new ResizeObserver(updateDropdownWidth);
if (homeSearch.value) {
resizeObserver.observe(homeSearch.value);
}
updateDropdownWidth();
document.querySelector('body').onclick = (e) => {
const className = e.target.className;
// 优化点击外部关闭逻辑兼容SVG图标
if (
!className.includes ||
(!className.includes('close-isopen') &&
!className.includes('devui-badge__content') &&
!className.includes('advanced-search') &&
e.target.tagName !== 'svg' && e.target.tagName !== 'path')
) {
isOpen.value = false;
}
};
});
onBeforeUnmount(() => {
if (resizeObserver && homeSearch.value) {
resizeObserver.unobserve(homeSearch.value);
}
});
</script>
<style scoped lang="scss">
@import 'devui-theme/styles-var/devui-var.scss';
// ----------------------------------------------------
// 通用样式与动画
// ----------------------------------------------------
$shadow-base: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
$shadow-hover: 0 8px 24px rgba(0, 0, 0, 0.15);
$primary-color: #5e7ce0;
.transition-transform {
transition: transform 0.3s ease;
}
.transition-color {
transition: color 0.3s ease;
}
.hover-lift {
transition: transform 0.3s ease, box-shadow 0.3s ease;
&:hover {
transform: translateY(-6px);
//box-shadow: $shadow-hover !important;
}
}
.hover-scale {
transition: transform 0.3s ease, box-shadow 0.3s ease;
&:hover {
transform: scale(1.05);
box-shadow: 0 4px 12px rgba(66, 133, 244, 0.15) !important;
}
}
.hover-shadow {
transition: box-shadow 0.3s ease;
&:hover {
box-shadow: $shadow-hover !important;
}
}
.hover-bob {
transition: transform 0.3s ease;
&:hover {
transform: translateY(-4px);
}
}
.hover-translate-x {
transition: transform 0.3s ease;
&:hover {
transform: translateX(6px);
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translate3d(0, 20px, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
.animate-fade-in-up {
animation: fadeInUp 0.6s ease-out forwards;
}
@keyframes fadeInLeft {
from {
opacity: 0;
transform: translate3d(-20px, 0, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
.animate-fade-in-left {
animation: fadeInLeft 0.6s ease-out forwards;
opacity: 0; // 初始不可见
}
@keyframes countUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.count-up {
display: inline-block;
animation: countUp 0.8s ease-out forwards;
}
.delay-100 { animation-delay: 100ms; }
.delay-200 { animation-delay: 200ms; }
.delay-300 { animation-delay: 300ms; }
// 基础样式
.home-container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
.home-content {
font-size: 14px;
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-self: center;
align-items: center;
gap: 20px;
.home-title {
display: flex;
flex-shrink: 0;
justify-content: center;
align-items: center;
gap: 20px;
h1 {
font-size: xx-large;
font-weight: bold;
}
img {
width: 50px;
}
}
.home-search {
width: 574px;
height: 46px;
border: 1px solid #dfe1e5;
box-shadow: 0px 2px 8px 0px rgba(60, 64, 67, 0.25);
border-radius: 24px;
flex-shrink: 0;
background-color: white;
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px;
transition: all 0.3s ease;
&:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
input {
border: none;
outline: none;
padding: 5px;
font-size: 14px;
}
.dropdown-trigger {
transition: color 0.3s ease;
&:hover {
color: $primary-color;
}
}
.advanced-search {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
transition: color 0.3s ease;
&:hover {
color: $primary-color;
}
&::before {
content: '';
position: absolute;
left: -10px;
top: 50%;
transform: translateY(-50%);
width: 1px;
height: 20px;
background-color: var(--devui-form-control-line, #d7d8da);
}
}
.advanced-search-menu {
height: 300px;
padding: 12px;
background-color: white;
}
}
}
}
.glow-border {
border: 1px solid var(--devui-form-control-line, #d7d8da);
border-color: var(--devui-form-control-line-active, #5e7ce0) !important;
box-shadow: 0 0 0 4px var(--devui-form-control-interactive-outline, rgba(94, 124, 224, 0.15));
transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
// 卡片通用样式
.bg-white {
border-radius: 8px;
box-shadow: $shadow-base;
transition: box-shadow 0.3s ease; // 添加过渡
}
// 顶部功能按钮
.top-btn {
display: flex;
justify-content: center;
align-items: center;
.func-icon {
transition: transform 0.3s ease;
}
&:hover .func-icon {
transform: scale(1.1);
}
}
// 威胁监控卡片
.data-card {
.data-item {
margin-bottom: 24px;
background: #f1f5fc;
border-radius: 8px;
padding: 16px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
.data-label {
font-size: 14px;
color: #606266;
display: block;
margin-bottom: 8px;
}
.data-value {
font-size: 24px;
font-weight: 600;
color: #303133;
margin-right: 16px;
}
.data-value.danger {
color: #f56c6c;
}
}
}
$primary-light: #e8f0fe;
// AI能力卡片
.ai-capability-row {
.capability-card {
height: 100%;
background: white;
border-radius: 10px;
padding: 18px 12px;
border: 1px solid #e9ecef;
text-align: center;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
justify-content: space-between;
&:hover {
border-color: #b8daff;
background: $primary-light;
transform: translateY(-5px);
box-shadow: 0 8px 16px rgba(66, 133, 244, 0.1);
}
.capability-icon {
text-align: center;
margin-bottom: 12px;
width: 50px;
height: 50px;
margin-left: auto;
margin-right: auto;
border-radius: 12px;
background-color: rgba(66, 133, 244, 0.1);
display: flex;
align-items: center;
justify-content: center;
img {
display: inline-block;
width: 28px;
}
}
&:hover .capability-icon img {
transform: scale(1.15);
}
.capability-title {
font-size: 16px;
font-weight: 600;
color: #202124;
margin-bottom: 6px;
}
h4 {
font-size: 12px;
color: $primary-color;
margin: 0 0 10px 0;
font-weight: 500;
}
.capability-desc {
font-size: 13px;
color: #5f6368;
line-height: 1.5;
}
}
}
// 团队成员卡片
.member-item {
&:hover .member-avatar {
transform: scale(1.05);
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
}
// 最新动态
.timeline-content {
margin-top: 4px;
cursor: pointer;
&:hover .font-medium {
color: $primary-color;
}
}
// 其他样式保持不变...
.home-search {
:deep(.devui-input-slot__prepend),
:deep(.devui-input-slot__append),
:deep(.devui-input__wrapper) {
border: none;
}
:deep(.devui-select__selection--glow-style),
:deep(.devui-input--glow-style) {
box-shadow: none !important;
}
}
.menu-item {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 4px;
cursor: pointer;
&:hover {
background-color: var(--devui-list-item-hover-bg, #f2f5fc);
color: var(--devui-list-item-hover-text, #526ecc);
}
}
.list-menu {
padding: 8px;
margin: 0;
width: 100px;
}
.title {
font-size: 14px;
font-weight: 500;
}
.notice-content {
flex: 1;
overflow: hidden;
margin-right: 8px;
span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: block;
}
}
.time-container {
display: flex;
align-items: center;
gap: 8px;
width: 140px;
flex-shrink: 0;
}
:deep(.devui-timeline-item-data-right) {
width: 80%;
}
// 文本样式
.text-lg {
font-size: 18px;
}
.text-sm {
font-size: 14px;
}
.text-xs {
font-size: 12px;
}
.font-bold {
font-weight: 600;
}
.font-medium {
font-weight: 500;
}
// 间距与布局
.mb-8 {
margin-bottom: 24px;
}
.p-4 {
padding: 16px;
}
.flex-col {
flex-direction: column;
}
.items-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.dashboard-page {
.section-title {
font-size: 18px;
font-weight: 600;
color: #303133;
margin-bottom: 16px;
display: flex;
justify-content: space-between;
align-items: center;
a {
font-weight: 400;
}
}
.main-row {
margin-bottom: 20px;
}
.ai-capability-row {
height: calc(100% - 46px);
.devui-col {
height: 100%;
}
}
}
/* 时间线样式 */
:deep(.devui-timeline) {
--devui-timeline-item-padding: 0 0 24px 0;
}
:deep(.devui-timeline-item-time) {
/* 年份标签样式 */
background-color: #fee2e2; /* 浅红背景 */
color: #dc2626; /* 红色文字 */
font-size: 12px;
padding: 2px 6px;
border-radius: 4px;
min-width: 40px;
text-align: center;
}
:deep(.devui-timeline-item-data-left) {
flex: none;
}
</style>