Explorar o código

Merge branch '历史记录内墙样式与外墙同步' into 20260415生产发布版本

# Conflicts:
#	src/main.ts
yanym hai 3 semanas
pai
achega
1b80289580

+ 18 - 0
src/api/indexAI.js

@@ -334,6 +334,24 @@ export function GetProductInfo(query) {
     })
 }
 
+// 外墙提交反馈信息
+export function outsideUpdateFeedBack(query) {
+    return request({
+        url: '/aidesign/outside/UpdateFeedBack',
+        method: 'post',
+        data: query
+    })
+}
+
+// 内墙提交反馈信息
+export function insideUpdateFeedBack(query) {
+    return request({
+        url: '/aidesign/inside/UpdateFeedBack',
+        method: 'post',
+        data: query
+    })
+}
+
 //获取确认下单地址
 export function GetOrderAddress() {
     const formData = new FormData();

BIN=BIN
src/assets/AIDesign/feedback_icon.png


BIN=BIN
src/assets/AIDesign/feedback_result.png


+ 3 - 1
src/main.ts

@@ -86,7 +86,8 @@ import {
   Search,
   Overlay,
     Switch,
-    Lazyload
+    ImagePreview,
+  Lazyload
 } from "vant";
 
 [
@@ -125,6 +126,7 @@ import {
   Search,
   Overlay,
     Switch,
+    ImagePreview,
     Lazyload
 ].forEach(x => Vue.use(x));
 

+ 6 - 0
src/router/index.ts

@@ -82,6 +82,12 @@ const router = new VueRouter({
           component: () => import("../views/AIDesign/diagnoseResult.vue"),
           meta: { requiresAuth: true } // 标记需要登录的页面
         },
+        //反馈页面
+          {
+              path: "/AIDesign/feedback",
+              component: () => import("../views/AIDesign/feedback.vue"),
+              meta: { requiresAuth: true }
+          },
         // 生成方案
         {
           path: "/AIDesign/GeneratePlan",

+ 150 - 0
src/views/AIDesign/feedback.vue

@@ -0,0 +1,150 @@
+<template>
+    <div class="resout-container AI-Design-container">
+        <div class="header">
+            <van-nav-bar title="一键反馈" left-arrow @click-left="returnPage" @click-right="toHome">
+                <template #right>
+                    <van-icon name="wap-home-o" color="#333" size="26" />
+                </template>
+            </van-nav-bar>
+        </div>
+        <div class="card" style="padding-top: 15px;">
+            <div v-if="feedbackResult == 0" class="title">写反馈</div>
+            <van-field
+                    v-if="feedbackResult == 0"
+                    v-model="feedbackMessage"
+                    rows="12"
+                    autosize
+                    @input="messageInput"
+                    style="padding: 0;"
+                    type="textarea"
+                    maxlength="300"
+                    :placeholder="textareaPlaceholder"
+                    show-word-limit
+            />
+            <img v-if="feedbackResult == 1" src="@/assets/AIDesign/feedback_result.png" class="feedback-result-img" />
+            <div v-if="feedbackResult == 1" class="feedback-result-txt">您已成功提交反馈,我们将尽快处理~</div>
+        </div>
+        <van-button
+                v-if="feedbackResult == 0"
+                type="primary"
+                size="large"
+                color="#2484F2"
+                :disabled="isBtnDisabled"
+                style="width: 90%;margin-top: 20px;border-radius: 15px;"
+                @click="applyFeedback">
+            提交反馈
+        </van-button>
+    </div>
+</template>
+
+<script lang="ts">
+    import { Component, Vue } from "vue-property-decorator";
+    import { outsideUpdateFeedBack, insideUpdateFeedBack } from "@/api/indexAI";
+    import { toLBHome } from '@/utils/index';
+    @Component
+    export default class extends Vue {
+
+        private isBtnDisabled = true;
+        private feedbackMessage = '';
+        private feedbackResult = 0;
+        private wallType: '';
+        private textareaPlaceholder = '差点意思?再生成一张会更好\n也可以在此提出您的宝贵意见...'
+
+        // 处理内外墙api
+        private applyFeedbackApi = {
+            outside: outsideUpdateFeedBack,
+            inside: insideUpdateFeedBack
+        };
+
+        activated(){
+            this.wallType = this.$route.query.wallType;
+            this.feedbackResult =  this.$route.query.feedbackResult;
+            this.initialize();
+        }
+
+        //初始化页面数据
+        private initialize() {
+            this.feedbackMessage = '';
+            this.isBtnDisabled = true;
+        }
+        
+        applyFeedback(){
+            let that = this;
+            const F_ID = this.$route.query.F_id || "";
+            const formData = new FormData();
+            formData.append('F_id', F_ID);
+            formData.append('Feedback', that.feedbackMessage);
+            that.applyFeedbackApi[that.wallType](formData).then(response => {
+                if (response.StatusCode == 200) {
+                    that.feedbackResult = 1;
+                }
+            })
+        }
+
+        messageInput(value){
+            let that = this;
+            if (value.trim() === "") {
+                that.isBtnDisabled = true;
+            }else {
+                that.isBtnDisabled = false;
+            }
+        }
+
+        returnPage() {
+            this.$router.back();
+        }
+
+        toHome() {
+            toLBHome()
+        }
+    }
+</script>
+
+<style scoped lang="scss">
+    .resout-container {
+        background: linear-gradient(to bottom, #dffef6, #e7f8f4);
+        min-height: 100vh;
+        flex-direction: column;
+        display: flex;
+        align-items: center;
+    }
+    .header {
+        border-bottom: 1px solid #f8f8f8;
+        .van-nav-bar__title {
+            font-size: 20px;
+            color: #333;
+        }
+        .van-icon {
+            font-size: 20px;
+            color: #333 !important;
+        }
+    }
+    .card{
+        width: 90%;
+        height: 60vh;
+        min-height: 60vh;
+        background-color: #FFFFFF;
+        border-radius: 15px;
+        margin-top: 70px;
+        flex-direction: column;
+        display: flex;
+        box-sizing: border-box;
+        padding: 15px;
+        .title{
+            font-size: 20px;
+            font-weight: 700;
+            margin-bottom: 15px;
+        }
+        .feedback-result-img{
+            width: 70%;
+            margin-left: 15%;
+            margin-top: 10%;
+        }
+        .feedback-result-txt{
+            font-size: 16px;
+            color: rgb(134, 144, 156);
+            text-align: center;
+            margin-top: 15px;
+        }
+    }
+</style>

+ 73 - 24
src/views/AIDesign/result.vue

@@ -1,4 +1,4 @@
-<template>
+<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
   <div class="resout-container AI-Design-container">
     <div class="header">
       <van-nav-bar title="生成结果" left-arrow @click-left="returnPage" @click-right="toHome">
@@ -10,7 +10,7 @@
 
     <div class="container">
       <!-- 历史生图 -->
-      <div class="history-section padded-lr-20" v-if="wallType === 'outside'">
+      <div class="history-section padded-lr-20" v-if="wallType === 'outside' || wallType === 'inside'">
         <div class="history-header" @click="viewHistory">
           <van-icon name="clock-o" color="#EC8868" />
           <span>历史生图</span>
@@ -29,13 +29,13 @@
             </div>
           </div>
           <div class="imgbox-b">
-            <div class="image-wrapper" @click="imgClick(UserFilePathUrl)">
+            <div class="image-wrapper" @click="imgClick(0)">
               <img :src="UserFilePathUrl" alt="房屋效果图" class="house-image" @error="handleImageError" />
               <div v-on="{
                 'click.stop': imgHasErr ? () => reloadImage('userFile') : () => { }
               }"></div>
             </div>
-            <div class="image-wrapper" @click="imgClick(imageUrl)">
+            <div class="image-wrapper" @click="imgClick(1)">
               <img :src="imageUrlSmall" alt="房屋效果图" class="house-image" @error="handleImageError" />
               <div v-on="{
                 'click.stop': imgHasErr ? () => reloadImage('imageSmall') : () => { }
@@ -49,13 +49,18 @@
             '生成失败,\n' + StateInfo :
             '正在为您加速生成中,先喝杯茶吧~\n退出本页不影响生成')) : '加载中...' }}</p>
         </div>
