Просмотр исходного кода

Merge branch 'feature_20260512_门店列表增加识别中图标'

zhujindu 1 неделя назад
Родитель
Сommit
70e2825e56
3 измененных файлов с 259 добавлено и 22 удалено
  1. 208 0
      src/components/aiGenerating.vue
  2. 26 11
      src/views/deviceOutside/index.vue
  3. 25 11
      src/views/deviceWithin/index.vue

+ 208 - 0
src/components/aiGenerating.vue

@@ -0,0 +1,208 @@
+<template>
+  <!-- 新的生成中动画组件 -->
+  <div class="ai-generating">
+    <!-- AI 星星图标 -->
+    <div class="ai-icon">
+      <svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+        <defs>
+          <linearGradient id="starGrad" x1="0%" y1="0%" x2="100%" y2="100%">
+            <stop offset="0%" stop-color="#6366f1" />
+            <stop offset="100%" stop-color="#a855f7" />
+          </linearGradient>
+        </defs>
+        <!-- 大星星 -->
+        <path
+          d="M10 2 L11.2 7.8 L17 9 L11.2 10.2 L10 16 L8.8 10.2 L3 9 L8.8 7.8 Z"
+          fill="url(#starGrad)"
+          style="animation: starPulse 1.8s ease-in-out infinite; transform-origin: 10px 9px">
+          <animateTransform
+            attributeName="transform"
+            type="scale"
+            values="1;1.12;1"
+            dur="1.8s"
+            repeatCount="indefinite"
+            additive="sum"
+            calcMode="ease" />
+        </path>
+        <!-- 小星星 -->
+        <circle cx="15.5" cy="4.5" r="1.5" fill="#a855f7" opacity="0.7">
+          <animate attributeName="opacity" values="0.4;1;0.4" dur="1.4s" repeatCount="indefinite" />
+          <animate attributeName="r" values="1.2;1.8;1.2" dur="1.4s" repeatCount="indefinite" />
+        </circle>
+        <!-- 微星 -->
+        <circle cx="4.5" cy="14.5" r="1" fill="#6366f1" opacity="0.5">
+          <animate
+            attributeName="opacity"
+            values="0.3;0.9;0.3"
+            dur="1.8s"
+            begin="0.5s"
+            repeatCount="indefinite" />
+          <animate
+            attributeName="r"
+            values="0.8;1.4;0.8"
+            dur="1.8s"
+            begin="0.5s"
+            repeatCount="indefinite" />
+        </circle>
+      </svg>
+    </div>
+
+    <!-- 三个跳动点 -->
+    <!-- <div class="dots-container">
+      <div class="dot"></div>
+      <div class="dot"></div>
+      <div class="dot"></div>
+    </div> -->
+
+    <!-- 渐变文字 -->
+    <span class="gen-text">报告生成中</span>
+  </div>
+</template>
+<style lang="scss" scoped>
+/* ===== AI 生成中动画 ===== */
+.ai-generating {
+  display: flex;
+  align-items: center;
+  gap: 5px;
+  background: linear-gradient(135deg, rgba(99, 102, 241, 0.08), rgba(168, 85, 247, 0.08));
+  border: 1px solid rgba(99, 102, 241, 0.2);
+  border-radius: 20px 0 0 20px;
+  padding: 3px 0px 3px 7px;
+  margin-right: -3px;
+}
+
+/* AI 图标 - 彩色渐变扫描动效 */
+.ai-icon {
+  width: 20px;
+  height: 20px;
+  position: relative;
+  flex-shrink: 0;
+}
+.ai-icon svg {
+  width: 20px;
+  height: 20px;
+}
+
+/* 三个跳动圆点 */
+.dots-container {
+  display: flex;
+  align-items: center;
+  gap: 3px;
+}
+.dot {
+  width: 5px;
+  height: 5px;
+  border-radius: 50%;
+  background: linear-gradient(135deg, #6366f1, #a855f7);
+  animation: dotBounce 1.4s ease-in-out infinite;
+}
+.dot:nth-child(1) {
+  animation-delay: 0s;
+}
+.dot:nth-child(2) {
+  animation-delay: 0.2s;
+}
+.dot:nth-child(3) {
+  animation-delay: 0.4s;
+}
+
+@keyframes dotBounce {
+  0%,
+  60%,
+  100% {
+    transform: translateY(0);
+    opacity: 0.5;
+  }
+  30% {
+    transform: translateY(-5px);
+    opacity: 1;
+  }
+}
+
+/* 生成中文字 */
+.gen-text {
+  font-size: 12px;
+  font-weight: 500;
+  background: linear-gradient(90deg, #6366f1, #a855f7, #6366f1);
+  background-size: 200% auto;
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+  animation: textShimmer 2s linear infinite;
+}
+@keyframes textShimmer {
+  0% {
+    background-position: 0% center;
+  }
+  100% {
+    background-position: 200% center;
+  }
+}
+
+/* AI 图标内部的星星动画 */
+@keyframes starPulse {
+  0%,
+  100% {
+    transform: scale(1) rotate(0deg);
+    opacity: 0.9;
+  }
+  50% {
+    transform: scale(1.15) rotate(15deg);
+    opacity: 1;
+  }
+}
+@keyframes starOrbit {
+  0% {
+    transform: rotate(0deg) translateX(5px) rotate(0deg);
+  }
+  100% {
+    transform: rotate(360deg) translateX(5px) rotate(-360deg);
+  }
+}
+
+/* 光晕扫描 */
+.scan-line {
+  position: absolute;
+  top: 0;
+  left: -100%;
+  width: 60%;
+  height: 100%;
+  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
+  animation: scanAnim 2s ease-in-out infinite;
+  border-radius: 50%;
+}
+@keyframes scanAnim {
+  0% {
+    left: -60%;
+  }
+  100% {
+    left: 160%;
+  }
+}
+.AISpan {
+  display: flex;
+  align-items: center;
+  color: #1989fa;
+  margin-right: 5px;
+  font-size: 12px;
+}
+.AISpan::before {
+  content: '';
+  display: inline-block;
+  width: 6px;
+  height: 6px;
+  border-radius: 50%;
+  background: #2979ff;
+  animation: blink 1.2s ease-in-out infinite;
+  margin-right: 5px;
+}
+@keyframes blink {
+  0%,
+  100% {
+    opacity: 0.3;
+  }
+  50% {
+    opacity: 1;
+  }
+}
+</style>

+ 26 - 11
src/views/deviceOutside/index.vue

@@ -367,19 +367,33 @@
               <template v-if="item.stateString == '已拜访'">
                 <template v-if="item.visitSource == 1">
                   <!-- 金牌店+同城分销店+可控店 -->
-                  <template v-if="item.wanmeiStore">
+                  <template v-if="item.jinpaiStore || item.fenxiaoStore || item.kekongStore">
                     <div class="statstext" style="background-color: #e3f0fe">
                       <span style="color: #387bca">已拜访</span>
-                      <div
-                        class="statstextIcon"
-                        style="background-color: #0057ba"
-                        @click="openPerfectStore(item)">
-                        <div style="margin: 4px; font-size: 14px; font-weight: 600">
-                          <img
-                            style="width: 18px; height: 20px; margin: 0 5px; vertical-align: -5px"
-                            :src="require('@/assets/shouzhi.png')" />完美门店报告
+                      <!-- 完美门店报告生成 -->
+                      <template v-if="item.wanmeiStore">
+                        <!-- <template v-if="false"> -->
+                        <div
+                          class="statstextIcon"
+                          style="background-color: #0057ba"
+                          @click="openPerfectStore(item)">
+                          <div style="margin: 4px; font-size: 14px; font-weight: 600">
+                            <img
+                              style="width: 18px; height: 20px; margin: 0 5px; vertical-align: -5px"
+                              :src="require('@/assets/shouzhi.png')" />完美门店报告
+                          </div>
                         </div>
-                      </div>
+                      </template>
+                      <!-- 完美门店报告生成中 -->
+                      <template v-else>
+                        <aiGenerating
+                          style="
+                            width: 100px;
+                            position: absolute;
+                            left: -40px;
+                            top: 31px;
+                          "></aiGenerating>
+                      </template>
                     </div>
                   </template>
                   <template v-else>
@@ -680,9 +694,10 @@ import xmgj from '@/assets/xmgj.png';
 import { getOrderUrlByStoreId } from '@/api/inventory';
 import { checkStoreAddressByStoreCode } from '@/api/visitstore';
 import { getPosition, getMapPoi, getkeywordPoi, getTicketFun } from '@/utils/TXApiFun';
+import aiGenerating from '@/components/aiGenerating';
 export default {
   name: 'outsidelist',
-  components: { tabBar, mapmarker },
+  components: { tabBar, mapmarker, aiGenerating },
   data() {
     return {
       yichang: yichang,

+ 25 - 11
src/views/deviceWithin/index.vue

@@ -394,19 +394,32 @@
               <!-- 正常拜访 -->
               <template v-if="item.visitSource == 1">
                 <!-- 金牌店+同城分销店+可控店 -->
-                <template v-if="item.wanmeiStore">
+                <template v-if="item.jinpaiStore || item.fenxiaoStore || item.kekongStore">
                   <div class="statstext" style="background-color: #e3f0fe">
                     <span style="color: #387bca">已拜访</span>
-                    <div
-                      class="statstextIcon"
-                      style="background-color: #0057ba"
-                      @click="openPerfectStore(item)">
-                      <div style="margin: 4px; font-size: 14px; font-weight: 600">
-                        <img
-                          style="width: 18px; height: 20px; margin: 0 5px; vertical-align: -5px"
-                          :src="require('@/assets/shouzhi.png')" />完美门店报告
+                    <!-- 完美门店报告生成 -->
+                    <template v-if="item.wanmeiStore">
+                      <div
+                        class="statstextIcon"
+                        style="background-color: #0057ba"
+                        @click="openPerfectStore(item)">
+                        <div style="margin: 4px; font-size: 14px; font-weight: 600">
+                          <img
+                            style="width: 18px; height: 20px; margin: 0 5px; vertical-align: -5px"
+                            :src="require('@/assets/shouzhi.png')" />完美门店报告
+                        </div>
                       </div>
-                    </div>
+                    </template>
+                    <!-- 完美门店报告生成中 -->
+                    <template v-else>
+                      <aiGenerating
+                        style="
+                          width: 100px;
+                          position: absolute;
+                          left: -40px;
+                          top: 31px;
+                        "></aiGenerating>
+                    </template>
                   </div>
                 </template>
                 <template v-else>
@@ -544,9 +557,10 @@ import { getOrderUrlByStoreId } from '@/api/inventory';
 import { checkStoreAddressByStoreCode } from '@/api/visitstore';
 import { getPosition, getTicketFun } from '@/utils/TXApiFun';
 import filtrate from '@/components/filtrate';
+import aiGenerating from '@/components/aiGenerating';
 export default {
   name: 'deviceWithin',
-  components: { tabBar, filtrate },
+  components: { tabBar, filtrate, aiGenerating },
   data() {
     return {
       Network: Network,