Browse Source

Merge branch 'feature_20250704_陈列SKU图片识别' into uat(dev)

# Conflicts:
#	src/views/week/dailyDetails.vue
#	src/views/week/dailyHistoricalDetails.vue
zhujindu 4 months ago
parent
commit
9f9f324036

+ 19 - 0
src/api/historicalVisit.js

@@ -0,0 +1,19 @@
+import request from '@/utils/request';
+
+// sku识别信息查询接口
+export function photoSkuImgSummary(query) {
+  return request({
+    url: '/mobile/photoSkuImgSummary/list',
+    method: 'get',
+    params: query,
+  });
+}
+
+// 反馈接口
+export function photoSkuFeedback(data) {
+  return request({
+    url: 'mobile/photoSkuFeedback',
+    method: 'post',
+    data,
+  });
+}

+ 5 - 0
src/router/index.js

@@ -324,6 +324,11 @@ const router = new VueRouter({
             keepAlive: true,
           },
         },
+        {
+          path: '/skuRecognize',
+          name: 'skuRecognize',
+          component: () => import('@/views/historicalVisit/skuRecognize.vue'),
+        },
       ],
     },
     {

+ 24 - 0
src/views/historicalVisit/historicalDetails.vue

@@ -93,6 +93,24 @@
           <p style="text-align: right">点评时间:{{ managerRemarkContents[0].createTime }}</p>
         </van-collapse-item>
       </van-collapse>
+      <div style="padding: 10px 16px; font-size: 16px; font-weight: bold">SKU图像识别结果</div>
+      <div class="card" v-if="list.isSku == '是'">
+        <div class="info" @click="toSkuRecognize">
+          <p
+            style="
+              width: 94%;
+              margin: 0;
+              line-height: 24px;
+              padding: 10px 0;
+              display: inline-block;
+            ">
+            拍摄的所有产品陈列照识别结果
+          </p>
+          <p class="arrowdetils1">
+            <van-icon name="arrow" />
+          </p>
+        </div>
+      </div>
       <div style="padding: 10px 16px; font-size: 16px; font-weight: bold">任务</div>
       <div class="card" v-if="list.visitSource != 2">
         <div
@@ -397,6 +415,12 @@ export default {
       });
       sessionStorage.setItem('collectionItemList', JSON.stringify(val.collectionItemList));
     },
