Add automatic VoIP call summaries and sync progress checklist.
When a PBX webhook includes recordingUrl or transcript, queue STT and AI to create a call_result note; mark API, bulk SMS, WooCommerce, and VoIP as done and defer online payments. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import { RouterLink } from 'vue-router';
|
||||
import axios from 'axios';
|
||||
import { api } from '@/lib/api';
|
||||
import type {
|
||||
@@ -46,6 +47,21 @@ const statusLabel: Record<string, string> = {
|
||||
failed: 'ناموفق',
|
||||
};
|
||||
|
||||
const summaryLabel: Record<string, string> = {
|
||||
none: '—',
|
||||
pending: 'در صف',
|
||||
processing: 'در حال ساخت',
|
||||
done: 'آماده',
|
||||
failed: 'ناموفق',
|
||||
skipped: 'رد شده',
|
||||
};
|
||||
|
||||
function noteLink(c: VoipCallLogDto): string | null {
|
||||
if (!c.summaryNoteId) return null;
|
||||
if (c.personId) return `/contacts/people/${c.personId}`;
|
||||
return '/notes';
|
||||
}
|
||||
|
||||
async function load() {
|
||||
loading.value = true;
|
||||
error.value = '';
|
||||
@@ -123,7 +139,7 @@ onMounted(() => {
|
||||
<div class="page">
|
||||
<UiPageHeader
|
||||
title="تلفن سازمانی"
|
||||
description="ثبت خودکار تماسهای سانترال روی پرونده مشتری و اعلان تماس ورودی"
|
||||
description="ثبت خودکار تماس، خلاصه گفتگو و اعلان تماس ورودی"
|
||||
>
|
||||
<template #actions>
|
||||
<UiButton variant="secondary" :disabled="loading" @click="load">
|
||||
@@ -145,6 +161,15 @@ onMounted(() => {
|
||||
<code>status</code>،
|
||||
<code>from</code>،
|
||||
<code>to</code>.
|
||||
برای خلاصه خودکار یکی از
|
||||
<code>recordingUrl</code>
|
||||
(لینک فایل ضبط) یا
|
||||
<code>transcript</code>
|
||||
(متن آماده) را بفرستید؛ پس از
|
||||
<code>completed</code>
|
||||
/
|
||||
<code>answered</code>
|
||||
صف خلاصه ساخته میشود.
|
||||
امضا اختیاری با هدر
|
||||
<code>X-Voip-Signature</code>
|
||||
(HMAC-SHA256 هگز).
|
||||
@@ -213,6 +238,7 @@ onMounted(() => {
|
||||
<th>از / به</th>
|
||||
<th>مشتری</th>
|
||||
<th>مدت</th>
|
||||
<th>خلاصه</th>
|
||||
<th>زمان</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -229,6 +255,27 @@ onMounted(() => {
|
||||
: '—'
|
||||
}}
|
||||
</td>
|
||||
<td class="summary-cell">
|
||||
<span
|
||||
class="summary-badge"
|
||||
:data-status="c.summaryStatus || 'none'"
|
||||
>
|
||||
{{ summaryLabel[c.summaryStatus] ?? c.summaryStatus ?? '—' }}
|
||||
</span>
|
||||
<p v-if="c.summary" class="summary-preview">
|
||||
{{ c.summary.slice(0, 120) }}{{ c.summary.length > 120 ? '…' : '' }}
|
||||
</p>
|
||||
<p v-if="c.summaryError && c.summaryStatus === 'failed'" class="warn">
|
||||
{{ c.summaryError }}
|
||||
</p>
|
||||
<RouterLink
|
||||
v-if="noteLink(c)"
|
||||
class="note-link"
|
||||
:to="noteLink(c)!"
|
||||
>
|
||||
مشاهده در پرونده
|
||||
</RouterLink>
|
||||
</td>
|
||||
<td>{{ formatJalaliNumeric(new Date(c.startedAt)) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -310,11 +357,48 @@ td {
|
||||
text-align: right;
|
||||
padding: 0.55rem;
|
||||
border-bottom: 1px solid #eef2f7;
|
||||
vertical-align: top;
|
||||
}
|
||||
th {
|
||||
color: #64748b;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.summary-cell {
|
||||
max-width: 16rem;
|
||||
}
|
||||
.summary-badge {
|
||||
display: inline-block;
|
||||
font-size: 0.78rem;
|
||||
padding: 0.15rem 0.45rem;
|
||||
border-radius: 6px;
|
||||
background: #f1f5f9;
|
||||
color: #475569;
|
||||
}
|
||||
.summary-badge[data-status='done'] {
|
||||
background: #ecfdf5;
|
||||
color: #047857;
|
||||
}
|
||||
.summary-badge[data-status='pending'],
|
||||
.summary-badge[data-status='processing'] {
|
||||
background: #eff6ff;
|
||||
color: #1d4ed8;
|
||||
}
|
||||
.summary-badge[data-status='failed'] {
|
||||
background: #fef2f2;
|
||||
color: #b91c1c;
|
||||
}
|
||||
.summary-preview {
|
||||
margin: 0.35rem 0 0;
|
||||
font-size: 0.82rem;
|
||||
color: #334155;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.note-link {
|
||||
display: inline-block;
|
||||
margin-top: 0.35rem;
|
||||
font-size: 0.8rem;
|
||||
color: #0f766e;
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
.form-grid {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
Reference in New Issue
Block a user