Forráskód Böngészése

Merge remote-tracking branch 'origin/master'

YPZ 1 hónapja
szülő
commit
ab993ddbdd

+ 4 - 1
ui/smarttrade-platform/src/api/knowledge/index.js

@@ -72,4 +72,7 @@ export const blocking = (data = {}) => post('/router/rest/chat/blocking', data,{
 export const downloadDocument = (params = {}) => {
     const { dataset_id,document_id, ...query } = params
     return get(`/router/rest/knowledge/document/${dataset_id}/documents/${document_id}/download`, params)
-}
+}
+
+
+export const messageReview = (data = {}) => post('/router/rest/chat/message/review', data)

+ 16 - 12
ui/smarttrade-platform/src/components/addMarketing.vue

@@ -757,7 +757,7 @@
         },
         goals: { sent: 0, openRate: 0, replyRate: 0, opportunities: 0 },
         channels: ['email'],
-        emailSender: '', emailSendTime: 'optimal',
+        emailSender: 'fan@storlead.com', emailSendTime: 'optimal',
         trackOpen: true, trackClick: true, trackReply: true,
         whatsappAccount: '业务账号1', whatsappInterval: '60', whatsappTemplate: '',
         linkedinAction: 'message', linkedinLimit: '30',
@@ -904,10 +904,6 @@
         try {
             const typeMap = { prospect: 1, nurture: 2, reactivate: 3, promote: 4, seasonal: 5, exhibition: 6, other: 7 }
             const priorityMap = { urgent: 1, high: 2, medium: 3, low: 4 }
-            const ownerMap = { sales1: 1, sales2: 2, sales3: 3 }
-            const selectedOwners = Array.isArray(newCampaign.value.owner)
-                ? newCampaign.value.owner.filter(Boolean)
-                : [newCampaign.value.owner].filter(Boolean)
             const channelConfig = newCampaign.value.channels.reduce((acc, channel) => {
                 if (channel === 'email') return acc + 1
                 if (channel === 'whatsapp') return acc + 2
@@ -922,7 +918,7 @@
                 description: newCampaign.value.description,
                 beginData: newCampaign.value.startDate || null,
                 endDate: newCampaign.value.endDate || null,
-                supervisor: selectedOwners.length ? ownerMap[selectedOwners[0]] || null : null,
+                supervisorList: newCampaign.value.owner,
                 linkToOpportunity: newCampaign.value.relatedOpportunity || null,
                 sendVolume: Number(newCampaign.value.goals.sent) || null,
                 openRate: Number(newCampaign.value.goals.openRate) || null,
@@ -948,14 +944,22 @@
                 customerIdList: customerList.value.map(c => c.id)
             }
             if (isEditMode.value) {
-                await editMarketing(payload)
-                ElMessage.success('营销活动已更新')
+                await editMarketing(payload).then(res => {
+                    ElMessage.success('营销活动已更新')
+                    emits('refresh')
+                    closeCreateModal()
+                }).catch(err => {
+                    ElMessage.error(err?.message || '更新营销活动失败')
+                })
             } else {
-                await addMarketing(payload)
-                ElMessage.success('营销活动已创建')
+                await addMarketing(payload).then(res => {
+                    ElMessage.success('营销活动已创建')
+                    emits('refresh')
+                    closeCreateModal()
+                }).catch(err => {
+                    ElMessage.error(err?.message || '创建营销活动失败')
+                })
             }
-            emits('refresh')
-            closeCreateModal()
         } catch (error) {
             ElMessage.error(error?.message || '创建营销活动失败')
         }

+ 14 - 10
ui/smarttrade-platform/src/components/marketing/marketingDetail.vue

@@ -29,7 +29,7 @@
               </div>
               <div class="detail-item">
                 <label>负责人</label>
-                <span>{{ selectedCampaign.owner }}</span>
+                <span>{{ supervisorUser }}</span>
               </div>
               <div class="detail-item">
                 <label>创建时间</label>
@@ -50,31 +50,31 @@
           <div class="detail-section">
             <div class="section-header">
               <h4><i class="fas fa-chart-line"></i> 核心数据</h4>
-              <div class="progress-info">达成 {{ selectedCampaign.progressPercent || 0 }}%</div>
+              <div class="progress-info">达成 {{ statsData.achievementRate }}%</div>
             </div>
             <div class="detail-progress-bar">
-              <div class="progress-fill" :style="{ width: (selectedCampaign.progressPercent || 0) + '%' }"></div>
+              <div class="progress-fill" :style="{ width: (statsData.achievementRate) + '%' }"></div>
             </div>
             <div class="metrics-grid">
               <div class="metric-card">
                 <div class="metric-icon blue"><i class="fas fa-paper-plane"></i></div>
                 <div class="metric-content">
-                  <div class="metric-value">{{ formatNumber(selectedCampaign.sendVolume) }}</div>
+                  <div class="metric-value">{{ statsData.sentCount }}</div>
                   <div class="metric-label">已发送</div>
                 </div>
               </div>
               <div class="metric-card">
                 <div class="metric-icon green"><i class="fas fa-envelope-open"></i></div>
                 <div class="metric-content">
-                  <div class="metric-value">{{ Math.round(selectedCampaign.sendVolume * selectedCampaign.openRate / 100) }}</div>
-                  <div class="metric-label">打开数 ({{ selectedCampaign.openRate }}%)</div>
+                  <div class="metric-value">{{ statsData.openCount }}</div>
+                  <div class="metric-label">打开数 ({{ statsData.openRate }}%)</div>
                 </div>
               </div>
               <div class="metric-card">
                 <div class="metric-icon purple"><i class="fas fa-reply"></i></div>
                 <div class="metric-content">
-                  <div class="metric-value">{{ Math.round(selectedCampaign.sendVolume * selectedCampaign.replyRate / 100) }}</div>
-                  <div class="metric-label">回复数 ({{ selectedCampaign.replyRate }}%)</div>
+                  <div class="metric-value">{{ statsData.replyCount }}</div>
+                  <div class="metric-label">回复数 ({{ statsData.replyRate }}%)</div>
                 </div>
               </div>
             </div>
@@ -149,7 +149,7 @@
           </div>
 
           <!-- 最近互动 -->
-          <div class="detail-section">
+          <!-- <div class="detail-section">
             <div class="section-header">
               <h4><i class="fas fa-comments"></i> 最近互动</h4>
               <button class="btn-link" @click="showAllInteractions">查看全部</button>
@@ -196,7 +196,7 @@
                 </div>
               </div>
             </div>
-          </div>
+          </div> -->
         </div>
         <div class="modal-footer">
           <!-- <button class="btn btn-secondary" @click="duplicateCampaign(selectedCampaign)">
@@ -230,6 +230,8 @@
     const selectedCampaign = ref()
     const sopDetails = ref([])
     const customerData = ref([])
+    const statsData = ref()
+    const supervisorUser = ref()
     const open = (data) => {
         getData(data.id)
         showCampaignDetailModal.value = true
@@ -242,6 +244,8 @@
             sopDetails.value = res.result.sopDetailList || []
             customerData.value = res.result.customerList || []
             sopName.value = res.result.sopEntity.name
+            statsData.value = res.result.stats
+            supervisorUser.value = (res.result.supervisorUserList || []).map(item => item.realName).join(',')
         })
     }
 

