97 lines
2.8 KiB
Vue
97 lines
2.8 KiB
Vue
<!--
|
||
Copyright 2024-2026 ChatterMate
|
||
|
||
Licensed under the Apache License, Version 2.0 (the "License");
|
||
you may not use this file except in compliance with the License.
|
||
You may obtain a copy of the License at
|
||
|
||
http://www.apache.org/licenses/LICENSE-2.0
|
||
|
||
Unless required by applicable law or agreed to in writing, software
|
||
distributed under the License is distributed on an "AS IS" BASIS,
|
||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
See the License for the specific language governing permissions and
|
||
limitations under the License.
|
||
-->
|
||
|
||
<script setup lang="ts">
|
||
import { ref, computed } from 'vue'
|
||
import { toast } from 'vue-sonner'
|
||
import channelsService, { type WhatsAppTemplate } from '@/services/channels'
|
||
import { DEFAULT_LANGUAGE } from '@/utils/whatsappLanguages'
|
||
import BaseModal from '@/components/common/BaseModal.vue'
|
||
import WhatsAppTemplateSelect, {
|
||
type TemplateSelection,
|
||
} from '@/components/conversations/WhatsAppTemplateSelect.vue'
|
||
|
||
const props = defineProps<{
|
||
accountId: string
|
||
sessionId: string
|
||
}>()
|
||
|
||
const emit = defineEmits<{
|
||
(e: 'close'): void
|
||
(e: 'sent', template: WhatsAppTemplate): void
|
||
}>()
|
||
|
||
const selection = ref<TemplateSelection | null>(null)
|
||
const sending = ref(false)
|
||
|
||
const canSend = computed(() => !!selection.value?.complete && !sending.value)
|
||
|
||
const send = async () => {
|
||
if (!selection.value || !canSend.value) return
|
||
const { template, components } = selection.value
|
||
try {
|
||
sending.value = true
|
||
await channelsService.sendWhatsAppTemplate(props.accountId, {
|
||
session_id: props.sessionId,
|
||
template_name: template.name,
|
||
language: template.language || DEFAULT_LANGUAGE,
|
||
components,
|
||
})
|
||
toast.success('模板已发送', { description: '客户可在接下来 24 小时内回复。' })
|
||
emit('sent', template)
|
||
} catch (error: any) {
|
||
toast.error('模板发送失败', {
|
||
description: error?.response?.data?.detail || '请重试',
|
||
closeButton: true,
|
||
})
|
||
} finally {
|
||
sending.value = false
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<BaseModal title="发送模板" @close="emit('close')">
|
||
<p class="tpl-intro">
|
||
该会话已超出 WhatsApp 的 24 小时窗口,发送已审核的模板可重新开启会话。
|
||
</p>
|
||
|
||
<WhatsAppTemplateSelect v-model:selection="selection" :account-id="accountId" />
|
||
|
||
<template #actions>
|
||
<button class="modal-btn" @click="emit('close')">取消</button>
|
||
<button
|
||
class="modal-btn modal-btn-primary"
|
||
:disabled="!canSend"
|
||
:aria-busy="sending"
|
||
@click="send"
|
||
>
|
||
<font-awesome-icon v-if="sending" icon="fa-solid fa-spinner" spin />
|
||
{{ sending ? '发送中…' : '发送模板' }}
|
||
</button>
|
||
</template>
|
||
</BaseModal>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.tpl-intro {
|
||
margin: 0 0 16px;
|
||
color: var(--muted);
|
||
font-size: 14px;
|
||
line-height: 1.6;
|
||
}
|
||
</style>
|