+        <div v-if="imageUrl" class="feedback" @click="toFeedback">
+          <img src="@/assets/AIDesign/feedback_icon.png" class="feedback-icon" />
+          <span v-if="F_Feedback == null">一键反馈</span>
+          <span v-if="F_Feedback != null">查看反馈</span>
+        </div>
       </div>
 
       <!-- 功能按钮组 -->
       <!-- 外墙 -->
-      <div class="button-group-outside" v-if="wallType === 'outside'">
+      <div class="button-group-outside" v-if="wallType === 'outside' || wallType === 'inside'">
         <button class="action-button-big flex-center" @click="handleAIfun"
-          v-if="agentFrom === 'stoneLikePaint' && allRes && allRes.F_DesignStyle != 'CHANGE_COLOR' && StateCode == 2">
+          v-if="agentFrom === 'stoneLikePaint' && allRes && allRes.F_DesignStyle != 'CHANGE_COLOR' && StateCode == 2 && wallType === 'outside'">
           <img src="@/assets/AIDesign/file-excel-line.png" class="icon" />
           <div>
             <div class="title">确认AI设计</div>
@@ -73,7 +78,7 @@
           </button>
           <!-- :class="projectDisableFlag == true ? 'save-button-disabled' : ''"  :disabled="projectDisableFlag"-->
           <button class="action-button-middle flex-center" @click="manualDesign"
