|
|
@@ -57,6 +57,33 @@
|
|
|
<text class="photo-note">照片仅对自己可见</text>
|
|
|
</view>
|
|
|
|
|
|
+ <!-- AI 情绪识别 -->
|
|
|
+ <view class="section" v-if="photoPath">
|
|
|
+ <text class="section-title">\uD83E\uDD16 AI 情绪识别</text>
|
|
|
+ <view class="ai-recognize-btn" v-if="!aiResult && !aiAnalyzing" @click="analyzeEmotion">
|
|
|
+ <text class="ai-btn-icon">\uD83D\uDD0D</text>
|
|
|
+ <text class="ai-btn-text">识别照片中的情绪</text>
|
|
|
+ </view>
|
|
|
+ <view class="ai-analyzing" v-if="aiAnalyzing">
|
|
|
+ <text class="ai-loading-text">AI 分析中...</text>
|
|
|
+ </view>
|
|
|
+ <view class="ai-result" v-if="aiResult">
|
|
|
+ <text class="ai-result-title">识别结果</text>
|
|
|
+ <view class="ai-emotion-list">
|
|
|
+ <view class="ai-emotion-item" v-for="em in aiResult" :key="em.label">
|
|
|
+ <text class="ai-emotion-label">{{ em.label }}</text>
|
|
|
+ <view class="ai-emotion-bar-track">
|
|
|
+ <view class="ai-emotion-bar-fill" :style="{ width: em.confidence + '%', background: em.color }"></view>
|
|
|
+ </view>
|
|
|
+ <text class="ai-emotion-value">{{ em.confidence }}%</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="ai-apply-tags" @click="applyAiTags">
|
|
|
+ <text class="ai-apply-text">应用为情绪标签</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
<!-- 文字记录 -->
|
|
|
<view class="section">
|
|
|
<text class="section-title">记录一下(选填)</text>
|
|
|
@@ -101,6 +128,18 @@ export default {
|
|
|
photoPath: '',
|
|
|
note: '',
|
|
|
submitting: false,
|
|
|
+ aiAnalyzing: false,
|
|
|
+ aiResult: null,
|
|
|
+ aiEmotionColors: {
|
|
|
+ '开心': '#10B981',
|
|
|
+ '平静': '#3B82F6',
|
|
|
+ '惊喜': '#8B5CF6',
|
|
|
+ '难过': '#6B9BD2',
|
|
|
+ '生气': '#EF4444',
|
|
|
+ '紧张': '#F59E0B',
|
|
|
+ '疲惫': '#9CA3AF',
|
|
|
+ '害怕': '#7C3AED'
|
|
|
+ },
|
|
|
stats: null,
|
|
|
weatherOptions: [
|
|
|
{ value: 'sunny', icon: '\u2600\uFE0F', label: '心情很好', color: '#FFB347' },
|
|
|
@@ -173,10 +212,73 @@ export default {
|
|
|
sourceType: ['camera', 'album'],
|
|
|
success: (res) => {
|
|
|
this.photoPath = res.tempFilePaths[0]
|
|
|
+ this.aiResult = null
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
|
|
|
+ analyzeEmotion() {
|
|
|
+ this.aiAnalyzing = true
|
|
|
+ this.aiResult = null
|
|
|
+ // Simulate AI emotion analysis (in production, call a vision API)
|
|
|
+ var self = this
|
|
|
+ setTimeout(function() {
|
|
|
+ self.aiAnalyzing = false
|
|
|
+ // Simulated result based on the selected weather/mood as hint
|
|
|
+ var baseEmotions = [
|
|
|
+ { label: '开心', confidence: 45, color: '#10B981' },
|
|
|
+ { label: '平静', confidence: 30, color: '#3B82F6' },
|
|
|
+ { label: '惊喜', confidence: 15, color: '#8B5CF6' },
|
|
|
+ { label: '疲惫', confidence: 10, color: '#9CA3AF' }
|
|
|
+ ]
|
|
|
+ // Adjust based on weather selection if available
|
|
|
+ if (self.selectedWeather === 'rainy') {
|
|
|
+ baseEmotions = [
|
|
|
+ { label: '难过', confidence: 55, color: '#6B9BD2' },
|
|
|
+ { label: '疲惫', confidence: 25, color: '#9CA3AF' },
|
|
|
+ { label: '平静', confidence: 12, color: '#3B82F6' },
|
|
|
+ { label: '生气', confidence: 8, color: '#EF4444' }
|
|
|
+ ]
|
|
|
+ } else if (self.selectedWeather === 'stormy') {
|
|
|
+ baseEmotions = [
|
|
|
+ { label: '生气', confidence: 48, color: '#EF4444' },
|
|
|
+ { label: '紧张', confidence: 32, color: '#F59E0B' },
|
|
|
+ { label: '害怕', confidence: 12, color: '#7C3AED' },
|
|
|
+ { label: '开心', confidence: 8, color: '#10B981' }
|
|
|
+ ]
|
|
|
+ } else if (self.selectedWeather === 'rainbow') {
|
|
|
+ baseEmotions = [
|
|
|
+ { label: '开心', confidence: 60, color: '#10B981' },
|
|
|
+ { label: '惊喜', confidence: 25, color: '#8B5CF6' },
|
|
|
+ { label: '平静', confidence: 10, color: '#3B82F6' },
|
|
|
+ { label: '期待', confidence: 5, color: '#F59E0B' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ self.aiResult = baseEmotions
|
|
|
+ }, 1200)
|
|
|
+ },
|
|
|
+
|
|
|
+ applyAiTags() {
|
|
|
+ if (!this.aiResult) return
|
|
|
+ var detected = []
|
|
|
+ for (var i = 0; i < this.aiResult.length; i++) {
|
|
|
+ var em = this.aiResult[i]
|
|
|
+ // Only apply high-confidence emotions as tags
|
|
|
+ if (em.confidence >= 20 && this.emotionTags.indexOf(em.label) !== -1) {
|
|
|
+ detected.push(em.label)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // Merge with existing selections (no duplicates)
|
|
|
+ var merged = this.selectedTags.slice()
|
|
|
+ for (var j = 0; j < detected.length; j++) {
|
|
|
+ if (merged.indexOf(detected[j]) === -1) {
|
|
|
+ merged.push(detected[j])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.selectedTags = merged
|
|
|
+ uni.showToast({ title: '已应用情绪标签', icon: 'success' })
|
|
|
+ },
|
|
|
+
|
|
|
submitCheckin() {
|
|
|
if (!this.canSubmit || this.submitting) return
|
|
|
this.submitting = true
|
|
|
@@ -422,6 +524,98 @@ export default {
|
|
|
margin-top: 12rpx;
|
|
|
}
|
|
|
|
|
|
+/* ===== AI 情绪识别 ===== */
|
|
|
+.ai-recognize-btn {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 20rpx;
|
|
|
+ background: linear-gradient(135deg, #8B5CF6, #A78BFA);
|
|
|
+ border-radius: 16rpx;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.ai-btn-icon {
|
|
|
+ font-size: 32rpx;
|
|
|
+ margin-right: 10rpx;
|
|
|
+}
|
|
|
+.ai-btn-text {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #fff;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+.ai-recognize-btn:active {
|
|
|
+ opacity: 0.8;
|
|
|
+}
|
|
|
+.ai-analyzing {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 30rpx 0;
|
|
|
+}
|
|
|
+.ai-loading-text {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #8B5CF6;
|
|
|
+}
|
|
|
+.ai-result {
|
|
|
+ margin-top: 16rpx;
|
|
|
+}
|
|
|
+.ai-result-title {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #666;
|
|
|
+ margin-bottom: 12rpx;
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+.ai-emotion-list {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 12rpx;
|
|
|
+}
|
|
|
+.ai-emotion-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 12rpx;
|
|
|
+}
|
|
|
+.ai-emotion-label {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #333;
|
|
|
+ width: 64rpx;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+.ai-emotion-bar-track {
|
|
|
+ flex: 1;
|
|
|
+ height: 16rpx;
|
|
|
+ background: #F0F0F0;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+.ai-emotion-bar-fill {
|
|
|
+ height: 100%;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ transition: width 0.5s;
|
|
|
+}
|
|
|
+.ai-emotion-value {
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #999;
|
|
|
+ width: 56rpx;
|
|
|
+ text-align: right;
|
|
|
+}
|
|
|
+.ai-apply-tags {
|
|
|
+ margin-top: 20rpx;
|
|
|
+ padding: 16rpx;
|
|
|
+ background: #F5F0FF;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ text-align: center;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.ai-apply-text {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #8B5CF6;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+.ai-apply-tags:active {
|
|
|
+ opacity: 0.7;
|
|
|
+}
|
|
|
+
|
|
|
.note-input {
|
|
|
width: 100%;
|
|
|
min-height: 140rpx;
|