zhangyuhan пре 5 месеци
родитељ
комит
0f3461e361
1 измењених фајлова са 134 додато и 110 уклоњено
  1. 134 110
      apps/mobile/src/views/ai-search/index.vue

+ 134 - 110
apps/mobile/src/views/ai-search/index.vue

@@ -35,15 +35,16 @@ const rightAction = ref({
 })
 
 function doBack() {
+  trickClick(`退出页面`)
   that.$router.back()
 }
 
 function onSelectRightAction(action) {
   console.log('action', action)
+  trickClick(action)
   if (action.text === '新对话') {
     doNewQuestion()
-  }
-  else {
+  } else {
     doAjaxGetHistoryList()
     historyModel.value.show = true
   }
@@ -57,7 +58,7 @@ const historyModel = ref({
 
 const historyListLabel = computed(() => {
   const periods = ['今天', '过去7天', '过去30天', '更早']
-  return periods.filter(period =>
+  return periods.filter((period) =>
     Array.isArray(historyModel.value.list[period])
   )
 })
@@ -70,6 +71,7 @@ const moreListModel = ref({
 })
 
 function doNewQuestion() {
+  trickClick(`新对话`)
   historyModel.value.show = false
   clearAskState()
   doSelectQuestionType(promptModel.value.typeList[0])
@@ -77,9 +79,21 @@ function doNewQuestion() {
 
 function trickClick(name, opts = {}) {
   console.log(`ai-${name}`, opts)
+  try {
+    window.__EasyJTrack.addTrack(name, {
+      breaker_name: name,
+      product_name: 'AI搜索',
+      breaker_id: 'ai-search',
+      desc: JSON.stringify(opts),
+      date: Date()
+    })
+  } catch (e) {
+    console.log(e)
+  }
 }
 
 async function goHistory(item) {
+  trickClick(`点击历史记录-${item.id}-${item.question}`, item.id)
   historyModel.value.show = false
   console.log('item', item)
   return ajaxGetHistoryDetail({
@@ -111,6 +125,9 @@ async function goHistory(item) {
           _data: v.answer
         })
       })
+      that.$nextTick(() => {
+        scrollToBottom()
+      })
     }
   })
 }
@@ -136,15 +153,16 @@ const promptModel = ref({
 })
 
 function onChangePrompt(index) {
+  trickClick(`切换提示词`)
   promptModel.value.current = index
 }
 
 const promptEle = ref(null)
 function doChangePrompt(val) {
+  trickClick(`切换提示词`)
   if (val) {
     promptEle.value.next()
-  }
-  else {
+  } else {
     promptEle.value.prev()
   }
 }
@@ -191,7 +209,7 @@ function getQuestionInputHeight() {
   }
   const nowKey = `${Date.now()}_${questionModel.value.input.length}`
   questionModel.value.style = {
-    'height': result.height,
+    height: result.height,
     'data-up': nowKey
   }
   questionModel.value.iconShow = canShow
@@ -226,20 +244,20 @@ function formatTypeofItemKey(params, type, spare = '-') {
   let formatFn = () => spare
   switch (type) {
     case 'money': {
-      formatFn = params => formatMoney(Number(params))
+      formatFn = (params) => formatMoney(Number(params))
       break
     }
     case 'money-table': {
-      formatFn = params =>
+      formatFn = (params) =>
         formatMoney(Number(params), { type: 'number', level: 1 })
       break
     }
     case 'date': {
-      formatFn = params => dateFormatter(Number(params) * 1000)
+      formatFn = (params) => dateFormatter(Number(params) * 1000)
       break
     }
     case 'date-ms': {
-      formatFn = params => dateFormatter(Number(params) * 1000, 'yyyy-MM-dd')
+      formatFn = (params) => dateFormatter(Number(params) * 1000, 'yyyy-MM-dd')
       break
     }
   }
@@ -251,8 +269,7 @@ function formatTypeofItemKey(params, type, spare = '-') {
 
 function preSortItem(item, splitKeys) {
   console.log('cee', item)
-  if (!item)
-    return {}
+  if (!item) return {}
   const { area, city, collect, projectInfo } = item
   item.id = item.infoId
   item.star = !!collect
@@ -270,8 +287,8 @@ function preSortItem(item, splitKeys) {
     Object.assign(item, projectInfo)
   }
   const region = city || area
-  const buyerClass
-    = item?.buyerClass && item?.buyerClass !== '其它'
+  const buyerClass =
+    item?.buyerClass && item?.buyerClass !== '其它'
       ? item?.buyerClass
       : undefined
 
@@ -283,7 +300,7 @@ function preSortItem(item, splitKeys) {
     item?.type || item?.subtype,
     // 有中标金额取中标金额,没有取预算,预算没有置空
     formatTypeofItemKey(item?.bidamount || item?.budget, 'money', '')
-  ].filter(v => v)
+  ].filter((v) => v)
 
   item.dateTime = item.publishtime ? item.publishtime * 1000 : ''
 
@@ -321,7 +338,7 @@ function preSortItem(item, splitKeys) {
       label: '中标单位',
       splitter: ':',
       text: Array.isArray(item.winnerInfo)
-        ? item.winnerInfo.map(w => w.winner).join(',')
+        ? item.winnerInfo.map((w) => w.winner).join(',')
         : '',
       detailTextSlot: 'winnerText',
       children: winnerList
@@ -368,8 +385,7 @@ function formatAskAnswer(res) {
   if (res.status === 1) {
     if (res.count === 0) {
       resultState = 2
-    }
-    else {
+    } else {
       resultState = 3
       askItem.list = (res.list || []).map((v) => {
         return formatCellItem(v, res.highlight || [])
@@ -379,8 +395,7 @@ function formatAskAnswer(res) {
       }
       askItem.count = res.count
     }
-  }
-  else {
+  } else {
     resultState = 1
   }
 
@@ -418,6 +433,9 @@ async function doAjaxSendMessage(question, type = '') {
     })
 
   changeMessageItem(askItem.fId, askItem)
+  setTimeout(() => {
+    scrollToBottom()
+  }, 200)
 }
 
 async function doSubmitMessage() {
@@ -427,8 +445,7 @@ async function doSubmitMessage() {
         console.log('xxx', res)
         if (res.data) {
           questionModel.value.nowId = res.data
-        }
-        else {
+        } else {
           that.$toast('会话创建失败,请稍后再试')
         }
       })
@@ -437,6 +454,7 @@ async function doSubmitMessage() {
       })
   }
   const question = questionModel.value.input
+  trickClick(`提交问题`, { text: question })
   doAjaxSendMessage(question)
 }
 
@@ -467,6 +485,7 @@ function doSendMessageOfUser(message) {
   that.$nextTick(() => {
     changeInputHeight()
     getQuestionInputHeight()
+    scrollToBottom()
   })
 }
 function doSendMessageOfCustom(data) {
@@ -484,6 +503,12 @@ function doSendMessageOfCustom(data) {
   return findId
 }
 
+function scrollToBottom() {
+  that.$nextTick(() => {
+    contentBottomEl.value.scrollIntoView({ behavior: 'smooth' })
+  })
+}
+
 function changeMessageItem(id, data) {
   const arr = askModel.value.list
   // 使用 for 循环倒序查找
@@ -538,14 +563,13 @@ function doSelectQuestionType(item) {
       message: item.toast,
       className: 'one-toast'
     })
-  }
-  else {
+  } else {
     promptModel.value.type = item.key
     promptModel.value.list = item.options
     promptModel.value.show = true
   }
 
-  trickClick('选择类型', {
+  trickClick('选择提问类型', {
     text: item.text
   })
 }
@@ -583,8 +607,6 @@ function resetQuestion(item) {
   })
 }
 
-
-
 function doAjaxGetHistoryList() {
   ajaxGetHistoryList().then((res) => {
     if (res?.data?.list) {
@@ -593,8 +615,6 @@ function doAjaxGetHistoryList() {
   })
 }
 
-
-
 function goToDetail(item) {
   savePageState()
   const query = {}
@@ -624,7 +644,7 @@ function doCollection(item, index) {
       }
     }
   })
-  trickClick('标讯收藏', {
+  trickClick('点击标讯收藏', {
     title: item.title,
     id: item.id
   })
@@ -662,8 +682,7 @@ function doCellAction(item, type) {
       message: item.message,
       id: item.id
     })
-  }
-  else {
+  } else {
     item.like = Number(!item.like)
     ajaxActionLike({
       cid: item.id,
@@ -680,7 +699,7 @@ function doCellAction(item, type) {
 
 const moreLike = computed(() => {
   const item = askModel.value.list.find(
-    v => v.id === moreListModel.value.selectId
+    (v) => v.id === moreListModel.value.selectId
   )
   console.log(item)
   return item || {}
@@ -707,8 +726,7 @@ async function getUserInfo() {
       console.log('o', phone)
     }
     return data
-  }
-  catch (error) {
+  } catch (error) {
     return {}
   }
 }
@@ -730,41 +748,44 @@ function checkBindPhone() {
 }
 
 function doDelTask(item) {
+  trickClick('删除对话记录', { id: item.id })
   console.log('item', item)
-  that.$dialog.confirm({
-    message: '是否要删除该对话记录?',
-    confirmButtonColor: '#ee0a24'
-  }).then(() => {
-    ajaxDelTask({ sid: item.id }).then((res) => {
-      if (res.data) {
-        that.$toast('删除成功')
-        doAjaxGetHistoryList()
-        if (item.id === questionModel.value.nowId) {
-          doNewQuestion()
+  that.$dialog
+    .confirm({
+      message: '是否要删除该对话记录?',
+      confirmButtonColor: '#ee0a24'
+    })
+    .then(() => {
+      ajaxDelTask({ sid: item.id }).then((res) => {
+        if (res.data) {
+          that.$toast('删除成功')
+          doAjaxGetHistoryList()
+          if (item.id === questionModel.value.nowId) {
+            doNewQuestion()
+          }
         }
-      }
+      })
     })
-  }).catch(() => {
-
-  })
+    .catch(() => {})
 }
 
 const cacheToLocalStorage = (key, state) => {
-  localStorage.setItem(key, JSON.stringify(state.value));
-};
+  localStorage.setItem(key, JSON.stringify(state.value))
+}
 
 // 函数:通用读取函数,支持自定义 key
 const loadFromLocalStorage = (key, state) => {
-  const cachedData = localStorage.getItem(key);
+  const cachedData = localStorage.getItem(key)
   if (cachedData) {
-    Object.assign(state.value, JSON.parse(cachedData));
+    Object.assign(state.value, JSON.parse(cachedData))
   }
-};
+}
 
 const contentEl = ref(null)
+const contentBottomEl = ref(null)
 const moreContentEl = ref(null)
 
-function getSetScrollTop (top) {
+function getSetScrollTop(top) {
   if (contentEl.value) {
     if (top) {
       contentEl.value.scrollTo(0, top)
@@ -774,7 +795,7 @@ function getSetScrollTop (top) {
   }
 }
 
-function getSetMoreScrollTop (top) {
+function getSetMoreScrollTop(top) {
   if (moreContentEl.value) {
     if (top) {
       moreContentEl.value.scrollTo(0, top)
@@ -784,7 +805,7 @@ function getSetMoreScrollTop (top) {
   }
 }
 
-function savePageState () {
+function savePageState() {
   localStorage.setItem('ai-search-cache', 'use')
   localStorage.setItem('ai-search-height', getSetScrollTop())
   localStorage.setItem('ai-search-more-height', getSetMoreScrollTop())
@@ -794,7 +815,7 @@ function savePageState () {
   cacheToLocalStorage('ai-search-questionModel', questionModel)
   cacheToLocalStorage('ai-search-askModel', askModel)
 }
-function echoPageState () {
+function echoPageState() {
   loadFromLocalStorage('ai-search-historyModel', historyModel)
   loadFromLocalStorage('ai-search-moreListModel', moreListModel)
   loadFromLocalStorage('ai-search-promptModel', promptModel)
@@ -846,7 +867,7 @@ function init() {
           return {
             text: v.goodsName,
             key: v.goodsType,
-            options: (v.problem || []).map(s => ({ text: s })),
+            options: (v.problem || []).map((s) => ({ text: s })),
             icon: 'icon-wenjian',
             disabled: !v.isUsed,
             toast: '剑鱼正在冒着火星子搭建,敬请期待!'
@@ -874,10 +895,10 @@ init()
           <i class="iconfont icon-back" />
         </span>
         <div class="flex flex-(items-center justify-between) header-left">
-          <img class="main-logo-img" src="@/assets/image/public/logo_new.png">
+          <img class="main-logo-img" src="@/assets/image/public/logo_new.png" />
           <div class="main-logo">
             <span class="main-text">剑鱼标讯</span>
-            <br>
+            <br />
             <span>jianyu360.cn</span>
           </div>
         </div>
@@ -898,11 +919,17 @@ init()
       </Popover>
     </div>
 
-    <div class="ai-search--content j-main" ref='contentEl'>
-      <div v-if="needBindPhone || needLogin" class="bind-phone-popup" @click="checkBindPhone" />
+    <div class="ai-search--content j-main" ref="contentEl">
+      <div
+        v-if="needBindPhone || needLogin"
+        class="bind-phone-popup"
+        @click="checkBindPhone"
+      />
       <div v-if="askModel.list.length === 0" class="ai-search--empty">
         <AppEmpty state="ai-logo">
-          我是剑鱼标讯AI助手想找什么,请开始问我吧!
+          我是剑鱼标讯AI助手想找什么
+          <br />
+          请开始问我吧!
         </AppEmpty>
       </div>
 
@@ -919,23 +946,21 @@ init()
           <div v-else class="ask-item--custom flex flex-(col)">
             <div class="flex flex-(items-center)">
               <div class="ask-logo">
-                <img src="@/assets/image/ai-search/logo-head.png" alt="ai">
+                <img src="@/assets/image/ai-search/logo-head.png" alt="ai" />
               </div>
 
               <div v-if="item.state === 0" class="flex flex-(items-center)">
                 {{ askStateMap[item.state] }}
-                <Loading
-                  style="margin-left: 8px"
-                  color="#2abed1"
-                  size="14px"
-                />
+                <Loading style="margin-left: 8px" color="#2abed1" size="14px" />
               </div>
               <div v-if="item.state === 1">
                 {{ askStateMap[item.state] }}
               </div>
               <div v-if="item.state === 2">
                 <span>{{ askStateMap[item.state] }}</span>
-                <span class="highlight-text" @click="resetQuestion(item)">重新提问</span>
+                <span class="highlight-text" @click="resetQuestion(item)"
+                  >重新提问</span
+                >
               </div>
               <div v-if="item.state === 3">
                 {{ askStateMap[item.state] }}
@@ -944,9 +969,7 @@ init()
 
             <div v-if="item.state === 3">
               <div class="cell-list-container">
-                <div class="cell-list-tip">
-                  以下是我为您整理的数据样例
-                </div>
+                <div class="cell-list-tip">以下是我为您整理的数据样例</div>
                 <div
                   v-for="(cell, index) in item.list"
                   :key="index"
@@ -976,7 +999,7 @@ init()
                           class="j-icon"
                           :class="{
                             'icon-star-fill': cell.star,
-                            'icon-star-streak': !cell.star,
+                            'icon-star-streak': !cell.star
                           }"
                         />
                         <span>&nbsp;{{ cell.star ? '已收藏' : '收藏' }}</span>
@@ -1001,15 +1024,13 @@ init()
                     v-show="item.like == 0"
                     src="@/assets/image/ai-search/like.png"
                     alt="like"
-                  >
+                  />
                   <img
                     v-show="item.like == 1"
                     src="@/assets/image/ai-search/like-active.png"
                     alt="like-active"
-                  >
-                  <div class="tip-popver">
-                    感谢您的认可!
-                  </div>
+                  />
+                  <div class="tip-popver">感谢您的认可!</div>
                 </div>
                 <div
                   class="cell-action-icon"
@@ -1021,6 +1042,7 @@ init()
             </div>
           </div>
         </div>
+        <div ref="contentBottomEl"></div>
       </div>
 
       <Overlay
@@ -1030,16 +1052,17 @@ init()
         @click="doClickInputIcon('scale')"
       />
       <div
-        class="question-input-container" :class="{
+        class="question-input-container"
+        :class="{
           [questionModel.inputTheme]: true,
-          'in-ask': questionModel.nowId,
+          'in-ask': questionModel.nowId
         }"
       >
         <div
           v-show="
-            questionModel.inputTheme === 'scale'
-              && promptModel.list.length > 0
-              && promptModel.show
+            questionModel.inputTheme === 'scale' &&
+            promptModel.list.length > 0 &&
+            promptModel.show
           "
           class="question-prompt-container"
         >
@@ -1096,7 +1119,7 @@ init()
             class="question-type-item"
             :class="{
               'is-disable': item.disabled,
-              'is-active': promptModel.type === item.key,
+              'is-active': promptModel.type === item.key
             }"
             @click="doSelectQuestionType(item)"
           >
@@ -1127,8 +1150,8 @@ init()
               >
                 <div
                   v-if="
-                    questionModel.inputTheme === 'scale'
-                      && questionModel.iconShow
+                    questionModel.inputTheme === 'scale' &&
+                    questionModel.iconShow
                   "
                   class="input-icon"
                   :style="{ 'margin-bottom': '8px' }"
@@ -1138,7 +1161,7 @@ init()
                     class="full-icon"
                     src="@/assets/image/ai-search/scale.png"
                     alt="submit"
-                  >
+                  />
                 </div>
                 <div
                   v-if="questionModel.inputTheme === 'full'"
@@ -1149,7 +1172,7 @@ init()
                     class="scale-icon"
                     src="@/assets/image/ai-search/disscale.png"
                     alt="submit"
-                  >
+                  />
                 </div>
                 <div
                   class="input-icon"
@@ -1160,12 +1183,13 @@ init()
                     class="submit-icon"
                     src="@/assets/image/icon/icon-submit.png"
                     alt="submit"
-                  >
+                  />
                 </div>
               </div>
             </template>
           </Field>
         </div>
+        <div class="safe-area-inside-bottom"></div>
       </div>
     </div>
 
@@ -1185,7 +1209,7 @@ init()
               <i class="iconfont icon-close_heidi" style="color: #c0c4cc" />
             </div>
             <div class="flex flex-(items-center)">
-              <img src="@/assets/image/ai-search/empty.png" alt="ai">
+              <img src="@/assets/image/ai-search/logo-head.png" alt="ai" />
               <span class="tip-text">为您搜索到的结果</span>
             </div>
           </div>
@@ -1198,18 +1222,16 @@ init()
               v-show="moreLike.like == 0"
               src="@/assets/image/ai-search/like.png"
               alt="like"
-            >
+            />
             <img
               v-show="moreLike.like == 1"
               src="@/assets/image/ai-search/like-active.png"
               alt="like-active"
-            >
-            <div class="tip-popver in-right">
-              感谢您的认可!
-            </div>
+            />
+            <div class="tip-popver in-right">感谢您的认可!</div>
           </div>
         </div>
-        <div class="j-main more-list-container" ref='moreContentEl'>
+        <div class="j-main more-list-container" ref="moreContentEl">
           <div class="cell-list-container">
             <div
               v-for="(cell, index) in moreListModel.list"
@@ -1240,7 +1262,7 @@ init()
                       class="j-icon"
                       :class="{
                         'icon-star-fill': cell.star,
-                        'icon-star-streak': !cell.star,
+                        'icon-star-streak': !cell.star
                       }"
                     />
                     <span>&nbsp;{{ cell.star ? '已收藏' : '收藏' }}</span>
@@ -1261,14 +1283,19 @@ init()
       position="right"
     >
       <div class="j-container">
-        <div class="j-header history-list-header flex flex-(items-center justify-between)">
+        <div
+          class="j-header history-list-header flex flex-(items-center justify-between)"
+        >
           <span>历史对话</span>
           <div class="item-del-icon" @click="historyModel.show = false">
             <i class="iconfont icon-delete_gray" />
           </div>
         </div>
         <div class="j-main">
-          <div v-if="historyListLabel.length > 0" class="history-list-container">
+          <div
+            v-if="historyListLabel.length > 0"
+            class="history-list-container"
+          >
             <div
               v-for="(label, index) in historyListLabel"
               :key="index"
@@ -1286,7 +1313,7 @@ init()
                 <div class="flex flex-(items-center justify-between)">
                   {{ item.question }}
                   <div class="item-del-icon" @click="doDelTask(item)">
-                    <i class="iconfont icon-delete_gray" />
+                    <i class="iconfont icon-dataDelete" />
                   </div>
                 </div>
               </div>
@@ -1297,9 +1324,7 @@ init()
             class="history-empty-container flex flex-(col items-center justify-center)"
           >
             <div class="flex flex-(col items-center align-center)">
-              <AppEmpty state="back">
-                您还没有和我聊天呢,现在开始吧
-              </AppEmpty>
+              <AppEmpty state="back"> 您还没有和我聊天呢,现在开始吧 </AppEmpty>
               <div class="new-question-button" @click="doNewQuestion">
                 开启对话
               </div>
@@ -1320,7 +1345,8 @@ init()
 .ai-search-- {
   //
   &page {
-    ::v-deep {}
+    ::v-deep {
+    }
 
     .bind-phone-popup {
       width: 100%;
@@ -1427,7 +1453,6 @@ init()
       padding: 12px 6px;
       margin-top: 12px;
 
-
       .cell-list-tip {
         color: #5f5e64;
         font-size: 14px;
@@ -1535,7 +1560,8 @@ init()
 
     .question-input-container {
       position: fixed;
-      padding-bottom: 36px;
+      padding-bottom: 12px;
+
       background-color: #fff;
       bottom: 0;
       width: 100%;
@@ -1578,7 +1604,6 @@ init()
         }
       }
       &.scale {
-
       }
       &.in-ask {
         padding-top: 12px;
@@ -1742,7 +1767,6 @@ init()
       .item-del-icon i {
         font-size: 22px;
       }
-
     }
     .item-del-icon {
       padding: 4px;