update
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
private const SCENARIOS = [
|
||||
'service_expiry',
|
||||
'service_renewal_reminder',
|
||||
'invoice_notification',
|
||||
'invoice_payment_reminder',
|
||||
];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$this->update(fn (array $disabled) => array_values(array_unique([...$disabled, ...self::SCENARIOS])));
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$this->update(fn (array $disabled) => array_values(array_diff($disabled, self::SCENARIOS)));
|
||||
}
|
||||
|
||||
private function update(callable $change): void
|
||||
{
|
||||
$row = DB::table('setting')->where('key', 'email_settings')->first();
|
||||
$value = $row ? (json_decode($row->value, true) ?: []) : [];
|
||||
$value['auto_disabled'] = $change((array) ($value['auto_disabled'] ?? []));
|
||||
|
||||
DB::table('setting')->updateOrInsert(
|
||||
['key' => 'email_settings'],
|
||||
['value' => json_encode($value), 'updated_at' => now()],
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\EmailTemplates;
|
||||
|
||||
use App\Support\EmailTemplateShell as T;
|
||||
|
||||
final class AccountTemplates
|
||||
{
|
||||
/**
|
||||
* @return array<int, array{scenario: string, name: string, subject: string, body: string}>
|
||||
*/
|
||||
public static function all(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'scenario' => 'verify_account_welcome',
|
||||
'name' => 'Mã xác thực tài khoản',
|
||||
'subject' => '[{{app_name}}] Mã xác thực tài khoản của bạn',
|
||||
'body' => T::title('Xác thực tài khoản')
|
||||
. T::greeting('{{full_name}}')
|
||||
. T::paragraph('Cảm ơn Quý khách đã đăng ký tài khoản tại <strong>{{app_name}}</strong>. Vui lòng nhập mã xác thực dưới đây để hoàn tất đăng ký:')
|
||||
. T::highlight('{{verify_code}}')
|
||||
. T::paragraph('Mã xác thực có hiệu lực trong <strong>5 phút</strong>. Nếu Quý khách không thực hiện yêu cầu này, vui lòng bỏ qua email.')
|
||||
. T::note('Không chia sẻ mã này cho bất kỳ ai, kể cả nhân viên Thế Giới Số.'),
|
||||
],
|
||||
[
|
||||
'scenario' => 'customer_password_reset_link',
|
||||
'name' => 'Link đặt lại mật khẩu khách hàng',
|
||||
'subject' => 'Yêu cầu đặt lại mật khẩu',
|
||||
'body' => T::title('Đặt lại mật khẩu')
|
||||
. T::greeting('{{full_name}}')
|
||||
. T::paragraph('Chúng tôi nhận được yêu cầu đặt lại mật khẩu cho tài khoản của Quý khách. Vui lòng bấm nút bên dưới để tạo mật khẩu mới. Link có hiệu lực trong <strong>{{expire_minutes}} phút</strong> và chỉ dùng được một lần.')
|
||||
. T::button('{{reset_url}}', 'ĐẶT LẠI MẬT KHẨU')
|
||||
. T::paragraph('Nếu Quý khách không yêu cầu, vui lòng bỏ qua email này — mật khẩu hiện tại vẫn giữ nguyên. Mọi thắc mắc xin liên hệ <strong>support@tgs.com.vn</strong> hoặc <strong>(028) 7309. 7379</strong>.')
|
||||
. T::note('Không chia sẻ link này cho bất kỳ ai, kể cả nhân viên Thế Giới Số.'),
|
||||
],
|
||||
[
|
||||
'scenario' => 'password_reset_admin',
|
||||
'name' => 'Admin cấp lại mật khẩu',
|
||||
'subject' => 'Mật khẩu của bạn đã được cập nhật — {{app_name}}',
|
||||
'body' => T::title('Mật khẩu đã được cập nhật')
|
||||
. T::greeting('{{full_name}}')
|
||||
. T::paragraph('Quản trị viên của <strong>{{app_name}}</strong> vừa cấp lại mật khẩu mới cho tài khoản của Quý khách. Vui lòng dùng thông tin bên dưới để đăng nhập:')
|
||||
. T::infoTable([
|
||||
'Tài khoản' => '{{email}}',
|
||||
'Mật khẩu mới' => '{{password}}',
|
||||
])
|
||||
. T::button('{{login_url}}', 'ĐĂNG NHẬP NGAY')
|
||||
. T::note('Vui lòng đổi mật khẩu ngay sau khi đăng nhập. Nếu Quý khách không yêu cầu thao tác này, hãy liên hệ ngay <strong>support@tgs.com.vn</strong>.'),
|
||||
],
|
||||
[
|
||||
'scenario' => 'customer_welcome',
|
||||
'name' => 'Chào mừng khách hàng mới',
|
||||
'subject' => 'Chào mừng Quý khách đến với {{app_name}}',
|
||||
'body' => T::title('Chào mừng đến với {{app_name}}')
|
||||
. T::greeting('{{full_name}}')
|
||||
. T::paragraph('Cảm ơn Quý khách đã tin tưởng lựa chọn <strong>{{app_name}}</strong>. Tài khoản của Quý khách đã được kích hoạt và sẵn sàng sử dụng.')
|
||||
. T::paragraph('Tại cổng quản lý, Quý khách có thể đặt mua dịch vụ Hosting, Cloud Server, tên miền, theo dõi hoá đơn và gửi yêu cầu hỗ trợ bất cứ lúc nào.')
|
||||
. T::button('{{login_url}}', 'ĐĂNG NHẬP NGAY')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'ticket_created',
|
||||
'name' => 'Ticket hỗ trợ mới',
|
||||
'subject' => '[#{{ticket_num}}] Yêu cầu hỗ trợ của bạn đã được tiếp nhận',
|
||||
'body' => T::title('Yêu cầu hỗ trợ đã được tiếp nhận')
|
||||
. T::greeting('{{full_name}}')
|
||||
. T::paragraph('Chúng tôi đã nhận được yêu cầu hỗ trợ của Quý khách và sẽ phản hồi trong thời gian sớm nhất. Thông tin ticket:')
|
||||
. T::infoTable([
|
||||
'Mã ticket' => '#{{ticket_num}}',
|
||||
'Tiêu đề' => '{{subject}}',
|
||||
], '{{room_row}}' . T::row('Trạng thái', '<span style="color: #16a34a;">Đang mở</span>'))
|
||||
. T::button('{{ticket_url}}', 'XEM CHI TIẾT TICKET')
|
||||
. T::paragraph('Đội ngũ hỗ trợ của <strong>{{app_name}}</strong> sẽ liên hệ với Quý khách qua email hoặc cập nhật trực tiếp trên hệ thống.')
|
||||
. T::autoNotice(),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\EmailTemplates;
|
||||
|
||||
use App\Support\EmailTemplateShell as T;
|
||||
|
||||
final class AdminTemplates
|
||||
{
|
||||
/**
|
||||
* @return array<int, array{scenario: string, name: string, subject: string, body: string}>
|
||||
*/
|
||||
public static function all(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'scenario' => 'admin_order_notification',
|
||||
'name' => '[Admin] Đơn hàng mới',
|
||||
'subject' => '[ADMIN] Đơn hàng mới #{{order_num}} — {{customer_email}}',
|
||||
'body' => T::title('Đơn hàng mới')
|
||||
. T::paragraph('Có đơn hàng mới vừa được đặt trên hệ thống <strong>{{company_name}}</strong>.')
|
||||
. T::heading('Thông tin khách hàng')
|
||||
. T::infoTable([
|
||||
'Mã đơn hàng' => '#{{order_num}}',
|
||||
'Thời gian' => '{{created_at}}',
|
||||
'Khách hàng' => '{{customer_name}}',
|
||||
'Email' => '{{customer_email}}',
|
||||
], '{{client_ip_row}}')
|
||||
. T::heading('Thông tin sản phẩm')
|
||||
. T::infoTable([
|
||||
'Sản phẩm' => '{{product_name}}',
|
||||
'Loại' => '{{product_type}}',
|
||||
'Chu kỳ thanh toán' => '{{billing_cycle}}',
|
||||
'Tổng tiền' => '{{total_formatted}}',
|
||||
])
|
||||
. '{{vm_block}}',
|
||||
],
|
||||
[
|
||||
'scenario' => 'admin_domain_order_new',
|
||||
'name' => '[Admin] Đơn đăng ký tên miền mới',
|
||||
'subject' => '[ADMIN] Đơn đăng ký tên miền mới - {{domain_name}}',
|
||||
'body' => T::title('Đơn đăng ký tên miền mới')
|
||||
. T::paragraph('Có đơn đăng ký tên miền mới trên hệ thống <strong>{{company_name}}</strong>, cần kiểm tra và đăng ký thủ công.')
|
||||
. T::infoTable([
|
||||
'Tên miền' => '{{domain_name}}',
|
||||
'Mã đơn hàng' => '{{order_num}}',
|
||||
'Tổng tiền' => '{{order_total}}',
|
||||
'Khách hàng' => '{{customer_name}}',
|
||||
'Email' => '{{customer_email}}',
|
||||
'Thời gian' => '{{created_at}}',
|
||||
])
|
||||
. T::button('{{admin_url}}', 'XEM ĐƠN HÀNG'),
|
||||
],
|
||||
[
|
||||
'scenario' => 'admin_hosting_account_created',
|
||||
'name' => '[Admin] Hosting account mới',
|
||||
'subject' => '[ADMIN] Hosting account mới — {{domain_name}}',
|
||||
'body' => T::title('Hosting account mới')
|
||||
. T::paragraph('Hệ thống <strong>{{company_name}}</strong> vừa khởi tạo hosting cho khách hàng.')
|
||||
. T::heading('Thông tin dịch vụ')
|
||||
. T::infoTable([
|
||||
'Tên miền' => '{{domain_name}}',
|
||||
'Gói hosting' => '{{hosting_plan}}',
|
||||
'Khách hàng' => '{{customer_name}}',
|
||||
'Email' => '{{customer_email}}',
|
||||
'Thời gian' => '{{created_at}}',
|
||||
])
|
||||
. T::heading('Máy chủ Plesk')
|
||||
. T::infoTable([
|
||||
'Máy chủ' => '{{server_name}}',
|
||||
'IP' => '{{server_ip}}',
|
||||
'Client ID' => '{{plesk_client_id}}',
|
||||
'Subscription ID' => '{{plesk_subscription_id}}',
|
||||
])
|
||||
. T::heading('Thông tin truy cập')
|
||||
. T::infoTable(
|
||||
['FTP Username' => '{{ftp_username}}'],
|
||||
'{{ftp_password_row}}'
|
||||
. T::row('Plesk Panel', '{{plesk_panel_url}}')
|
||||
. T::row('Plesk Login', '{{plesk_login}}')
|
||||
. '{{plesk_password_row}}',
|
||||
),
|
||||
],
|
||||
[
|
||||
'scenario' => 'admin_trial_registration_request',
|
||||
'name' => '[Admin] Yêu cầu dùng thử VPS',
|
||||
'subject' => '[ADMIN] Yêu cầu dùng thử Cloud VPS - {{customer_name}}',
|
||||
'body' => T::title('Yêu cầu dùng thử Cloud VPS')
|
||||
. T::paragraph('Có khách hàng vừa gửi yêu cầu dùng thử Cloud VPS trên hệ thống <strong>{{company_name}}</strong>.')
|
||||
. T::heading('Thông tin khách hàng')
|
||||
. T::infoTable([
|
||||
'Khách hàng' => '{{customer_name}}',
|
||||
'Email' => '{{customer_email}}',
|
||||
'Số điện thoại' => '{{customer_phone}}',
|
||||
'Thời gian' => '{{created_at}}',
|
||||
])
|
||||
. T::heading('Cấu hình yêu cầu')
|
||||
. T::infoTable([
|
||||
'CPU' => '{{cpu}}',
|
||||
'RAM' => '{{ram}}',
|
||||
'SSD' => '{{ssd}}',
|
||||
'Hệ điều hành' => '{{os}}',
|
||||
], '{{other_row}}'),
|
||||
],
|
||||
[
|
||||
'scenario' => 'admin_manual_deposit_pending',
|
||||
'name' => '[Admin] Yêu cầu nạp tiền chờ duyệt',
|
||||
'subject' => '[ADMIN] Yêu cầu nạp tiền chờ duyệt - {{transaction_code}}',
|
||||
'body' => T::title('Yêu cầu nạp tiền chờ duyệt')
|
||||
. T::paragraph('Có yêu cầu nạp tiền thủ công mới trên hệ thống <strong>{{company_name}}</strong>, vui lòng kiểm tra chứng từ và duyệt trong trang quản trị.')
|
||||
. T::infoTable([
|
||||
'Mã giao dịch' => '{{transaction_code}}',
|
||||
'Số tiền' => '<span style="color: #f16723;">{{amount_formatted}}</span>',
|
||||
'Thời gian' => '{{created_at}}',
|
||||
'Khách hàng' => '{{customer_name}}',
|
||||
'Email' => '{{customer_email}}',
|
||||
], '{{customer_phone_row}}{{client_ip_row}}{{proof_row}}'),
|
||||
],
|
||||
[
|
||||
'scenario' => 'admin_ticket_notification',
|
||||
'name' => '[Admin] Ticket hỗ trợ mới',
|
||||
'subject' => '[ADMIN] Ticket mới #{{ticket_num}} — {{customer_email}}',
|
||||
'body' => T::title('Ticket hỗ trợ mới')
|
||||
. T::infoTable([
|
||||
'Mã ticket' => '#{{ticket_num}}',
|
||||
'Tiêu đề' => '{{subject_text}}',
|
||||
'Phòng ban' => '{{room}}',
|
||||
'Khách hàng' => '{{customer_name}}',
|
||||
'Email' => '{{customer_email}}',
|
||||
])
|
||||
. T::note('{{description}}', 'Nội dung:')
|
||||
. T::button('{{ticket_url}}', 'XEM TICKET'),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\EmailTemplates;
|
||||
|
||||
use App\Support\EmailTemplateShell as T;
|
||||
|
||||
final class BillingTemplates
|
||||
{
|
||||
/**
|
||||
* @return array<int, array{scenario: string, name: string, subject: string, body: string, types?: array<string, string>}>
|
||||
*/
|
||||
public static function all(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'scenario' => 'invoice_notification',
|
||||
'name' => 'Thông báo hoá đơn / gia hạn cước',
|
||||
'subject' => '{{title}} #{{invoice_number}} - {{company_name}}',
|
||||
'body' => T::title('{{title}}')
|
||||
. T::greeting('{{customer_name}}')
|
||||
. T::paragraph('{{body_message}}')
|
||||
. T::infoTable([
|
||||
'Số hoá đơn' => '{{invoice_number}}',
|
||||
'Ngày lập' => '{{created_date}}',
|
||||
'Hạn thanh toán' => '{{due_date}}',
|
||||
'Tổng tiền' => '{{total}} VNĐ',
|
||||
'Trạng thái' => '{{status_label}}',
|
||||
], '{{outstanding_row}}')
|
||||
. T::paragraph('{{intro_note}}')
|
||||
. '{{pay_button}}{{attachments_block}}{{note_block}}'
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'invoice_payment_reminder',
|
||||
'name' => 'Nhắc thanh toán hoá đơn',
|
||||
'subject' => 'Nhắc thanh toán hoá đơn {{invoice_number}}',
|
||||
'body' => T::title('Nhắc thanh toán hoá đơn')
|
||||
. T::greeting('{{client_name}}')
|
||||
. T::paragraph('{{status_line}} Vui lòng thanh toán để dịch vụ không bị gián đoạn.')
|
||||
. T::infoTable([
|
||||
'Số hoá đơn' => '{{invoice_number}}',
|
||||
'Hạn thanh toán' => '{{due_date}}',
|
||||
'Tổng tiền' => '{{total}} VNĐ',
|
||||
], '{{paid_row}}' . T::row('Còn phải thanh toán', '<span style="color: #dc2626;">{{outstanding}} VNĐ</span>'))
|
||||
. T::button('{{login_url}}', 'THANH TOÁN NGAY')
|
||||
. T::paragraph('Nếu Quý khách đã thanh toán, vui lòng bỏ qua email này.')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'customer_deposit_success',
|
||||
'name' => 'Nạp tiền thành công',
|
||||
'subject' => 'Thông báo nạp tiền thành công - {{amount_formatted}} VNĐ',
|
||||
'body' => T::title('Nạp tiền thành công')
|
||||
. T::greeting('{{customer_name}}')
|
||||
. T::paragraph('Tài khoản của Quý khách đã được nạp tiền thành công. Chi tiết giao dịch:')
|
||||
. T::infoTable([
|
||||
'Mã giao dịch' => '{{transaction_code}}',
|
||||
'Số tiền nạp' => '<span style="color: #16a34a;">{{amount_formatted}} VNĐ</span>',
|
||||
'Tiền khuyến mãi' => '{{credit_formatted}} VNĐ',
|
||||
'Thời gian' => '{{deposit_date}}',
|
||||
'Số dư hiện tại' => '{{current_total_formatted}} VNĐ',
|
||||
'Số dư khuyến mãi' => '{{current_credit_formatted}} VNĐ',
|
||||
])
|
||||
. T::button('{{login_url}}', 'XEM TÀI KHOẢN')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'manual_deposit_status',
|
||||
'name' => 'Trạng thái nạp tiền thủ công',
|
||||
'subject' => '{{company_name}} - Trạng thái nạp tiền',
|
||||
'types' => ['status_label' => 'string'],
|
||||
'body' => T::title('Cập nhật yêu cầu nạp tiền')
|
||||
. T::greeting('{{customer_name}}')
|
||||
. T::paragraph('{{status_message}}')
|
||||
. T::infoTable([
|
||||
'Trạng thái' => '<span style="display: inline-block; border-radius: 20px; padding: 2px 12px; background-color: {{status_bg}}; color: {{status_color}};">{{status_label}}</span>',
|
||||
'Mã giao dịch' => '{{transaction_code}}',
|
||||
'Số tiền' => '{{amount_formatted}} VNĐ',
|
||||
'Thời gian gửi' => '{{deposit_date}}',
|
||||
], '{{processed_date_row}}')
|
||||
. T::button('{{portal_url}}', 'XEM YÊU CẦU NẠP TIỀN')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'order_created',
|
||||
'name' => 'Xác nhận đơn hàng',
|
||||
'subject' => 'Xác nhận đơn hàng #{{order_num}}',
|
||||
'body' => T::title('Xác nhận đơn hàng')
|
||||
. T::greeting('{{client_name}}')
|
||||
. T::paragraph('Cảm ơn Quý khách đã đặt hàng tại <strong>{{company_name}}</strong>! Đơn hàng đã được tiếp nhận thành công.')
|
||||
. T::infoTable([
|
||||
'Mã đơn hàng' => '{{order_num}}',
|
||||
'Mã hoá đơn' => '{{invoice_num}}',
|
||||
'Tổng tiền' => '{{order_total}} VNĐ',
|
||||
])
|
||||
. T::paragraph('Chúng tôi sẽ xử lý đơn hàng trong thời gian sớm nhất và thông báo cho Quý khách khi dịch vụ được kích hoạt.')
|
||||
. T::supportLine()
|
||||
. T::autoNotice(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'domain_order_received',
|
||||
'name' => 'Đơn đăng ký tên miền đã ghi nhận',
|
||||
'subject' => 'Đơn đăng ký tên miền {{domain_name}} đã được ghi nhận',
|
||||
'body' => T::title('Đã ghi nhận đơn đăng ký tên miền')
|
||||
. T::greeting('{{customer_name}}')
|
||||
. T::paragraph('Cảm ơn Quý khách đã đặt mua tên miền tại <strong>{{company_name}}</strong>. Đơn hàng đang chờ đội ngũ kỹ thuật kiểm tra và đăng ký.')
|
||||
. T::infoTable([
|
||||
'Tên miền' => '{{domain_name}}',
|
||||
'Mã đơn hàng' => '{{order_num}}',
|
||||
'Tổng tiền' => '{{order_total}}',
|
||||
'Thời gian' => '{{created_at}}',
|
||||
])
|
||||
. T::note('Việc đặt mua chưa đồng nghĩa tên miền đã được đăng ký thành công. Nếu tên miền không còn khả dụng, số tiền đã thanh toán sẽ được hoàn lại vào tài khoản.')
|
||||
. T::button('{{order_url}}', 'XEM ĐƠN HÀNG')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'domain_order_approved',
|
||||
'name' => 'Tên miền được duyệt',
|
||||
'subject' => 'Tên miền {{domain_name}} đã được duyệt đăng ký',
|
||||
'body' => T::title('Tên miền đã được duyệt')
|
||||
. T::greeting('{{client_name}}')
|
||||
. T::paragraph('Đơn đăng ký tên miền của Quý khách đã được <strong style="color: #16a34a;">duyệt và kích hoạt thành công</strong>.')
|
||||
. T::infoTable([
|
||||
'Tên miền' => '{{domain_name}}',
|
||||
'Mã đơn hàng' => '{{order_num}}',
|
||||
])
|
||||
. T::paragraph('Tên miền hiện đã hoạt động.')
|
||||
. T::supportLine()
|
||||
. T::autoNotice(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'domain_order_rejected',
|
||||
'name' => 'Tên miền bị từ chối',
|
||||
'subject' => 'Tên miền {{domain_name}} đã bị từ chối đăng ký',
|
||||
'body' => T::title('Tên miền bị từ chối đăng ký')
|
||||
. T::greeting('{{client_name}}')
|
||||
. T::paragraph('Rất tiếc, đơn đăng ký tên miền của Quý khách đã bị <strong style="color: #dc2626;">từ chối</strong>.')
|
||||
. T::infoTable([
|
||||
'Tên miền' => '{{domain_name}}',
|
||||
'Mã đơn hàng' => '{{order_num}}',
|
||||
'Lý do' => '{{reason}}',
|
||||
])
|
||||
. T::paragraph('Số tiền đã thanh toán sẽ được hoàn lại vào tài khoản của Quý khách.')
|
||||
. T::supportLine()
|
||||
. T::autoNotice(),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\EmailTemplates;
|
||||
|
||||
use App\Support\EmailTemplateShell as T;
|
||||
|
||||
final class ServiceTemplates
|
||||
{
|
||||
private const ACTIVE = '<span style="color: #16a34a;">Đang hoạt động</span>';
|
||||
|
||||
/**
|
||||
* @return array<int, array{scenario: string, name: string, subject: string, body: string}>
|
||||
*/
|
||||
public static function all(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'scenario' => 'vm_credentials',
|
||||
'name' => 'Khởi tạo VPS (thông tin truy cập)',
|
||||
'subject' => 'VPS của bạn đã sẵn sàng — {{product_name}}',
|
||||
'body' => T::title('Cloud VPS đã sẵn sàng')
|
||||
. T::greeting('{{full_name}}')
|
||||
. T::paragraph('Cảm ơn Quý khách đã tin tưởng sử dụng dịch vụ của <strong>{{app_name}}</strong>. Cloud VPS <strong>{{product_name}}</strong> đã được khởi tạo thành công.')
|
||||
. T::heading('Thông tin dịch vụ')
|
||||
. T::infoTable(['Dịch vụ' => '{{product_name}}'], '{{product_billing_row}}{{product_price_row}}{{os_name_row}}{{service_due_exp_row}}')
|
||||
. T::heading('Thông tin truy cập')
|
||||
. T::infoTable([
|
||||
'IP / Host' => '{{service_host}}',
|
||||
'Tài khoản' => '{{service_username}}',
|
||||
'Mật khẩu' => '{{service_password}}',
|
||||
], '{{service_port_row}}')
|
||||
. T::button('{{login_url}}', 'QUẢN LÝ DỊCH VỤ')
|
||||
. T::note('Vui lòng đổi mật khẩu ngay sau lần đăng nhập đầu tiên và không chia sẻ thông tin truy cập cho người khác.')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'hosting_information',
|
||||
'name' => 'Thông tin truy cập Hosting',
|
||||
'subject' => 'Thông tin truy cập {{product_name}}',
|
||||
'body' => T::title('Thông tin truy cập Hosting')
|
||||
. T::greeting('{{client_name}}')
|
||||
. T::paragraph('Cảm ơn Quý khách đã tin tưởng sử dụng dịch vụ của <strong>{{company_name}}</strong>. Hosting của Quý khách đã được khởi tạo thành công.')
|
||||
. T::heading('Thông tin gói dịch vụ')
|
||||
. T::infoTable([
|
||||
'Gói dịch vụ' => '{{product_name}}',
|
||||
'Chu kỳ thanh toán' => '{{product_billing}}',
|
||||
'Giá' => '{{product_price}} VNĐ',
|
||||
'Ngày hết hạn' => '{{service_due_exp}}',
|
||||
])
|
||||
. T::heading('Thông tin truy cập Hosting')
|
||||
. T::infoTable([
|
||||
'IP / Host' => '{{service_host}}',
|
||||
'Tài khoản' => '{{service_username}}',
|
||||
'Mật khẩu' => '{{service_password}}',
|
||||
])
|
||||
. T::heading('Thông tin truy cập FTP')
|
||||
. T::infoTable([
|
||||
'FTP Host' => '{{service_host}}',
|
||||
'Tài khoản FTP' => '{{ftp_account}}',
|
||||
'Mật khẩu FTP' => '{{ftp_password}}',
|
||||
])
|
||||
. T::button('{{login_url}}', 'QUẢN LÝ DỊCH VỤ')
|
||||
. T::note('Vui lòng lưu thông tin truy cập ở nơi an toàn và không chia sẻ cho người khác.')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'hosting_account_created',
|
||||
'name' => 'Hosting đã khởi tạo',
|
||||
'subject' => 'Hosting của bạn đã sẵn sàng — {{domain_name}}',
|
||||
'body' => T::title('Hosting đã sẵn sàng')
|
||||
. T::greeting('{{full_name}}')
|
||||
. T::paragraph('Gói hosting cho tên miền <strong>{{domain_name}}</strong> tại <strong>{{app_name}}</strong> đã được khởi tạo thành công. Dưới đây là thông tin truy cập:')
|
||||
. T::infoTable([
|
||||
'Tên miền' => '{{domain_name}}',
|
||||
'Gói hosting' => '{{hosting_plan}}',
|
||||
], '{{server_host_row}}{{ftp_username_row}}{{ftp_password_row}}' . T::row('Trạng thái', self::ACTIVE))
|
||||
. '{{ftp_password_notice}}'
|
||||
. '{{plesk_block}}'
|
||||
. T::button('{{login_url}}', 'ĐĂNG NHẬP NGAY')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'vm_suspended',
|
||||
'name' => 'VPS bị tạm ngưng',
|
||||
'subject' => '[Thế Giới Số] Dịch vụ Cloud VPS của bạn đã bị tạm ngưng',
|
||||
'body' => T::title('Dịch vụ Cloud VPS đã bị tạm ngưng')
|
||||
. T::greeting('{{customer_name}}')
|
||||
. T::paragraph('Dịch vụ Cloud VPS của Quý khách hiện đã bị <strong>tạm ngưng (Suspend)</strong> do chưa thanh toán gia hạn. Vui lòng thanh toán sớm để dịch vụ được kích hoạt lại.')
|
||||
. T::infoTable([
|
||||
'Tên dịch vụ' => '{{vm_name}}',
|
||||
'VM ID' => '{{vmware_id}}',
|
||||
'Thời gian tạm ngưng' => '{{suspended_at}}',
|
||||
])
|
||||
. T::note('Sau <strong>30 ngày</strong> kể từ ngày tạm ngưng, nếu không thanh toán, dịch vụ sẽ bị <strong>xoá vĩnh viễn</strong> và dữ liệu không thể khôi phục.', 'Quan trọng:')
|
||||
. T::button('{{login_url}}', 'THANH TOÁN NGAY')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'service_expiry',
|
||||
'name' => 'Dịch vụ sắp hết hạn',
|
||||
'subject' => 'Thông báo dịch vụ {{product_name}} sắp hết hạn',
|
||||
'body' => T::title('Dịch vụ sắp hết hạn')
|
||||
. T::greeting('Quý khách')
|
||||
. T::paragraph('<strong>{{company_name}}</strong> xin thông báo dịch vụ của Quý khách sắp hết hạn sử dụng:')
|
||||
. T::infoTable([
|
||||
'Dịch vụ' => '{{product_name}}',
|
||||
'Ngày hết hạn' => '<span style="color: #dc2626;">{{service_due_exp}}</span>',
|
||||
'Thời hạn' => 'Còn {{service_remaining}} ngày',
|
||||
])
|
||||
. T::paragraph('Vui lòng gia hạn trước ngày hết hạn để dịch vụ không bị gián đoạn.')
|
||||
. T::button('{{login_url}}', 'GIA HẠN NGAY')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'service_renewal_reminder',
|
||||
'name' => 'Nhắc gia hạn dịch vụ',
|
||||
'subject' => 'Nhắc gia hạn dịch vụ {{product_name}}',
|
||||
'body' => T::title('Nhắc gia hạn dịch vụ')
|
||||
. T::greeting('{{client_name}}')
|
||||
. T::paragraph('Dịch vụ <strong>{{product_name}}</strong>{{server_name_suffix}} của Quý khách sắp đến hạn thanh toán. Vui lòng gia hạn sớm để tránh gián đoạn dịch vụ.')
|
||||
. T::infoTable([
|
||||
'Dịch vụ' => '{{product_name}}',
|
||||
'Ngày hết hạn' => '<span style="color: #dc2626;">{{expires_at}}</span>',
|
||||
], '{{price_row}}')
|
||||
. T::button('{{login_url}}', 'GIA HẠN NGAY')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'vm_creation_failed',
|
||||
'name' => 'Khởi tạo VPS thất bại',
|
||||
'subject' => 'Thông báo: Không thể khởi tạo máy chủ ảo - Đơn hàng #{{order_num}}',
|
||||
'body' => T::title('Thông báo về đơn hàng #{{order_num}}')
|
||||
. T::subtitle('Đội ngũ kỹ thuật đang xử lý yêu cầu của Quý khách')
|
||||
. T::greeting('{{full_name}}')
|
||||
. T::paragraph('Hệ thống chưa khởi tạo được dịch vụ cho đơn hàng của Quý khách. Đội ngũ kỹ thuật của <strong>{{app_name}}</strong> đã được thông báo và đang hỗ trợ nhanh nhất có thể.')
|
||||
. T::infoTable([
|
||||
'Mã đơn hàng' => '#{{order_num}}',
|
||||
'Sản phẩm' => '{{product_name}}',
|
||||
])
|
||||
. T::paragraph('Quý khách không cần thực hiện thêm thao tác nào. Chúng tôi sẽ liên hệ lại khi dịch vụ được kích hoạt thành công.')
|
||||
. T::button('{{invoice_url}}', 'XEM ĐƠN HÀNG')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'vm_rebuild_failed',
|
||||
'name' => 'Rebuild VPS thất bại',
|
||||
'subject' => 'Thông báo: Cài lại hệ điều hành thất bại - {{vm_name}}',
|
||||
'body' => T::title('Cài lại hệ điều hành chưa thành công')
|
||||
. T::subtitle('Đội ngũ kỹ thuật đang xử lý yêu cầu của Quý khách')
|
||||
. T::greeting('{{full_name}}')
|
||||
. T::paragraph('Rất tiếc, yêu cầu cài lại hệ điều hành (rebuild) cho VPS của Quý khách chưa thực hiện thành công. Đội ngũ kỹ thuật của <strong>{{app_name}}</strong> đã được thông báo để kiểm tra và xử lý.')
|
||||
. T::infoTable([
|
||||
'Tên VPS' => '{{vm_name}}',
|
||||
'IP' => '{{ip}}',
|
||||
])
|
||||
. T::paragraph('VPS của Quý khách <strong>vẫn hoạt động bình thường</strong> trên cấu hình cũ, không có dữ liệu nào bị ảnh hưởng.')
|
||||
. T::button('{{service_url}}', 'XEM DỊCH VỤ')
|
||||
. T::supportLine(),
|
||||
],
|
||||
[
|
||||
'scenario' => 'vm_password_changed',
|
||||
'name' => 'Đổi mật khẩu VPS',
|
||||
'subject' => 'Mật khẩu VPS của bạn đã được thay đổi — {{app_name}}',
|
||||
'body' => T::title('Mật khẩu VPS đã được thay đổi')
|
||||
. T::greeting('{{full_name}}')
|
||||
. T::paragraph('Mật khẩu đăng nhập máy chủ ảo của Quý khách tại <strong>{{app_name}}</strong> đã được thay đổi thành công.')
|
||||
. T::infoTable(['Máy chủ' => '{{vm_name}}'], '{{new_password_row}}' . T::row('Trạng thái', '<span style="color: #16a34a;">Đổi mật khẩu thành công</span>'))
|
||||
. T::button('{{login_url}}', 'QUẢN LÝ DỊCH VỤ')
|
||||
. T::note('Nếu Quý khách không thực hiện thao tác này, vui lòng liên hệ ngay <strong>support@tgs.com.vn</strong> hoặc <strong>(028) 7309. 7379</strong>.'),
|
||||
],
|
||||
[
|
||||
'scenario' => 'snapshot_action',
|
||||
'name' => 'Thao tác Snapshot VPS',
|
||||
'subject' => '{{action_title}} — {{app_name}}',
|
||||
'body' => T::title('{{action_icon}} {{action_title}}')
|
||||
. T::subtitle('{{action_desc}}')
|
||||
. T::greeting('{{full_name}}')
|
||||
. T::paragraph('Thao tác snapshot máy chủ ảo của Quý khách tại <strong>{{app_name}}</strong> đã hoàn tất.')
|
||||
. T::infoTable([
|
||||
'Máy chủ' => '{{vm_name}}',
|
||||
'Snapshot' => '{{snapshot_name}}',
|
||||
'Thời gian' => '{{action_at}}',
|
||||
'Trạng thái' => '<span style="color: #16a34a;">{{action_status}}</span>',
|
||||
])
|
||||
. T::button('{{login_url}}', 'QUẢN LÝ DỊCH VỤ')
|
||||
. T::supportLine(),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders\EmailTemplates;
|
||||
|
||||
final class TemplateVariables
|
||||
{
|
||||
/**
|
||||
* @var array<string, array{0: string, 1: string, 2: string}> key => [label, type, example]
|
||||
*/
|
||||
public const DEFINITIONS = [
|
||||
'app_name' => ['Tên công ty', 'string', 'Thế Giới Số'],
|
||||
'company_name' => ['Tên công ty', 'string', 'Thế Giới Số'],
|
||||
'login_url' => ['Link đăng nhập', 'url', 'https://tgs.com.vn/dang-nhap'],
|
||||
|
||||
'full_name' => ['Tên khách hàng', 'string', 'Nguyễn Văn A'],
|
||||
'client_name' => ['Tên khách hàng', 'string', 'Nguyễn Văn A'],
|
||||
'customer_name' => ['Tên khách hàng', 'string', 'Nguyễn Văn A'],
|
||||
'customer_email' => ['Email khách hàng', 'string', 'khachhang@example.com'],
|
||||
'customer_phone' => ['Số điện thoại khách hàng', 'string', '0901 234 567'],
|
||||
'email' => ['Email đăng nhập', 'string', 'khachhang@example.com'],
|
||||
|
||||
'verify_code' => ['Mã xác thực', 'string', '482913'],
|
||||
'reset_url' => ['Link đặt lại mật khẩu', 'url', 'https://tgs.com.vn/dat-lai-mat-khau?token=abc'],
|
||||
'expire_minutes' => ['Số phút hiệu lực', 'string', '60'],
|
||||
'password' => ['Mật khẩu mới', 'string', 'Xk9#pL2m'],
|
||||
|
||||
'product_name' => ['Tên dịch vụ', 'string', 'Cloud VPS Pro'],
|
||||
'product_billing' => ['Chu kỳ thanh toán', 'string', '12 tháng'],
|
||||
'product_price' => ['Giá dịch vụ', 'string', '1.200.000'],
|
||||
'product_billing_row' => ['[Tự động] Dòng chu kỳ thanh toán', 'html', ''],
|
||||
'product_price_row' => ['[Tự động] Dòng giá dịch vụ', 'html', ''],
|
||||
'os_name_row' => ['[Tự động] Dòng hệ điều hành', 'html', ''],
|
||||
'service_host' => ['Địa chỉ IP / Host', 'string', '103.0.0.10'],
|
||||
'service_username' => ['Tài khoản đăng nhập', 'string', 'root'],
|
||||
'service_password' => ['Mật khẩu dịch vụ', 'string', 'Xk9#pL2m'],
|
||||
'service_port_row' => ['[Tự động] Dòng cổng kết nối', 'html', ''],
|
||||
'service_due_exp_row' => ['[Tự động] Dòng hạn sử dụng', 'html', ''],
|
||||
'service_due_exp' => ['Ngày hết hạn', 'string', '31/12/2026'],
|
||||
'service_remaining' => ['Số ngày còn lại', 'string', '7'],
|
||||
'ftp_account' => ['Tài khoản FTP', 'string', 'ftp_example'],
|
||||
'ftp_password' => ['Mật khẩu FTP', 'string', 'Ftp#2026'],
|
||||
'vm_name' => ['Tên VPS', 'string', 'VPS-Pro-01'],
|
||||
'vmware_id' => ['VM ID', 'string', 'vm-1024'],
|
||||
'suspended_at' => ['Thời gian tạm ngưng', 'string', '08/10/2026 09:00'],
|
||||
'server_name_suffix' => ['[Tự động] Tên máy chủ kèm theo', 'html', ''],
|
||||
'expires_at' => ['Ngày hết hạn', 'string', '31/12/2026'],
|
||||
'price_row' => ['[Tự động] Dòng số tiền gia hạn', 'html', ''],
|
||||
'invoice_url' => ['Link đơn hàng', 'url', 'https://tgs.com.vn/don-hang'],
|
||||
'ip' => ['Địa chỉ IP', 'string', '103.0.0.10'],
|
||||
'service_url' => ['Link dịch vụ', 'url', 'https://tgs.com.vn/dich-vu'],
|
||||
'new_password_row' => ['[Tự động] Dòng mật khẩu mới', 'html', ''],
|
||||
'snapshot_name' => ['Tên snapshot', 'string', 'backup-2026-10-08'],
|
||||
'action_at' => ['Thời gian thực hiện', 'string', '08/10/2026 09:00:00'],
|
||||
'action_icon' => ['Biểu tượng thao tác', 'string', '📸'],
|
||||
'action_title' => ['Tiêu đề thao tác', 'string', 'Tạo snapshot thành công'],
|
||||
'action_desc' => ['Mô tả thao tác', 'string', 'Snapshot máy chủ ảo đã được tạo'],
|
||||
'action_status' => ['Trạng thái thao tác', 'string', 'Thành công'],
|
||||
|
||||
'domain_name' => ['Tên miền', 'string', 'example.vn'],
|
||||
'hosting_plan' => ['Gói hosting', 'string', 'Premium Hosting 1'],
|
||||
'server_host_row' => ['[Tự động] Dòng máy chủ / FTP host', 'html', ''],
|
||||
'ftp_username_row' => ['[Tự động] Dòng tài khoản FTP', 'html', ''],
|
||||
'ftp_password_row' => ['[Tự động] Dòng mật khẩu FTP', 'html', ''],
|
||||
'ftp_password_notice' => ['[Tự động] Lưu ý mật khẩu FTP', 'html', ''],
|
||||
'plesk_block' => ['[Tự động] Khối tài khoản Plesk', 'html', ''],
|
||||
'server_name' => ['Tên máy chủ', 'string', 'plesk-01'],
|
||||
'server_ip' => ['IP máy chủ', 'string', '103.0.0.20'],
|
||||
'plesk_client_id' => ['Plesk Client ID', 'string', '15'],
|
||||
'plesk_subscription_id' => ['Plesk Subscription ID', 'string', '42'],
|
||||
'ftp_username' => ['Tài khoản FTP', 'string', 'ftp_example'],
|
||||
'plesk_panel_url' => ['Địa chỉ Plesk Panel', 'string', 'https://103.0.0.20:8443'],
|
||||
'plesk_login' => ['Tài khoản Plesk', 'string', 'example_vn'],
|
||||
'plesk_password_row' => ['[Tự động] Dòng mật khẩu Plesk', 'html', ''],
|
||||
'created_at' => ['Thời gian tạo', 'string', '08/10/2026 09:00:00'],
|
||||
|
||||
'title' => ['Tiêu đề thông báo', 'string', 'Thông báo hóa đơn'],
|
||||
'body_message' => ['Lời nhắn', 'string', 'Vui lòng xem thông tin hóa đơn của bạn.'],
|
||||
'invoice_number' => ['Số hoá đơn', 'string', 'INV-2026-0001'],
|
||||
'created_date' => ['Ngày lập', 'string', '01/10/2026'],
|
||||
'due_date' => ['Hạn thanh toán', 'string', '15/10/2026'],
|
||||
'total' => ['Tổng tiền', 'string', '1.200.000'],
|
||||
'status_label' => ['[Tự động] Trạng thái hoá đơn', 'html', ''],
|
||||
'outstanding_row' => ['[Tự động] Dòng đã trả / còn thiếu', 'html', ''],
|
||||
'intro_note' => ['Ghi chú đính kèm', 'string', 'File PDF hóa đơn đã được đính kèm trong email này.'],
|
||||
'pay_button' => ['[Tự động] Nút thanh toán', 'html', ''],
|
||||
'attachments_block' => ['[Tự động] Danh sách file đính kèm', 'html', ''],
|
||||
'note_block' => ['[Tự động] Ghi chú hoá đơn', 'html', ''],
|
||||
'outstanding' => ['Số tiền còn phải trả', 'string', '1.200.000'],
|
||||
'status_line' => ['Tình trạng hạn thanh toán', 'string', 'Hoá đơn sẽ đến hạn sau 3 ngày.'],
|
||||
'paid_row' => ['[Tự động] Dòng đã thanh toán', 'html', ''],
|
||||
'transaction_code' => ['Mã giao dịch', 'string', 'NAP20261008001'],
|
||||
'amount_formatted' => ['Số tiền', 'string', '500,000'],
|
||||
'credit_formatted' => ['Tiền khuyến mãi', 'string', '0'],
|
||||
'current_total_formatted' => ['Số dư hiện tại', 'string', '1,500,000'],
|
||||
'current_credit_formatted' => ['Số dư khuyến mãi hiện tại', 'string', '0'],
|
||||
'deposit_date' => ['Thời gian nạp', 'string', '08/10/2026 09:00:00'],
|
||||
'status_color' => ['Màu chữ trạng thái', 'string', '#16a34a'],
|
||||
'status_bg' => ['Màu nền trạng thái', 'string', '#dcfce7'],
|
||||
'status_message' => ['Nội dung trạng thái', 'string', 'Yêu cầu nạp tiền của bạn đã được duyệt.'],
|
||||
'processed_date_row' => ['[Tự động] Dòng thời gian xử lý', 'html', ''],
|
||||
'portal_url' => ['Link trang nạp tiền', 'url', 'https://tgs.com.vn/nap-tien'],
|
||||
|
||||
'order_num' => ['Mã đơn hàng', 'string', 'DH20261008001'],
|
||||
'invoice_num' => ['Mã hoá đơn', 'string', 'INV-2026-0001'],
|
||||
'order_total' => ['Tổng tiền đơn hàng', 'string', '1.200.000'],
|
||||
'order_url' => ['Link đơn hàng', 'url', 'https://tgs.com.vn/don-hang'],
|
||||
'reason' => ['Lý do', 'string', 'Tên miền đã có người đăng ký'],
|
||||
'admin_url' => ['Link quản trị', 'url', 'https://admin.tgs.com.vn'],
|
||||
'client_ip_row' => ['[Tự động] Dòng IP khách', 'html', ''],
|
||||
'product_type' => ['Loại sản phẩm', 'string', 'Cloud VPS'],
|
||||
'billing_cycle' => ['Chu kỳ thanh toán', 'string', '12 tháng'],
|
||||
'total_formatted' => ['Tổng tiền', 'string', '1.200.000 VNĐ'],
|
||||
'vm_block' => ['[Tự động] Khối thông tin VPS', 'html', ''],
|
||||
|
||||
'ticket_num' => ['Mã ticket', 'string', 'TK1024'],
|
||||
'subject' => ['Tiêu đề ticket', 'string', 'Không truy cập được VPS'],
|
||||
'room_row' => ['[Tự động] Dòng phòng ban', 'html', ''],
|
||||
'ticket_url' => ['Link ticket', 'url', 'https://tgs.com.vn/tickets/TK1024'],
|
||||
'subject_text' => ['Tiêu đề ticket', 'string', 'Không truy cập được VPS'],
|
||||
'room' => ['Phòng ban', 'string', 'Kỹ thuật'],
|
||||
'description' => ['Nội dung ticket', 'string', 'VPS không SSH được từ sáng nay.'],
|
||||
|
||||
'customer_phone_row' => ['[Tự động] Dòng số điện thoại', 'html', ''],
|
||||
'proof_row' => ['[Tự động] Dòng chứng từ', 'html', ''],
|
||||
'cpu' => ['CPU', 'string', '2 vCPU'],
|
||||
'ram' => ['RAM', 'string', '4 GB'],
|
||||
'ssd' => ['SSD', 'string', '60 GB'],
|
||||
'os' => ['Hệ điều hành', 'string', 'Ubuntu 24.04'],
|
||||
'other_row' => ['[Tự động] Dòng yêu cầu khác', 'html', ''],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use RuntimeException;
|
||||
|
||||
class LegacyProductCatalogSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$catalog = [
|
||||
'vps' => [
|
||||
'category' => ['name' => 'VPS', 'slug' => 'vps', 'type' => 'vps', 'sort_order' => 10],
|
||||
'product_type' => 'vps',
|
||||
'ids' => [1, 2, 3, 4, 22, 23, 24, 25, 26, 28, 34, 35, 36, 37, 38, 71, 82, 84, 85, 86, 87, 88, 89, 90],
|
||||
],
|
||||
'hosting' => [
|
||||
'category' => ['name' => 'Hosting', 'slug' => 'hosting', 'type' => 'hosting', 'sort_order' => 20],
|
||||
'product_type' => 'hosting',
|
||||
'ids' => [5, 6, 7, 17, 18, 19, 20, 46, 47, 72, 73, 74, 75, 77, 83],
|
||||
],
|
||||
'cloud-storage' => [
|
||||
'category' => ['name' => 'Cloud Storage', 'slug' => 'cloud-storage', 'type' => 'cloud', 'sort_order' => 30],
|
||||
'product_type' => 'cloud',
|
||||
'ids' => [39, 40, 41, 42, 43, 57, 58, 59, 78],
|
||||
],
|
||||
'email' => [
|
||||
'category' => ['name' => 'Email', 'slug' => 'email', 'type' => 'email', 'sort_order' => 40],
|
||||
'product_type' => 'email',
|
||||
'ids' => [16, 52, 53, 54, 55, 56, 67, 68, 69, 70, 94, 95, 96, 97],
|
||||
],
|
||||
'hardware' => [
|
||||
'category' => ['name' => 'Hardware', 'slug' => 'hardware', 'type' => 'hardware', 'sort_order' => 50],
|
||||
'product_type' => 'hardware',
|
||||
'ids' => [62, 63, 64, 76, 79, 81],
|
||||
],
|
||||
'web-design' => [
|
||||
'category' => ['name' => 'Thiết kế website', 'slug' => 'thiet-ke-website', 'type' => 'web_design', 'sort_order' => 60],
|
||||
'product_type' => 'web_design',
|
||||
'ids' => [14],
|
||||
],
|
||||
'it-support' => [
|
||||
'category' => ['name' => 'IT Support', 'slug' => 'it-support', 'type' => 'it_support', 'sort_order' => 70],
|
||||
'product_type' => 'it_support',
|
||||
'ids' => [66],
|
||||
],
|
||||
'other' => [
|
||||
'category' => ['name' => 'Other', 'slug' => 'other', 'type' => null, 'sort_order' => 80],
|
||||
'product_type' => 'other',
|
||||
'ids' => [8, 9, 10, 11, 12, 13, 15, 21, 27, 29, 30, 31, 32, 33, 44, 45, 48, 49, 50, 51, 60, 61, 65, 80, 91, 92, 93, 98, 99, 100, 101, 102],
|
||||
],
|
||||
];
|
||||
|
||||
$allIds = collect($catalog)->pluck('ids')->flatten()->map(fn ($id) => (int) $id);
|
||||
|
||||
if ($allIds->count() !== 102 || $allIds->unique()->count() !== 102) {
|
||||
throw new RuntimeException('Product catalog mapping must contain exactly 102 unique product IDs.');
|
||||
}
|
||||
|
||||
$missing = $allIds->diff(DB::table('products')->whereIn('id', $allIds)->pluck('id'));
|
||||
if ($missing->isNotEmpty()) {
|
||||
throw new RuntimeException('Missing products: ' . $missing->implode(', '));
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($catalog): void {
|
||||
foreach ($catalog as $definition) {
|
||||
$category = $definition['category'];
|
||||
DB::table('product_categories')->updateOrInsert(
|
||||
['slug' => $category['slug']],
|
||||
$category + [
|
||||
'parent_id' => null,
|
||||
'is_active' => true,
|
||||
'deleted_at' => null,
|
||||
'updated_at' => now(),
|
||||
'created_at' => now(),
|
||||
],
|
||||
);
|
||||
|
||||
$categoryId = DB::table('product_categories')
|
||||
->where('slug', $category['slug'])
|
||||
->value('id');
|
||||
|
||||
DB::table('products')
|
||||
->whereIn('id', $definition['ids'])
|
||||
->update([
|
||||
'product_categories_id' => $categoryId,
|
||||
'product_type' => $definition['product_type'],
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
$this->command?->info('Categorized all 102 legacy products.');
|
||||
}
|
||||
}
|
||||
@@ -3,275 +3,96 @@
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Template;
|
||||
use App\Support\EmailTemplateShell;
|
||||
use App\Support\MailPlaceholders;
|
||||
use Database\Seeders\EmailTemplates\AccountTemplates;
|
||||
use Database\Seeders\EmailTemplates\AdminTemplates;
|
||||
use Database\Seeders\EmailTemplates\BillingTemplates;
|
||||
use Database\Seeders\EmailTemplates\ServiceTemplates;
|
||||
use Database\Seeders\EmailTemplates\TemplateVariables;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class TemplateSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
public function run(): void
|
||||
{
|
||||
$Templates = [
|
||||
[
|
||||
'name' => 'Client Signup Verify Email',
|
||||
'subject' => 'Thông tin kích hoạt tài khoản khách hàng',
|
||||
'message' =>
|
||||
'<table cellpadding=0 cellspacing=0 role=presentation style=width:600px><tr><td align=center><table cellpadding=0 cellspacing=0 role=presentation style=width:100%><tr><td style=border-radius:4px;background-color:#fff;padding:48px;text-align:left;font-family:Montserrat,-apple-system,sans-serif;font-size:16px;line-height:24px;color:#626262><p style=margin-bottom:10px;font-size:20px;font-weight:600>Kính chào Quý khách<p>Cảm ơn bạn đã đăng ký tài khoản tại {$company_name}! Để hoàn tất quá trình đăng ký, vui lòng truy cập đường dẫn dưới đây để xác minh tài khoản của bạn.<p style="text-align:center;margin:24px 0"><a href={$link_verify} style="font-family:sans-serif;display:inline-block;font-size:16px;font-weight:600;line-height:100%;color:#fff;text-decoration:none;background-color:#f16723;border-radius:4px;padding:16px 24px">XÁC NHẬN TÀI KHOẢN</a><p>Hoặc bạn có thể copy đường dẫn sau đưa lên trình duyệt để active tài khoản:<p><a href={$link_verify} style=color:#f16723;word-break:break-all>{$link_verify}</a><p>Sau khi xác minh, bạn sẽ có thể sử dụng tài khoản của mình và truy cập các dịch vụ của chúng tôi.<p>Nếu bạn có bất kỳ câu hỏi nào, vui lòng liên hệ với chúng tôi để được hỗ trợ.<p>Lưu ý:<ul style=margin:0;padding-left:30px><li>Đây là tin nhắn tự động. Vui lòng không trả lời tin nhắn này!</ul></table></table>',
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Server information',
|
||||
'subject' => 'Thông tin truy cập VPS {$os_name}',
|
||||
'message' =>
|
||||
'<table cellpadding=0 cellspacing=0 role=presentation style=width:100%><tr><td style=border-radius:4px;background-color:#fff;text-align:left;font-family:Montserrat,-apple-system,sans-serif;font-size:16px;line-height:24px;color:#626262><p style=margin-bottom:10px>Kính gửi Quý khách<p>Cảm ơn Quý khách đã tin tưởng và sử dụng dịch vụ của {$company_name}, Cloud VPS của Quý khách đã được khởi tạo thành công, Quý khách vui lòng sử dụng thông tin sau vào quản lý.<p style=margin-bottom:6px><strong>Thông tin gói VPS:</strong><ul style="margin:0 0 16px;padding-left:20px"><li><strong>{$product_name}</strong><li>Chu kỳ thanh toán: <strong>{$product_billing}</strong><li>Giá: <strong>{$product_price} đ</strong></ul><p style=margin-bottom:6px><strong>Thông tin truy cập VPS:</strong><ul style="margin:0 0 16px;padding-left:20px"><li><strong>IP:</strong> {$service_host}<li><strong>User:</strong> {$service_username}<li><strong>Port:</strong> {$service_port}<li><strong>Password:</strong> {$service_password}<li><strong>Hệ điều hành:</strong> {$os_name}<li><strong>Ngày hết hạn:</strong> {$service_due_exp}</ul><p>Nếu bạn có bất kỳ câu hỏi nào, vui lòng liên hệ với chúng tôi để được hỗ trợ.<p>Trân trọng!</table>',
|
||||
'type_id' => 4,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Hosting Information',
|
||||
'subject' => 'Thông tin truy cập {$product_name}',
|
||||
'message' =>
|
||||
'<table cellpadding=0 cellspacing=0 role=presentation style=width:100%><tr><td style=border-radius:4px;background-color:#fff;text-align:left;font-family:Montserrat,-apple-system,sans-serif;font-size:16px;line-height:24px;color:#626262><p style=margin-bottom:10px>Kính gửi Quý khách<p>Cảm ơn Quý khách đã tin tưởng và sử dụng dịch vụ của {$company_name}, Hosting của Quý khách đã được khởi tạo thành công, Quý khách vui lòng sử dụng thông tin sau vào quản lý.<p style=margin-bottom:6px><strong>Thông tin gói Hosting:</strong><ul style="margin:0 0 16px;padding-left:20px"><li><strong>{$product_name}</strong><li>Chu kỳ thanh toán: <strong>{$product_billing}</strong><li>Giá: <strong>{$product_price} đ</strong></ul><p style=margin-bottom:6px><strong>Thông tin truy cập Hosting:</strong><ul style="margin:0 0 16px;padding-left:20px"><li><strong>IP:</strong> {$service_host}<li><strong>User:</strong> {$service_username}<li><strong>Password:</strong> {$service_password}<li><strong>Ngày hết hạn:</strong> {$service_due_exp}</ul><p style=margin-bottom:6px><strong>Thông tin truy cập FTP Hosting:</strong><ul style="margin:0 0 16px;padding-left:20px"><li><strong>IP:</strong> {$service_host}<li><strong>User:</strong> {$ftp_account}<li><strong>Password:</strong> {$ftp_password}</ul><p>Cảm ơn quý khách đã sử dụng dịch vụ của {$company_name}.<p>Nếu bạn có bất kỳ câu hỏi nào, vui lòng liên hệ với chúng tôi để được hỗ trợ.<p>Trân trọng!</table>',
|
||||
'type_id' => 3,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Customer Password Reset',
|
||||
'subject' => 'Khôi phục mật khẩu | Password Recovery',
|
||||
'message' =>
|
||||
'<table cellpadding=0 cellspacing=0 role=presentation style=width:100%><tr><td style=padding:48px;text-align:center><tr><td style=border-radius:4px;background-color:#fff;text-align:left;font-family:Montserrat,-apple-system,sans-serif;font-size:16px;line-height:24px;color:#626262><p style=margin-bottom:10px>Kính chào Quý khách<p>Mật khẩu của quý khách đã được khôi phục thành công, vui lòng sử dụng mật khẩu sau đây để truy cập vào tài khoản của bạn.<table cellpadding=0 cellspacing=0 role=presentation style=width:100%;max-height:30px;overflow:hidden><tr style=text-align:center><td style=border-radius:4px;background-color:#f16723;text-align:center;font-family:Montserrat,-apple-system,sans-serif;padding-left:48px;padding-right:48px><p style=font-family:sans-serif;display:block;font-size:16px;font-weight:600;line-height:100%;color:#fff;text-decoration:none;padding:10px>{$password}</table><p>Vui lòng thay đổi mật khẩu của quý khách ngay sau khi đăng nhập.<p>Nếu bạn có bất kỳ câu hỏi nào, vui lòng liên hệ với chúng tôi để được hỗ trợ.<p>Lưu ý:<ul style=margin:0;padding-left:30px><li>Đây là tin nhắn tự động. Vui lòng không trả lời tin nhắn này!</ul></table>',
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Order Created',
|
||||
'subject' => 'Xác nhận đơn hàng #{$order_num}',
|
||||
'message' =>
|
||||
'<table cellpadding=0 cellspacing=0 role=presentation style=width:100%><tr><td style=border-radius:4px;background-color:#fff;text-align:left;font-family:Montserrat,-apple-system,sans-serif;font-size:16px;line-height:24px;color:#626262><p style=margin-bottom:10px;font-size:20px;font-weight:600>Kính chào {$client_name},<p>Cảm ơn bạn đã đặt hàng tại <strong>{$company_name}</strong>! Đơn hàng của bạn đã được tiếp nhận thành công.<p style=margin-bottom:6px><strong>Thông tin đơn hàng:</strong><ul style="margin:0 0 16px;padding-left:20px"><li>Mã đơn hàng: <strong>{$order_num}</strong><li>Mã hóa đơn: <strong>{$invoice_num}</strong><li>Tổng tiền: <strong>{$order_total} đ</strong></ul><p>Chúng tôi sẽ xử lý đơn hàng của bạn trong thời gian sớm nhất và thông báo khi dịch vụ được kích hoạt.<p>Nếu bạn có bất kỳ câu hỏi nào, vui lòng liên hệ với chúng tôi để được hỗ trợ.<p>Lưu ý:<ul style=margin:0;padding-left:20px><li>Đây là tin nhắn tự động. Vui lòng không trả lời tin nhắn này!</ul></table>',
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Domain Order New',
|
||||
'subject' => '[ADMIN] Đơn đăng ký tên miền mới - {$domain_name}',
|
||||
'message' =>
|
||||
'<table cellpadding=0 cellspacing=0 role=presentation style=width:100%><tr><td style=border-radius:4px;background-color:#fff;text-align:left;font-family:Montserrat,-apple-system,sans-serif;font-size:16px;line-height:24px;color:#626262><p style=margin-bottom:10px;font-size:20px;font-weight:600>Thông báo đơn đăng ký tên miền mới<p>Có một đơn đăng ký tên miền mới vừa được đặt tại <strong>{$company_name}</strong>.<p style=margin-bottom:6px><strong>Thông tin đơn hàng:</strong><ul style="margin:0 0 16px;padding-left:20px"><li>Tên miền: <strong>{$domain_name}</strong><li>Mã đơn hàng: <strong>{$order_num}</strong><li>Tổng tiền: <strong>{$order_total}</strong><li>Khách hàng: <strong>{$customer_name}</strong><li>Email: <strong>{$customer_email}</strong><li>Thời gian: <strong>{$created_at}</strong></ul><table cellpadding=0 cellspacing=0 role=presentation style="margin:24px 0"><tr><td style=border-radius:4px;background-color:#f16723;text-align:center;font-family:Montserrat,-apple-system,sans-serif;padding-left:48px;padding-right:48px><a href={$admin_url} style="font-family:sans-serif;display:block;font-size:16px;font-weight:600;line-height:100%;color:#fff;text-decoration:none;padding:16px 24px">XEM ĐƠN HÀNG</a></table><p>Lưu ý:<ul style=margin:0;padding-left:20px><li>Đây là tin nhắn tự động. Vui lòng không trả lời tin nhắn này!</ul></table>',
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Domain Order Approved',
|
||||
'subject' => 'Tên miền {$domain_name} đã được duyệt đăng ký',
|
||||
'message' =>
|
||||
'<table cellpadding=0 cellspacing=0 role=presentation style=width:100%;font-family:Montserrat,-apple-system><tr><td style=background-color:#eceff1;font-family:Montserrat,-apple-system,sans-serif align=center><table cellpadding=0 cellspacing=0 role=presentation style=width:600px><tr><td align=center><table cellpadding=0 cellspacing=0 role=presentation style=width:100%><tr><td style=padding:48px;text-align:center> <tr style=background-color:#fff><td style="text-align:center;padding:20px;border-bottom:.5px solid #ececec"><img alt={$company_name} src={$company_logo} style=max-height:100px><tr><td style=border-radius:4px;background-color:#fff;padding:48px;text-align:left;font-family:Montserrat,-apple-system,sans-serif;font-size:16px;line-height:24px;color:#626262><p style=margin-bottom:10px;font-size:20px;font-weight:600>Kính chào {$client_name},<p>Chúng tôi xin thông báo rằng đơn đăng ký tên miền của bạn đã được <strong style=color:#22c55e>duyệt và kích hoạt thành công</strong>.<p><strong>Thông tin tên miền:</strong><ul><li>Tên miền: <strong>{$domain_name}</strong><li>Mã đơn hàng: <strong>{$order_num}</strong></ul><p>Tên miền của bạn hiện đã hoạt động. Nếu bạn có bất kỳ câu hỏi nào, vui lòng liên hệ với chúng tôi để được hỗ trợ.<p>Lưu ý:<ul><li>Đây là tin nhắn tự động. Vui lòng không trả lời tin nhắn này!</ul><p> </table><tr><td style=padding:48px;text-align:center> </table></table>',
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Domain Order Rejected',
|
||||
'subject' => 'Tên miền {$domain_name} đã bị từ chối đăng ký',
|
||||
'message' =>
|
||||
'<table cellpadding=0 cellspacing=0 role=presentation style=width:100%;font-family:Montserrat,-apple-system><tr><td style=background-color:#eceff1;font-family:Montserrat,-apple-system,sans-serif align=center><table cellpadding=0 cellspacing=0 role=presentation style=width:600px><tr><td align=center><table cellpadding=0 cellspacing=0 role=presentation style=width:100%><tr><td style=padding:48px;text-align:center> <tr style=background-color:#fff><td style="text-align:center;padding:20px;border-bottom:.5px solid #ececec"><img alt={$company_name} src={$company_logo} style=max-height:100px><tr><td style=border-radius:4px;background-color:#fff;padding:48px;text-align:left;font-family:Montserrat,-apple-system,sans-serif;font-size:16px;line-height:24px;color:#626262><p style=margin-bottom:10px;font-size:20px;font-weight:600>Kính chào {$client_name},<p>Chúng tôi xin thông báo rằng đơn đăng ký tên miền của bạn đã bị <strong style=color:#ef4444>từ chối</strong>.<p><strong>Thông tin đơn hàng:</strong><ul><li>Tên miền: <strong>{$domain_name}</strong><li>Mã đơn hàng: <strong>{$order_num}</strong><li>Lý do từ chối: <strong>{$reason}</strong></ul><p>Số dư đã thanh toán sẽ được hoàn lại vào tài khoản của bạn. Nếu bạn có bất kỳ câu hỏi nào, vui lòng liên hệ với chúng tôi để được hỗ trợ.<p>Lưu ý:<ul><li>Đây là tin nhắn tự động. Vui lòng không trả lời tin nhắn này!</ul><p> </table><tr><td style=padding:48px;text-align:center> </table></table>',
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Service Expiry',
|
||||
'subject' => 'Thông báo dịch vụ sắp hết hạn',
|
||||
'message' =>
|
||||
'<table cellpadding=0 cellspacing=0 role=presentation style=width:100%;font-family:Montserrat,-apple-system><tr><td style=background-color:#eceff1;font-family:Montserrat,-apple-system,sans-serif align=center><table cellpadding=0 cellspacing=0 role=presentation style=width:600px><tr><td align=center><table cellpadding=0 cellspacing=0 role=presentation style=width:100%><tr><td style=padding:48px;text-align:center> <tr style=background-color:#fff><td style="text-align:center;padding:20px;border-bottom:.5px solid #ececec"><img alt={$company_name} class="CToWUd a6T"data-bit=iit src={$company_logo} style=max-height:100px tabindex=0><tr><td style=border-radius:4px;background-color:#fff;padding:48px;text-align:left;font-family:Montserrat,-apple-system,sans-serif;font-size:16px;line-height:24px;color:#626262><p style=margin-bottom:10px>Kính gửi Quý khách<p>{$company_name} xin gửi Quý khách danh sách các dịch vụ sắp hết hạn, cụ thể như sau:<p><strong>Thông tin gói dịch vụ:</strong><ul><li><strong>{$product_name}</strong><li>Ngày hết hạn: <strong>{$service_due_exp}</strong><li>Thời hạn: Còn <strong>{$service_remaining} </strong>ngày</ul><p>Vui lòng gia hạn dịch vụ trước thời hạn để không ảnh hưởng dịch vụ.<p>Nếu bạn có bất kỳ câu hỏi nào, vui lòng liên hệ với chúng tôi để được hỗ trợ.<p>Trân trọng.</table><tr><td style=padding:48px;text-align:center> </table></table>',
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
];
|
||||
|
||||
// Header/Footer dùng chung cho các template mới (style "700px card")
|
||||
$header = <<<'HTML'
|
||||
<table style="border-collapse: collapse; width: 100%; background-color: #efefef;" border="0" cellspacing="0" cellpadding="0"><tbody><tr><td style="padding: 20px;" align="center" valign="top"><table style="padding-top: 20px; padding-bottom: 20px; border-collapse: collapse; background-color: #ffffff; width: 700px;" border="0" cellspacing="0" cellpadding="0"><tbody><tr class="Header"><td style="width: 700px;" valign="top"><table align="center" width="700" bgcolor="#ffffff" style="border-collapse: collapse; width: 700px; max-width: 100%; text-align: center; background-color: #ffffff; border-top: 5px solid #f16723;" border="0" cellspacing="0" cellpadding="0"><tbody><tr><td style="padding: 0;"><a href="https://tgs.com.vn" style="display: block;" target="_blank" rel="noopener"><img src="https://res.cloudinary.com/izpast9i/image/upload/v1786499308/email_header.png" alt="Thư gửi từ Công Ty Cổ Phần Giải Pháp Công Nghệ Thế Giới Số" style="width: 100%; display: block; border: none;" width="700"></a></td></tr></tbody></table></td></tr>
|
||||
HTML;
|
||||
|
||||
$footer = <<<'HTML'
|
||||
<tr class="Footer"><td align="center" valign="top"><table border="0" cellpadding="0" cellspacing="0" width="700" align="center" background="https://res.cloudinary.com/izpast9i/image/upload/v1786500298/email_footer.png" bgcolor="#F16723" style="border-collapse: collapse; width: 700px; background-image: url("https://res.cloudinary.com/izpast9i/image/upload/v1786500298/email_footer.png"); background-size: cover; background-position: center; background-repeat: no-repeat;"><tbody><tr><td style="padding: 40px 30px 20px 30px; text-align: center;"><strong style="font-size: 14px; line-height: 22px; color: #ffffff;">CÔNG TY CỔ PHẦN GIẢI PHÁP CÔNG NGHỆ THẾ GIỚI SỐ</strong></td></tr><tr><td style="padding: 6px 30px 0 30px; text-align: center;"><span style="font-size: 12px; line-height: 18px; color: #ffffff;">Địa chỉ: 128/38 Tân Hương, Phường Phú Thọ Hòa, Thành Phố Hồ Chí Minh</span></td></tr><tr><td style="padding: 6px 30px 16px 30px; text-align: center;"><span style="font-size: 12px; line-height: 18px; color: #ffffff;">Tel: {$support_phone} - Email: <a href="mailto:{$support_email}" style="color: #ffffff; text-decoration: none;">{$support_email}</a></span></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table>
|
||||
HTML;
|
||||
|
||||
// Header/Footer dùng chung cho các template dạng banner cam (CacDV/ThongTin)
|
||||
$bannerFooter = <<<'HTML'
|
||||
<tr class="ThongTin"><td align="center" valign="top" bgcolor="#065d88"><table style="border-collapse: collapse; background-color: #f06824; border-top: 0; border-bottom: 0; width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr style="height: 30px;"><td style="height: 30px;" valign="top" height="10"> </td></tr><tr style="height: 148px;"><td style="padding: 0; font-family: Helvetica, Arial, sans-serif; text-decoration: none; color: #e7e7e7; font-size: 16px; font-weight: normal; line-height: 150%; vertical-align: top; text-align: center; height: 148px;" align="center"><p style="margin: 0; padding: 0; font-family: Helvetica, Arial, sans-serif; color: white; font-size: 11pt; line-height: 200%;"><span style="color: #ffffff; font-family: 'times new roman', times, serif;"><strong style="font-size: 20px;">CÔNG TY CỔ PHẦN GIẢI PHÁP CÔNG NGHỆ THẾ GIỚI SỐ</strong></span><br><span style="color: #ffffff; font-family: arial, helvetica, sans-serif; font-size: 12pt;">Địa chỉ: 128/38 Tân Hương, Phường Phú Thọ Hòa, Thành Phố Hồ Chí Minh</span><br><span style="color: #ffffff; font-family: arial, helvetica, sans-serif; font-size: 12pt;">Tel: {$support_phone}</span><br><span style="font-family: arial, helvetica, sans-serif; font-size: 12pt;">Email: <a style="color: #ffffff; text-decoration: none;" href="mailto:{$support_email}">{$support_email}</a></span></p><p style="margin: 0; padding: 0; font-family: Helvetica, Arial, sans-serif; color: white; font-size: 11pt; line-height: 200%;"><strong>🥇Thế Giới Số🥇</strong>- Premium HOSTING • CLOUD • SERVER & WEBSITE | 15+ năm Phụng Sự 🚀</p></td></tr><tr><td style="height: 30px; color: #ffffff;" valign="top" height="30"> </td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table>
|
||||
HTML;
|
||||
|
||||
$bannerHead = <<<'HTML'
|
||||
<table style="border-collapse: collapse; width: 100%; background-color: #efefef;" border="0" cellspacing="0" cellpadding="0"><tbody><tr><td style="padding: 20px;" align="center" valign="top"><table style="padding-top: 20px; padding-bottom: 20px; border-collapse: collapse; background-color: #ffffff; width: 700px;" border="0" cellspacing="0" cellpadding="0"><tbody><tr><td style="width: 700px;" valign="top"><table style="border-collapse: collapse; width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody>
|
||||
HTML;
|
||||
|
||||
$newTemplates = [
|
||||
[
|
||||
'name' => 'VPS bị tạm ngưng',
|
||||
'scenario' => 'vm_suspended',
|
||||
'format' => 'html',
|
||||
'subject' => '[Thế Giới Số] Dịch vụ Cloud VPS của bạn đã bị tạm ngưng',
|
||||
'message' => $header . <<<'HTML'
|
||||
<tr class="NoiDungKM"><td style="width: 700px; padding: 25px; background-color: #ffffff;" valign="top"><p style="font-weight: bold;"><strong>Kính chào <span style="color: #f16723;">{$customer_name},</span></strong></p><p style="text-align: justify;">Dịch vụ Cloud VPS của bạn hiện đã bị <strong>tạm ngưng (Suspend)</strong> do chưa thanh toán gia hạn. Vui lòng nhanh chóng liên hệ hoặc thanh toán để tránh mất dữ liệu.</p><table cellpadding="0" cellspacing="0" border="0" style="width: 100%; table-layout: fixed; border: 1px solid #e8e8e8; border-right: 0;"><tbody><tr><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;">Tên dịch vụ</td><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;"><strong>{$vm_name}</strong></td></tr><tr bgcolor="#FFF1E6"><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;">VM ID</td><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;"><strong>{$vmware_id}</strong></td></tr><tr><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;">Thời gian tạm ngưng</td><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;"><strong>{$suspended_at}</strong></td></tr></tbody></table><p style="background: #fffbeb; border: 1.5px solid #f59e0b; border-radius: 6px; padding: 12px 16px; color: #92400e;">⏰ <strong>Sau 30 ngày kể từ ngày tạm ngưng</strong>, nếu không có thanh toán, dịch vụ sẽ bị <strong>xóa vĩnh viễn</strong> và toàn bộ dữ liệu sẽ không thể khôi phục.</p><table cellspacing="0" cellpadding="0" style="margin: 16px auto 16px auto;"><tbody><tr><td align="center" style="background-color: #f16723; padding: 10px 20px; border-radius: 4px;"><a href="{$login_url}" target="_blank" rel="noopener" style="text-decoration: none;"><strong style="color: #ffffff;">Đăng nhập thanh toán ngay</strong></a></td></tr></tbody></table><p style="text-align: justify; color: #666666; font-size: 13px;">Email này được gửi tự động. Vui lòng không trả lời email này.</p></td></tr>
|
||||
HTML
|
||||
. $footer,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Đơn đăng ký tên miền đã ghi nhận',
|
||||
'scenario' => 'domain_order_received',
|
||||
'format' => 'html',
|
||||
'subject' => 'Đơn đăng ký tên miền {$domain_name} đã được ghi nhận',
|
||||
'message' => $header . <<<'HTML'
|
||||
<tr class="NoiDungKM"><td style="width: 700px; padding: 25px; background-color: #ffffff;" valign="top"><p style="font-weight: bold;"><strong>Kính chào <span style="color: #f16723;">{$customer_name},</span></strong></p><p style="text-align: justify;">Cảm ơn Quý khách đã đặt mua tên miền tại <strong>{$company_name}</strong>. Đơn hàng của Quý khách đang chờ đội ngũ kỹ thuật kiểm tra và đăng ký thủ công.</p><p><strong>Thông tin đơn hàng:</strong></p><ul><li>Tên miền: <strong>{$domain_name}</strong></li><li>Mã đơn hàng: <strong>{$order_num}</strong></li><li>Tổng tiền: <strong>{$order_total}</strong></li><li>Thời gian: <strong>{$created_at}</strong></li></ul><p style="text-align: justify;">Lưu ý: việc đặt mua không đồng nghĩa tên miền đã được đăng ký thành công. Nếu tên miền không còn khả dụng, số dư đã thanh toán sẽ được hoàn lại vào tài khoản.</p><table cellpadding="0" cellspacing="0" role="presentation" style="margin: 16px auto;"><tbody><tr><td style="border-radius: 4px; background-color: #f16723; text-align: center;"><a href="{$order_url}" target="_blank" rel="noopener" style="font-family: sans-serif; display: block; font-size: 16px; font-weight: 600; line-height: 100%; color: #ffffff; text-decoration: none; padding: 16px 24px;">XEM ĐƠN HÀNG CỦA TÔI</a></td></tr></tbody></table><p style="text-align: justify; color: #666666; font-size: 13px;">Email này được gửi tự động. Vui lòng không trả lời email này.</p></td></tr>
|
||||
HTML
|
||||
. $footer,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Hosting đã khởi tạo',
|
||||
'scenario' => 'hosting_account_created',
|
||||
'format' => 'html',
|
||||
'subject' => 'Hosting của bạn đã sẵn sàng — {$domain_name}',
|
||||
'message' => $header . <<<'HTML'
|
||||
<tr class="NoiDungKM"><td style="width: 700px; padding: 25px; background-color: #ffffff;" valign="top"><p style="font-size: 21px; font-weight: bold; text-align: center;"><strong>Hosting của bạn đã sẵn sàng</strong></p><p style="font-weight: bold;"><strong>Kính chào <span style="color: #f16723;">{$full_name},</span></strong></p><p style="text-align: justify;">Gói hosting cho tên miền <strong>{$domain_name}</strong> tại <strong>{$app_name}</strong> đã được khởi tạo thành công. Dưới đây là thông tin truy cập:</p><table cellpadding="0" cellspacing="0" border="0" style="width: 100%; table-layout: fixed; border: 1px solid #e8e8e8; border-right: 0;"><tbody><tr><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8; width: 200px;">Tên miền:</td><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;"><strong>{$domain_name}</strong></td></tr><tr bgcolor="#FFF1E6"><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;">Gói hosting:</td><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;"><strong>{$hosting_plan}</strong></td></tr>{$server_host_row}{$ftp_username_row}{$ftp_password_row}<tr bgcolor="#FFF1E6"><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;">Trạng thái:</td><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;"><strong style="color: #16a34a;">Đang hoạt động ✓</strong></td></tr></tbody></table>{$ftp_password_notice}{$plesk_block}<p style="text-align: justify;">Bạn có thể đăng nhập vào cổng quản lý để theo dõi và quản lý dịch vụ của mình.</p><table cellspacing="0" cellpadding="0" style="margin: 16px auto 16px auto;"><tbody><tr><td align="center" style="background-color: #f16723; padding: 10px 20px; border-radius: 4px;"><a href="{$login_url}" target="_blank" rel="noopener" style="text-decoration: none;"><strong style="color: #ffffff;">Đăng nhập ngay</strong></a></td></tr></tbody></table><p style="text-align: justify; color: #6b7280; font-size: 13px;">Nếu bạn không yêu cầu dịch vụ này, vui lòng liên hệ ngay với chúng tôi qua <strong>{$support_email}</strong> hoặc <strong>{$support_phone}</strong>.</p></td></tr>
|
||||
HTML
|
||||
. $footer,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Trạng thái nạp tiền thủ công',
|
||||
'scenario' => 'manual_deposit_status',
|
||||
'format' => 'html',
|
||||
'subject' => '{$company_name} - Trạng thái nạp tiền',
|
||||
'message' => <<<'HTML'
|
||||
<table cellpadding="0" cellspacing="0" role="presentation" style="width:100%;background-color:#eceff1;font-family:Montserrat,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif"><tr><td align="center" style="padding:48px 12px"><table cellpadding="0" cellspacing="0" role="presentation" style="width:600px;max-width:100%;background-color:#ffffff;border-radius:4px;overflow:hidden"><tr><td style="padding:48px;text-align:left;font-size:16px;line-height:24px;color:#626262"><p style="margin:0 0 10px;font-size:20px;font-weight:600;color:#263238">Kính chào {$customer_name},</p><p style="margin:0 0 18px">{$status_message}</p><table cellpadding="0" cellspacing="0" role="presentation" style="width:100%;margin:22px 0;border:1px solid #ececec;border-radius:4px;overflow:hidden"><tr><td style="padding:12px 16px;background-color:#fafafa;color:#78909c;width:42%;border-bottom:1px solid #ececec">Trạng thái</td><td style="padding:12px 16px;border-bottom:1px solid #ececec"><span style="display:inline-block;border-radius:20px;background-color:{$status_bg};color:{$status_color};font-weight:600;padding:6px 12px">{$status_label}</span></td></tr><tr><td style="padding:12px 16px;background-color:#fafafa;color:#78909c;width:42%;border-bottom:1px solid #ececec">Mã giao dịch</td><td style="padding:12px 16px;border-bottom:1px solid #ececec;font-weight:600;color:#263238">{$transaction_code}</td></tr><tr><td style="padding:12px 16px;background-color:#fafafa;color:#78909c;width:42%;border-bottom:1px solid #ececec">Số tiền</td><td style="padding:12px 16px;border-bottom:1px solid #ececec;font-weight:600;color:#263238">{$amount_formatted} VNĐ</td></tr><tr><td style="padding:12px 16px;background-color:#fafafa;color:#78909c;width:42%;border-bottom:1px solid #ececec">Thời gian gửi</td><td style="padding:12px 16px;border-bottom:1px solid #ececec;color:#263238">{$deposit_date}</td></tr>{$processed_date_row}</table><table cellpadding="0" cellspacing="0" role="presentation" style="margin:24px 0"><tr><td style="border-radius:4px;background-color:#f16723;text-align:center;padding-left:32px;padding-right:32px"><a href="{$portal_url}" style="font-family:Montserrat,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;display:block;font-size:16px;font-weight:600;line-height:100%;color:#fff;text-decoration:none;padding:16px 24px">XEM YÊU CẦU NẠP TIỀN</a></td></tr></table><p style="margin:0 0 12px">Nếu bạn cần hỗ trợ thêm, vui lòng liên hệ {$support_email} hoặc {$support_phone}.</p></td></tr></table></td></tr></table>
|
||||
HTML,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Thanh toán đơn hàng thành công',
|
||||
'scenario' => 'order_payment_success',
|
||||
'format' => 'html',
|
||||
'subject' => '✅ Thanh toán thành công - Đơn hàng #{$order_num}',
|
||||
'message' => <<<'HTML'
|
||||
<div style="max-width: 620px; margin: 30px auto; font-family: 'Segoe UI', Arial, sans-serif;"><div style="background: #fff; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.08);"><div style="background: linear-gradient(135deg, #16a34a 0%, #15803d 100%); padding: 36px 40px; text-align: center;"><div style="font-size: 48px; margin-bottom: 12px;">✅</div><h1 style="color: #fff; margin: 0 0 6px; font-size: 24px; font-weight: 700;">Đặt hàng thành công!</h1><p style="color: #bbf7d0; margin: 0; font-size: 14px;">Đơn hàng #{$order_num} đã được xác nhận và thanh toán</p></div><div style="padding: 36px 40px;"><p style="font-size: 16px; color: #374151; margin-bottom: 20px; line-height: 1.6;">Xin chào <strong>{$customer_name}</strong>,<br>Cảm ơn bạn đã tin tưởng sử dụng dịch vụ của chúng tôi. Đơn hàng của bạn đã được xác nhận và đang trong quá trình khởi tạo.</p><div style="font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: #9ca3af; margin: 28px 0 10px;">Thông tin đơn hàng</div><table style="width: 100%; border-collapse: collapse; background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 8px;"><tr><td style="padding: 10px 16px; font-size: 14px; color:#6b7280;">Mã đơn hàng</td><td style="padding: 10px 16px; font-size: 14px; font-weight:600;">#{$order_num}</td></tr><tr><td style="padding: 10px 16px; font-size: 14px; color:#6b7280;">Tổng thanh toán</td><td style="padding: 10px 16px; font-size: 14px; font-weight:600;">{$amount_formatted} VNĐ</td></tr></table>{$vm_block}{$addon_block}<div style="background: #eff6ff; border-left: 3px solid #3b82f6; padding: 12px 16px; border-radius: 0 6px 6px 0; font-size: 13px; color: #1e40af; margin-top: 24px;">⚠️ Vui lòng <strong>đổi mật khẩu ngay</strong> sau khi đăng nhập lần đầu để bảo mật tài khoản.<br>Nếu cần hỗ trợ, liên hệ: <strong>{$support_email}</strong> hoặc <strong>{$support_phone}</strong></div></div><div style="text-align: center; padding: 20px 40px; border-top: 1px solid #f3f4f6; font-size: 12px; color: #9ca3af;">Email này được gửi tự động. Vui lòng không trả lời email này.</div></div></div>
|
||||
HTML,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Admin cấp lại mật khẩu',
|
||||
'scenario' => 'password_reset_admin',
|
||||
'format' => 'html',
|
||||
'subject' => 'Mật khẩu của bạn đã được cập nhật — {$app_name}',
|
||||
'message' => $bannerHead . <<<'HTML'
|
||||
<tr><td style="background-color: #f06824; padding: 34px 30px 30px; text-align: center; font-family: Arial, Helvetica, sans-serif; color: #ffffff;" align="center" valign="top" bgcolor="#f06824"><div style="font-size: 42px; line-height: 1; margin-bottom: 12px;">🔐</div><h1 style="margin: 0 0 8px; padding: 0; color: #ffffff; font-family: Arial, Helvetica, sans-serif; font-size: 24px; font-weight: 700;">Mật khẩu của bạn đã được cập nhật</h1><div style="font-size: 14px; color: #ffffff;">Quản trị viên vừa cấp lại mật khẩu mới cho tài khoản của bạn</div></td></tr><tr><td style="text-align: center; padding: 0 30px;" align="center" valign="top"><table style="border-collapse: collapse; background-color: #ffffff; width: 100%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr><td style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 1.7; color: #000000; padding: 15px 0;"><div>Xin chào <strong>{$full_name}</strong>,</div><div> </div><div>Quản trị viên của <strong>{$app_name}</strong> vừa cấp lại mật khẩu mới cho tài khoản của bạn. Vui lòng sử dụng thông tin bên dưới để đăng nhập và đổi lại mật khẩu ngay sau đó.</div><div> </div><table style="border-collapse: collapse; width: 100%; background-color: #f9fafb; border: 1px dashed #d1d5db; border-radius: 6px;"><tr><td style="padding: 14px 18px; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 1.8; color: #000000;"><div>Tài khoản: <strong>{$email}</strong></div><div>Mật khẩu mới: <strong>{$password}</strong></div></td></tr></table><div> </div><div style="text-align: center;"><a style="display: inline-block; background-color: #f06824; color: #ffffff !important; text-decoration: none; padding: 12px 28px; border-radius: 3px; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 700;" href="{$login_url}" target="_blank" rel="noopener">Đăng nhập ngay</a></div><div> </div><div style="color: #6b7280; font-size: 13px;">Nếu bạn không yêu cầu thao tác này, vui lòng liên hệ ngay với chúng tôi qua <strong>{$support_email}</strong>.</div></td></tr></tbody></table></td></tr>
|
||||
HTML
|
||||
. $bannerFooter,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Nhắc gia hạn dịch vụ',
|
||||
'scenario' => 'service_renewal_reminder',
|
||||
'format' => 'html',
|
||||
'subject' => 'Nhắc gia hạn dịch vụ {$product_name}',
|
||||
'message' => $header . <<<'HTML'
|
||||
<tr class="NoiDungKM"><td style="width: 700px; padding: 25px; background-color: #ffffff;" valign="top"><p style="font-size: 21px; font-weight: bold; text-align: center;"><strong>Nhắc gia hạn dịch vụ</strong></p><p style="font-weight: bold;"><strong>Kính chào <span style="color: #f16723;">{$client_name},</span></strong></p><p style="text-align: justify;">Dịch vụ <strong>{$product_name}</strong>{$server_name_suffix} của bạn sắp đến hạn thanh toán. Vui lòng gia hạn sớm để tránh gián đoạn dịch vụ.</p><table cellpadding="0" cellspacing="0" border="0" style="width: 100%; table-layout: fixed; border: 1px solid #e8e8e8; border-right: 0;"><tbody><tr><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8; width: 200px;">Dịch vụ:</td><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;"><strong>{$product_name}</strong></td></tr><tr bgcolor="#FFF1E6"><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;">Ngày hết hạn:</td><td style="padding: 7px 11px; border-right: 1px solid #e8e8e8;"><strong style="color: #dc2626;">{$expires_at}</strong></td></tr>{$price_row}</tbody></table><p style="text-align: justify;">Bạn có thể đăng nhập vào cổng quản lý để gia hạn dịch vụ.</p><table cellspacing="0" cellpadding="0" style="margin: 16px auto 16px auto;"><tbody><tr><td align="center" style="background-color: #f16723; padding: 10px 20px; border-radius: 4px;"><a href="{$login_url}" target="_blank" rel="noopener" style="text-decoration: none;"><strong style="color: #ffffff;">Đăng nhập ngay</strong></a></td></tr></tbody></table><p style="text-align: justify; color: #666666; font-size: 13px;">Email này được gửi tự động. Vui lòng không trả lời email này.</p></td></tr>
|
||||
HTML
|
||||
. $footer,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Thao tác Snapshot VPS',
|
||||
'scenario' => 'snapshot_action',
|
||||
'format' => 'html',
|
||||
'subject' => '{$action_title} — {$app_name}',
|
||||
'message' => $bannerHead . <<<'HTML'
|
||||
<tr><td style="background-color: #f06824; padding: 34px 30px 30px; text-align: center; font-family: Arial, Helvetica, sans-serif; color: #ffffff;" align="center" valign="top" bgcolor="#f06824"><div style="font-size: 42px; line-height: 1; margin-bottom: 12px;">{$action_icon}</div><h1 style="margin: 0 0 8px; padding: 0; color: #ffffff; font-family: Arial, Helvetica, sans-serif; font-size: 24px; font-weight: 700;">{$action_title}</h1><div style="font-size: 14px; color: #ffffff;">{$action_desc}</div></td></tr><tr><td style="text-align: center; padding: 0 30px;" align="center" valign="top"><table style="border-collapse: collapse; background-color: #ffffff; width: 100%;"><tbody><tr><td style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 1.7; color: #000000; padding: 15px 0;"><div>Xin chào <strong>{$full_name}</strong>,</div><div> </div><div>Thao tác snapshot máy chủ ảo của bạn tại <strong>{$app_name}</strong> đã hoàn tất.</div><div> </div><table style="border-collapse: collapse; width: 100%; background-color: #f9fafb; border: 1px dashed #d1d5db; border-radius: 6px;"><tr><td style="padding: 14px 18px; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 1.8; color: #000000;"><div>Máy chủ: <strong>{$vm_name}</strong></div><div>Snapshot: <strong>{$snapshot_name}</strong></div><div>Thời gian: <strong>{$action_at}</strong></div><div>Trạng thái: <strong style="color: #16a34a;">{$action_status}</strong></div></td></tr></table><div> </div><div style="text-align: center;"><a style="display: inline-block; background-color: #f06824; color: #ffffff !important; text-decoration: none; padding: 12px 28px; border-radius: 3px; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 700;" href="{$login_url}" target="_blank" rel="noopener">Đăng nhập ngay</a></div><div> </div><div style="color: #6b7280; font-size: 13px;">Nếu bạn có thắc mắc, vui lòng liên hệ với chúng tôi qua <strong>{$support_email}</strong> hoặc <strong>{$support_phone}</strong>.</div></td></tr></tbody></table></td></tr>
|
||||
HTML
|
||||
. $bannerFooter,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Ticket hỗ trợ mới',
|
||||
'scenario' => 'ticket_created',
|
||||
'format' => 'html',
|
||||
'subject' => '[#{$ticket_num}] Yêu cầu hỗ trợ của bạn đã được tiếp nhận',
|
||||
'message' => $bannerHead . <<<'HTML'
|
||||
<tr><td style="background-color: #f06824; padding: 34px 30px 30px; text-align: center; font-family: Arial, Helvetica, sans-serif; color: #ffffff;" align="center" valign="top" bgcolor="#f06824"><div style="font-size: 42px; line-height: 1; margin-bottom: 12px;">🎫</div><h1 style="margin: 0 0 8px; padding: 0; color: #ffffff; font-family: Arial, Helvetica, sans-serif; font-size: 24px; font-weight: 700;">Yêu cầu hỗ trợ đã được tiếp nhận</h1><div style="font-size: 14px; color: #ffffff;">Chúng tôi sẽ phản hồi trong thời gian sớm nhất</div></td></tr><tr><td style="text-align: center; padding: 0 30px;" align="center" valign="top"><table style="border-collapse: collapse; background-color: #ffffff; width: 100%;"><tbody><tr><td style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 1.7; color: #000000; padding: 15px 0;"><div>Xin chào <strong>{$full_name}</strong>,</div><div> </div><div>Chúng tôi đã nhận được yêu cầu hỗ trợ của Quý khách và sẽ xử lý trong thời gian sớm nhất. Dưới đây là thông tin ticket của Quý khách:</div><div> </div><table style="border-collapse: collapse; width: 100%; background-color: #f9f9f9; border: 1px solid #e0e0e0; border-radius: 4px;"><tr><td style="padding: 16px 20px;"><table style="border-collapse: collapse; width: 100%;"><tr><td style="font-family: Arial, Helvetica, sans-serif; font-size: 13px; color: #666666; padding: 4px 0; width: 140px;" valign="top">Mã ticket:</td><td style="font-family: Arial, Helvetica, sans-serif; font-size: 13px; color: #000000; padding: 4px 0; font-weight: 700;" valign="top">#{$ticket_num}</td></tr><tr><td style="font-family: Arial, Helvetica, sans-serif; font-size: 13px; color: #666666; padding: 4px 0;" valign="top">Tiêu đề:</td><td style="font-family: Arial, Helvetica, sans-serif; font-size: 13px; color: #000000; padding: 4px 0;" valign="top">{$subject}</td></tr>{$room_row}<tr><td style="font-family: Arial, Helvetica, sans-serif; font-size: 13px; color: #666666; padding: 4px 0;" valign="top">Trạng thái:</td><td style="font-family: Arial, Helvetica, sans-serif; font-size: 13px; padding: 4px 0;" valign="top"><span style="background-color: #28a745; color: #ffffff; padding: 2px 8px; border-radius: 3px; font-size: 11px; font-weight: 700;">Đang mở</span></td></tr></table></td></tr></table><div> </div><div style="text-align: center;"><a style="display: inline-block; background-color: #f06824; color: #ffffff !important; text-decoration: none; padding: 12px 28px; border-radius: 3px; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 700;" href="{$ticket_url}" target="_blank" rel="noopener">Xem chi tiết ticket</a></div><div> </div><div>Đội ngũ hỗ trợ của <strong>{$app_name}</strong> sẽ liên hệ với Quý khách qua email hoặc cập nhật trực tiếp trên hệ thống. Cảm ơn Quý khách đã tin tưởng sử dụng dịch vụ của chúng tôi.</div></td></tr></tbody></table></td></tr>
|
||||
HTML
|
||||
. $bannerFooter,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Mã xác thực tài khoản',
|
||||
'scenario' => 'verify_account_welcome',
|
||||
'format' => 'html',
|
||||
'subject' => '[{$app_name}] Mã xác thực tài khoản của bạn',
|
||||
'message' => $header . <<<'HTML'
|
||||
<tr class="NoiDungKM"><td style="width: 700px; padding: 25px; background-color: #ffffff;" valign="top"><p style="font-size: 21px; font-weight: bold; text-align: center;"><strong>Xác thực tài khoản {$app_name}</strong></p><p style="font-weight: bold;"><strong>Kính chào <span style="color: #f16723;">{$full_name},</span></strong></p><p style="text-align: justify;">Cảm ơn bạn đã đăng ký tài khoản tại <strong>{$app_name}</strong>. Để hoàn tất quá trình đăng ký, vui lòng sử dụng mã xác thực dưới đây:</p><table cellspacing="0" cellpadding="0" style="margin: 16px auto 16px auto;"><tbody><tr><td align="center" style="background-color: #f5f5f5; border: 2px dashed #f16723; border-radius: 8px; padding: 16px 40px;"><span style="font-family: 'Courier New', monospace; font-size: 36px; font-weight: 700; color: #f16723; letter-spacing: 8px;">{$verify_code}</span></td></tr></tbody></table><p style="text-align: justify; color: #666666; font-size: 13px;">Mã xác thực có hiệu lực trong <strong>5 phút</strong>. Vui lòng không chia sẻ mã này với bất kỳ ai.</p><p style="text-align: justify;">Nếu bạn không thực hiện yêu cầu này, vui lòng bỏ qua email này.</p></td></tr>
|
||||
HTML
|
||||
. $footer,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Khởi tạo VPS thất bại',
|
||||
'scenario' => 'vm_creation_failed',
|
||||
'format' => 'html',
|
||||
'subject' => 'Thông báo: Không thể khởi tạo máy chủ ảo - Đơn hàng #{$order_num}',
|
||||
'message' => $bannerHead . <<<'HTML'
|
||||
<tr><td style="background-color: #f06824; padding: 34px 30px 30px; text-align: center; font-family: Arial, Helvetica, sans-serif; color: #ffffff;" align="center" valign="top" bgcolor="#f06824"><div style="font-size: 42px; line-height: 1; margin-bottom: 12px;">⚠️</div><h1 style="margin: 0 0 8px; padding: 0; color: #ffffff; font-family: Arial, Helvetica, sans-serif; font-size: 24px; font-weight: 700;">Thông báo về đơn hàng #{$order_num}</h1><div style="font-size: 14px; color: #ffffff;">Đội ngũ kỹ thuật đang xử lý yêu cầu của Quý khách</div></td></tr><tr><td style="text-align: center; padding: 0 30px;" align="center" valign="top"><table style="border-collapse: collapse; background-color: #ffffff; width: 100%;"><tbody><tr><td style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 1.7; color: #000000; padding: 15px 0;"><div>Xin chào <strong>{$full_name}</strong>,</div><div> </div><div>Chúng tôi đã nhận được yêu cầu khởi tạo dịch vụ cho đơn hàng của Quý khách. Hiện tại hệ thống đang trong quá trình xử lý và đội ngũ kỹ thuật của <strong>{$app_name}</strong> đã được thông báo để hỗ trợ nhanh nhất có thể.</div><div> </div><div><strong>Thông tin đơn hàng:</strong></div><div> + Mã đơn hàng: <strong>#{$order_num}</strong></div><div> + Sản phẩm: <strong>{$product_name}</strong></div><div> </div><div>Quý khách không cần thực hiện thêm bất kỳ thao tác nào. Chúng tôi sẽ liên hệ lại khi dịch vụ được kích hoạt thành công.</div><div> </div><div style="text-align: center;"><a style="display: inline-block; background-color: #f06824; color: #ffffff !important; text-decoration: none; padding: 12px 28px; border-radius: 3px; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 700;" href="{$invoice_url}" target="_blank" rel="noopener">Xem đơn hàng của bạn</a></div><div> </div><div>Nếu cần hỗ trợ khẩn cấp, Quý khách vui lòng liên hệ qua email <strong>{$support_email}</strong> hoặc tổng đài <strong>{$support_phone}</strong>.</div></td></tr></tbody></table></td></tr>
|
||||
HTML
|
||||
. $bannerFooter,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Đổi mật khẩu VPS',
|
||||
'scenario' => 'vm_password_changed',
|
||||
'format' => 'html',
|
||||
'subject' => 'Mật khẩu VM của bạn đã được thay đổi — {$app_name}',
|
||||
'message' => $bannerHead . <<<'HTML'
|
||||
<tr><td style="background-color: #f06824; padding: 34px 30px 30px; text-align: center; font-family: Arial, Helvetica, sans-serif; color: #ffffff;" align="center" valign="top" bgcolor="#f06824"><div style="font-size: 42px; line-height: 1; margin-bottom: 12px;">🔑</div><h1 style="margin: 0 0 8px; padding: 0; color: #ffffff; font-family: Arial, Helvetica, sans-serif; font-size: 24px; font-weight: 700;">Mật khẩu VM đã được thay đổi</h1><div style="font-size: 14px; color: #ffffff;">Mật khẩu máy chủ ảo của bạn đã được cập nhật thành công</div></td></tr><tr><td style="text-align: center; padding: 0 30px;" align="center" valign="top"><table style="border-collapse: collapse; background-color: #ffffff; width: 100%;"><tbody><tr><td style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 1.7; color: #000000; padding: 15px 0;"><div>Xin chào <strong>{$full_name}</strong>,</div><div> </div><div>Mật khẩu đăng nhập vào máy chủ ảo (VM) của bạn tại <strong>{$app_name}</strong> đã được thay đổi thành công.</div><div> </div><table style="border-collapse: collapse; width: 100%; background-color: #f9fafb; border: 1px dashed #d1d5db; border-radius: 6px;"><tr><td style="padding: 14px 18px; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 1.8; color: #000000;"><div>Máy chủ: <strong>{$vm_name}</strong></div>{$new_password_row}<div>Trạng thái: <strong style="color: #16a34a;">Đổi mật khẩu thành công ✓</strong></div></td></tr></table><div> </div><div style="text-align: center;"><a style="display: inline-block; background-color: #f06824; color: #ffffff !important; text-decoration: none; padding: 12px 28px; border-radius: 3px; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 700;" href="{$login_url}" target="_blank" rel="noopener">Đăng nhập ngay</a></div><div> </div><div style="color: #6b7280; font-size: 13px;">Nếu bạn không thực hiện thao tác này, vui lòng liên hệ ngay với chúng tôi qua <strong>{$support_email}</strong> hoặc <strong>{$support_phone}</strong>.</div></td></tr></tbody></table></td></tr>
|
||||
HTML
|
||||
. $bannerFooter,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
[
|
||||
'name' => 'Rebuild VPS thất bại',
|
||||
'scenario' => 'vm_rebuild_failed',
|
||||
'format' => 'html',
|
||||
'subject' => 'Thông báo: Cài lại hệ điều hành thất bại - {$vm_name}',
|
||||
'message' => $bannerHead . <<<'HTML'
|
||||
<tr><td style="background-color: #f06824; padding: 34px 30px 30px; text-align: center; font-family: Arial, Helvetica, sans-serif; color: #ffffff;" align="center" valign="top" bgcolor="#f06824"><div style="font-size: 42px; line-height: 1; margin-bottom: 12px;">⚠️</div><h1 style="margin: 0 0 8px; padding: 0; color: #ffffff; font-family: Arial, Helvetica, sans-serif; font-size: 24px; font-weight: 700;">Thông báo về VPS {$vm_name}</h1><div style="font-size: 14px; color: #ffffff;">Đội ngũ kỹ thuật đang xử lý yêu cầu của Quý khách</div></td></tr><tr><td style="text-align: center; padding: 0 30px;" align="center" valign="top"><table style="border-collapse: collapse; background-color: #ffffff; width: 100%;"><tbody><tr><td style="font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 1.7; color: #000000; padding: 15px 0;"><div>Xin chào <strong>{$full_name}</strong>,</div><div> </div><div>Rất tiếc, yêu cầu cài lại hệ điều hành (rebuild) cho VPS của Quý khách hiện chưa thực hiện thành công. Đội ngũ kỹ thuật của <strong>{$app_name}</strong> đã được thông báo để kiểm tra và xử lý.</div><div> </div><div><strong>Thông tin dịch vụ:</strong></div><div> + Tên VPS: <strong>{$vm_name}</strong></div><div> + IP: <strong>{$ip}</strong></div><div> </div><div>VPS hiện tại của Quý khách <strong>vẫn đang hoạt động bình thường</strong> trên cấu hình cũ, không có dữ liệu hay dịch vụ nào bị gián đoạn.</div><div> </div><div style="text-align: center;"><a style="display: inline-block; background-color: #f06824; color: #ffffff !important; text-decoration: none; padding: 12px 28px; border-radius: 3px; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 700;" href="{$service_url}" target="_blank" rel="noopener">Xem dịch vụ của bạn</a></div><div> </div><div>Nếu cần hỗ trợ khẩn cấp, Quý khách vui lòng liên hệ qua email <strong>{$support_email}</strong> hoặc tổng đài <strong>{$support_phone}</strong>.</div></td></tr></tbody></table></td></tr>
|
||||
HTML
|
||||
. $bannerFooter,
|
||||
'type_id' => 0,
|
||||
'status' => 1,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($newTemplates as $item) {
|
||||
if (!Template::where('scenario', $item['scenario'])->exists()) {
|
||||
Template::create($item);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($Templates as $item) {
|
||||
Template::create($item);
|
||||
foreach (self::templates() as $item) {
|
||||
$this->upsert($item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array{scenario: string, name: string, subject: string, message: string, types?: array<string, string>}>
|
||||
*/
|
||||
public static function templates(): array
|
||||
{
|
||||
$layout = [
|
||||
'scenario' => 'layout',
|
||||
'name' => 'Bố cục Header/Footer (mặc định)',
|
||||
'subject' => '',
|
||||
'message' => EmailTemplateShell::page('{{$content}}'),
|
||||
];
|
||||
|
||||
$scenarios = array_map(
|
||||
fn (array $item) => [...$item, 'message' => EmailTemplateShell::page($item['body'])],
|
||||
[
|
||||
...AccountTemplates::all(),
|
||||
...ServiceTemplates::all(),
|
||||
...BillingTemplates::all(),
|
||||
...AdminTemplates::all(),
|
||||
],
|
||||
);
|
||||
|
||||
return [$layout, ...$scenarios];
|
||||
}
|
||||
|
||||
private function upsert(array $item): void
|
||||
{
|
||||
$scenario = $item['scenario'];
|
||||
|
||||
$template = Template::query()
|
||||
->where(fn ($q) => $q->where('key', $scenario)->orWhere('scenario', $scenario))
|
||||
->orderByRaw('`key` = ? desc', [$scenario])
|
||||
->orderBy('id')
|
||||
->first() ?? new Template(['type_id' => 0, 'status' => 1]);
|
||||
|
||||
$template->fill([
|
||||
'key' => $scenario,
|
||||
'scenario' => $scenario,
|
||||
'name' => $item['name'],
|
||||
'subject' => $item['subject'],
|
||||
'message' => $item['message'],
|
||||
'format' => 'html',
|
||||
]);
|
||||
|
||||
$template->metadata = [
|
||||
...($template->metadata ?? []),
|
||||
'variables' => $this->variables($template, $item['types'] ?? []),
|
||||
];
|
||||
|
||||
$template->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $typeOverrides
|
||||
* @return array<int, array{key: string, label: string, type: string, example: string}>
|
||||
*/
|
||||
private function variables(Template $template, array $typeOverrides): array
|
||||
{
|
||||
$existing = $template->variables();
|
||||
|
||||
return collect(MailPlaceholders::extract($template->subject, $template->message))
|
||||
->map(function (string $key) use ($existing, $typeOverrides) {
|
||||
[$label, $type, $example] = TemplateVariables::DEFINITIONS[$key] ?? [$key, 'string', ''];
|
||||
|
||||
return [
|
||||
'key' => $key,
|
||||
'label' => $existing[$key]['label'] ?? $label,
|
||||
'type' => $typeOverrides[$key] ?? $type,
|
||||
'example' => $existing[$key]['example'] ?? $example,
|
||||
];
|
||||
})
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user