feat: 项目初始化及当前全部内容提交
This commit is contained in:
@@ -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>
|
||||
Reference in New Issue
Block a user