Ver código fonte

chore: auto bump version and changelog [skip ci]

iwt 2 meses atrás
pai
commit
565dd78297

+ 21 - 0
cfc-backend/src/main/java/com/etotem/cfc/controller/HealthReportController.java

@@ -1246,6 +1246,27 @@ public class HealthReportController {
         return foods;
     }
 
+    /**
+     * 提交报告反馈(v1.1:日志记录,不入库)
+     */
+    @Operation(summary = "提交报告反馈")
+    @PostMapping("/feedback/submit")
+    public Result<String> submitFeedback(@RequestBody Map<String, Object> params) {
+        Object contentObj = params.get("content");
+        if (contentObj == null || contentObj.toString().trim().isEmpty()) {
+            return Result.error("反馈内容不能为空");
+        }
+        Long reportId = params.get("reportId") != null
+                ? Long.valueOf(params.get("reportId").toString()) : null;
+        String type = params.get("type") != null ? params.get("type").toString() : "其他";
+        String content = contentObj.toString().trim();
+        if (content.length() > 500) {
+            return Result.error("反馈内容不能超过500字");
+        }
+        log.info("用户报告反馈 - reportId: {}, type: {}, content: {}", reportId, type, content);
+        return Result.success("感谢您的反馈");
+    }
+
     /**
      * 保存上传文件到本地存储
      */

+ 157 - 0
cfc-frontend/components/feedback-popup.vue

