feat: add bulk delete with validation to IP Pool and update provisioning logic and email notifications
This commit is contained in:
@@ -5,39 +5,46 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Thông báo đơn hàng mới</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; background: #f4f4f4; margin: 0; padding: 0; }
|
||||
.wrapper { max-width: 640px; margin: 30px auto; background: #fff; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.08); }
|
||||
.header { background: #1e40af; padding: 24px 32px; }
|
||||
.header h1 { color: #fff; margin: 0; font-size: 20px; }
|
||||
.header span { color: #bfdbfe; font-size: 13px; }
|
||||
.body { padding: 32px; color: #374151; }
|
||||
.body p { line-height: 1.7; margin: 0 0 12px; }
|
||||
.section-title { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: #6b7280; margin: 24px 0 10px; }
|
||||
.info-box { background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 6px; padding: 16px 20px; }
|
||||
.info-box table { width: 100%; border-collapse: collapse; }
|
||||
.info-box td { padding: 5px 0; font-size: 14px; vertical-align: top; }
|
||||
.info-box td:first-child { color: #6b7280; width: 160px; white-space: nowrap; }
|
||||
.info-box td:last-child { font-weight: 600; color: #111827; }
|
||||
* { box-sizing: border-box; }
|
||||
body { font-family: 'Segoe UI', Arial, sans-serif; background: #f0f4f8; margin: 0; padding: 0; }
|
||||
.wrapper { max-width: 620px; margin: 30px auto; }
|
||||
.card { background: #fff; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.08); }
|
||||
.header { background: linear-gradient(135deg, #1e40af 0%, #1d4ed8 100%); padding: 36px 40px; text-align: center; }
|
||||
.header .icon { font-size: 48px; margin-bottom: 12px; }
|
||||
.header h1 { color: #fff; margin: 0 0 6px; font-size: 22px; font-weight: 700; }
|
||||
.header p { color: #bfdbfe; margin: 0; font-size: 14px; }
|
||||
.body { padding: 36px 40px; }
|
||||
.section-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: #9ca3af; margin: 24px 0 10px; }
|
||||
.section-label:first-child { margin-top: 0; }
|
||||
.info-table { width: 100%; border-collapse: collapse; background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden; }
|
||||
.info-table td { padding: 10px 16px; font-size: 14px; border-bottom: 1px solid #f3f4f6; }
|
||||
.info-table tr:last-child td { border-bottom: none; }
|
||||
.info-table td:first-child { color: #6b7280; width: 45%; }
|
||||
.info-table td:last-child { font-weight: 600; color: #111827; }
|
||||
.badge { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; }
|
||||
.badge-blue { background: #dbeafe; color: #1e40af; }
|
||||
.badge-green { background: #dcfce7; color: #15803d; }
|
||||
.divider { border: none; border-top: 1px solid #e5e7eb; margin: 24px 0; }
|
||||
.footer { background: #f9fafb; border-top: 1px solid #e5e7eb; padding: 16px 32px; text-align: center; font-size: 12px; color: #9ca3af; }
|
||||
.badge-blue { background: #dbeafe; color: #1e40af; }
|
||||
.amount-row td:last-child { font-size: 16px; font-weight: 800; color: #1e40af; }
|
||||
.vm-box { background: #f0fdf4; border: 1.5px solid #86efac; border-radius: 10px; padding: 20px 24px; margin-top: 10px; }
|
||||
.vm-row { display: flex; align-items: center; padding: 8px 0; border-bottom: 1px solid #dcfce7; }
|
||||
.vm-row:last-child { border-bottom: none; }
|
||||
.vm-label { color: #15803d; font-size: 13px; width: 130px; flex-shrink: 0; }
|
||||
.vm-value { font-family: 'Courier New', monospace; font-size: 14px; font-weight: 700; color: #111827; word-break: break-all; }
|
||||
.footer { text-align: center; padding: 20px 40px; border-top: 1px solid #f3f4f6; font-size: 12px; color: #9ca3af; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<div class="header">
|
||||
<h1>📦 Đơn hàng mới đã được thanh toán</h1>
|
||||
<span>Thông báo tự động từ hệ thống quản lý</span>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="icon">📦</div>
|
||||
<h1>Đơn hàng mới đã thanh toán</h1>
|
||||
<p>Đơn #{{ $order_num ?? 'N/A' }} — {{ $created_at ?? now()->format('d/m/Y H:i:s') }}</p>
|
||||
</div>
|
||||
|
||||
<div class="body">
|
||||
<p>Một đơn hàng mới vừa được khách hàng tạo và thanh toán thành công trên hệ thống.</p>
|
||||
|
||||
<div class="section-title">Thông tin khách hàng</div>
|
||||
<div class="info-box">
|
||||
<table>
|
||||
<div class="body">
|
||||
<div class="section-label">Thông tin khách hàng</div>
|
||||
<table class="info-table">
|
||||
<tr>
|
||||
<td>Tên khách hàng</td>
|
||||
<td>{{ $customer_name ?? 'N/A' }}</td>
|
||||
@@ -46,16 +53,16 @@
|
||||
<td>Email</td>
|
||||
<td>{{ $customer_email ?? 'N/A' }}</td>
|
||||
</tr>
|
||||
@if(!empty($client_ip))
|
||||
<tr>
|
||||
<td>IP đặt hàng</td>
|
||||
<td>{{ $client_ip ?? 'N/A' }}</td>
|
||||
<td>{{ $client_ip }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="section-title">Thông tin đơn hàng</div>
|
||||
<div class="info-box">
|
||||
<table>
|
||||
<div class="section-label">Thông tin đơn hàng</div>
|
||||
<table class="info-table">
|
||||
<tr>
|
||||
<td>Mã đơn hàng</td>
|
||||
<td>#{{ $order_num ?? 'N/A' }}</td>
|
||||
@@ -72,55 +79,45 @@
|
||||
<td>Chu kỳ thanh toán</td>
|
||||
<td>{{ $billing_cycle ?? 'N/A' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr class="amount-row">
|
||||
<td>Tổng tiền</td>
|
||||
<td><strong>{{ number_format($total ?? 0, 0, ',', '.') }} VNĐ</strong></td>
|
||||
<td>{{ number_format($total ?? 0, 0, ',', '.') }} VNĐ</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Trạng thái</td>
|
||||
<td><span class="badge badge-green">Đã thanh toán</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Thời gian</td>
|
||||
<td>{{ $created_at ?? now()->format('d/m/Y H:i:s') }}</td>
|
||||
<td><span class="badge badge-green">✅ Đã thanh toán</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if(!empty($username) || !empty($password) || !empty($ip))
|
||||
<div class="section-title">Thông tin dịch vụ</div>
|
||||
<div class="info-box">
|
||||
<table>
|
||||
@if(!empty($ip) || !empty($username) || !empty($password))
|
||||
<div class="section-label">Thông tin dịch vụ Cloud VPS</div>
|
||||
<div class="vm-box">
|
||||
@if(!empty($ip))
|
||||
<div class="vm-row">
|
||||
<span class="vm-label">🌐 IP Address</span>
|
||||
<span class="vm-value">{{ $ip }}</span>
|
||||
</div>
|
||||
@endif
|
||||
@if(!empty($username))
|
||||
<tr>
|
||||
<td>Username</td>
|
||||
<td>{{ $username }}</td>
|
||||
</tr>
|
||||
<div class="vm-row">
|
||||
<span class="vm-label">👤 Username</span>
|
||||
<span class="vm-value">{{ $username }}</span>
|
||||
</div>
|
||||
@endif
|
||||
@if(!empty($password))
|
||||
<tr>
|
||||
<td>Password</td>
|
||||
<td>{{ $password }}</td>
|
||||
</tr>
|
||||
<div class="vm-row">
|
||||
<span class="vm-label">🔑 Password</span>
|
||||
<span class="vm-value">{{ $password }}</span>
|
||||
</div>
|
||||
@endif
|
||||
@if(!empty($ip))
|
||||
<tr>
|
||||
<td>IP Address</td>
|
||||
<td>{{ $ip }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<hr class="divider">
|
||||
<p style="font-size:13px;color:#6b7280;">
|
||||
Email này được gửi tự động bởi hệ thống. Vui lòng không trả lời email này.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
© {{ date('Y') }} {{ $company_name ?? 'Portal Admin' }} — Hệ thống quản lý dịch vụ
|
||||
<div class="footer">
|
||||
© {{ date('Y') }} {{ $company_name ?? 'Portal Admin' }} — Hệ thống quản lý dịch vụ<br>
|
||||
Email này được gửi tự động. Vui lòng không trả lời.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user