-
- {{ toFaDigits(preview.dealCount) }}
- معامله منتقل میشود
-
-
- {{ toFaDigits(preview.leadForms.length) }}
- فرم سرنخ به مقصد وصل میشود
-
-
- هشدار
- کاریز مبدا پیشفرض است و بعد از ادغام حذف میشود.
-
-
+
+
-
مقصد انتخابشده کاریز پیشفرض است.
-
+
+
+
+
+
+ مرحلههای مبدا را نگاشت کنید
+
+
+ هر مرحله فقط به مرحلهای با وضعیت سازگار در مقصد وصل میشود.
+
+
+
-
-
-
-
-
مرحلههای مبدا را نگاشت کنید
-
هر مرحله فقط به مرحلهای با وضعیت سازگار در مقصد وصل میشود.
-
+
+
+
+
+ بازبینی نهایی
+
+ «{{ toFaDigits(preview.dealCount) }}» معامله منتقل میشود.
+ {{ toFaDigits(preview.leadForms.length) }} فرم سرنخ به مقصد وصل میشود.
+ کاریز «{{ preview.source.name }}» حذف میشود.
+
+
+
-
-
-
-
-
بازبینی نهایی
-
- «{{ toFaDigits(preview.dealCount) }}» معامله منتقل میشود.
- {{ toFaDigits(preview.leadForms.length) }} فرم سرنخ به مقصد وصل میشود.
- کاریز «{{ preview.source.name }}» حذف میشود.
-
-
-
+
+ {{ preview.source.name }}
+ {{ selectedTarget?.name }}
+
+ همه فرمهای سرنخ به مقصد وصل میشوند.
+
+
+
+
-
-
-
مبدا
-
{{ preview.source.name }}
-
-
-
مقصد
-
{{ selectedTarget?.name }}
-
-
-
روش فرمها
-
همه فرمهای سرنخ به مقصد وصل میشوند.
-
-
-
-
+
+ در حال بارگذاری پیشنمایش ادغام…
+ برای شروع ادغام، از فهرست کاریزها دکمهٔ «ادغام» را بزنید.
+
+
-
- در حال بارگذاری پیشنمایش ادغام…
- برای شروع ادغام، از فهرست کاریزها دکمهٔ «ادغام» را بزنید.
-
- فروشنده در پنل مونتیفای از «تنظیمات ← یکپارچهسازیها ← CRM» توکن صادر میکند و
- Base URL، Token و Store ID را به شما میدهد. توکن فقط روی سرور و بهصورت رمزشده نگهداری میشود.
-
{{ EVENT_LABELS[d.event as WebhookEvent] ?? d.event }}
-
{{ d.status }}
-
{{ d.statusCode ?? '—' }}
-
{{ toFaDigits(d.attempts) }}
-
-
-
-
-
-
+ آخرین ارسالهای وبهوک
+
+
+
+
+
+
+
+
+ {{ formatJalaliNumeric(new Date((record as WebhookDeliveryDto).createdAt)) }}
+
+
+ {{
+ EVENT_LABELS[(record as WebhookDeliveryDto).event as WebhookEvent] ??
+ (record as WebhookDeliveryDto).event
+ }}
+
+
+ {{ (record as WebhookDeliveryDto).status }}
+
+
+ {{ (record as WebhookDeliveryDto).statusCode ?? '—' }}
+
+
+ {{ toFaDigits((record as WebhookDeliveryDto).attempts) }}
+
+
+
+
+
+
+
-
-
diff --git a/apps/web/src/views/ReportsView.vue b/apps/web/src/views/ReportsView.vue
index 01483b5..8f807cd 100644
--- a/apps/web/src/views/ReportsView.vue
+++ b/apps/web/src/views/ReportsView.vue
@@ -1339,9 +1339,6 @@ const activityMax = computed(() =>
گزارشات و داشبورد
-
- نمای جامع عملکرد فروش، مشتریان، فعالیتها و تیم
-
diff --git a/apps/web/src/views/ReservationsView.vue b/apps/web/src/views/ReservationsView.vue
index e1b740f..44d60d7 100644
--- a/apps/web/src/views/ReservationsView.vue
+++ b/apps/web/src/views/ReservationsView.vue
@@ -360,12 +360,7 @@ onMounted(() => {
-
- رزرو و نوبتدهی
-
- تعریف خدمت، انتخاب بازه آزاد و ثبت نوبت برای مشتری
-
-
+ رزرو و نوبتدهی
diff --git a/apps/web/src/views/SalesForecastView.vue b/apps/web/src/views/SalesForecastView.vue
index ca779c1..8233915 100644
--- a/apps/web/src/views/SalesForecastView.vue
+++ b/apps/web/src/views/SalesForecastView.vue
@@ -528,9 +528,6 @@ onBeforeUnmount(() => {
>
هدف و پیشبینی
-
- اهداف ماهانه را تنظیم و پیشبینیهای خود را مشاهده نمایید
-
diff --git a/apps/web/src/views/SmsCampaignsView.vue b/apps/web/src/views/SmsCampaignsView.vue
index 1462d17..f684ba7 100644
--- a/apps/web/src/views/SmsCampaignsView.vue
+++ b/apps/web/src/views/SmsCampaignsView.vue
@@ -417,12 +417,7 @@ onMounted(() => {
-
- پیامک گروهی
-
- ارسال انبوه پیامک به اشخاص یا لیدهای فیلترشده
-
-
+ پیامک گروهی
بروزرسانی
diff --git a/apps/web/src/views/TahesabSalesReportView.vue b/apps/web/src/views/TahesabSalesReportView.vue
index 7afe745..613236b 100644
--- a/apps/web/src/views/TahesabSalesReportView.vue
+++ b/apps/web/src/views/TahesabSalesReportView.vue
@@ -688,9 +688,6 @@ onUnmounted(() => {
گزارش فروش تهحساب
-
- وزن خالص فروش و خرید بعد از مرجوعی، به تفکیک گروه و کارشناس{{ showInternet ? ' و فروش اینترنتی' : '' }}
-
diff --git a/apps/web/src/views/TahesabSettingsView.vue b/apps/web/src/views/TahesabSettingsView.vue
index f8cb47f..a262711 100644
--- a/apps/web/src/views/TahesabSettingsView.vue
+++ b/apps/web/src/views/TahesabSettingsView.vue
@@ -11,18 +11,40 @@ import type {
} from '@mento/shared';
import { brand } from '@mento/shared';
import { toFaDigits } from '@/lib/jalali';
+import { registerTableColumns, useTableColumns } from '@/lib/tableColumns';
import {
- UiBadge,
- UiBusyOverlay,
- UiButton,
- UiCard,
- UiField,
- UiInput,
- UiPageHeader,
- UiPagination,
- UiSelect,
-} from '@/components/ui';
-import UiIcon from '@/components/UiIcon.vue';
+ Alert as AAlert,
+ Button as AButton,
+ Card as ACard,
+ Checkbox as ACheckbox,
+ Col as ACol,
+ Flex as AFlex,
+ Form as AForm,
+ FormItem as AFormItem,
+ Input as AInput,
+ InputPassword as AInputPassword,
+ List as AList,
+ ListItem as AListItem,
+ Modal as AModal,
+ Pagination as APagination,
+ Progress as AProgress,
+ Row as ARow,
+ Select as ASelect,
+ Space as ASpace,
+ Spin as ASpin,
+ Table as ATable,
+ Tag as ATag,
+ Typography,
+} from 'ant-design-vue';
+import type { TableColumnsType } from 'ant-design-vue';
+import {
+ DeleteOutlined,
+ EditOutlined,
+ ReloadOutlined,
+ SafetyCertificateOutlined,
+} from '@ant-design/icons-vue';
+
+const { Title: ATypographyTitle, Text: ATypographyText, Paragraph: ATypographyParagraph } = Typography;
const loading = ref(false);
const saving = ref(false);
@@ -70,6 +92,13 @@ const syncResults = ref([]);
const LIST_ALL_CODE_PAGE = 2000;
const LIST_ALL_EMPTY_STOP = 2;
const SYNC_TABLE_PAGE_SIZES = [10, 20, 50, 100];
+
+const CUSTOMER_COL_LABELS = ['کد مشتری', 'نام و نام خانوادگی', 'تلفن', 'وضعیت لینک'] as const;
+const PRODUCT_COL_LABELS = ['نام', 'عیار', 'آخرین سند', 'وضعیت'] as const;
+registerTableColumns('tahesab.customers', [...CUSTOMER_COL_LABELS]);
+registerTableColumns('tahesab.products', [...PRODUCT_COL_LABELS]);
+const customerTableCols = useTableColumns(() => 'tahesab.customers');
+const productTableCols = useTableColumns(() => 'tahesab.products');
const syncTablePageSize = ref(50);
const syncTablePage = ref(1);
@@ -719,664 +748,540 @@ async function importProductsBulk(mode: 'pending' | 'all') {
}
}
+const connectionOptions = computed(() =>
+ items.value.map((row) => ({ value: row.id, label: `${row.label} (${row.dbName})` })),
+);
+
+const customerColumns = computed>(() => {
+ const all: TableColumnsType = [
+ { title: 'کد مشتری', key: 'کد مشتری' },
+ { title: 'نام و نام خانوادگی', key: 'نام و نام خانوادگی' },
+ { title: 'تلفن', key: 'تلفن' },
+ { title: 'وضعیت لینک', key: 'وضعیت لینک' },
+ { title: 'عملیات', key: 'عملیات' },
+ ];
+ return all.filter((col) => {
+ const key = String(col.key ?? '');
+ if (key === 'عملیات') return true;
+ return customerTableCols.isVisible(key);
+ });
+});
+
+const productColumns = computed>(() => {
+ const all: TableColumnsType = [
+ { title: 'نام', key: 'نام' },
+ { title: 'عیار', key: 'عیار' },
+ { title: 'آخرین سند', key: 'آخرین سند' },
+ { title: 'وضعیت', key: 'وضعیت' },
+ { title: 'عملیات', key: 'عملیات' },
+ ];
+ return all.filter((col) => {
+ const key = String(col.key ?? '');
+ if (key === 'عملیات') return true;
+ return productTableCols.isVisible(key);
+ });
+});
+
onMounted(load);
-
-
+
+
+ اتصال نرمافزار مالی تهحساب
+
-
{{ error }}
-
{{ ok }}
+
+
-
- اتصال شما بهخاطر گواهی SSL خودامضا قطع است. روی همان کارت اتصال،
- فعالسازی SSL خودامضا را بزنید؛ بعد دوباره «نمایش مشتریان» را امتحان کنید.
-
+
+ اتصال شما بهخاطر گواهی SSL خودامضا قطع است. روی همان کارت اتصال،
+ فعالسازی SSL خودامضا را بزنید؛ بعد دوباره «نمایش مشتریان» را امتحان کنید.
+
+
-
-
-
+
+
+
+
- فعالسازی SSL خودامضا
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ اتصال پیشفرض سازمان
+ اتصال فعال باشد
+
+
+
+ پذیرش گواهی SSL خودامضا (برای IP محلی یا پورت داخلی بدون گواهی رسمی)
+
+
+
+
+
+
+
+
+ {{ editingId ? 'بهروزرسانی اتصال' : 'افزودن اتصال' }}
+
+ انصراف
+
+
+
+
+
+
+
+
+
+ با استفاده از این بخش میتوانید اشخاص و طرفحسابهای تهحساب را به عنوان مخاطب وارد نرمافزار کرده و سوابق مالی آنها را پیوند دهید.
+
+
+
+
+
+
+ (sync.connectionId = (v as string | undefined) ?? '')"
+ />
+
+
+
+
+
+
+
+
+ اگر «از» و «تا» خالی باشد، همهٔ مشتریان تهحساب خوانده و در جدول زیر نمایش داده میشوند. بازهٔ دستی حداکثر ۲۰۰۰ کد است.
+
+
+
+
+
+
+
+
+
+
+
+ نمایش مشتریان
+
+
+ وارد کردن همهٔ واردنشدهها ({{ toFaDigits(pendingImportCodes().length) }})
+
+
+ فقط مشتریانی که وارد نشدهاند
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ جستجو در تهحساب
+
+
+ وارد کردن نتایج جدید ({{ toFaDigits(pendingImportCodes().length) }})
+
+
+
+
+
+
+
+
+ «همگامسازی گروهها» گروه هر مشتری لینکشده را از تهحساب میخواند؛ فقط گروهِ آمده از تهحساب عوض
+ میشود و گروههایی که دستی دادهاید میمانند.
+ «ثبت لینکنشدهها» برای هر شخصی که به تهحساب لینک نیست اول تطبیق (موبایل، بعد نام) را امتحان
+ میکند تا مشتری تکراری ساخته نشود؛ اگر پیدا نشد با گروه، آدرس، کد ملی و تاریخ تولد ساخته میشود.
+
+
+
+ همگامسازی گروهها از تهحساب
+
+
+ ثبت مشتریهای لینکنشده در تهحساب
+
+
+
+
+ این اشخاص ثبت نشدند ({{ toFaDigits(exportIssues.length) }}). از پرونده، بخش «تهحساب و دارایی»
+ دستی لینک یا ثبت کنید:
- ویرایش
-
-
-
-
+
+
+
+
+
+ {{ item.name || 'بدون نام' }}
+
+ —
+ {{ item.status === 'ambiguous' ? 'چند مشتری مشابه در تهحساب پیدا شد' : item.error || 'خطا' }}
+
+
+
- تست اتصال
-
-
-
-
-
- حذف
-
-
-
-
-
+
+
+
-
-
-
-
-
-
- با استفاده از این بخش میتوانید اشخاص و طرفحسابهای تهحساب را به عنوان مخاطب وارد نرمافزار کرده و سوابق مالی آنها را پیوند دهید.
-
-
-
-
-
-
-
-
-
-
-
-
۱) وارد کردن دستهای با بازه کد مشتری
-
- اگر «از» و «تا» خالی باشد، همهٔ مشتریان تهحساب خوانده و در جدول زیر نمایش داده میشوند. بازهٔ دستی حداکثر ۲۰۰۰ کد است.
-
-
-
-
-
-
-
- نمایش مشتریان
-
-
- وارد کردن همهٔ واردنشدهها ({{ toFaDigits(pendingImportCodes().length) }})
-
-
-
-
-
-
-
۲) جستجوی تکی یا فیلتر مشخصات
-
-
-
-
-
-
-
- جستجو در تهحساب
-
-
- وارد کردن نتایج جدید ({{ toFaDigits(pendingImportCodes().length) }})
-
-
-
-
-
-
۳) گروهها و ثبت مشتریهای منتکت در تهحساب
-
- «همگامسازی گروهها» گروه هر مشتری لینکشده را از تهحساب میخواند؛ فقط گروهِ آمده از تهحساب عوض
- میشود و گروههایی که دستی دادهاید میمانند.
- «ثبت لینکنشدهها» برای هر شخصی که به تهحساب لینک نیست اول تطبیق (موبایل، بعد نام) را امتحان
- میکند تا مشتری تکراری ساخته نشود؛ اگر پیدا نشد با گروه، آدرس، کد ملی و تاریخ تولد ساخته میشود.
-
-
-
- همگامسازی گروهها از تهحساب
-
-
- ثبت مشتریهای لینکنشده در تهحساب
-
-
-
-
- این اشخاص ثبت نشدند ({{ toFaDigits(exportIssues.length) }}). از پرونده، بخش «تهحساب و دارایی»
- دستی لینک یا ثبت کنید:
-
-
+ همهٔ مشتریان این نتایج قبلاً وارد شدهاند.
+
+
+ {{ (record as SyncResult).moshtariCode }}
+
+
+ {{ (record as SyncResult).name || 'بدون نام' }}
+
+
+ {{ (record as SyncResult).tel }}
+
+
+
+ لینک شده{{ (record as SyncResult).personName ? ` (${(record as SyncResult).personName})` : '' }}
+
+ آماده ورود
+
+
+
+ وارد کردن
+
+
+ مشاهده شخص
+
+
+
+
+
+ (syncTablePageSize = n)"
+ />
+
+
+
+
+
-
-
- نامهای کارساختهٔ تهحساب (لیست DoListNameKarsakhte)
- را بهعنوان محصول با دستهٔ «{{ productCategoryLabel }}» وارد کنید.
- موجودی همچنان از تهحساب است؛ اینجا فقط کاتالوگ برای معامله/فاکتور ساخته میشود.
-
+
+
+
+ نامهای کارساختهٔ تهحساب (لیست DoListNameKarsakhte)
+ را بهعنوان محصول با دستهٔ «{{ productCategoryLabel }}» وارد کنید.
+ موجودی همچنان از تهحساب است؛ اینجا فقط کاتالوگ برای معامله/فاکتور ساخته میشود.
+
-
- سانترال یا سرویس VoIP شما باید رویداد تماس را با JSON به آدرس وبهوک بفرستد.
- فیلدهای اصلی:
- callId،
- direction (inbound/outbound)،
- status،
- from،
- to.
- برای خلاصه خودکار یکی از
- recordingUrl
- (لینک فایل ضبط) یا
- transcript
- (متن آماده) را بفرستید؛ پس از
- completed
- /
- answered
- صف خلاصه ساخته میشود.
- امضا اختیاری با هدر
- X-Voip-Signature
- (HMAC-SHA256 هگز).
-
-
-
-
-
-
-
-
-
-
+
+
+
+ سانترال یا سرویس VoIP شما باید رویداد تماس را با JSON به آدرس وبهوک بفرستد. فیلدهای اصلی:
+ callId، direction (inbound/outbound)، status،
+ from، to. برای خلاصه خودکار یکی از recordingUrl
+ (لینک فایل ضبط) یا transcript (متن آماده) را بفرستید؛ پس از
+ completed / answered صف خلاصه ساخته میشود. امضا اختیاری با هدر
+ X-Voip-Signature (HMAC-SHA256 هگز).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ذخیره اتصال
+
+
+
+
+
+
+
+
+
+
+
+ {{ c.label }}
+
+ تماسهای ثبتشده {{ toFaDigits(c.callCount) }} ·
+ {{
+ c.lastEventAt
+ ? `آخرین رویداد ${formatJalaliNumeric(new Date(c.lastEventAt))}`
+ : 'هنوز رویدادی نیامده'
+ }}
+
+
+ Click-to-Call فعال
+
+
+
+
+
+ حذف
+
+
+
+
+
+
+ {{ webhookUrl }}
+