fix some bugs 4

This commit is contained in:
2026-07-18 22:22:21 +03:30
parent d5e452d02b
commit a2f3e320d5
8 changed files with 343 additions and 8 deletions
@@ -0,0 +1,145 @@
<template>
<BasicModal
v-model:visible="visibleProxy"
:width="isMobile ? '94vw' : '36rem'"
:title="modalTitle"
ok-text="ارسال پیامک"
:loading="loading"
:ok-button-props="{ disabled: !canSubmit }"
@ok="submit"
@close="close"
>
<div class="customer-sms-modal flex flex-col gap-3">
<p class="m-0 text-xs" style="color: var(--admin-text-secondary)">
گیرنده:
<strong dir="ltr" class="text-primary">{{ customer?.mobile || '—' }}</strong>
</p>
<div class="flex flex-wrap gap-2">
<a-button
v-for="snippet in snippets"
:key="snippet.key"
size="small"
@click="appendSnippet(snippet.insert)"
>
{{ snippet.label }}
</a-button>
</div>
<a-textarea
v-model:value="message"
:rows="6"
:maxlength="700"
show-count
placeholder="متن پیامک را بنویسید…"
class="customer-sms-modal__textarea"
/>
<p v-if="profanityHit" class="m-0 text-xs text-red-500">
متن حاوی عبارت نامناسب است — قبل از ارسال اصلاح کنید.
</p>
<p class="m-0 text-xs" style="color: var(--admin-text-secondary)">
متغیرها در سرور جایگزین می‌شوند: %نام% · %نام_اپ% · %لینک_اپ%
</p>
</div>
</BasicModal>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { message as antMessage } from 'ant-design-vue'
import type { Customer } from '@/model/customer'
import { isMobile } from '@core/utils/is'
import BasicModal from '@/components/BasicModal.vue'
import {
buildDirectSmsSnippets,
findProfanity,
sendCustomerDirectSms
} from '@/api/customerDirectSms'
import { getConfiguration } from '@/api/configuration'
const props = defineProps<{
visible: boolean
customer: Customer | null
}>()
const emit = defineEmits<{
(e: 'update:visible', value: boolean): void
(e: 'sent'): void
}>()
const visibleProxy = computed({
get: () => props.visible,
set: (v: boolean) => emit('update:visible', v)
})
const loading = ref(false)
const message = ref('')
const appName = ref('')
const appUrl = ref('')
const modalTitle = computed(() =>
props.customer?.name ? `پیامک به ${props.customer.name}` : 'ارسال پیامک به مشتری'
)
const snippets = computed(() =>
buildDirectSmsSnippets(props.customer, appName.value, appUrl.value)
)
const profanityHit = computed(() => findProfanity(message.value))
const canSubmit = computed(
() => message.value.trim().length > 0 && !profanityHit.value && !loading.value
)
watch(
() => props.visible,
async (open) => {
if (!open) return
message.value = ''
try {
const rows = await getConfiguration()
const list = Array.isArray(rows) ? rows : []
appName.value = String(list.find((r) => r.key === 'name_fa')?.value ?? '').trim()
appUrl.value = String(list.find((r) => r.key === 'app_url')?.value ?? '').trim()
} catch {
appName.value = ''
appUrl.value = ''
}
}
)
function appendSnippet(text: string) {
if (!text) return
const current = message.value
const needsSpace = current.length > 0 && !/\s$/.test(current)
message.value = current + (needsSpace ? ' ' : '') + text
}
function close() {
visibleProxy.value = false
}
async function submit() {
if (!props.customer?.id || !canSubmit.value) return
const hit = findProfanity(message.value)
if (hit) {
antMessage.error('متن حاوی محتوای نامناسب است')
return
}
try {
loading.value = true
await sendCustomerDirectSms({
customer_id: Number(props.customer.id),
message: message.value.trim()
})
antMessage.success('پیامک ارسال شد')
emit('sent')
close()
} catch (e) {
console.error(e)
} finally {
loading.value = false
}
}
</script>