Edit SMS automation

This commit is contained in:
2026-09-13 21:22:41 +03:30
parent cc23e453de
commit 8925c77ae0
8 changed files with 410 additions and 56 deletions
+28 -49
View File
@@ -2,8 +2,8 @@
import { computed, onMounted, ref } from 'vue';
import axios from 'axios';
import { api } from '@/lib/api';
import JalaliDateInput from '@/components/JalaliDateInput.vue';
import { formatLocalDateTimeInput, parseLocalInput } from '@/lib/jalali';
import MessageIntervalPicker from '@/components/MessageIntervalPicker.vue';
import { toFaDigits } from '@/lib/jalali';
import type {
CreateMessageAutomationRuleRequest,
MessageAutomationChannel,
@@ -30,9 +30,11 @@ const editingId = ref<string | null>(null);
const name = ref('');
const trigger = ref<MessageAutomationTrigger>('invoice_issued');
const startAt = ref('');
const startDelayValue = ref(0);
const startDelayUnit = ref<MessageAutomationDelayUnit>('minutes');
const repeatCount = ref(1);
const intervalAt = ref('');
const intervalValue = ref(2);
const intervalUnit = ref<MessageAutomationDelayUnit>('days');
const notifyTarget = ref<MessageAutomationTarget>('person');
const channel = ref<MessageAutomationChannel>('sms');
const title = ref('');
@@ -44,38 +46,15 @@ const personNote = computed(
'ناتیف داخل برنامه برای کارکنان است؛ برای مشتری پیامک ارسال می‌شود.',
);
function delayMs(value: number, unit: MessageAutomationDelayUnit) {
const n = Math.max(0, Math.trunc(Number(value) || 0));
if (unit === 'minutes') return n * 60_000;
if (unit === 'hours') return n * 3_600_000;
return n * 86_400_000;
}
function delayToIso(value: number, unit: MessageAutomationDelayUnit) {
if (!value) return '';
return formatLocalDateTimeInput(new Date(Date.now() + delayMs(value, unit)));
}
function isoToDelay(iso: string): {
value: number;
unit: MessageAutomationDelayUnit;
} {
const date = parseLocalInput(iso);
if (!date) return { value: 0, unit: 'minutes' };
const mins = Math.max(0, Math.round((date.getTime() - Date.now()) / 60_000));
if (mins === 0) return { value: 0, unit: 'minutes' };
if (mins % (24 * 60) === 0) return { value: mins / (24 * 60), unit: 'days' };
if (mins % 60 === 0) return { value: mins / 60, unit: 'hours' };
return { value: mins, unit: 'minutes' };
}
function resetForm() {
editingId.value = null;
name.value = '';
trigger.value = 'invoice_issued';
startAt.value = '';
startDelayValue.value = 0;
startDelayUnit.value = 'minutes';
repeatCount.value = 1;
intervalAt.value = delayToIso(2, 'days');
intervalValue.value = 2;
intervalUnit.value = 'days';
notifyTarget.value = 'person';
channel.value = 'sms';
title.value = '';
@@ -87,9 +66,11 @@ function startEdit(row: MessageAutomationRuleDto) {
editingId.value = row.id;
name.value = row.name;
trigger.value = row.trigger;
startAt.value = delayToIso(row.startDelayValue, row.startDelayUnit);
startDelayValue.value = row.startDelayValue;
startDelayUnit.value = row.startDelayUnit;
repeatCount.value = row.repeatCount;
intervalAt.value = delayToIso(row.intervalValue, row.intervalUnit);
intervalValue.value = row.intervalValue;
intervalUnit.value = row.intervalUnit;
notifyTarget.value = row.notifyTarget;
channel.value = row.channel;
title.value = row.title;
@@ -101,9 +82,9 @@ function scheduleLabel(row: MessageAutomationRuleDto) {
const start =
row.startDelayValue === 0
? 'همان لحظه'
: `${row.startDelayValue} ${MESSAGE_AUTOMATION_UNIT_LABELS[row.startDelayUnit]} بعد`;
: `${toFaDigits(row.startDelayValue)} ${MESSAGE_AUTOMATION_UNIT_LABELS[row.startDelayUnit]} بعد`;
if (row.repeatCount <= 1) return start;
return `${start} · ${row.repeatCount} بار، هر ${row.intervalValue} ${MESSAGE_AUTOMATION_UNIT_LABELS[row.intervalUnit]}`;
return `${start} · ${toFaDigits(row.repeatCount)} بار، هر ${toFaDigits(row.intervalValue)} ${MESSAGE_AUTOMATION_UNIT_LABELS[row.intervalUnit]}`;
}
async function load() {
@@ -122,17 +103,15 @@ async function load() {
}
function payload(): CreateMessageAutomationRuleRequest {
const start = isoToDelay(startAt.value);
const interval = isoToDelay(intervalAt.value);
return {
name: name.value.trim(),
isActive: true,
trigger: trigger.value,
startDelayValue: start.value,
startDelayUnit: start.unit,
startDelayValue: startDelayValue.value,
startDelayUnit: startDelayUnit.value,
repeatCount: repeatCount.value,
intervalValue: Math.max(1, interval.value || 1),
intervalUnit: interval.value ? interval.unit : 'days',
intervalValue: Math.max(1, intervalValue.value || 1),
intervalUnit: intervalUnit.value,
notifyTarget: notifyTarget.value,
channel: channel.value,
title: title.value.trim(),
@@ -230,10 +209,10 @@ onMounted(load);
</label>
<div class="field span-5">
<span>شروع ارسال</span>
<JalaliDateInput
v-model="startAt"
mode="datetime"
placeholder="همان لحظه"
<MessageIntervalPicker
v-model:value="startDelayValue"
v-model:unit="startDelayUnit"
allow-immediate
/>
</div>
<label class="field span-2">
@@ -242,10 +221,10 @@ onMounted(load);
</label>
<div v-if="repeatCount > 1" class="field span-5">
<span>فاصله بین پیام‌ها</span>
<JalaliDateInput
v-model="intervalAt"
mode="datetime"
placeholder="انتخاب روز و ساعت"
<MessageIntervalPicker
v-model:value="intervalValue"
v-model:unit="intervalUnit"
interval
/>
</div>
<label class="field span-4">