@@ -0,0 +1,157 @@
+<template>
+  <view class="fb-overlay" v-if="visible" @tap="close">
+    <view class="fb-body" @tap.stop>
+      <view class="fb-header">
+        <text class="fb-title">报告反馈</text>
+        <text class="fb-close" @tap="close">×</text>
+      </view>
+      <textarea class="fb-textarea" v-model="content" placeholder="请描述您的问题或建议..." maxlength="500" />
+      <picker :value="typeIndex" :range="types" @change="onTypeChange">
+        <view class="fb-picker">
+          <text>{{ types[typeIndex] }}</text>
+          <text class="fb-arrow">▼</text>
+        </view>
+      </picker>
+      <view class="fb-actions">
+        <view class="fb-btn fb-btn-cancel" @tap="close">取消</view>
+        <view class="fb-btn fb-btn-submit" @tap="submit">提交反馈</view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import { submitFeedback } from '../utils/api.js'
+
+export default {
+  props: {
+    visible: Boolean,
+    reportId: Number
+  },
+  data: function() {
+    return {
+      content: '',
+      types: ['功能建议', '数据疑问', '内容错误', '其他'],
+      typeIndex: 0,
+      submitting: false
+    }
+  },
+  methods: {
+    onTypeChange: function(e) {
+      this.typeIndex = e.detail.value
+    },
+    close: function() {
+      this.$emit('close')
+    },
+    submit: function() {
+      if (!this.content.trim()) {
+        uni.showToast({ title: '请填写内容', icon: 'none' })
+        return
+      }
+      if (this.submitting) return
+      this.submitting = true
+      var self = this
+      var payload = {
+        reportId: this.reportId,
+        type: this.types[this.typeIndex],
+        content: this.content.trim()
+      }
+      submitFeedback(payload).then(function(res) {
+        if (res.code === 200) {
+          uni.showToast({ title: '感谢反馈', icon: 'success' })
+          self.content = ''
+          self.typeIndex = 0
+          self.close()
+        } else {
+          uni.showToast({ title: res.message || '提交失败', icon: 'none' })
+        }
+      }).catch(function() {
+        uni.showToast({ title: '提交失败', icon: 'none' })
+      }).then(function() {
+        self.submitting = false
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+.fb-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0,0,0,0.4);
+  z-index: 999;
+  display: flex;
+  align-items: flex-end;
+}
+.fb-body {
+  background: #fff;
+  border-radius: 20rpx 20rpx 0 0;
+  padding: 30rpx;
+  width: 100%;
+  box-sizing: border-box;
+}
+.fb-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20rpx;
+}
+.fb-title {
+  font-size: 32rpx;
+  font-weight: 600;
+  color: #333;
+}
+.fb-close {
+  font-size: 40rpx;
+  color: #999;
+  padding: 0 10rpx;
+}
+.fb-textarea {
+  width: 100%;
+  height: 200rpx;
+  border: 1rpx solid #eee;
+  border-radius: 12rpx;
+  padding: 20rpx;
+  font-size: 26rpx;
+  box-sizing: border-box;
+  margin-bottom: 16rpx;
+}
+.fb-picker {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 20rpx;
+  border: 1rpx solid #eee;
+  border-radius: 12rpx;
+  margin-bottom: 20rpx;
+  font-size: 26rpx;
+  color: #333;
+}
+.fb-arrow {
+  color: #999;
+  font-size: 22rpx;
+}
+.fb-actions {
+  display: flex;
+}
+.fb-btn {
+  flex: 1;
+  text-align: center;
+  padding: 20rpx;
+  border-radius: 12rpx;
+  font-size: 28rpx;
+}
+.fb-btn-cancel {
+  border: 1rpx solid #ddd;
+  color: #666;
+  margin-right: 20rpx;
+}
+.fb-btn-submit {
+  background: #4A9BD7;
+  color: #fff;
+}
+</style>

+ 30 - 1
cfc-frontend/pages/health/gut-flora-detail.vue

@@ -125,11 +125,19 @@
         </view>
       </view>
 
+      <view class="feedback-section" @tap="openFeedback">
+        <text class="feedback-icon">💬</text>
+        <text class="feedback-text">对这个报告有疑问或建议?告诉我们</text>
+        <text class="feedback-arrow">›</text>
+      </view>
+
       <view class="bottom-spacer"></view>
     </scroll-view>
 
     <health-knowledge-popup :visible="knowledgeVisible" :data="knowledgeData" @close="closeKnowledge" />
 
+    <feedback-popup :visible="feedbackVisible" :report-id="reportId" @close="closeFeedback" />
+
     <view class="fab" v-if="!isEditing" @tap="toggleEdit">
       <text class="fab-icon">✏️</text>
     </view>
@@ -143,6 +151,7 @@
 <script>
 import { getReportDetail, editHealthReport, queryKnowledgeBase } from '../../utils/api.js'
 import HealthKnowledgePopup from '../../components/health-knowledge-popup.vue'
+import FeedbackPopup from '../../components/feedback-popup.vue'
 
 var INDICATOR_TYPE_MAP = {
   '维生素': 'vitamin',
@@ -155,7 +164,7 @@ var INDICATOR_TYPE_MAP = {
 }
 
 export default {
-  components: { HealthKnowledgePopup },
+  components: { HealthKnowledgePopup, FeedbackPopup },
   data() {
     return {
       reportId: null,
@@ -173,6 +182,7 @@ export default {
       indicatorCount: 0,
       knowledgeVisible: false,
       knowledgeData: {},
+      feedbackVisible: false,
       indStatuses: ['正常', '偏低', '偏高', '缺乏', '不足', '过多', '异常']
     }
   },
@@ -275,6 +285,12 @@ export default {
       this.knowledgeVisible = false
       this.knowledgeData = {}
     },
+    openFeedback: function() {
+      this.feedbackVisible = true
+    },
+    closeFeedback: function() {
+      this.feedbackVisible = false
+    },
     toggleEdit: function() {
       this.isEditing = true
     },
@@ -379,5 +395,18 @@ export default {
 .bottom-bar { position: fixed; bottom: 0; left: 0; right: 0; display: flex; padding: 20rpx 30rpx; background: #fff; border-top: 1rpx solid #eee; gap: 20rpx; z-index: 100; }
 .btn-cancel { flex: 1; padding: 20rpx; border: 1rpx solid #ddd; border-radius: 12rpx; text-align: center; font-size: 28rpx; color: #666; }
 .btn-save { flex: 1; padding: 20rpx; background: #4A9BD7; border-radius: 12rpx; text-align: center; font-size: 28rpx; color: #fff; }
+.feedback-section {
+  display: flex;
+  align-items: center;
+  padding: 24rpx 30rpx;
+  background: #fff;
+  margin: 16rpx;
+  border-radius: 12rpx;
+  border: 1rpx solid #f0f0f0;
+}
+.feedback-icon { font-size: 32rpx; margin-right: 12rpx; }
+.feedback-text { flex: 1; font-size: 26rpx; color: #4A9BD7; }
+.feedback-arrow { font-size: 28rpx; color: #ccc; }
+
 .bottom-spacer { height: 40rpx; }
 </style>

+ 3 - 0
cfc-frontend/utils/api.js

@@ -1563,6 +1563,9 @@ export const createReportSurvey = (reportId, childId) => request('/api/health/su
 export const submitReportSurvey = (surveyId, surveyData) => request('/api/health/survey/submit', 'POST', { surveyId, surveyData })
 export const getSurveyStatus = (reportId) => request('/api/health/survey/status', 'POST', { reportId })
 
+// ===== Report Feedback (gut flora report feedback) =====
+export const submitFeedback = (data) => request('/api/health/feedback/submit', 'POST', data)
+
 // ===== 閲嶈鍏崇郴锛堣仈绯讳汉锛?=====
 export const getContactList = (data) => request('/api/contact/list', 'POST', data)
 export const getContactDetail = (id) => request('/api/contact/detail', 'POST', { id: id })

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-05feb334067f271d14686959c502f1ddfd5e6049
+02f80042d04ccdc672dc44be0347cb167658dd55

+ 2 - 2
cfc-web/package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "cfc-web",
-  "version": "1.0.388",
+  "version": "1.0.389",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "cfc-web",
-      "version": "1.0.388",
+      "version": "1.0.389",
       "dependencies": {
         "@wangeditor/editor": "^5.1.23",
         "@wangeditor/editor-for-vue": "^1.0.2",

+ 1 - 1
cfc-web/package.json

@@ -1,6 +1,6 @@
 {
   "name": "cfc-web",
-  "version": "1.0.389",
+  "version": "1.0.390",
   "private": true,
   "scripts": {
     "dev": "vue-cli-service serve",