-            v-if="showArtificial && StateCode == 2 && !projectDisableFlag">
+            v-if="showArtificial && StateCode == 2 && !projectDisableFlag && wallType === 'outside'">
             <img src="@/assets/AIDesign/bsIcon.png" class="iconbig" />
             <div>
               <div class="title">转人工设计
@@ -84,20 +89,32 @@
         </div>
       </div>
       <!-- 内墙 -->
-      <div class="button-group" v-if="wallType === 'inside'">
-        <button class="action-button" :disabled="regenerateDisable"
-          :class="regenerateDisable == true ? 'save-button-disabled' : ''" @click="regenerate">
-          <van-icon class="icon" name="replay" />
-          <span class="text">重新生成</span>
-        </button>
-        <button class="action-button" @click="viewHistory">
-          <van-icon class="icon" name="clock-o" />
-          <span class="text">历史生图</span>
-          <span v-if="!readState" class="badge-dot"></span>
-        </button>
-      </div>
-
+      <!--<div class="button-group" v-if="wallType === 'inside'">-->
+        <!--<button class="action-button" :disabled="regenerateDisable"-->
+          <!--:class="regenerateDisable == true ? 'save-button-disabled' : ''" @click="regenerate">-->
+          <!--<van-icon class="icon" name="replay" />-->
+          <!--<span class="text">重新生成</span>-->
+        <!--</button>-->
+        <!--<button class="action-button" @click="viewHistory">-->
+          <!--<van-icon class="icon" name="clock-o" />-->
+          <!--<span class="text">历史生图</span>-->
+          <!--<span v-if="!readState" class="badge-dot"></span>-->
+        <!--</button>-->
+      <!--</div>-->
     </div>
+    <van-image-preview
+            v-model="showImagePreview"
+            :images="imagePreviewArray"
+            :loop="false"
+            :start-position="imagePreviewIndex"
+            @change="imagePreviewOnChange">
+      <template v-slot:index>
+        <div class="image-preview-header">
+          <div>{{imagePreviewIndex+1}}/{{imagePreviewArray.length}}</div>
+          <div>{{imagePreviewIndex == 0 ? '原图' : '效果图'}}</div>
+        </div>
+      </template>
+    </van-image-preview>
   </div>
 </template>
 <script lang="ts">
