|
@@ -14,6 +14,15 @@
|
|
|
<text class="section-title-text">心·心理</text>
|
|
<text class="section-title-text">心·心理</text>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
|
|
+ <!-- ===== 家庭天盘模块(今日运势 / 今日心情 / 吉位) ===== -->
|
|
|
|
|
+ <FamilyTianpanCard
|
|
|
|
|
+ v-if="isLoggedIn"
|
|
|
|
|
+ :visible="isLoggedIn"
|
|
|
|
|
+ :fortune="dailyFortune"
|
|
|
|
|
+ :mood="todayMood"
|
|
|
|
|
+ :dominantElement="dominantElement"
|
|
|
|
|
+ :weeklyTip="familyWeeklyInsight" />
|
|
|
|
|
+
|
|
|
<!-- 游客登录引导卡 -->
|
|
<!-- 游客登录引导卡 -->
|
|
|
<template v-if="!isLoggedIn">
|
|
<template v-if="!isLoggedIn">
|
|
|
<LoginGuideCard
|
|
<LoginGuideCard
|
|
@@ -61,40 +70,37 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- ===== 大五人格雷达图(始终显示) ===== -->
|
|
|
|
|
- <view class="emi-section">
|
|
|
|
|
- <view class="emi-card">
|
|
|
|
|
- <view class="personality-header">
|
|
|
|
|
- <text class="emi-card-title">大五人格</text>
|
|
|
|
|
- <view class="test-btn" @click="goAssessment">
|
|
|
|
|
- <text class="test-btn-text">测试</text>
|
|
|
|
|
|
|
+ <!-- ===== 心理报告上传 ===== -->
|
|
|
|
|
+ <view class="report-upload-section" v-if="isLoggedIn">
|
|
|
|
|
+ <view class="report-upload-card">
|
|
|
|
|
+ <view class="report-upload-header">
|
|
|
|
|
+ <text class="report-upload-title">心理报告</text>
|
|
|
|
|
+ <view class="report-upload-btn" @click="chooseAndUploadReport">
|
|
|
|
|
+ <text class="report-upload-btn-text">上传报告</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
- <template v-if="emiData">
|
|
|
|
|
- <RadarChart
|
|
|
|
|
- :dimensions="personalityDimensions"
|
|
|
|
|
- :scores="personalityScores"
|
|
|
|
|
- :childName="currentChildName || '孩子'"
|
|
|
|
|
- fillColor="#8B5CF6"
|
|
|
|
|
- gridColor="#EDE9FE"
|
|
|
|
|
- labelColor="#6D28D9" />
|
|
|
|
|
- <view class="emi-footer">
|
|
|
|
|
- <text class="emi-overall">综合EQ分: {{ emiData.overallScore || 0 }}</text>
|
|
|
|
|
- <view class="emi-link" @click="goEmotionReport">
|
|
|
|
|
- <text class="emi-link-text">查看完整报告</text>
|
|
|
|
|
- <text class="emi-link-arrow">→</text>
|
|
|
|
|
- </view>
|
|
|
|
|
|
|
+ <view class="report-upload-body">
|
|
|
|
|
+ <text class="report-upload-desc">上传 EMI 心理测评报告或第三方心理评估报告,系统将自动解析并生成可视化分析</text>
|
|
|
|
|
+ <view class="report-support-list">
|
|
|
|
|
+ <text class="report-support-item">支持格式: PDF、JPG、PNG</text>
|
|
|
|
|
+ <text class="report-support-item">单文件不超过 20MB</text>
|
|
|
</view>
|
|
</view>
|
|
|
- </template>
|
|
|
|
|
- <template v-else-if="!emiLoading">
|
|
|
|
|
- <view class="placeholder-content">
|
|
|
|
|
- <text class="placeholder-icon">🧠</text>
|
|
|
|
|
- <text class="placeholder-title">心理评估</text>
|
|
|
|
|
- <text class="placeholder-desc">完成 EMI 心理测评后,可在此查看大五人格雷达图</text>
|
|
|
|
|
- <view class="placeholder-btn" @click="goAssessment" v-if="isLoggedIn">预约测评</view>
|
|
|
|
|
- <view class="placeholder-btn" @click="goLogin" v-else>立即登录</view>
|
|
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <!-- 已上传报告列表 -->
|
|
|
|
|
+ <view class="report-list" v-if="uploadedReports && uploadedReports.length > 0">
|
|
|
|
|
+ <view class="report-item" v-for="report in uploadedReports" :key="report.id" @click="viewReport(report)">
|
|
|
|
|
+ <text class="report-item-icon">📄</text>
|
|
|
|
|
+ <text class="report-item-name">{{ report.fileName || '心理报告' }}</text>
|
|
|
|
|
+ <text class="report-item-date">{{ formatDate(report.createdAt) }}</text>
|
|
|
|
|
+ <text class="report-item-status" :class="report.status === 'parsed' ? 'parsed' : 'pending'">
|
|
|
|
|
+ {{ report.status === 'parsed' ? '已解析' : '待解析' }}
|
|
|
|
|
+ </text>
|
|
|
</view>
|
|
</view>
|
|
|
- </template>
|
|
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="report-empty" v-else-if="!reportUploadLoading">
|
|
|
|
|
+ <text class="report-empty-icon">📁</text>
|
|
|
|
|
+ <text class="report-empty-text">暂无上传的报告</text>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
@@ -294,15 +300,6 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- ===== 家庭天盘模块(今日运势 / 今日心情 / 吉位) ===== -->
|
|
|
|
|
- <FamilyTianpanCard
|
|
|
|
|
- v-if="isLoggedIn"
|
|
|
|
|
- :visible="isLoggedIn"
|
|
|
|
|
- :fortune="dailyFortune"
|
|
|
|
|
- :mood="todayMood"
|
|
|
|
|
- :dominantElement="dominantElement"
|
|
|
|
|
- :weeklyTip="familyWeeklyInsight" />
|
|
|
|
|
-
|
|
|
|
|
<!-- 底部占位 -->
|
|
<!-- 底部占位 -->
|
|
|
<view class="bottom-spacer"></view>
|
|
<view class="bottom-spacer"></view>
|
|
|
<AIFloatingAvatar />
|
|
<AIFloatingAvatar />
|
|
@@ -407,7 +404,11 @@ export default {
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
// 家庭天盘 - 每日运势数据
|
|
// 家庭天盘 - 每日运势数据
|
|
|
- dailyFortuneData: null
|
|
|
|
|
|
|
+ dailyFortuneData: null,
|
|
|
|
|
+
|
|
|
|
|
+ // 心理报告上传
|
|
|
|
|
+ uploadedReports: [],
|
|
|
|
|
+ reportUploadLoading: false
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
computed: {
|
|
computed: {
|
|
@@ -673,6 +674,98 @@ export default {
|
|
|
console.error('Failed to load family fortune:', err)
|
|
console.error('Failed to load family fortune:', err)
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
|
|
+ // ===== 心理报告上传 =====
|
|
|
|
|
+ chooseAndUploadReport: function() {
|
|
|
|
|
+ var self = this
|
|
|
|
|
+ uni.chooseImage({
|
|
|
|
|
+ count: 1,
|
|
|
|
|
+ sizeType: ['original', 'compressed'],
|
|
|
|
|
+ sourceType: ['album', 'camera'],
|
|
|
|
|
+ success: function(chooseRes) {
|
|
|
|
|
+ self.reportUploadLoading = true
|
|
|
|
|
+ var tempFilePath = chooseRes.tempFilePaths[0]
|
|
|
|
|
+ var fileName = '心理报告_' + Date.now() + '.jpg'
|
|
|
|
|
+
|
|
|
|
|
+ uni.uploadFile({
|
|
|
|
|
+ url: config.baseUrl + '/api/mind/report/upload',
|
|
|
|
|
+ filePath: tempFilePath,
|
|
|
|
|
+ name: 'report',
|
|
|
|
|
+ formData: {
|
|
|
|
|
+ familyId: self.currentChildId || ''
|
|
|
|
|
+ },
|
|
|
|
|
+ header: {
|
|
|
|
|
+ 'Authorization': 'Bearer ' + uni.getStorageSync('token')
|
|
|
|
|
+ },
|
|
|
|
|
+ success: function(uploadRes) {
|
|
|
|
|
+ self.reportUploadLoading = false
|
|
|
|
|
+ if (uploadRes.statusCode === 200) {
|
|
|
|
|
+ var result = JSON.parse(uploadRes.data)
|
|
|
|
|
+ if (result.code === 200) {
|
|
|
|
|
+ self.uploadedReports.unshift(result.data)
|
|
|
|
|
+ uni.showToast({ title: '上传成功', icon: 'success' })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uni.showToast({ title: result.message || '上传失败', icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uni.showToast({ title: '上传失败: ' + uploadRes.statusCode, icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ fail: function(err) {
|
|
|
|
|
+ self.reportUploadLoading = false
|
|
|
|
|
+ uni.showToast({ title: '上传失败: ' + (err.errMsg || ''), icon: 'none' })
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ fail: function() {
|
|
|
|
|
+ // 用户取消选择
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ viewReport: function(report) {
|
|
|
|
|
+ if (report && report.fileUrl) {
|
|
|
|
|
+ uni.downloadFile({
|
|
|
|
|
+ url: report.fileUrl,
|
|
|
|
|
+ success: function(res) {
|
|
|
|
|
+ if (res.statusCode === 200) {
|
|
|
|
|
+ uni.openDocument({
|
|
|
|
|
+ filePath: res.tempFilePath,
|
|
|
|
|
+ success: function() {
|
|
|
|
|
+ console.log('打开报告成功')
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ loadUploadedReports: function() {
|
|
|
|
|
+ var self = this
|
|
|
|
|
+ uni.request({
|
|
|
|
|
+ url: config.baseUrl + '/api/mind/report/list',
|
|
|
|
|
+ method: 'POST',
|
|
|
|
|
+ data: { familyId: self.currentChildId || '' },
|
|
|
|
|
+ header: {
|
|
|
|
|
+ 'Authorization': 'Bearer ' + uni.getStorageSync('token')
|
|
|
|
|
+ },
|
|
|
|
|
+ success: function(res) {
|
|
|
|
|
+ if (res.data && res.data.code === 200 && res.data.data) {
|
|
|
|
|
+ self.uploadedReports = res.data.data
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ formatDate: function(dateStr) {
|
|
|
|
|
+ if (!dateStr) return ''
|
|
|
|
|
+ var d = new Date(dateStr)
|
|
|
|
|
+ var month = d.getMonth() + 1
|
|
|
|
|
+ var day = d.getDate()
|
|
|
|
|
+ return month + '月' + day + '日'
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
sectionVisible: function(key) {
|
|
sectionVisible: function(key) {
|
|
|
return this.visibleSections.length === 0 || this.visibleSections.indexOf(key) !== -1
|
|
return this.visibleSections.length === 0 || this.visibleSections.indexOf(key) !== -1
|
|
|
},
|
|
},
|