Browse Source

feat: portrait-edit UI redesign - remove AI generation, enlarge textarea, fix save button to bottom

Sisyphus Agent 1 day ago
parent
commit
381e191eca
1 changed files with 21 additions and 72 deletions
  1. 21 72
      cfc-frontend/pages/profile/portrait-edit.vue

+ 21 - 72
cfc-frontend/pages/profile/portrait-edit.vue

@@ -3,23 +3,14 @@
     <view class="section">
     <view class="section">
       <view class="section-title">我的画像描述</view>
       <view class="section-title">我的画像描述</view>
       <view class="hint">请输入你的个人画像描述,AI 会根据这些信息提供更有针对性的建议(最多 2000 字)</view>
       <view class="hint">请输入你的个人画像描述,AI 会根据这些信息提供更有针对性的建议(最多 2000 字)</view>
-      
-      <!-- 操作按钮行 -->
-      <view class="action-row">
-        <button class="action-btn" :loading="generating" @click="onGenerate" v-if="!portraitPrompt">
-          🪄 AI 生成画像
-        </button>
-        <button class="action-btn secondary" :loading="regenerating" @click="onRegenerate" v-if="portraitPrompt">
-          🔄 重画画像
-        </button>
-      </view>
-      
+
       <textarea
       <textarea
         class="portrait-textarea"
         class="portrait-textarea"
         :value="portraitPrompt"
         :value="portraitPrompt"
         placeholder="例如:我家孩子 8 岁,偏瘦,挑食,容易积食,睡眠不足..."
         placeholder="例如:我家孩子 8 岁,偏瘦,挑食,容易积食,睡眠不足..."
         maxlength="2000"
         maxlength="2000"
         @input="onInput"
         @input="onInput"
+        auto-height
       ></textarea>
       ></textarea>
       <view class="char-count">{{ portraitPrompt.length }}/2000</view>
       <view class="char-count">{{ portraitPrompt.length }}/2000</view>
     </view>
     </view>
@@ -28,21 +19,21 @@
       <view class="section-title">参考指标(自动生成)</view>
       <view class="section-title">参考指标(自动生成)</view>
       <view class="snapshot-text">{{ renderedSnapshot }}</view>
       <view class="snapshot-text">{{ renderedSnapshot }}</view>
     </view>
     </view>
+  </view>
 
 
+  <view class="save-bar">
     <button class="save-btn" :loading="saving" @click="onSave">保存</button>
     <button class="save-btn" :loading="saving" @click="onSave">保存</button>
   </view>
   </view>
 </template>
 </template>
 
 
 <script>
 <script>
-import { getPortrait, editPortrait, generatePortrait, regeneratePortrait } from '../../utils/api.js'
+import { getPortrait, editPortrait } from '../../utils/api.js'
 export default {
 export default {
   data() {
   data() {
     return {
     return {
       portraitPrompt: '',
       portraitPrompt: '',
       renderedSnapshot: '',
       renderedSnapshot: '',
-      saving: false,
-      generating: false,
-      regenerating: false
+      saving: false
     }
     }
   },
   },
   onLoad() {
   onLoad() {
@@ -63,45 +54,6 @@ export default {
     onInput(e) {
     onInput(e) {
       this.portraitPrompt = e.detail.value
       this.portraitPrompt = e.detail.value
     },
     },
-    async onGenerate() {
-      this.generating = true
-      try {
-        const memberId = this.$store.state.currentMemberId
-        const res = await generatePortrait({ memberId })
-        if (res.code === 200 && res.data) {
-          this.portraitPrompt = res.data.portraitPrompt || ''
-          this.renderedSnapshot = res.data.renderedSnapshot || ''
-          uni.showToast({ title: '生成成功', icon: 'success' })
-        } else {
-          uni.showToast({ title: res.message || '生成失败', icon: 'none' })
-        }
-      } catch (e) {
-        uni.showToast({ title: '生成失败', icon: 'none' })
-      } finally {
-        this.generating = false
-      }
-    },
-    async onRegenerate() {
-      this.regenerating = true
-      try {
-        const memberId = this.$store.state.currentMemberId
-        const res = await regeneratePortrait({ 
-          memberId,
-          previousPortrait: this.portraitPrompt  // 传入当前画像作为参考
-        })
-        if (res.code === 200 && res.data) {
-          this.portraitPrompt = res.data.portraitPrompt || ''
-          this.renderedSnapshot = res.data.renderedSnapshot || ''
-          uni.showToast({ title: '重画成功', icon: 'success' })
-        } else {
-          uni.showToast({ title: res.message || '重画失败', icon: 'none' })
-        }
-      } catch (e) {
-        uni.showToast({ title: '重画失败', icon: 'none' })
-      } finally {
-        this.regenerating = false
-      }
-    },
     async onSave() {
     async onSave() {
       this.saving = true
       this.saving = true
       try {
       try {
@@ -125,8 +77,10 @@ export default {
 <style scoped>
 <style scoped>
 .portrait-edit-page {
 .portrait-edit-page {
   padding: 24rpx;
   padding: 24rpx;
+  padding-bottom: 160rpx;
   min-height: 100vh;
   min-height: 100vh;
   background: #f5f5f5;
   background: #f5f5f5;
+  box-sizing: border-box;
 }
 }
 .section {
 .section {
   background: #fff;
   background: #fff;
@@ -145,25 +99,9 @@ export default {
   color: #999;
   color: #999;
   margin-bottom: 16rpx;
   margin-bottom: 16rpx;
 }
 }
-.action-row {
-  display: flex;
-  gap: 16rpx;
-  margin-bottom: 16rpx;
-}
-.action-btn {
-  flex: 1;
-  height: 72rpx;
-  border-radius: 36rpx;
-  font-size: 26rpx;
-  background: linear-gradient(135deg, #667eea, #764ba2);
-  color: #fff;
-}
-.action-btn.secondary {
-  background: linear-gradient(135deg, #F97316, #F59E0B);
-}
 .portrait-textarea {
 .portrait-textarea {
   width: 100%;
   width: 100%;
-  height: 300rpx;
+  min-height: 500rpx;
   border: 1rpx solid #eee;
   border: 1rpx solid #eee;
   border-radius: 8rpx;
   border-radius: 8rpx;
   padding: 16rpx;
   padding: 16rpx;
@@ -183,6 +121,18 @@ export default {
   white-space: pre-wrap;
   white-space: pre-wrap;
   line-height: 1.6;
   line-height: 1.6;
 }
 }
+.save-bar {
+  position: fixed;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  padding: 20rpx 24rpx;
+  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
+  background: #fff;
+  box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.08);
+  box-sizing: border-box;
+  z-index: 100;
+}
 .save-btn {
 .save-btn {
   background: #F97316;
   background: #F97316;
   color: #fff;
   color: #fff;
@@ -190,6 +140,5 @@ export default {
   height: 88rpx;
   height: 88rpx;
   line-height: 88rpx;
   line-height: 88rpx;
   font-size: 32rpx;
   font-size: 32rpx;
-  margin-top: 32rpx;
 }
 }
 </style>
 </style>