+ 20 - 4
ui/smarttrade-platform/src/views/KnowledgeView.vue

@@ -255,10 +255,10 @@
             <div class="qa-footer">
               <div class="qa-time">{{ qa.time }}</div>
               <div class="qa-rating">
-                <button class="rating-btn" :class="{ active: qa.rating === 'positive' }" @click="rateQA(qa, 'positive')">
+                <button class="rating-btn" @click="rateQA(qa, 'positive')"><!-- :class="{ active: qa.rating === 'positive' }" -->
                   <i class="fas fa-thumbs-up"></i><span style="margin-left: 2px;">{{qa.agree}}</span>
                 </button>
-                <button class="rating-btn" :class="{ active: qa.rating === 'negative' }" @click="rateQA(qa, 'negative')">
+                <button class="rating-btn" @click="rateQA(qa, 'negative')"><!-- :class="{ active: qa.rating === 'negative' }" -->
                   <i class="fas fa-thumbs-down"></i><span style="margin-left: 2px;">{{qa.disagree}}</span>
                 </button>
               </div>
@@ -676,7 +676,7 @@
 
 <script setup>
 import { ref, computed } from 'vue'
-import { knowledgeDatasets,knowledgeDocuments,createKnowledge,createChunk,editChunk,chatMessages,baseTraining,creatTraining,baseStatistics,getAllChunks,getChunks,getAllDocumnets,delDocuments,delChunk,getDocumentDetail,blocking,downloadDocument } from '../api/knowledge'
+import { knowledgeDatasets,knowledgeDocuments,createKnowledge,createChunk,editChunk,chatMessages,baseTraining,creatTraining,baseStatistics,getAllChunks,getChunks,getAllDocumnets,delDocuments,delChunk,getDocumentDetail,blocking,downloadDocument,messageReview } from '../api/knowledge'
 import { formatTimeAgo } from '@/utils/time'
 import { ElMessage } from 'element-plus'
 
@@ -1189,7 +1189,23 @@ const optimizeAnswer = (item) => {
 
 const rateQA = (qa, rating) => {
   qa.rating = rating
-  showToastMessage('感谢您的反馈', 'success')
+  let params = {
+    agree:rating=='positive'?'1':'0',
+    disagree:rating=='positive'?'0':'1',
+    aiMessageId:qa.id
+  }
+  messageReview(params).then(res => {
+    if(res.success){
+      if(rating=='positive'){
+        qa.agree++
+      }else{
+        qa.disagree++
+      }
+      showToastMessage('感谢您的反馈', 'success')
+    }else{
+      return ElMessage.error('请求超时,请稍后再试')
+    }
+  })
 }
 
 const toggleSetting = (key) => {

+ 2 - 2
ui/smarttrade-platform/src/views/MarketingView.vue

@@ -34,13 +34,13 @@
           <p>平均打开率</p>
         </div>
       </div>
-      <div class="stat-card-lg">
+      <!-- <div class="stat-card-lg">
         <div class="stat-icon-lg purple"><i class="fas fa-mouse-pointer"></i></div>
         <div class="stat-content-lg">
           <h3>{{ statsData?.clickRate }}</h3>
           <p>点击率</p>
         </div>
-      </div>
+      </div> -->
       <div class="stat-card-lg">
         <div class="stat-icon-lg orange"><i class="fas fa-reply"></i></div>
         <div class="stat-content-lg">