feat: 项目初始化及当前全部内容提交

This commit is contained in:
2025-07-15 17:37:50 +08:00
parent ec817067f1
commit e78f192d34
622 changed files with 75174 additions and 383 deletions
+381
View File
@@ -0,0 +1,381 @@
<template>
<div class="emotion-analysis">
<a-card size="small" class="analysis-card">
<template #title>
<div class="card-title">
<HeartOutlined class="title-icon" />
情绪分析
</div>
</template>
<div class="analysis-content">
<!-- 主要情绪 -->
<div class="primary-emotion" v-if="analysis.primaryEmotion">
<div class="emotion-label">主要情绪</div>
<a-tag
:color="getEmotionColor(analysis.primaryEmotion)"
class="emotion-tag"
>
{{ getEmotionText(analysis.primaryEmotion) }}
</a-tag>
<div class="emotion-intensity" v-if="analysis.intensity">
强度: {{ Math.round(analysis.intensity * 100) }}%
</div>
</div>
<!-- 情绪极性 -->
<div class="emotion-polarity" v-if="analysis.polarity">
<div class="polarity-label">情绪倾向</div>
<a-tag
:color="getPolarityColor(analysis.polarity)"
class="polarity-tag"
>
{{ getPolarityText(analysis.polarity) }}
</a-tag>
</div>
<!-- 情绪分布 -->
<div class="emotions-distribution" v-if="analysis.emotions && Object.keys(analysis.emotions).length > 0">
<div class="distribution-label">情绪分布</div>
<div class="emotion-bars">
<div
class="emotion-bar"
v-for="(value, emotion) in analysis.emotions"
:key="emotion"
>
<div class="bar-label">{{ getEmotionText(emotion) }}</div>
<div class="bar-container">
<div
class="bar-fill"
:style="{
width: `${value * 100}%`,
background: getEmotionGradient(emotion)
}"
></div>
</div>
<div class="bar-value">{{ Math.round(value * 100) }}%</div>
</div>
</div>
</div>
<!-- 关键词 -->
<div class="keywords" v-if="analysis.keywords && analysis.keywords.length > 0">
<div class="keywords-label">关键词</div>
<div class="keywords-list">
<a-tag
v-for="keyword in analysis.keywords"
:key="keyword"
class="keyword-tag"
>
{{ keyword }}
</a-tag>
</div>
</div>
<!-- 建议 -->
<div class="suggestion" v-if="analysis.suggestion">
<div class="suggestion-label">
<BulbOutlined class="suggestion-icon" />
建议
</div>
<div class="suggestion-content">{{ analysis.suggestion }}</div>
</div>
<!-- 置信度 -->
<div class="confidence" v-if="analysis.confidence">
<div class="confidence-label">分析置信度</div>
<a-progress
:percent="Math.round(analysis.confidence * 100)"
:stroke-color="getConfidenceColor(analysis.confidence)"
size="small"
:show-info="true"
/>
</div>
</div>
</a-card>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { HeartOutlined, BulbOutlined } from '@ant-design/icons-vue'
const props = defineProps({
analysis: {
type: Object,
required: true,
default: () => ({})
}
})
// 情绪映射
const emotionMap = {
joy: '喜悦',
sadness: '悲伤',
anger: '愤怒',
fear: '恐惧',
surprise: '惊讶',
disgust: '厌恶',
trust: '信任',
anticipation: '期待',
anxiety: '焦虑',
depression: '抑郁',
excitement: '兴奋',
calm: '平静',
stress: '压力',
happiness: '快乐',
worry: '担忧',
relief: '放松',
frustration: '沮丧',
hope: '希望',
love: '爱',
hate: '恨'
}
// 极性映射
const polarityMap = {
positive: '积极',
negative: '消极',
neutral: '中性'
}
// 获取情绪文本
const getEmotionText = (emotion) => {
return emotionMap[emotion] || emotion
}
// 获取极性文本
const getPolarityText = (polarity) => {
return polarityMap[polarity] || polarity
}
// 获取情绪颜色
const getEmotionColor = (emotion) => {
const colorMap = {
joy: 'gold',
happiness: 'gold',
excitement: 'orange',
love: 'magenta',
trust: 'blue',
hope: 'cyan',
calm: 'green',
relief: 'green',
sadness: 'blue',
depression: 'purple',
worry: 'orange',
anxiety: 'orange',
stress: 'red',
anger: 'red',
frustration: 'red',
hate: 'red',
fear: 'volcano',
surprise: 'lime',
anticipation: 'geekblue',
disgust: 'default'
}
return colorMap[emotion] || 'default'
}
// 获取极性颜色
const getPolarityColor = (polarity) => {
const colorMap = {
positive: 'success',
negative: 'error',
neutral: 'default'
}
return colorMap[polarity] || 'default'
}
// 获取情绪渐变色
const getEmotionGradient = (emotion) => {
const gradientMap = {
joy: 'linear-gradient(90deg, #ffd700, #ffed4e)',
happiness: 'linear-gradient(90deg, #ff9a9e, #fecfef)',
excitement: 'linear-gradient(90deg, #ff6b6b, #ffa726)',
love: 'linear-gradient(90deg, #ff6b9d, #c44569)',
trust: 'linear-gradient(90deg, #4facfe, #00f2fe)',
hope: 'linear-gradient(90deg, #43e97b, #38f9d7)',
calm: 'linear-gradient(90deg, #667eea, #764ba2)',
relief: 'linear-gradient(90deg, #a8edea, #fed6e3)',
sadness: 'linear-gradient(90deg, #74b9ff, #0984e3)',
depression: 'linear-gradient(90deg, #6c5ce7, #a29bfe)',
worry: 'linear-gradient(90deg, #fdcb6e, #e17055)',
anxiety: 'linear-gradient(90deg, #fd79a8, #fdcb6e)',
stress: 'linear-gradient(90deg, #e84393, #fd79a8)',
anger: 'linear-gradient(90deg, #d63031, #e84393)',
frustration: 'linear-gradient(90deg, #e17055, #d63031)',
hate: 'linear-gradient(90deg, #2d3436, #636e72)',
fear: 'linear-gradient(90deg, #fd79a8, #fdcb6e)',
surprise: 'linear-gradient(90deg, #00b894, #00cec9)',
anticipation: 'linear-gradient(90deg, #74b9ff, #0984e3)',
disgust: 'linear-gradient(90deg, #636e72, #2d3436)'
}
return gradientMap[emotion] || 'linear-gradient(90deg, #ddd, #bbb)'
}
// 获取置信度颜色
const getConfidenceColor = (confidence) => {
if (confidence >= 0.8) return '#52c41a'
if (confidence >= 0.6) return '#faad14'
return '#ff4d4f'
}
</script>
<style lang="scss" scoped>
.emotion-analysis {
.analysis-card {
border-radius: var(--border-radius);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
:deep(.ant-card-head) {
border-bottom: 1px solid var(--border-color);
padding: var(--spacing-sm) var(--spacing-md);
.ant-card-head-title {
padding: 0;
}
}
:deep(.ant-card-body) {
padding: var(--spacing-md);
}
}
.card-title {
display: flex;
align-items: center;
gap: var(--spacing-xs);
font-size: 14px;
font-weight: 600;
color: var(--primary-color);
.title-icon {
font-size: 16px;
}
}
.analysis-content {
.primary-emotion,
.emotion-polarity,
.emotions-distribution,
.keywords,
.suggestion,
.confidence {
margin-bottom: var(--spacing-md);
&:last-child {
margin-bottom: 0;
}
}
.emotion-label,
.polarity-label,
.distribution-label,
.keywords-label,
.suggestion-label,
.confidence-label {
font-size: 12px;
color: var(--text-secondary);
margin-bottom: var(--spacing-xs);
font-weight: 500;
}
.emotion-tag,
.polarity-tag {
font-size: 12px;
border-radius: var(--border-radius-small);
margin-right: var(--spacing-xs);
}
.emotion-intensity {
font-size: 11px;
color: var(--text-secondary);
margin-top: 2px;
}
.emotion-bars {
.emotion-bar {
display: flex;
align-items: center;
gap: var(--spacing-xs);
margin-bottom: var(--spacing-xs);
&:last-child {
margin-bottom: 0;
}
.bar-label {
font-size: 11px;
color: var(--text-secondary);
min-width: 40px;
text-align: right;
}
.bar-container {
flex: 1;
height: 8px;
background: var(--bg-secondary);
border-radius: 4px;
overflow: hidden;
.bar-fill {
height: 100%;
border-radius: 4px;
transition: width 0.3s ease;
}
}
.bar-value {
font-size: 11px;
color: var(--text-secondary);
min-width: 30px;
text-align: right;
}
}
}
.keywords-list {
display: flex;
flex-wrap: wrap;
gap: var(--spacing-xs);
.keyword-tag {
font-size: 11px;
border-radius: var(--border-radius-small);
background: var(--bg-secondary);
border: 1px solid var(--border-color);
color: var(--text-secondary);
}
}
.suggestion-label {
display: flex;
align-items: center;
gap: var(--spacing-xs);
.suggestion-icon {
font-size: 12px;
color: var(--primary-color);
}
}
.suggestion-content {
font-size: 12px;
color: var(--text-primary);
line-height: 1.5;
background: var(--bg-secondary);
padding: var(--spacing-sm);
border-radius: var(--border-radius-small);
border-left: 3px solid var(--primary-color);
}
.confidence {
:deep(.ant-progress) {
.ant-progress-text {
font-size: 11px;
}
}
}
}
}
</style>