feat: integrate WhatsApp send into customer detail with AI reply generation
This commit is contained in:
@@ -246,6 +246,19 @@
|
|||||||
<view class="detail-footer">
|
<view class="detail-footer">
|
||||||
<button class="close-btn" @click="showDetailModal = false">关闭</button>
|
<button class="close-btn" @click="showDetailModal = false">关闭</button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<view class="whatsapp-section" v-if="currentCustomer.whatsapp_id">
|
||||||
|
<view class="whatsapp-header">
|
||||||
|
<text class="whatsapp-title">📱 WhatsApp 快捷发送</text>
|
||||||
|
</view>
|
||||||
|
<view class="whatsapp-input-row">
|
||||||
|
<input class="whatsapp-input" v-model="whatsappText" placeholder="输入消息内容,或点击AI生成" />
|
||||||
|
<view class="whatsapp-actions">
|
||||||
|
<view class="wa-btn ai-btn" @click="generateWhatsAppReply">AI生成</view>
|
||||||
|
<view class="wa-btn send-btn" @click="sendWhatsApp">发送</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@@ -273,7 +286,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { onShow } from '@dcloudio/uni-app'
|
import { onShow } from '@dcloudio/uni-app'
|
||||||
import { customerApi, healthApi, silentPatternApi } from '@/utils/api.js'
|
import { customerApi, healthApi, silentPatternApi, whatsappApi, translateApi } from '@/utils/api.js'
|
||||||
|
|
||||||
const filter = ref('all')
|
const filter = ref('all')
|
||||||
const customers = ref([])
|
const customers = ref([])
|
||||||
@@ -287,6 +300,7 @@ const conversationCustomer = ref(null)
|
|||||||
const conversation = ref([])
|
const conversation = ref([])
|
||||||
const healthOverview = ref(null)
|
const healthOverview = ref(null)
|
||||||
const healthScores = ref({})
|
const healthScores = ref({})
|
||||||
|
const whatsappText = ref('')
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
name: '',
|
name: '',
|
||||||
company: '',
|
company: '',
|
||||||
@@ -488,6 +502,55 @@ const importCustomers = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const generateWhatsAppReply = async () => {
|
||||||
|
if (!currentCustomer.value?.whatsapp_id) return
|
||||||
|
const lastMsg = conversation.value.length > 0 ? conversation.value[conversation.value.length - 1].content : ''
|
||||||
|
if (!lastMsg) {
|
||||||
|
whatsappText.value = 'Hello, any update on this?'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
uni.showLoading({ title: 'AI生成中...' })
|
||||||
|
const res = await translateApi.getReply(lastMsg, 'professional', 1)
|
||||||
|
uni.hideLoading()
|
||||||
|
if (res.suggestions && res.suggestions[0]) {
|
||||||
|
whatsappText.value = res.suggestions[0].content || res.suggestions[0]
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
uni.hideLoading()
|
||||||
|
whatsappText.value = 'Hello, any update on this?'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sendWhatsApp = async () => {
|
||||||
|
if (!whatsappText.value || !currentCustomer.value?.whatsapp_id) {
|
||||||
|
uni.showToast({ title: '请输入消息内容', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
uni.showLoading({ title: '发送中...' })
|
||||||
|
await whatsappApi.send(currentCustomer.value.whatsapp_id, whatsappText.value)
|
||||||
|
uni.hideLoading()
|
||||||
|
uni.showToast({ title: '已发送', icon: 'success' })
|
||||||
|
const msg = whatsappText.value
|
||||||
|
whatsappText.value = ''
|
||||||
|
showConversation(currentCustomer.value)
|
||||||
|
} catch (err) {
|
||||||
|
uni.hideLoading()
|
||||||
|
const phone = currentCustomer.value.whatsapp_id.replace(/[^0-9]/g, '')
|
||||||
|
uni.showModal({
|
||||||
|
title: 'API发送失败',
|
||||||
|
content: '是否通过 WhatsApp 链接发送?',
|
||||||
|
success: (r) => {
|
||||||
|
if (r.confirm) {
|
||||||
|
uni.setClipboardData({ data: msg })
|
||||||
|
uni.setClipboardData({ data: `https://wa.me/${phone}?text=${encodeURIComponent(whatsappText.value || msg)}` })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const deleteCustomer = async (id) => {
|
const deleteCustomer = async (id) => {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '确认删除',
|
title: '确认删除',
|
||||||
@@ -1089,4 +1152,63 @@ const deleteCustomer = async (id) => {
|
|||||||
color: #999;
|
color: #999;
|
||||||
padding: 60rpx;
|
padding: 60rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.whatsapp-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
background: #f0f5ff;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.whatsapp-header {
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.whatsapp-title {
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.whatsapp-input-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.whatsapp-input {
|
||||||
|
width: 100%;
|
||||||
|
height: 72rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
border: 2rpx solid #d6e4ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.whatsapp-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wa-btn {
|
||||||
|
flex: 1;
|
||||||
|
height: 64rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-btn {
|
||||||
|
background: #fff;
|
||||||
|
color: #1890ff;
|
||||||
|
border: 2rpx solid #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send-btn {
|
||||||
|
background: #25d366;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -242,6 +242,11 @@ export const healthApi = {
|
|||||||
customerHealth: (id) => request(`/customers/${id}/health`),
|
customerHealth: (id) => request(`/customers/${id}/health`),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const whatsappApi = {
|
||||||
|
send: (to, text, templateName = null, templateParams = null, mediaUrl = null, mediaType = null) =>
|
||||||
|
request('/whatsapp/send', 'POST', { to, text, template_name: templateName, template_params: templateParams, media_url: mediaUrl, media_type: mediaType }),
|
||||||
|
}
|
||||||
|
|
||||||
export const customerApi = {
|
export const customerApi = {
|
||||||
list: (page = 1, size = 20, status) => {
|
list: (page = 1, size = 20, status) => {
|
||||||
let params = `page=${page}&size=${size}`
|
let params = `page=${page}&size=${size}`
|
||||||
|
|||||||
Reference in New Issue
Block a user