181 lines
4.6 KiB
TypeScript
181 lines
4.6 KiB
TypeScript
import { Injectable, Logger } from '@nestjs/common';
|
||
import { PrismaService } from '../prisma/prisma.service';
|
||
import { SmsService } from '../common/services/sms.service';
|
||
|
||
export interface CreateContactSubmissionDto {
|
||
name: string;
|
||
phone: string;
|
||
email?: string;
|
||
subject?: string;
|
||
message: string;
|
||
}
|
||
|
||
export interface UpdateContactInfoItemDto {
|
||
key: string;
|
||
title: string;
|
||
value: string;
|
||
icon?: string;
|
||
order?: number;
|
||
}
|
||
|
||
@Injectable()
|
||
export class ContactService {
|
||
private readonly logger = new Logger(ContactService.name);
|
||
|
||
constructor(
|
||
private readonly prisma: PrismaService,
|
||
private readonly smsService: SmsService,
|
||
) {}
|
||
|
||
async submitContactForm(dto: CreateContactSubmissionDto) {
|
||
const submission = await this.prisma.contactSubmission.create({
|
||
data: {
|
||
name: dto.name,
|
||
phone: dto.phone,
|
||
email: dto.email,
|
||
subject: dto.subject,
|
||
message: dto.message,
|
||
},
|
||
});
|
||
|
||
// Send SMS confirmation to User & notification to Admin
|
||
try {
|
||
const userPatternId = parseInt(
|
||
process.env.MELIPAYAMAK_CONTACT_USER_BODY_ID || '508081',
|
||
10,
|
||
);
|
||
await this.smsService.sendPatternSms({
|
||
to: dto.phone,
|
||
bodyId: userPatternId,
|
||
args: [dto.name, 'فرم تماس'],
|
||
});
|
||
|
||
const adminPhone = process.env.ADMIN_MOBILE || '09364100228';
|
||
const adminPatternId = parseInt(
|
||
process.env.MELIPAYAMAK_CONTACT_ADMIN_BODY_ID || '508083',
|
||
10,
|
||
);
|
||
await this.smsService.sendPatternSms({
|
||
to: adminPhone,
|
||
bodyId: adminPatternId,
|
||
args: [dto.name, dto.phone],
|
||
});
|
||
} catch (err) {
|
||
this.logger.error(
|
||
`SMS trigger error on contact submission: ${err.message}`,
|
||
);
|
||
}
|
||
|
||
return {
|
||
success: true,
|
||
message:
|
||
'پیام شما با موفقیت ثبت شد و بهزودی کارشناسان ما با شما تماس خواهند گرفت.',
|
||
submissionId: submission.id,
|
||
};
|
||
}
|
||
|
||
async getContactInfo() {
|
||
let items = await this.prisma.contactInfo.findMany({
|
||
orderBy: { order: 'asc' },
|
||
});
|
||
|
||
if (items.length === 0) {
|
||
// Seed default items if empty
|
||
const defaultItems = [
|
||
{
|
||
key: 'branch_info',
|
||
title: 'اطلاعات نمایندگی',
|
||
value:
|
||
'تلفنهای تماس\n۰۲۱-۸۸۸۸ ۴۴۴۴\n\nشنبه تا چهارشنبه ۹:۰۰ الی ۱۸:۰۰',
|
||
icon: 'phone',
|
||
order: 1,
|
||
},
|
||
{
|
||
key: 'email_info',
|
||
title: 'پست الکترونیک',
|
||
value: 'info@canina-iran.com\n\nپاسخگویی در کمتر از ۲۴ ساعت کاری',
|
||
icon: 'mail',
|
||
order: 2,
|
||
},
|
||
{
|
||
key: 'address_info',
|
||
title: 'نشانی دفتر مرکزی',
|
||
value: 'تهران، جردن، خیابان سعیدی، ساختمان کانینا، طبقه ۵، واحد ۱۹',
|
||
icon: 'map-pin',
|
||
order: 3,
|
||
},
|
||
];
|
||
|
||
for (const item of defaultItems) {
|
||
await this.prisma.contactInfo.upsert({
|
||
where: { key: item.key },
|
||
update: {},
|
||
create: item,
|
||
});
|
||
}
|
||
|
||
items = await this.prisma.contactInfo.findMany({
|
||
orderBy: { order: 'asc' },
|
||
});
|
||
}
|
||
|
||
return items;
|
||
}
|
||
|
||
async getAllSubmissions(page = 1, limit = 20, status?: string) {
|
||
const skip = (page - 1) * limit;
|
||
const where = status ? { status } : {};
|
||
|
||
const [items, total] = await Promise.all([
|
||
this.prisma.contactSubmission.findMany({
|
||
where,
|
||
skip,
|
||
take: limit,
|
||
orderBy: { createdAt: 'desc' },
|
||
}),
|
||
this.prisma.contactSubmission.count({ where }),
|
||
]);
|
||
|
||
return {
|
||
items,
|
||
total,
|
||
page,
|
||
limit,
|
||
totalPages: Math.ceil(total / limit),
|
||
};
|
||
}
|
||
|
||
async updateSubmissionStatus(
|
||
id: string,
|
||
status: string,
|
||
adminNotes?: string,
|
||
) {
|
||
return this.prisma.contactSubmission.update({
|
||
where: { id },
|
||
data: { status, adminNotes },
|
||
});
|
||
}
|
||
|
||
async updateContactInfoItems(items: UpdateContactInfoItemDto[]) {
|
||
for (const item of items) {
|
||
await this.prisma.contactInfo.upsert({
|
||
where: { key: item.key },
|
||
update: {
|
||
title: item.title,
|
||
value: item.value,
|
||
icon: item.icon,
|
||
order: item.order ?? 0,
|
||
},
|
||
create: {
|
||
key: item.key,
|
||
title: item.title,
|
||
value: item.value,
|
||
icon: item.icon,
|
||
order: item.order ?? 0,
|
||
},
|
||
});
|
||
}
|
||
return this.getContactInfo();
|
||
}
|
||
}
|