@@ -124,8 +141,12 @@ export default class extends Vue {
   private type = '';
   private wallType = '';
   private F_OutsideType = null;
+  private F_Feedback = null;
   private defaultImg = require('@/assets/AIDesign/imgErrIcon.jpg'); // 替换为实际图片路径
   private imgHasErr = false;
+  private showImagePreview = false;
+  private imagePreviewArray = [];
+  private imagePreviewIndex = 0
   // 处理内外墙api
   private GetEntityToApi = {
     outside: GetEntity,
@@ -322,9 +343,14 @@ export default class extends Vue {
   toHome() {
     toLBHome()
   }
-  imgClick(url) {
-    ImagePreview([url]);
+  imgClick(index) {
+      this.showImagePreview = true;
+      this.imagePreviewIndex = index;
+    // ImagePreview([this.UserFilePathUrl,this.imageUrl],index);
   }
+    imagePreviewOnChange(index){
+      this.imagePreviewIndex = index;
+    }
   private startPolling(): void {
     // 立即执行一次检查
     this.GetEntityData();
@@ -372,6 +398,7 @@ export default class extends Vue {
           this.StateInfo = response.Data.Description;
           this.projectId = response.Data.ProjectID;
           this.F_OutsideType = response.Data.F_OutsideType;
+          this.F_Feedback = response.Data.F_Feedback;
           let DesignCount = response.Data.DesignCount || 0;
           // 外墙-服务商随身邦
           if (this.agentFrom === 'stoneLikePaint' && this.wallType === 'outside') {
@@ -388,6 +415,7 @@ export default class extends Vue {
             that.imageUrl = response.Data.BaseUrl + high_Definition_img;
             that.imageUrlSmall = response.Data.BaseUrl + response.Data.F_ResultSmallFilePath;
             that.UserFilePathUrl = response.Data.BaseUrl + response.Data.F_UserFilePath;
+            that.imagePreviewArray = [that.UserFilePathUrl,that.imageUrl];
           }
           if (response.Data.StateCode == 1) {
             let createTime = new Date(response.Data.CreateDate);
@@ -430,6 +458,7 @@ export default class extends Vue {
           this.StateCode = response.Data.StateCode;
           this.StateInfo = response.Data.Description;
           this.F_OutsideType = response.Data.F_OutsideType;
+          this.F_Feedback = response.Data.F_Feedback;
           this.projectId = response.Data.ProjectID;
           let DesignCount = response.Data.DesignCount || 0;
           // 外墙-服务商随身邦
@@ -447,6 +476,7 @@ export default class extends Vue {
             that.imageUrl = response.Data.BaseUrl + high_Definition_img;
             that.imageUrlSmall = response.Data.BaseUrl + response.Data.F_ResultSmallFilePath;
             that.UserFilePathUrl = response.Data.BaseUrl + response.Data.F_UserFilePath;
+            that.imagePreviewArray = [that.UserFilePathUrl,that.imageUrl];
           }
           if (response.Data.StateCode == 2 || response.Data.StateCode == 3 || response.Data.StateCode == 4) {
             that.regenerateDisable = false;
@@ -556,6 +586,12 @@ export default class extends Vue {
     });
   }
 
+  private toFeedback(){
+      let that = this;
+      const F_ID = this.$route.query.F_id || "";
+      this.$router.push({ path: '/AIDesign/feedback', query: { F_id: F_ID, feedbackResult: that.F_Feedback == null ? 0 : 1, wallType: this.wallType } });
+  }
+
   private viewHistory(): void {
     this.UpdateReadStateFn();
     // console.log('查看历史生成');
@@ -663,7 +699,16 @@ export default class extends Vue {
   border-radius: 10px;
   overflow: hidden;
   box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
-
+  .feedback{
+    padding: 15px 10px 15px 10px;
+    font-size: 16px;
+    color: rgba(22, 93, 255, 1);
+    .feedback-icon{
+      width: 20px;
+      margin-right: 5px;
+      margin-bottom: -5px;
+    }
+  }
   .comparisonWrapper {
     display: flex;
     flex-direction: column;
@@ -933,7 +978,11 @@ export default class extends Vue {
   }
 }
 
-
+.image-preview-header{
+  flex-direction: column;
+  display: flex;
+  align-items: center;
+}
 .van-nav-bar__title {
   font-size: 20px;
   color: #333;