+    toSkuRecognize() {
+      this.$router.push({
+        path: '/skuRecognize',
+        query: { visitId: this.visitsId },
+      });
+    },
     onClickLeft() {
       if (this.$route.query.token) {
         this.$router.push({

+ 0 - 22
src/views/historicalVisit/hisvistdeils.vue

@@ -246,25 +246,6 @@
             <delete-upload-img :imgs="item.fileInfoList"></delete-upload-img>
           </div>
         </div>
-        <!-- SKU识别 -->
-        <!-- 生动化陈列 sku -->
-        <template v-if="photoSkuImgSummaryeList && photoSkuImgSummaryeList.length">
-          <div class="skuNum" style="padding: 10px 0">
-            SKU识别:{{ photoSkuImgSummaryeList.length }}个
-          </div>
-          <el-table
-            :data="photoSkuImgSummaryeList"
-            style="width: 100%; border-radius: 10px"
-            border
-            class="table-headermd">
-            <el-table-column label="SKU名称" prop="name" width="180" align="center">
-              <template slot-scope="scope">
-                <span class="tipTitle">{{ scope.row.name }}</span>
-              </template>
-            </el-table-column>
-            <el-table-column label="数量" prop="count" align="center"></el-table-column>
-          </el-table>
-        </template>
       </van-form>
     </div>
     <van-dialog v-model="listShow" title="历史回显" show-cancel-button :showConfirmButton="false">
@@ -321,7 +302,6 @@ export default {
       checkShow: false,
       infoData: {},
       putInCode: '',
-      photoSkuImgSummaryeList: [],
     };
   },
   activated() {
@@ -393,8 +373,6 @@ export default {
         this.toastLoading().clear();
         this.infoData = res.data;
         var collectionItemLists = res.data.sfaTaskList[this.$route.query.ids].collectionItemList;
-        this.photoSkuImgSummaryeList =
-          res.data.sfaTaskList[this.$route.query.ids].photoSkuImgSummaryeList;
         if (res.data.sfaTaskList[this.$route.query.ids].checkUnManage == 'Y') {
           this.checkShow = true;
         } else {

+ 257 - 0
src/views/historicalVisit/skuRecognize.vue

@@ -0,0 +1,257 @@
+<template>
+  <div class="skuRecognize">
+    <van-nav-bar class="navBar" title="拜访任务详情" left-arrow @click-left="onClickLeft">
+      <template #right>
+        <div
+          v-if="detail && detail.skuPhotoIdentifyId"
+          class="feedback"
+          @click="feedbackShow = true">
+          识别异常反馈
+        </div>
+      </template>
+    </van-nav-bar>
+    <div class="content" v-if="detail">
+      <div class="title">产品陈列照</div>
+      <div class="tipsTitle">{{ detail.skuDescribe }}</div>
+      <div>
+        <van-row gutter="10">
+          <van-col span="4" v-for="(urls, index) in detail.fileUrlList" :key="index">
+            <div class="img-box">
+              <img :src="urls" @click="previewsImg(index)" />
+            </div>
+          </van-col>
+        </van-row>
+      </div>
+      <div class="skuDeatil" v-if="detail.skuList">
+        <div class="tableTitle">SKU识别:{{ detail.skuTotal }}个</div>
+        <el-table
+          :data="detail.skuList"
+          style="width: 100%; border-radius: 10px"
+          border
+          class="table-headermd">
+          <el-table-column label="序号" type="index" align="center"> </el-table-column>
+          <el-table-column label="品类" prop="skuProductType" align="center"></el-table-column>
+          <el-table-column label="SKU名称" prop="name" align="center">
+            <template slot-scope="scope">
+              <span class="tipTitle">{{ scope.row.name }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="排面数" prop="count" align="center" width="60"></el-table-column>
+        </el-table>
+      </div>
+      <!-- 返回历史 -->
+      <div class="feedbackHistorical" v-if="detail.feedbackList.length">
+        <div class="tableTitle">识别异常反馈</div>
+        <div class="historicalContent">
+          <div class="rejectMsgItem" v-for="(item, index) in detail.feedbackList" :key="index">
+            <div class="item approver">
+              <span class="label">反馈人:</span>
+              <span class="value">{{ item.nickName }}</span>
+            </div>
+            <div class="item approvalTime">
+              <span class="label">反馈时间:</span>
+              <span class="value">{{ item.createTime }}</span>
+            </div>
+            <div class="item rejectCause">
+              <span class="label">反馈内容:</span>
+              <span class="value">{{ item.feedbackContent }}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 识别异常反馈 -->
+    <van-popup v-model="feedbackShow" round class="feedbackMsgBox" :close-on-click-overlay="false">
+      <div class="feedbackTitle">SKU图像识别结果异常反馈</div>
+      <div class="feedbackContent">
+        <van-field
+          v-model="feedbackMessage"
+          rows="2"
+          autosize
+          type="textarea"
+          placeholder="若识别SKU有遗漏、缺失,请在此反馈,本部会根据实际情况优化模型,谢谢!" />
+      </div>
+      <div class="btnBox">
+        <van-button type="info" plain @click="feedbackShow = false">取消</van-button>
+        <van-button type="info" @click="feedbackSubmit">提交</van-button>
+      </div>
+    </van-popup>
+  </div>
+</template>
+
+<script>
+import deleteUploadImg from '@/components/deleteUploadImg';
+import { photoSkuImgSummary, photoSkuFeedback } from '@/api/historicalVisit.js';
+import { ImagePreview } from 'vant';
+export default {
+  name: 'skuRecognize',
+  components: { deleteUploadImg },
+  data() {
+    return {
+      visitsId: '',
+      detail: null,
+      feedbackShow: false,
+      feedbackMessage: '', //反馈内容
+    };
+  },
+  activated() {
+    this.visitsId = this.$route.query.visitId || '';
+    this.getDetail();
+  },
+  methods: {
+    getDetail() {
+      this.toastLoading(0, '加载中...', true);
+      photoSkuImgSummary({ visitsId: this.visitsId })
+        .then((res) => {
+          this.toastLoading().clear();
+          if (res.code == 200) {
+            this.detail = res.data;
+          } else {
+            this.$dialog.alert({
+              message: res.msg,
+            });
+          }
+        })
+        .catch((err) => {
+          this.$dialog.alert({
+            message: err.msg,
+          });
+        });
+    },
+    // 提交反馈
+    feedbackSubmit() {
+      if (this.feedbackMessage == '') {
+        this.$toast('请输入反馈意见!');
+        return;
+      }
+      photoSkuFeedback({
+        photoIdentifyId: this.detail.skuPhotoIdentifyId, //long	sku识别信息id
+        feedbackContent: this.feedbackMessage, //string	内容
+      }).then((res) => {
+        this.feedbackShow = false;
+        this.getDetail();
+      });
+    },
+    previewsImg(index) {
+      ImagePreview({
+        images: this.detail.fileUrlList,
+        startPosition: index,
+      });
+    },
+    onClickLeft() {
+      this.$router.go(-1);
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.skuRecognize {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+  .content {
+    flex: 1;
+    overflow-y: auto;
+    background: #fff;
+    padding: 10px 15px;
+    margin-top: 10px;
+    .title {
+      font-size: 16px;
+      padding-bottom: 10px;
+    }
+    .tipsTitle {
+      font-size: 14px;
+      padding-bottom: 10px;
+    }
+    .tableTitle {
+      padding: 10px 0;
+      font-size: 16px;
+      font-weight: bold;
+      background: #f5f5f5;
+    }
+    .skuDeatil {
+      .table-headermd {
+        font-size: 12px;
+        text-align: center;
+        position: initial;
+        width: 98% !important;
+        margin: 0 auto;
+        border-right: 0;
+        border-radius: 10px;
+        .el-table__cell {
+          padding: 6px 0 !important;
+        }
+      }
+      .table-headermd th.el-table__cell {
+        background-color: #1989fa;
+        color: #fff;
+      }
+    }
+    .feedbackHistorical {
+      .historicalContent {
+        flex: 1;
+        overflow-y: auto;
+        .rejectMsgItem {
+          margin-bottom: 20px;
+          border: 1px solid #ccc;
+          padding: 10px;
+          .item {
+            padding: 5px 0;
+            span {
+              display: inline-block;
+            }
+          }
+          .label {
+            width: 80px;
+            font-size: 14px;
+            font-weight: 600;
+          }
+          .value {
+            font-size: 14px;
+          }
+        }
+      }
+    }
+    .img-box {
+      width: 100%;
+      height: 50px;
+      position: relative;
+      display: inline-block;
+      border-radius: 6px;
+      overflow: hidden;
+      img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+  }
+  .feedbackMsgBox {
+    min-height: 30%;
+    width: 90%;
+    padding: 10px 20px;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+    .feedbackTitle {
+      padding: 10px 0;
+      text-align: center;
+      font-size: 16px;
+      font-weight: 600px;
+    }
+    .feedbackContent {
+      flex: 1;
+      overflow-y: auto;
+    }
+    .btnBox {
+      height: 44px;
+      display: flex;
+      justify-content: space-between;
+      button {
+        width: 45%;
+      }
+    }
+  }
+}
+</style>

+ 48 - 6
src/views/week/dailyDetails.vue

@@ -387,8 +387,14 @@
           </van-collapse-item>
           <van-collapse-item title="今日拜访照片" name="10" v-if="reportTarget.photos">
             <div v-for="(item, index) in reportTarget.photos" :key="index">
-              <p style="margin-bottom: 10px; margin-top: 0">{{ item.taskName }}</p>
-              <van-row gutter="10" class="visitIMG1">
+              <p style="margin-bottom: 10px">{{ item.taskName }}</p>
+              <van-row
+                gutter="10"
+                class="visitIMG1"
+                :style="{
+                  overflow: 'hidden',
+                  height: item.visitIMG1Flag ? 'auto' : '85px',
+                }">
                 <van-col
                   span="6"
                   style="padding-bottom: 10px"
@@ -398,6 +404,42 @@
                   <img :src="itemImg.fileUrl" alt="" />
                 </van-col>
               </van-row>
+              <div
+                v-if="item.photos.length > 4"
+                class="arrowIcon"
+                style="
+                  display: flex;
+                  align-items: center;
+                  justify-content: center;
+                  padding: 5px 0;
+                  font-size: 14px;
+                  color: #969799;
+                "
+                @click="setVisitIMG1Flag(item)">
+                <template v-if="item.visitIMG1Flag">
+                  <span style="margin-right: 5px">折叠</span>
+                  <van-icon size="14" :name="require('@/assets/Icon/arrow-up.png')" />
+                </template>
+                <template v-else>
+                  <span style="margin-right: 5px">展开</span>
+                  <van-icon size="14" :name="require('@/assets/Icon/arrow-down.png')" />
+                </template>
+              </div>
+              <!-- 生动化陈列 sku -->
+              <template v-if="item.photoSkuImgSummaryeList && item.photoSkuImgSummaryeList.length">
+                <el-table
+                  :data="item.photoSkuImgSummaryeList"
+                  border
+                  class="table-headermd table-headermdhome"
+                  style="width: 100%">
+                  <el-table-column label="门店名称(编号)" prop="name" align="center">
+                    <template slot-scope="scope">
+                      {{ scope.row.name }}({{ scope.row.code }})
+                    </template>
+                  </el-table-column>
+                  <el-table-column label="数量" prop="count" width="80px" align="center" />
+                </el-table>
+              </template>
             </div>
           </van-collapse-item>
           <van-collapse-item v-if="JZQuota" name="21" title="魔术漆过账(千元)">
@@ -802,6 +844,10 @@ export default {
     this.setShareFlag = false;
   },
   methods: {
+    setVisitIMG1Flag(item) {
+      this.$set(item, 'visitIMG1Flag', !item.visitIMG1Flag);
+      this.$forceUpdate();
+    },
     setDailyDetailsBox(flag) {
       this.setDailyDetailsBoxFlag = flag;
     },
@@ -853,10 +899,6 @@ export default {
       this.shareImgFlag = false;
       this.setShareFlag = true;
     },
-    setVisitIMG1Flag(item) {
-      this.$set(item, 'visitIMG1Flag', !item.visitIMG1Flag);
-      this.$forceUpdate();
-    },
     pviewFn(val, imgVal) {
       var imgList = [];
       var photos = this.reportTarget.photos[val].photos;

+ 31 - 5
src/views/week/dailyHistoricalDetails.vue

@@ -438,7 +438,7 @@
                   <van-icon size="14" :name="require('@/assets/Icon/arrow-down.png')" />
                 </template>
               </div>
-              <!-- 生动化陈列 sku -->
+              <!-- 生动化陈列 sku   -->
               <template v-if="item.photoSkuImgSummaryeList && item.photoSkuImgSummaryeList.length">
                 <el-table
                   :data="item.photoSkuImgSummaryeList"
@@ -776,6 +776,10 @@ export default {
     this.setShareFlag = false;
   },
   methods: {
+    setVisitIMG1Flag(item) {
+      this.$set(item, 'visitIMG1Flag', !item.visitIMG1Flag);
+      this.$forceUpdate();
+    },
     setDailyDetailsBox(flag) {
       this.setDailyDetailsBoxFlag = flag;
     },
@@ -827,10 +831,6 @@ export default {
       this.shareImgFlag = false;
       this.setShareFlag = true;
     },
-    setVisitIMG1Flag(item) {
-      this.$set(item, 'visitIMG1Flag', !item.visitIMG1Flag);
-      this.$forceUpdate();
-    },
     pviewFn(val, imgVal) {
       var imgList = [];
       var photos = this.reportTarget.photos[val].photos;
@@ -1043,6 +1043,15 @@ export default {
           }
           this.imgList = imgList;
         }
+        this.reportContents = res.data.reportContents;
+        var imgList = [];
+        if (res.data.photos != null) {
+          for (var k = 0; k < res.data.photos.length; k++) {
+            res.data.photos[k].visitIMG1Flag = false;
+            imgList.push(res.data.photos[k].fileUrl + '');
+          }
+        }
+        this.imgList = imgList;
       });
     },
     userTodayPlanNum() {
@@ -1233,6 +1242,23 @@ export default {
   height: 75px;
   border-radius: 6px;
 }
+
+.table-headermd {
+  font-size: 12px;
+  text-align: center;
+  position: initial;
+  width: 98% !important;
+  margin: 0 auto;
+  border-right: 0;
+  border-radius: 10px;
+  .el-table__cell {
+    padding: 6px 0 !important;
+  }
+}
+.table-headermd th.el-table__cell {
+  background-color: #1989fa;
+  color: #fff;
+}
 .el-dialog__wrapper {
   z-index: 9999 !important;
   display: flex;