mirror of
https://github.com/v2board/v2board.git
synced 2025-01-11 16:49:10 +08:00
commit
56fd3f5b99
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Services\OrderService;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@ -42,14 +43,14 @@ class CheckOrder extends Command
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
$order = Order::get();
|
$orders = Order::get();
|
||||||
foreach ($order as $item) {
|
foreach ($orders as $item) {
|
||||||
switch ($item->status) {
|
switch ($item->status) {
|
||||||
// cancel
|
// cancel
|
||||||
case 0:
|
case 0:
|
||||||
if (strtotime($item->created_at) <= (time() - 1800)) {
|
if (strtotime($item->created_at) <= (time() - 1800)) {
|
||||||
$item->status = 2;
|
$orderService = new OrderService($item);
|
||||||
$item->save();
|
$orderService->cancel();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
@ -64,7 +65,7 @@ class CheckOrder extends Command
|
|||||||
{
|
{
|
||||||
$user = User::find($order->user_id);
|
$user = User::find($order->user_id);
|
||||||
$plan = Plan::find($order->plan_id);
|
$plan = Plan::find($order->plan_id);
|
||||||
if ($order->cycle === 'onetime_price') {
|
if ((string)$order->cycle === 'onetime_price') {
|
||||||
return $this->buyByOneTime($order, $user, $plan);
|
return $this->buyByOneTime($order, $user, $plan);
|
||||||
}
|
}
|
||||||
return $this->buyByCycle($order, $user, $plan);
|
return $this->buyByCycle($order, $user, $plan);
|
||||||
@ -73,7 +74,7 @@ class CheckOrder extends Command
|
|||||||
private function buyByCycle(Order $order, User $user, Plan $plan)
|
private function buyByCycle(Order $order, User $user, Plan $plan)
|
||||||
{
|
{
|
||||||
// change plan process
|
// change plan process
|
||||||
if ($order->type == 3) {
|
if ((int)$order->type === 3) {
|
||||||
$user->expired_at = time();
|
$user->expired_at = time();
|
||||||
}
|
}
|
||||||
if ($order->refund_amount) {
|
if ($order->refund_amount) {
|
||||||
|
@ -38,7 +38,8 @@ class ResetTraffic extends Command
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
$user = User::where('expired_at', '!=', NULL);
|
$user = User::where('expired_at', '!=', NULL)
|
||||||
|
->where('expired_at', '>', time());
|
||||||
$resetTrafficMethod = config('v2board.reset_traffic_method', 0);
|
$resetTrafficMethod = config('v2board.reset_traffic_method', 0);
|
||||||
switch ((int)$resetTrafficMethod) {
|
switch ((int)$resetTrafficMethod) {
|
||||||
// 1 a month
|
// 1 a month
|
||||||
@ -64,21 +65,17 @@ class ResetTraffic extends Command
|
|||||||
|
|
||||||
private function resetByExpireDay($user):void
|
private function resetByExpireDay($user):void
|
||||||
{
|
{
|
||||||
$date = date('Y-m-d', time());
|
|
||||||
$startAt = strtotime((string)$date);
|
|
||||||
$endAt = (int)$startAt + 24 * 3600;
|
|
||||||
$lastDay = date('d', strtotime('last day of +0 months'));
|
$lastDay = date('d', strtotime('last day of +0 months'));
|
||||||
if ((string)$lastDay === '29') {
|
$users = [];
|
||||||
$endAt = (int)$startAt + 72 * 3600;
|
foreach ($user->get() as $item) {
|
||||||
|
$expireDay = date('d', $item->expired_at);
|
||||||
|
if ($expireDay === date('d') || (string)$lastDay === '29' || (string)$lastDay === '30') {
|
||||||
|
array_push($users, $item->id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((string)$lastDay === '30') {
|
$user->whereIn('id', $users)->update([
|
||||||
$endAt = (int)$startAt + 48 * 3600;
|
'u' => 0,
|
||||||
}
|
'd' => 0
|
||||||
$user->where('expired_at', '>=', (int)$startAt)
|
]);
|
||||||
->where('expired_at', '<', (int)$endAt)
|
|
||||||
->update([
|
|
||||||
'u' => 0,
|
|
||||||
'd' => 0
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ namespace App\Console\Commands;
|
|||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\MailLog;
|
use App\Models\MailLog;
|
||||||
use App\Jobs\SendEmail;
|
use App\Jobs\SendEmailJob;
|
||||||
|
|
||||||
class SendRemindMail extends Command
|
class SendRemindMail extends Command
|
||||||
{
|
{
|
||||||
@ -50,10 +50,10 @@ class SendRemindMail extends Command
|
|||||||
private function remindExpire($user)
|
private function remindExpire($user)
|
||||||
{
|
{
|
||||||
if (($user->expired_at - 86400) < time() && $user->expired_at > time()) {
|
if (($user->expired_at - 86400) < time() && $user->expired_at > time()) {
|
||||||
SendEmail::dispatch([
|
SendEmailJob::dispatch([
|
||||||
'email' => $user->email,
|
'email' => $user->email,
|
||||||
'subject' => '在' . config('v2board.app_name', 'V2board') . '的服务即将到期',
|
'subject' => '在' . config('v2board.app_name', 'V2board') . '的服务即将到期',
|
||||||
'template_name' => 'mail.sendRemindExpire',
|
'template_name' => 'remindExpire',
|
||||||
'template_value' => [
|
'template_value' => [
|
||||||
'name' => config('v2board.app_name', 'V2Board'),
|
'name' => config('v2board.app_name', 'V2Board'),
|
||||||
'url' => config('v2board.app_url')
|
'url' => config('v2board.app_url')
|
||||||
@ -69,10 +69,10 @@ class SendRemindMail extends Command
|
|||||||
->where('template_name', 'mail.sendRemindTraffic')
|
->where('template_name', 'mail.sendRemindTraffic')
|
||||||
->count();
|
->count();
|
||||||
if ($sendCount > 0) return;
|
if ($sendCount > 0) return;
|
||||||
SendEmail::dispatch([
|
SendEmailJob::dispatch([
|
||||||
'email' => $user->email,
|
'email' => $user->email,
|
||||||
'subject' => '在' . config('v2board.app_name', 'V2board') . '的流量使用已达到80%',
|
'subject' => '在' . config('v2board.app_name', 'V2board') . '的流量使用已达到80%',
|
||||||
'template_name' => 'mail.sendRemindTraffic',
|
'template_name' => 'remindTraffic',
|
||||||
'template_value' => [
|
'template_value' => [
|
||||||
'name' => config('v2board.app_name', 'V2Board'),
|
'name' => config('v2board.app_name', 'V2Board'),
|
||||||
'url' => config('v2board.app_url')
|
'url' => config('v2board.app_url')
|
||||||
|
@ -9,6 +9,17 @@ use App\Http\Controllers\Controller;
|
|||||||
|
|
||||||
class ConfigController extends Controller
|
class ConfigController extends Controller
|
||||||
{
|
{
|
||||||
|
public function getEmailTemplate()
|
||||||
|
{
|
||||||
|
$path = resource_path('views/mail/');
|
||||||
|
$files = array_map(function ($item) use ($path) {
|
||||||
|
return str_replace($path, '', $item);
|
||||||
|
}, glob($path . '*'));
|
||||||
|
return response([
|
||||||
|
'data' => $files
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function fetch()
|
public function fetch()
|
||||||
{
|
{
|
||||||
// TODO: default should be in Dict
|
// TODO: default should be in Dict
|
||||||
@ -18,7 +29,8 @@ class ConfigController extends Controller
|
|||||||
'invite_force' => (int)config('v2board.invite_force', 0),
|
'invite_force' => (int)config('v2board.invite_force', 0),
|
||||||
'invite_commission' => config('v2board.invite_commission', 10),
|
'invite_commission' => config('v2board.invite_commission', 10),
|
||||||
'invite_gen_limit' => config('v2board.invite_gen_limit', 5),
|
'invite_gen_limit' => config('v2board.invite_gen_limit', 5),
|
||||||
'invite_never_expire' => config('v2board.invite_never_expire', 0)
|
'invite_never_expire' => config('v2board.invite_never_expire', 0),
|
||||||
|
'commission_first_time_enable' => config('v2board.commission_first_time_enable', 1)
|
||||||
],
|
],
|
||||||
'site' => [
|
'site' => [
|
||||||
'safe_mode_enable' => (int)config('v2board.safe_mode_enable', 0),
|
'safe_mode_enable' => (int)config('v2board.safe_mode_enable', 0),
|
||||||
@ -71,6 +83,9 @@ class ConfigController extends Controller
|
|||||||
],
|
],
|
||||||
'tutorial' => [
|
'tutorial' => [
|
||||||
'apple_id' => config('v2board.apple_id')
|
'apple_id' => config('v2board.apple_id')
|
||||||
|
],
|
||||||
|
'email' => [
|
||||||
|
'email_template' => config('v2board.email_template', 'default')
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
|
@ -34,7 +34,9 @@ class CouponController extends Controller
|
|||||||
abort(500, '创建失败');
|
abort(500, '创建失败');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!Coupon::find($request->input('id'))->update($params)) {
|
try {
|
||||||
|
Coupon::find($request->input('id'))->update($params);
|
||||||
|
} catch (\Exception $e) {
|
||||||
abort(500, '保存失败');
|
abort(500, '保存失败');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use App\Http\Requests\Admin\MailSend;
|
|||||||
use App\Services\UserService;
|
use App\Services\UserService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Jobs\SendEmail;
|
use App\Jobs\SendEmailJob;
|
||||||
|
|
||||||
class MailController extends Controller
|
class MailController extends Controller
|
||||||
{
|
{
|
||||||
@ -28,16 +28,16 @@ class MailController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($users as $user) {
|
foreach ($users as $user) {
|
||||||
SendEmail::dispatch([
|
SendEmailJob::dispatch([
|
||||||
'email' => $user->email,
|
'email' => $user->email,
|
||||||
'subject' => $request->input('subject'),
|
'subject' => $request->input('subject'),
|
||||||
'template_name' => 'mail.sendEmailCustom',
|
'template_name' => 'notify',
|
||||||
'template_value' => [
|
'template_value' => [
|
||||||
'name' => config('v2board.app_name', 'V2Board'),
|
'name' => config('v2board.app_name', 'V2Board'),
|
||||||
'url' => config('v2board.app_url'),
|
'url' => config('v2board.app_url'),
|
||||||
'content' => $request->input('content')
|
'content' => $request->input('content')
|
||||||
]
|
]
|
||||||
])->onQueue('other_mail');
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response([
|
return response([
|
||||||
|
@ -29,7 +29,9 @@ class NoticeController extends Controller
|
|||||||
abort(500, '保存失败');
|
abort(500, '保存失败');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!Notice::find($request->input('id'))->update($data)) {
|
try {
|
||||||
|
Notice::find($request->input('id'))->update($data);
|
||||||
|
} catch (\Exception $e) {
|
||||||
abort(500, '保存失败');
|
abort(500, '保存失败');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use App\Http\Requests\Admin\OrderUpdate;
|
use App\Http\Requests\Admin\OrderUpdate;
|
||||||
|
use App\Services\OrderService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
@ -48,7 +49,7 @@ class OrderController extends Controller
|
|||||||
|
|
||||||
public function update(OrderUpdate $request)
|
public function update(OrderUpdate $request)
|
||||||
{
|
{
|
||||||
$updateData = $request->only([
|
$params = $request->only([
|
||||||
'status',
|
'status',
|
||||||
'commission_status'
|
'commission_status'
|
||||||
]);
|
]);
|
||||||
@ -59,7 +60,19 @@ class OrderController extends Controller
|
|||||||
abort(500, '订单不存在');
|
abort(500, '订单不存在');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$order->update($updateData)) {
|
if (isset($params['status']) && (int)$params['status'] === 2) {
|
||||||
|
$orderService = new OrderService($order);
|
||||||
|
if (!$orderService->cancel()) {
|
||||||
|
abort(500, '更新失败');
|
||||||
|
}
|
||||||
|
return response([
|
||||||
|
'data' => true
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$order->update($params);
|
||||||
|
} catch (\Exception $e) {
|
||||||
abort(500, '更新失败');
|
abort(500, '更新失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,9 +30,10 @@ class PlanController extends Controller
|
|||||||
}
|
}
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
// update user group id
|
// update user group id
|
||||||
User::where('plan_id', $plan->id)
|
try {
|
||||||
->update(['group_id' => $plan->group_id]);
|
User::where('plan_id', $plan->id)->update(['group_id' => $plan->group_id]);
|
||||||
if (!$plan->update($params)) {
|
$plan->update($params);
|
||||||
|
} catch (\Exception $e) {
|
||||||
DB::rollBack();
|
DB::rollBack();
|
||||||
abort(500, '保存失败');
|
abort(500, '保存失败');
|
||||||
}
|
}
|
||||||
@ -79,7 +80,10 @@ class PlanController extends Controller
|
|||||||
if (!$plan) {
|
if (!$plan) {
|
||||||
abort(500, '该订阅不存在');
|
abort(500, '该订阅不存在');
|
||||||
}
|
}
|
||||||
if (!$plan->update($updateData)) {
|
|
||||||
|
try {
|
||||||
|
$plan->update($updateData);
|
||||||
|
} catch (\Exception $e) {
|
||||||
abort(500, '保存失败');
|
abort(500, '保存失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,24 +40,33 @@ class ServerController extends Controller
|
|||||||
if (isset($params['tags'])) {
|
if (isset($params['tags'])) {
|
||||||
$params['tags'] = json_encode($params['tags']);
|
$params['tags'] = json_encode($params['tags']);
|
||||||
}
|
}
|
||||||
if (isset($params['rules'])) {
|
|
||||||
if (!is_object(json_decode($params['rules']))) {
|
if (isset($params['ruleSettings'])) {
|
||||||
|
if (!is_object(json_decode($params['ruleSettings']))) {
|
||||||
abort(500, '审计规则配置格式不正确');
|
abort(500, '审计规则配置格式不正确');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($params['settings'])) {
|
if (isset($params['networkSettings'])) {
|
||||||
if (!is_object(json_decode($params['settings']))) {
|
if (!is_object(json_decode($params['networkSettings']))) {
|
||||||
abort(500, '传输协议配置格式不正确');
|
abort(500, '传输协议配置格式不正确');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($params['tlsSettings'])) {
|
||||||
|
if (!is_object(json_decode($params['tlsSettings']))) {
|
||||||
|
abort(500, 'TLS配置格式不正确');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($request->input('id')) {
|
if ($request->input('id')) {
|
||||||
$server = Server::find($request->input('id'));
|
$server = Server::find($request->input('id'));
|
||||||
if (!$server) {
|
if (!$server) {
|
||||||
abort(500, '服务器不存在');
|
abort(500, '服务器不存在');
|
||||||
}
|
}
|
||||||
if (!$server->update($params)) {
|
try {
|
||||||
|
$server->update($params);
|
||||||
|
} catch (\Exception $e) {
|
||||||
abort(500, '保存失败');
|
abort(500, '保存失败');
|
||||||
}
|
}
|
||||||
return response([
|
return response([
|
||||||
@ -156,7 +165,9 @@ class ServerController extends Controller
|
|||||||
if (!$server) {
|
if (!$server) {
|
||||||
abort(500, '该服务器不存在');
|
abort(500, '该服务器不存在');
|
||||||
}
|
}
|
||||||
if (!$server->update($params)) {
|
try {
|
||||||
|
$server->update($params);
|
||||||
|
} catch (\Exception $e) {
|
||||||
abort(500, '保存失败');
|
abort(500, '保存失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,4 +175,19 @@ class ServerController extends Controller
|
|||||||
'data' => true
|
'data' => true
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function copy(Request $request)
|
||||||
|
{
|
||||||
|
$server = Server::find($request->input('id'));
|
||||||
|
if (!$server) {
|
||||||
|
abort(500, '服务器不存在');
|
||||||
|
}
|
||||||
|
if (!Server::create($server->toArray())) {
|
||||||
|
abort(500, '复制失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
return response([
|
||||||
|
'data' => true
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,9 @@ class TutorialController extends Controller
|
|||||||
abort(500, '创建失败');
|
abort(500, '创建失败');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!Tutorial::find($request->input('id'))->update($params)) {
|
try {
|
||||||
|
Tutorial::find($request->input('id'))->update($params);
|
||||||
|
} catch (\Exception $e) {
|
||||||
abort(500, '保存失败');
|
abort(500, '保存失败');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,10 @@ class UserController extends Controller
|
|||||||
}
|
}
|
||||||
$params['group_id'] = $plan->group_id;
|
$params['group_id'] = $plan->group_id;
|
||||||
}
|
}
|
||||||
if (!$user->update($params)) {
|
|
||||||
|
try {
|
||||||
|
$user->update($params);
|
||||||
|
} catch (\Exception $e) {
|
||||||
abort(500, '保存失败');
|
abort(500, '保存失败');
|
||||||
}
|
}
|
||||||
return response([
|
return response([
|
||||||
|
@ -57,7 +57,7 @@ class AppController extends Controller
|
|||||||
abort(500, '参数错误');
|
abort(500, '参数错误');
|
||||||
}
|
}
|
||||||
$user = $request->user;
|
$user = $request->user;
|
||||||
if ($user->expired_at < time()) {
|
if ($user->expired_at < time() && $user->expired_at !== NULL) {
|
||||||
abort(500, '订阅计划已过期');
|
abort(500, '订阅计划已过期');
|
||||||
}
|
}
|
||||||
$server = Server::where('show', 1)
|
$server = Server::where('show', 1)
|
||||||
@ -78,25 +78,25 @@ class AppController extends Controller
|
|||||||
$json->outbound->settings->vnext[0]->users[0]->alterId = (int)$user->v2ray_alter_id;
|
$json->outbound->settings->vnext[0]->users[0]->alterId = (int)$user->v2ray_alter_id;
|
||||||
$json->outbound->settings->vnext[0]->remark = (string)$server->name;
|
$json->outbound->settings->vnext[0]->remark = (string)$server->name;
|
||||||
$json->outbound->streamSettings->network = $server->network;
|
$json->outbound->streamSettings->network = $server->network;
|
||||||
if ($server->settings) {
|
if ($server->networkSettings) {
|
||||||
switch ($server->network) {
|
switch ($server->network) {
|
||||||
case 'tcp':
|
case 'tcp':
|
||||||
$json->outbound->streamSettings->tcpSettings = json_decode($server->settings);
|
$json->outbound->streamSettings->tcpSettings = json_decode($server->networkSettings);
|
||||||
break;
|
break;
|
||||||
case 'kcp':
|
case 'kcp':
|
||||||
$json->outbound->streamSettings->kcpSettings = json_decode($server->settings);
|
$json->outbound->streamSettings->kcpSettings = json_decode($server->networkSettings);
|
||||||
break;
|
break;
|
||||||
case 'ws':
|
case 'ws':
|
||||||
$json->outbound->streamSettings->wsSettings = json_decode($server->settings);
|
$json->outbound->streamSettings->wsSettings = json_decode($server->networkSettings);
|
||||||
break;
|
break;
|
||||||
case 'http':
|
case 'http':
|
||||||
$json->outbound->streamSettings->httpSettings = json_decode($server->settings);
|
$json->outbound->streamSettings->httpSettings = json_decode($server->networkSettings);
|
||||||
break;
|
break;
|
||||||
case 'domainsocket':
|
case 'domainsocket':
|
||||||
$json->outbound->streamSettings->dsSettings = json_decode($server->settings);
|
$json->outbound->streamSettings->dsSettings = json_decode($server->networkSettings);
|
||||||
break;
|
break;
|
||||||
case 'quic':
|
case 'quic':
|
||||||
$json->outbound->streamSettings->quicSettings = json_decode($server->settings);
|
$json->outbound->streamSettings->quicSettings = json_decode($server->networkSettings);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Controllers\Client;
|
namespace App\Http\Controllers\Client;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Middleware\User;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Utils\Helper;
|
use App\Utils\Helper;
|
||||||
@ -49,9 +48,9 @@ class ClientController extends Controller
|
|||||||
foreach ($server as $item) {
|
foreach ($server as $item) {
|
||||||
$uri .= "vmess=" . $item->host . ":" . $item->port . ", method=none, password=" . $user->v2ray_uuid . ", fast-open=false, udp-relay=false, tag=" . $item->name;
|
$uri .= "vmess=" . $item->host . ":" . $item->port . ", method=none, password=" . $user->v2ray_uuid . ", fast-open=false, udp-relay=false, tag=" . $item->name;
|
||||||
if ($item->network == 'ws') {
|
if ($item->network == 'ws') {
|
||||||
$uri .= ', obfs=ws';
|
$uri .= ', obfs=' . ($item->tls ? 'wss' : 'ws');
|
||||||
if ($item->settings) {
|
if ($item->networkSettings) {
|
||||||
$wsSettings = json_decode($item->settings);
|
$wsSettings = json_decode($item->networkSettings);
|
||||||
if (isset($wsSettings->path)) $uri .= ', obfs-uri=' . $wsSettings->path;
|
if (isset($wsSettings->path)) $uri .= ', obfs-uri=' . $wsSettings->path;
|
||||||
if (isset($wsSettings->headers->Host)) $uri .= ', obfs-host=' . $wsSettings->headers->Host;
|
if (isset($wsSettings->headers->Host)) $uri .= ', obfs-host=' . $wsSettings->headers->Host;
|
||||||
}
|
}
|
||||||
@ -69,9 +68,9 @@ class ClientController extends Controller
|
|||||||
$str = '';
|
$str = '';
|
||||||
$str .= $item->name . '= vmess, ' . $item->host . ', ' . $item->port . ', chacha20-ietf-poly1305, "' . $user->v2ray_uuid . '", over-tls=' . ($item->tls ? "true" : "false") . ', certificate=0, group=' . config('v2board.app_name', 'V2Board');
|
$str .= $item->name . '= vmess, ' . $item->host . ', ' . $item->port . ', chacha20-ietf-poly1305, "' . $user->v2ray_uuid . '", over-tls=' . ($item->tls ? "true" : "false") . ', certificate=0, group=' . config('v2board.app_name', 'V2Board');
|
||||||
if ($item->network === 'ws') {
|
if ($item->network === 'ws') {
|
||||||
$str .= ', obfs=ws';
|
$uri .= ', obfs=' . ($item->tls ? 'wss' : 'ws');
|
||||||
if ($item->settings) {
|
if ($item->networkSettings) {
|
||||||
$wsSettings = json_decode($item->settings);
|
$wsSettings = json_decode($item->networkSettings);
|
||||||
if (isset($wsSettings->path)) $str .= ', obfs-path="' . $wsSettings->path . '"';
|
if (isset($wsSettings->path)) $str .= ', obfs-path="' . $wsSettings->path . '"';
|
||||||
if (isset($wsSettings->headers->Host)) $str .= ', obfs-header="Host:' . $wsSettings->headers->Host . '"';
|
if (isset($wsSettings->headers->Host)) $str .= ', obfs-header="Host:' . $wsSettings->headers->Host . '"';
|
||||||
}
|
}
|
||||||
@ -111,8 +110,8 @@ class ClientController extends Controller
|
|||||||
}
|
}
|
||||||
if ($item->network == 'ws') {
|
if ($item->network == 'ws') {
|
||||||
$array['network'] = $item->network;
|
$array['network'] = $item->network;
|
||||||
if ($item->settings) {
|
if ($item->networkSettings) {
|
||||||
$wsSettings = json_decode($item->settings);
|
$wsSettings = json_decode($item->networkSettings);
|
||||||
if (isset($wsSettings->path)) $array['ws-path'] = $wsSettings->path;
|
if (isset($wsSettings->path)) $array['ws-path'] = $wsSettings->path;
|
||||||
if (isset($wsSettings->headers->Host)) $array['ws-headers'] = [
|
if (isset($wsSettings->headers->Host)) $array['ws-headers'] = [
|
||||||
'Host' => $wsSettings->headers->Host
|
'Host' => $wsSettings->headers->Host
|
||||||
|
@ -13,6 +13,7 @@ use App\Models\User;
|
|||||||
use App\Models\InviteCode;
|
use App\Models\InviteCode;
|
||||||
use App\Utils\Helper;
|
use App\Utils\Helper;
|
||||||
use App\Utils\Dict;
|
use App\Utils\Dict;
|
||||||
|
use App\Utils\CacheKey;
|
||||||
|
|
||||||
class AuthController extends Controller
|
class AuthController extends Controller
|
||||||
{
|
{
|
||||||
@ -35,11 +36,10 @@ class AuthController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((int)config('v2board.email_verify', 0)) {
|
if ((int)config('v2board.email_verify', 0)) {
|
||||||
$redisKey = 'sendEmailVerify:' . $request->input('email');
|
|
||||||
if (empty($request->input('email_code'))) {
|
if (empty($request->input('email_code'))) {
|
||||||
abort(500, '邮箱验证码不能为空');
|
abort(500, '邮箱验证码不能为空');
|
||||||
}
|
}
|
||||||
if (Cache::get($redisKey) !== $request->input('email_code')) {
|
if (Cache::get(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email'))) !== $request->input('email_code')) {
|
||||||
abort(500, '邮箱验证码有误');
|
abort(500, '邮箱验证码有误');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ class AuthController extends Controller
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$user->invite_user_id = $inviteCode->user_id ? $inviteCode->user_id : null;
|
$user->invite_user_id = $inviteCode->user_id ? $inviteCode->user_id : null;
|
||||||
if (!(int)config('v2board.invite_never_expire', env('V2BOARD_INVITE_NEVER_EXPIRE'))) {
|
if (!(int)config('v2board.invite_never_expire', 0)) {
|
||||||
$inviteCode->status = 1;
|
$inviteCode->status = 1;
|
||||||
$inviteCode->save();
|
$inviteCode->save();
|
||||||
}
|
}
|
||||||
@ -86,7 +86,7 @@ class AuthController extends Controller
|
|||||||
abort(500, '注册失败');
|
abort(500, '注册失败');
|
||||||
}
|
}
|
||||||
if ((int)config('v2board.email_verify', 0)) {
|
if ((int)config('v2board.email_verify', 0)) {
|
||||||
Cache::forget($redisKey);
|
Cache::forget(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email')));
|
||||||
}
|
}
|
||||||
$request->session()->put('email', $user->email);
|
$request->session()->put('email', $user->email);
|
||||||
$request->session()->put('id', $user->id);
|
$request->session()->put('id', $user->id);
|
||||||
@ -189,8 +189,7 @@ class AuthController extends Controller
|
|||||||
|
|
||||||
public function forget(AuthForget $request)
|
public function forget(AuthForget $request)
|
||||||
{
|
{
|
||||||
$redisKey = 'sendEmailVerify:' . $request->input('email');
|
if (Cache::get(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email'))) !== $request->input('email_code')) {
|
||||||
if (Cache::get($redisKey) !== $request->input('email_code')) {
|
|
||||||
abort(500, '邮箱验证码有误');
|
abort(500, '邮箱验证码有误');
|
||||||
}
|
}
|
||||||
$user = User::where('email', $request->input('email'))->first();
|
$user = User::where('email', $request->input('email'))->first();
|
||||||
@ -202,7 +201,7 @@ class AuthController extends Controller
|
|||||||
if (!$user->save()) {
|
if (!$user->save()) {
|
||||||
abort(500, '重置失败');
|
abort(500, '重置失败');
|
||||||
}
|
}
|
||||||
Cache::forget($redisKey);
|
Cache::forget(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email')));
|
||||||
return response([
|
return response([
|
||||||
'data' => true
|
'data' => true
|
||||||
]);
|
]);
|
||||||
|
@ -9,9 +9,10 @@ use Illuminate\Http\Exceptions\HttpResponseException;
|
|||||||
use Illuminate\Support\Facades\Mail;
|
use Illuminate\Support\Facades\Mail;
|
||||||
use App\Utils\Helper;
|
use App\Utils\Helper;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use App\Jobs\SendEmail;
|
use App\Jobs\SendEmailJob;
|
||||||
use App\Models\InviteCode;
|
use App\Models\InviteCode;
|
||||||
use App\Utils\Dict;
|
use App\Utils\Dict;
|
||||||
|
use App\Utils\CacheKey;
|
||||||
|
|
||||||
class CommController extends Controller
|
class CommController extends Controller
|
||||||
{
|
{
|
||||||
@ -38,25 +39,25 @@ class CommController extends Controller
|
|||||||
public function sendEmailVerify(CommSendEmailVerify $request)
|
public function sendEmailVerify(CommSendEmailVerify $request)
|
||||||
{
|
{
|
||||||
$email = $request->input('email');
|
$email = $request->input('email');
|
||||||
$cacheKey = 'sendEmailVerify:' . $email;
|
if (Cache::get(CacheKey::get('LAST_SEND_EMAIL_VERIFY_TIMESTAMP', $email))) {
|
||||||
if (Cache::get($cacheKey)) {
|
|
||||||
abort(500, '验证码已发送,请过一会再请求');
|
abort(500, '验证码已发送,请过一会再请求');
|
||||||
}
|
}
|
||||||
$code = Helper::randomChar(6);
|
$code = rand(100000, 999999);
|
||||||
$subject = config('v2board.app_name', 'V2Board') . '邮箱验证码';
|
$subject = config('v2board.app_name', 'V2Board') . '邮箱验证码';
|
||||||
|
|
||||||
SendEmail::dispatch([
|
SendEmailJob::dispatch([
|
||||||
'email' => $email,
|
'email' => $email,
|
||||||
'subject' => $subject,
|
'subject' => $subject,
|
||||||
'template_name' => 'mail.sendEmailVerify',
|
'template_name' => 'verify',
|
||||||
'template_value' => [
|
'template_value' => [
|
||||||
'name' => config('v2board.app_name', 'V2Board'),
|
'name' => config('v2board.app_name', 'V2Board'),
|
||||||
'code' => $code,
|
'code' => $code,
|
||||||
'url' => config('v2board.app_url')
|
'url' => config('v2board.app_url')
|
||||||
]
|
]
|
||||||
])->onQueue('verify_mail');
|
]);
|
||||||
|
|
||||||
Cache::put($cacheKey, $code, 60);
|
Cache::put(CacheKey::get('EMAIL_VERIFY_CODE', $email), $code, 300);
|
||||||
|
Cache::put(CacheKey::get('LAST_SEND_EMAIL_VERIFY_TIMESTAMP', $email), time(), 60);
|
||||||
return response([
|
return response([
|
||||||
'data' => true
|
'data' => true
|
||||||
]);
|
]);
|
||||||
|
@ -101,65 +101,11 @@ class DeepbworkController extends Controller
|
|||||||
if (empty($nodeId) || empty($localPort)) {
|
if (empty($nodeId) || empty($localPort)) {
|
||||||
abort(500, '参数错误');
|
abort(500, '参数错误');
|
||||||
}
|
}
|
||||||
$server = Server::find($nodeId);
|
$serverService = new ServerService();
|
||||||
if (!$server) {
|
try {
|
||||||
abort(500, '节点不存在');
|
$json = $serverService->getConfig($nodeId, $localPort);
|
||||||
}
|
} catch (\Exception $e) {
|
||||||
$json = json_decode(self::SERVER_CONFIG);
|
abort(500, $e->getMessage());
|
||||||
$json->inboundDetour[0]->port = (int)$localPort;
|
|
||||||
$json->inbound->port = (int)$server->server_port;
|
|
||||||
$json->inbound->streamSettings->network = $server->network;
|
|
||||||
if ($server->settings) {
|
|
||||||
switch ($server->network) {
|
|
||||||
case 'tcp':
|
|
||||||
$json->inbound->streamSettings->tcpSettings = json_decode($server->settings);
|
|
||||||
break;
|
|
||||||
case 'kcp':
|
|
||||||
$json->inbound->streamSettings->kcpSettings = json_decode($server->settings);
|
|
||||||
break;
|
|
||||||
case 'ws':
|
|
||||||
$json->inbound->streamSettings->wsSettings = json_decode($server->settings);
|
|
||||||
break;
|
|
||||||
case 'http':
|
|
||||||
$json->inbound->streamSettings->httpSettings = json_decode($server->settings);
|
|
||||||
break;
|
|
||||||
case 'domainsocket':
|
|
||||||
$json->inbound->streamSettings->dsSettings = json_decode($server->settings);
|
|
||||||
break;
|
|
||||||
case 'quic':
|
|
||||||
$json->inbound->streamSettings->quicSettings = json_decode($server->settings);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($server->rules) {
|
|
||||||
$rules = json_decode($server->rules);
|
|
||||||
// domain
|
|
||||||
if (isset($rules->domain) && !empty($rules->domain)) {
|
|
||||||
$domainObj = new \StdClass();
|
|
||||||
$domainObj->type = 'field';
|
|
||||||
$domainObj->domain = $rules->domain;
|
|
||||||
$domainObj->outboundTag = 'block';
|
|
||||||
array_push($json->routing->rules, $domainObj);
|
|
||||||
}
|
|
||||||
// protocol
|
|
||||||
if (isset($rules->protocol) && !empty($rules->protocol)) {
|
|
||||||
$protocolObj = new \StdClass();
|
|
||||||
$protocolObj->type = 'field';
|
|
||||||
$protocolObj->protocol = $rules->protocol;
|
|
||||||
$protocolObj->outboundTag = 'block';
|
|
||||||
array_push($json->routing->rules, $protocolObj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((int)$server->tls) {
|
|
||||||
$json->inbound->streamSettings->security = 'tls';
|
|
||||||
$tls = (object)[
|
|
||||||
'certificateFile' => '/home/v2ray.crt',
|
|
||||||
'keyFile' => '/home/v2ray.key'
|
|
||||||
];
|
|
||||||
$json->inbound->streamSettings->tlsSettings = new \StdClass();
|
|
||||||
$json->inbound->streamSettings->tlsSettings->certificates[0] = $tls;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
die(json_encode($json, JSON_UNESCAPED_UNICODE));
|
die(json_encode($json, JSON_UNESCAPED_UNICODE));
|
||||||
|
@ -89,72 +89,18 @@ class PoseidonController extends Controller
|
|||||||
if (empty($nodeId) || empty($localPort)) {
|
if (empty($nodeId) || empty($localPort)) {
|
||||||
return $this->error('invalid parameters', 400);
|
return $this->error('invalid parameters', 400);
|
||||||
}
|
}
|
||||||
$server = Server::find($nodeId);
|
|
||||||
if (!$server) {
|
|
||||||
return $this->error("server could not be found", 404);
|
|
||||||
}
|
|
||||||
$json = json_decode(self::SERVER_CONFIG);
|
|
||||||
$json->inboundDetour[0]->port = (int)$localPort;
|
|
||||||
$json->inbound->port = (int)$server->server_port;
|
|
||||||
$json->inbound->streamSettings->network = $server->network;
|
|
||||||
if ($server->settings) {
|
|
||||||
switch ($server->network) {
|
|
||||||
case 'tcp':
|
|
||||||
$json->inbound->streamSettings->tcpSettings = json_decode($server->settings);
|
|
||||||
break;
|
|
||||||
case 'kcp':
|
|
||||||
$json->inbound->streamSettings->kcpSettings = json_decode($server->settings);
|
|
||||||
break;
|
|
||||||
case 'ws':
|
|
||||||
$json->inbound->streamSettings->wsSettings = json_decode($server->settings);
|
|
||||||
break;
|
|
||||||
case 'http':
|
|
||||||
$json->inbound->streamSettings->httpSettings = json_decode($server->settings);
|
|
||||||
break;
|
|
||||||
case 'domainsocket':
|
|
||||||
$json->inbound->streamSettings->dsSettings = json_decode($server->settings);
|
|
||||||
break;
|
|
||||||
case 'quic':
|
|
||||||
$json->inbound->streamSettings->quicSettings = json_decode($server->settings);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($server->rules) {
|
$serverService = new ServerService();
|
||||||
$rules = json_decode($server->rules);
|
try {
|
||||||
// domain
|
$json = $serverService->getConfig($nodeId, $localPort);
|
||||||
if (isset($rules->domain) && !empty($rules->domain)) {
|
$json->poseidon = [
|
||||||
$domainObj = new \StdClass();
|
'license_key' => (string)config('v2board.server_license'),
|
||||||
$domainObj->type = 'field';
|
|
||||||
$domainObj->domain = $rules->domain;
|
|
||||||
$domainObj->outboundTag = 'block';
|
|
||||||
array_push($json->routing->rules, $domainObj);
|
|
||||||
}
|
|
||||||
// protocol
|
|
||||||
if (isset($rules->protocol) && !empty($rules->protocol)) {
|
|
||||||
$protocolObj = new \StdClass();
|
|
||||||
$protocolObj->type = 'field';
|
|
||||||
$protocolObj->protocol = $rules->protocol;
|
|
||||||
$protocolObj->outboundTag = 'block';
|
|
||||||
array_push($json->routing->rules, $protocolObj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((int)$server->tls) {
|
|
||||||
$json->inbound->streamSettings->security = 'tls';
|
|
||||||
$tls = (object)[
|
|
||||||
'certificateFile' => '/home/v2ray.crt',
|
|
||||||
'keyFile' => '/home/v2ray.key'
|
|
||||||
];
|
];
|
||||||
$json->inbound->streamSettings->tlsSettings = new \StdClass();
|
|
||||||
$json->inbound->streamSettings->tlsSettings->certificates[0] = $tls;
|
return $this->success($json);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->error($e->getMessage(), 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
$json->poseidon = [
|
|
||||||
'license_key' => (string)config('v2board.server_license'),
|
|
||||||
];
|
|
||||||
|
|
||||||
return $this->success($json);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function verifyToken(Request $request)
|
protected function verifyToken(Request $request)
|
||||||
|
@ -45,7 +45,7 @@ class InviteController extends Controller
|
|||||||
$codes = InviteCode::where('user_id', $request->session()->get('id'))
|
$codes = InviteCode::where('user_id', $request->session()->get('id'))
|
||||||
->where('status', 0)
|
->where('status', 0)
|
||||||
->get();
|
->get();
|
||||||
$commission_rate = config('v2board.invite_commission');
|
$commission_rate = config('v2board.invite_commission', 10);
|
||||||
$user = User::find($request->session()->get('id'));
|
$user = User::find($request->session()->get('id'));
|
||||||
if ($user->commission_rate) {
|
if ($user->commission_rate) {
|
||||||
$commission_rate = $user->commission_rate;
|
$commission_rate = $user->commission_rate;
|
||||||
|
@ -4,6 +4,8 @@ namespace App\Http\Controllers\User;
|
|||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\User\OrderSave;
|
use App\Http\Requests\User\OrderSave;
|
||||||
|
use App\Services\OrderService;
|
||||||
|
use App\Services\UserService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
@ -162,8 +164,7 @@ class OrderController extends Controller
|
|||||||
$order->cycle = $request->input('cycle');
|
$order->cycle = $request->input('cycle');
|
||||||
$order->trade_no = Helper::guid();
|
$order->trade_no = Helper::guid();
|
||||||
$order->total_amount = $plan[$request->input('cycle')];
|
$order->total_amount = $plan[$request->input('cycle')];
|
||||||
// discount start
|
// coupon start
|
||||||
// coupon
|
|
||||||
if (isset($coupon)) {
|
if (isset($coupon)) {
|
||||||
switch ($coupon->type) {
|
switch ($coupon->type) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -181,13 +182,13 @@ class OrderController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// user
|
// coupon complete
|
||||||
|
// discount start
|
||||||
if ($user->discount) {
|
if ($user->discount) {
|
||||||
$order->discount_amount = $order->discount_amount + ($order->total_amount * ($user->discount / 100));
|
$order->discount_amount = $order->discount_amount + ($order->total_amount * ($user->discount / 100));
|
||||||
}
|
}
|
||||||
// discount complete
|
|
||||||
$order->total_amount = $order->total_amount - $order->discount_amount;
|
|
||||||
// discount end
|
// discount end
|
||||||
|
$order->total_amount = $order->total_amount - $order->discount_amount;
|
||||||
// renew and change subscribe process
|
// renew and change subscribe process
|
||||||
if ($user->plan_id !== NULL && $order->plan_id !== $user->plan_id) {
|
if ($user->plan_id !== NULL && $order->plan_id !== $user->plan_id) {
|
||||||
if (!(int)config('v2board.plan_change_enable', 1)) abort(500, '目前不允许更改订阅,请联系客服或提交工单');
|
if (!(int)config('v2board.plan_change_enable', 1)) abort(500, '目前不允许更改订阅,请联系客服或提交工单');
|
||||||
@ -207,13 +208,37 @@ class OrderController extends Controller
|
|||||||
// invite process
|
// invite process
|
||||||
if ($user->invite_user_id && $order->total_amount > 0) {
|
if ($user->invite_user_id && $order->total_amount > 0) {
|
||||||
$order->invite_user_id = $user->invite_user_id;
|
$order->invite_user_id = $user->invite_user_id;
|
||||||
$inviter = User::find($user->invite_user_id);
|
$commissionFirstTime = (int)config('v2board.commission_first_time_enable', 1);
|
||||||
if ($inviter && $inviter->commission_rate) {
|
if (!$commissionFirstTime || ($commissionFirstTime && !Order::where('user_id', $user->id)->where('status', 3)->first())) {
|
||||||
$order->commission_balance = $order->total_amount * ($inviter->commission_rate / 100);
|
$inviter = User::find($user->invite_user_id);
|
||||||
} else {
|
if ($inviter && $inviter->commission_rate) {
|
||||||
$order->commission_balance = $order->total_amount * (config('v2board.invite_commission', 10) / 100);
|
$order->commission_balance = $order->total_amount * ($inviter->commission_rate / 100);
|
||||||
|
} else {
|
||||||
|
$order->commission_balance = $order->total_amount * (config('v2board.invite_commission', 10) / 100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// use balance
|
||||||
|
if ($user->balance && $order->total_amount > 0) {
|
||||||
|
$remainingBalance = $user->balance - $order->total_amount;
|
||||||
|
$userService = new UserService();
|
||||||
|
if ($remainingBalance > 0) {
|
||||||
|
if (!$userService->addBalance($order->user_id, - $order->total_amount)) {
|
||||||
|
DB::rollBack();
|
||||||
|
abort(500, '余额不足');
|
||||||
|
}
|
||||||
|
$order->balance_amount = $order->total_amount;
|
||||||
|
$order->total_amount = 0;
|
||||||
|
} else {
|
||||||
|
if (!$userService->addBalance($order->user_id, - $user->balance)) {
|
||||||
|
DB::rollBack();
|
||||||
|
abort(500, '余额不足');
|
||||||
|
}
|
||||||
|
$order->balance_amount = $user->balance;
|
||||||
|
$order->total_amount = $order->total_amount - $user->balance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!$order->save()) {
|
if (!$order->save()) {
|
||||||
DB::rollback();
|
DB::rollback();
|
||||||
abort(500, '订单创建失败');
|
abort(500, '订单创建失败');
|
||||||
@ -371,8 +396,8 @@ class OrderController extends Controller
|
|||||||
if ($order->status !== 0) {
|
if ($order->status !== 0) {
|
||||||
abort(500, '只可以取消待支付订单');
|
abort(500, '只可以取消待支付订单');
|
||||||
}
|
}
|
||||||
$order->status = 2;
|
$orderService = new OrderService($order);
|
||||||
if (!$order->save()) {
|
if (!$orderService->cancel()) {
|
||||||
abort(500, '取消失败');
|
abort(500, '取消失败');
|
||||||
}
|
}
|
||||||
return response([
|
return response([
|
||||||
|
@ -132,7 +132,9 @@ class UserController extends Controller
|
|||||||
if (!$user) {
|
if (!$user) {
|
||||||
abort(500, '该用户不存在');
|
abort(500, '该用户不存在');
|
||||||
}
|
}
|
||||||
if (!$user->update($updateData)) {
|
try {
|
||||||
|
$user->update($updateData);
|
||||||
|
} catch (\Exception $e) {
|
||||||
abort(500, '保存失败');
|
abort(500, '保存失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,11 +7,14 @@ use Illuminate\Foundation\Http\FormRequest;
|
|||||||
class ConfigSave extends FormRequest
|
class ConfigSave extends FormRequest
|
||||||
{
|
{
|
||||||
CONST RULES = [
|
CONST RULES = [
|
||||||
|
// invite & commission
|
||||||
'safe_mode_enable' => 'in:0,1',
|
'safe_mode_enable' => 'in:0,1',
|
||||||
'invite_force' => 'in:0,1',
|
'invite_force' => 'in:0,1',
|
||||||
'invite_commission' => 'integer',
|
'invite_commission' => 'integer',
|
||||||
'invite_gen_limit' => 'integer',
|
'invite_gen_limit' => 'integer',
|
||||||
'invite_never_expire' => 'in:0,1',
|
'invite_never_expire' => 'in:0,1',
|
||||||
|
'commission_first_time_enable' => 'in:0,1',
|
||||||
|
// site
|
||||||
'stop_register' => 'in:0,1',
|
'stop_register' => 'in:0,1',
|
||||||
'email_verify' => 'in:0,1',
|
'email_verify' => 'in:0,1',
|
||||||
'app_name' => '',
|
'app_name' => '',
|
||||||
@ -56,7 +59,9 @@ class ConfigSave extends FormRequest
|
|||||||
'frontend_background_url' => 'nullable|url',
|
'frontend_background_url' => 'nullable|url',
|
||||||
// tutorial
|
// tutorial
|
||||||
'apple_id' => 'email',
|
'apple_id' => 'email',
|
||||||
'apple_id_password' => ''
|
'apple_id_password' => '',
|
||||||
|
// email
|
||||||
|
'email_template' => ''
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,6 @@ use Illuminate\Foundation\Http\FormRequest;
|
|||||||
class ServerSave extends FormRequest
|
class ServerSave extends FormRequest
|
||||||
{
|
{
|
||||||
CONST RULES = [
|
CONST RULES = [
|
||||||
'rules' => '',
|
|
||||||
'show' => '',
|
'show' => '',
|
||||||
'name' => 'required',
|
'name' => 'required',
|
||||||
'group_id' => 'required|array',
|
'group_id' => 'required|array',
|
||||||
@ -19,7 +18,9 @@ class ServerSave extends FormRequest
|
|||||||
'tags' => 'nullable|array',
|
'tags' => 'nullable|array',
|
||||||
'rate' => 'required|numeric',
|
'rate' => 'required|numeric',
|
||||||
'network' => 'required|in:tcp,kcp,ws,http,domainsocket,quic',
|
'network' => 'required|in:tcp,kcp,ws,http,domainsocket,quic',
|
||||||
'settings' => ''
|
'networkSettings' => '',
|
||||||
|
'ruleSettings' => '',
|
||||||
|
'tlsSettings' => ''
|
||||||
];
|
];
|
||||||
/**
|
/**
|
||||||
* Get the validation rules that apply to the request.
|
* Get the validation rules that apply to the request.
|
||||||
|
@ -14,6 +14,7 @@ class AdminRoute
|
|||||||
// Config
|
// Config
|
||||||
$router->get ('/config/fetch', 'Admin\\ConfigController@fetch');
|
$router->get ('/config/fetch', 'Admin\\ConfigController@fetch');
|
||||||
$router->post('/config/save', 'Admin\\ConfigController@save');
|
$router->post('/config/save', 'Admin\\ConfigController@save');
|
||||||
|
$router->get ('/config/getEmailTemplate', 'Admin\\ConfigController@getEmailTemplate');
|
||||||
// Plan
|
// Plan
|
||||||
$router->get ('/plan/fetch', 'Admin\\PlanController@fetch');
|
$router->get ('/plan/fetch', 'Admin\\PlanController@fetch');
|
||||||
$router->post('/plan/save', 'Admin\\PlanController@save');
|
$router->post('/plan/save', 'Admin\\PlanController@save');
|
||||||
@ -27,6 +28,7 @@ class AdminRoute
|
|||||||
$router->post('/server/group/drop', 'Admin\\ServerController@groupDrop');
|
$router->post('/server/group/drop', 'Admin\\ServerController@groupDrop');
|
||||||
$router->post('/server/drop', 'Admin\\ServerController@drop');
|
$router->post('/server/drop', 'Admin\\ServerController@drop');
|
||||||
$router->post('/server/update', 'Admin\\ServerController@update');
|
$router->post('/server/update', 'Admin\\ServerController@update');
|
||||||
|
$router->post('/server/copy', 'Admin\\ServerController@copy');
|
||||||
// Order
|
// Order
|
||||||
$router->get ('/order/fetch', 'Admin\\OrderController@fetch');
|
$router->get ('/order/fetch', 'Admin\\OrderController@fetch');
|
||||||
$router->post('/order/repair', 'Admin\\OrderController@repair');
|
$router->post('/order/repair', 'Admin\\OrderController@repair');
|
||||||
|
@ -10,7 +10,7 @@ use Illuminate\Queue\SerializesModels;
|
|||||||
use Illuminate\Support\Facades\Mail;
|
use Illuminate\Support\Facades\Mail;
|
||||||
use App\Models\MailLog;
|
use App\Models\MailLog;
|
||||||
|
|
||||||
class SendEmail implements ShouldQueue
|
class SendEmailJob implements ShouldQueue
|
||||||
{
|
{
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
protected $params;
|
protected $params;
|
||||||
@ -22,6 +22,7 @@ class SendEmail implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function __construct($params)
|
public function __construct($params)
|
||||||
{
|
{
|
||||||
|
$this->onQueue('send_email');
|
||||||
$this->params = $params;
|
$this->params = $params;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +36,7 @@ class SendEmail implements ShouldQueue
|
|||||||
$params = $this->params;
|
$params = $this->params;
|
||||||
$email = $params['email'];
|
$email = $params['email'];
|
||||||
$subject = $params['subject'];
|
$subject = $params['subject'];
|
||||||
|
$params['template_name'] = 'mail.' . config('v2board.email_template', 'default') . '.' . $params['template_name'];
|
||||||
try {
|
try {
|
||||||
Mail::send(
|
Mail::send(
|
||||||
$params['template_name'],
|
$params['template_name'],
|
36
app/Services/OrderService.php
Normal file
36
app/Services/OrderService.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Models\Order;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class OrderService
|
||||||
|
{
|
||||||
|
public $order;
|
||||||
|
|
||||||
|
public function __construct(Order $order)
|
||||||
|
{
|
||||||
|
$this->order = $order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cancel():bool
|
||||||
|
{
|
||||||
|
$order = $this->order;
|
||||||
|
DB::beginTransaction();
|
||||||
|
$order->status = 2;
|
||||||
|
if (!$order->save()) {
|
||||||
|
DB::rollBack();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($order->balance_amount) {
|
||||||
|
$userService = new UserService();
|
||||||
|
if (!$userService->addBalance($order->user_id, $order->balance_amount)) {
|
||||||
|
DB::rollBack();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DB::commit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -3,9 +3,13 @@
|
|||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\Models\Server;
|
||||||
|
|
||||||
class ServerService
|
class ServerService
|
||||||
{
|
{
|
||||||
|
|
||||||
|
CONST SERVER_CONFIG = '{"api":{"services":["HandlerService","StatsService"],"tag":"api"},"stats":{},"inbound":{"port":443,"protocol":"vmess","settings":{"clients":[]},"sniffing":{"enabled": true,"destOverride": ["http","tls"]},"streamSettings":{"network":"tcp"},"tag":"proxy"},"inboundDetour":[{"listen":"0.0.0.0","port":23333,"protocol":"dokodemo-door","settings":{"address":"0.0.0.0"},"tag":"api"}],"log":{"loglevel":"debug","access":"access.log","error":"error.log"},"outbound":{"protocol":"freedom","settings":{}},"outboundDetour":[{"protocol":"blackhole","settings":{},"tag":"block"}],"routing":{"rules":[{"inboundTag":"api","outboundTag":"api","type":"field"}]},"policy":{"levels":{"0":{"handshake":4,"connIdle":300,"uplinkOnly":5,"downlinkOnly":30,"statsUserUplink":true,"statsUserDownlink":true}}}}';
|
||||||
|
|
||||||
public function getAvailableUsers($groupId)
|
public function getAvailableUsers($groupId)
|
||||||
{
|
{
|
||||||
return User::whereIn('group_id', $groupId)
|
return User::whereIn('group_id', $groupId)
|
||||||
@ -28,4 +32,77 @@ class ServerService
|
|||||||
])
|
])
|
||||||
->get();
|
->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getConfig(int $nodeId, int $localPort)
|
||||||
|
{
|
||||||
|
$server = Server::find($nodeId);
|
||||||
|
if (!$server) {
|
||||||
|
abort(500, '节点不存在');
|
||||||
|
}
|
||||||
|
$json = json_decode(self::SERVER_CONFIG);
|
||||||
|
$json->inboundDetour[0]->port = (int)$localPort;
|
||||||
|
$json->inbound->port = (int)$server->server_port;
|
||||||
|
$json->inbound->streamSettings->network = $server->network;
|
||||||
|
if ($server->networkSettings) {
|
||||||
|
switch ($server->network) {
|
||||||
|
case 'tcp':
|
||||||
|
$json->inbound->streamSettings->tcpSettings = json_decode($server->networkSettings);
|
||||||
|
break;
|
||||||
|
case 'kcp':
|
||||||
|
$json->inbound->streamSettings->kcpSettings = json_decode($server->networkSettings);
|
||||||
|
break;
|
||||||
|
case 'ws':
|
||||||
|
$json->inbound->streamSettings->wsSettings = json_decode($server->networkSettings);
|
||||||
|
break;
|
||||||
|
case 'http':
|
||||||
|
$json->inbound->streamSettings->httpSettings = json_decode($server->networkSettings);
|
||||||
|
break;
|
||||||
|
case 'domainsocket':
|
||||||
|
$json->inbound->streamSettings->dsSettings = json_decode($server->networkSettings);
|
||||||
|
break;
|
||||||
|
case 'quic':
|
||||||
|
$json->inbound->streamSettings->quicSettings = json_decode($server->networkSettings);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($server->ruleSettings) {
|
||||||
|
$rules = json_decode($server->ruleSettings);
|
||||||
|
// domain
|
||||||
|
if (isset($rules->domain) && !empty($rules->domain)) {
|
||||||
|
$domainObj = new \StdClass();
|
||||||
|
$domainObj->type = 'field';
|
||||||
|
$domainObj->domain = $rules->domain;
|
||||||
|
$domainObj->outboundTag = 'block';
|
||||||
|
array_push($json->routing->rules, $domainObj);
|
||||||
|
}
|
||||||
|
// protocol
|
||||||
|
if (isset($rules->protocol) && !empty($rules->protocol)) {
|
||||||
|
$protocolObj = new \StdClass();
|
||||||
|
$protocolObj->type = 'field';
|
||||||
|
$protocolObj->protocol = $rules->protocol;
|
||||||
|
$protocolObj->outboundTag = 'block';
|
||||||
|
array_push($json->routing->rules, $protocolObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((int)$server->tls) {
|
||||||
|
$tlsSettings = json_decode($server->tlsSettings);
|
||||||
|
$json->inbound->streamSettings->security = 'tls';
|
||||||
|
$tls = (object)[
|
||||||
|
'certificateFile' => '/home/v2ray.crt',
|
||||||
|
'keyFile' => '/home/v2ray.key'
|
||||||
|
];
|
||||||
|
$json->inbound->streamSettings->tlsSettings = new \StdClass();
|
||||||
|
if (isset($tlsSettings->serverName)) {
|
||||||
|
$json->inbound->streamSettings->tlsSettings->serverName = (string)$tlsSettings->serverName;
|
||||||
|
}
|
||||||
|
if (isset($tlsSettings->allowInsecure)) {
|
||||||
|
$json->inbound->streamSettings->tlsSettings->allowInsecure = (int)$tlsSettings->allowInsecure ? true : false;
|
||||||
|
}
|
||||||
|
$json->inbound->streamSettings->tlsSettings->certificates[0] = $tls;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $json;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,4 +47,20 @@ class UserService
|
|||||||
{
|
{
|
||||||
return User::all();
|
return User::all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addBalance(int $userId, int $balance):bool
|
||||||
|
{
|
||||||
|
$user = User::find($userId);
|
||||||
|
if (!$user) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$user->balance = $user->balance + $balance;
|
||||||
|
if ($user->balance < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!$user->save()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,16 @@ namespace App\Utils;
|
|||||||
|
|
||||||
class CacheKey
|
class CacheKey
|
||||||
{
|
{
|
||||||
|
CONST KEYS = [
|
||||||
|
'EMAIL_VERIFY_CODE' => '邮箱验证吗',
|
||||||
|
'LAST_SEND_EMAIL_VERIFY_TIMESTAMP' => '最后一次发送邮箱验证码时间'
|
||||||
|
];
|
||||||
|
|
||||||
|
public static function get(string $key, $uniqueValue)
|
||||||
|
{
|
||||||
|
if (!in_array($key, array_keys(self::KEYS))) {
|
||||||
|
abort(500, 'key is not in cache key list');
|
||||||
|
}
|
||||||
|
return $key . '_' . $uniqueValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Utils;
|
namespace App\Utils;
|
||||||
|
|
||||||
|
use App\Models\Server;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
class Helper
|
class Helper
|
||||||
{
|
{
|
||||||
public static function guid($format = false)
|
public static function guid($format = false)
|
||||||
@ -53,23 +56,23 @@ class Helper
|
|||||||
return $str;
|
return $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function buildVmessLink($item, $user)
|
public static function buildVmessLink(Server $server, User $user)
|
||||||
{
|
{
|
||||||
$config = [
|
$config = [
|
||||||
"v" => "2",
|
"v" => "2",
|
||||||
"ps" => $item->name,
|
"ps" => $server->name,
|
||||||
"add" => $item->host,
|
"add" => $server->host,
|
||||||
"port" => $item->port,
|
"port" => $server->port,
|
||||||
"id" => $user->v2ray_uuid,
|
"id" => $user->v2ray_uuid,
|
||||||
"aid" => "2",
|
"aid" => "2",
|
||||||
"net" => $item->network,
|
"net" => $server->network,
|
||||||
"type" => "none",
|
"type" => "none",
|
||||||
"host" => "",
|
"host" => "",
|
||||||
"path" => "",
|
"path" => "",
|
||||||
"tls" => $item->tls ? "tls" : ""
|
"tls" => $server->tls ? "tls" : ""
|
||||||
];
|
];
|
||||||
if ($item->network == 'ws') {
|
if ((string)$server->network === 'ws') {
|
||||||
$wsSettings = json_decode($item->settings);
|
$wsSettings = json_decode($server->networkSettings);
|
||||||
if (isset($wsSettings->path)) $config['path'] = $wsSettings->path;
|
if (isset($wsSettings->path)) $config['path'] = $wsSettings->path;
|
||||||
if (isset($wsSettings->headers->Host)) $config['host'] = $wsSettings->headers->Host;
|
if (isset($wsSettings->headers->Host)) $config['host'] = $wsSettings->headers->Host;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
"fideloper/proxy": "^4.0",
|
"fideloper/proxy": "^4.0",
|
||||||
"laravel/framework": "^6.0",
|
"laravel/framework": "^6.0",
|
||||||
"laravel/tinker": "^1.0",
|
"laravel/tinker": "^1.0",
|
||||||
"lokielse/omnipay-alipay": "^3.0",
|
"lokielse/omnipay-alipay": "3.0.6",
|
||||||
"php-curl-class/php-curl-class": "^8.6",
|
"php-curl-class/php-curl-class": "^8.6",
|
||||||
"stripe/stripe-php": "^7.5",
|
"stripe/stripe-php": "^7.5",
|
||||||
"symfony/yaml": "^4.3"
|
"symfony/yaml": "^4.3"
|
||||||
|
@ -67,7 +67,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'timezone' => 'UTC',
|
'timezone' => 'Asia/Shanghai',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -236,5 +236,5 @@ return [
|
|||||||
| The only modification by laravel config
|
| The only modification by laravel config
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
'version' => '1.2.2'
|
'version' => '1.2.3'
|
||||||
];
|
];
|
||||||
|
@ -87,6 +87,7 @@ CREATE TABLE `v2_order` (
|
|||||||
`discount_amount` int(11) DEFAULT NULL,
|
`discount_amount` int(11) DEFAULT NULL,
|
||||||
`surplus_amount` int(11) DEFAULT NULL COMMENT '剩余价值',
|
`surplus_amount` int(11) DEFAULT NULL COMMENT '剩余价值',
|
||||||
`refund_amount` int(11) DEFAULT NULL COMMENT '退款金额',
|
`refund_amount` int(11) DEFAULT NULL COMMENT '退款金额',
|
||||||
|
`balance_amount` int(11) DEFAULT NULL COMMENT '使用余额',
|
||||||
`status` tinyint(1) NOT NULL DEFAULT '0',
|
`status` tinyint(1) NOT NULL DEFAULT '0',
|
||||||
`commission_status` tinyint(1) NOT NULL DEFAULT '0',
|
`commission_status` tinyint(1) NOT NULL DEFAULT '0',
|
||||||
`commission_balance` int(11) NOT NULL DEFAULT '0',
|
`commission_balance` int(11) NOT NULL DEFAULT '0',
|
||||||
@ -131,6 +132,9 @@ CREATE TABLE `v2_server` (
|
|||||||
`network` varchar(11) NOT NULL,
|
`network` varchar(11) NOT NULL,
|
||||||
`settings` text,
|
`settings` text,
|
||||||
`rules` text,
|
`rules` text,
|
||||||
|
`networkSettings` text,
|
||||||
|
`tlsSettings` text,
|
||||||
|
`ruleSettings` text,
|
||||||
`show` tinyint(1) NOT NULL DEFAULT '0',
|
`show` tinyint(1) NOT NULL DEFAULT '0',
|
||||||
`created_at` int(11) NOT NULL,
|
`created_at` int(11) NOT NULL,
|
||||||
`updated_at` int(11) NOT NULL,
|
`updated_at` int(11) NOT NULL,
|
||||||
@ -239,4 +243,4 @@ CREATE TABLE `v2_user` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
-- 2020-03-05 14:10:26
|
-- 2020-03-17 14:16:01
|
||||||
|
@ -185,3 +185,18 @@ CHANGE `expired_at` `expired_at` bigint(20) NULL DEFAULT '0' AFTER `token`;
|
|||||||
|
|
||||||
ALTER TABLE `v2_tutorial`
|
ALTER TABLE `v2_tutorial`
|
||||||
DROP `icon`;
|
DROP `icon`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_server`
|
||||||
|
CHANGE `settings` `networkSettings` text COLLATE 'utf8_general_ci' NULL AFTER `network`,
|
||||||
|
CHANGE `rules` `ruleSettings` text COLLATE 'utf8_general_ci' NULL AFTER `networkSettings`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_server`
|
||||||
|
CHANGE `tags` `tags` varchar(255) COLLATE 'utf8_general_ci' NULL AFTER `server_port`,
|
||||||
|
CHANGE `rate` `rate` varchar(11) COLLATE 'utf8_general_ci' NOT NULL AFTER `tags`,
|
||||||
|
CHANGE `network` `network` varchar(11) COLLATE 'utf8_general_ci' NOT NULL AFTER `rate`,
|
||||||
|
CHANGE `networkSettings` `networkSettings` text COLLATE 'utf8_general_ci' NULL AFTER `network`,
|
||||||
|
CHANGE `tls` `tls` tinyint(4) NOT NULL DEFAULT '0' AFTER `networkSettings`,
|
||||||
|
ADD `tlsSettings` text COLLATE 'utf8_general_ci' NULL AFTER `tls`;
|
||||||
|
|
||||||
|
ALTER TABLE `v2_order`
|
||||||
|
ADD `balance_amount` int(11) NULL COMMENT '使用余额' AFTER `refund_amount`;
|
||||||
|
4
pm2.yaml
4
pm2.yaml
@ -1,5 +1,5 @@
|
|||||||
apps:
|
apps:
|
||||||
- name : 'V2Board'
|
- name : 'V2Board'
|
||||||
script : 'php artisan queue:work --queue=verify_mail,other_mail'
|
script : 'php artisan queue:work --queue=send_email'
|
||||||
instances: 4
|
instances: 4
|
||||||
out_file : './storage/logs/queue/queue.log'
|
out_file : './storage/logs/queue/queue.log'
|
||||||
|
2
public/assets/admin/umi.js
vendored
2
public/assets/admin/umi.js
vendored
File diff suppressed because one or more lines are too long
2
public/assets/user/umi.css
vendored
2
public/assets/user/umi.css
vendored
File diff suppressed because one or more lines are too long
2
public/assets/user/umi.js
vendored
2
public/assets/user/umi.js
vendored
File diff suppressed because one or more lines are too long
187
resources/views/mail/classic/notify.blade.php
Normal file
187
resources/views/mail/classic/notify.blade.php
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>网站公告</title>
|
||||||
|
<style type="text/css">
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-webkit-text-size-adjust: none;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100%;
|
||||||
|
line-height: 1.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 640px) {
|
||||||
|
body {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 22px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 18px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrap {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body itemscope itemtype="http://schema.org/EmailMessage"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;"
|
||||||
|
bgcolor="#f6f6f6">
|
||||||
|
<table class="body-wrap"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background-color: #f6f6f6; margin: 0;"
|
||||||
|
bgcolor="#f6f6f6">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"
|
||||||
|
valign="top">
|
||||||
|
</td>
|
||||||
|
<td class="container" width="600"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto;"
|
||||||
|
valign="top">
|
||||||
|
<div class="content"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;">
|
||||||
|
<table class="main" width="100%" cellpadding="0" cellspacing="0"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;"
|
||||||
|
bgcolor="#fff">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="alert alert-warning"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 22px; font-weight: bold; vertical-align: top; color: #fff; font-weight: 500; text-align: center; border-radius: 3px 3px 0 0; background-color: #0073ba; margin: 0; padding: 20px;"
|
||||||
|
align="center" bgcolor="#0073ba" valign="top">
|
||||||
|
网站公告
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-wrap"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;"
|
||||||
|
valign="top">
|
||||||
|
<table width="100%" cellpadding="0" cellspacing="0"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 34px; vertical-align: top; line-height: 1em; margin: 0; padding: 20px 0 30px;"
|
||||||
|
valign="top">
|
||||||
|
Dear Customer
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 16px; color: #4a4a4a; vertical-align: top; margin: 0; padding: 0 10px 20px;"
|
||||||
|
valign="top">
|
||||||
|
{!! nl2br($content) !!}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #757575; vertical-align: top; margin: 0; padding: 0 0 20px;"
|
||||||
|
valign="top">
|
||||||
|
(本邮件由系统自动发出,请勿直接回复)
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; text-align: center; vertical-align: top; margin: 0; padding: 0 0 20px;"
|
||||||
|
valign="top">
|
||||||
|
<a href="{{$url}}"
|
||||||
|
class="btn-primary"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; color: #fff; text-decoration: none; line-height: 2em; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; text-transform: capitalize; background-color: #0073ba; margin: 0; border-color: #0073ba; border-style: solid; border-width: 8px 20px;">登录 {{$name}}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="footer"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">
|
||||||
|
<table width="100%"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="aligncenter content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0;"
|
||||||
|
align="center" valign="top">
|
||||||
|
© {{$name}}. All Rights Reserved.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="aligncenter content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0 0 20px;"
|
||||||
|
align="center" valign="top">
|
||||||
|
<a href="{{$url}}/#/subscribe"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: none; margin: 0;">我的订阅</a> |
|
||||||
|
<a href="{{$url}}/#/tutorial"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: none; margin: 0;">使用教程</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"
|
||||||
|
valign="top">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
187
resources/views/mail/classic/remindExpire.blade.php
Normal file
187
resources/views/mail/classic/remindExpire.blade.php
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>到期提示</title>
|
||||||
|
<style type="text/css">
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-webkit-text-size-adjust: none;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100%;
|
||||||
|
line-height: 1.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 640px) {
|
||||||
|
body {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 22px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 18px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrap {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body itemscope itemtype="http://schema.org/EmailMessage"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;"
|
||||||
|
bgcolor="#f6f6f6">
|
||||||
|
<table class="body-wrap"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background-color: #f6f6f6; margin: 0;"
|
||||||
|
bgcolor="#f6f6f6">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"
|
||||||
|
valign="top">
|
||||||
|
</td>
|
||||||
|
<td class="container" width="600"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto;"
|
||||||
|
valign="top">
|
||||||
|
<div class="content"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;">
|
||||||
|
<table class="main" width="100%" cellpadding="0" cellspacing="0"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;"
|
||||||
|
bgcolor="#fff">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="alert alert-warning"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 22px; font-weight: bold; vertical-align: top; color: #fff; font-weight: 500; text-align: center; border-radius: 3px 3px 0 0; background-color: #0073ba; margin: 0; padding: 20px;"
|
||||||
|
align="center" bgcolor="#0073ba" valign="top">
|
||||||
|
到期提示
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-wrap"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;"
|
||||||
|
valign="top">
|
||||||
|
<table width="100%" cellpadding="0" cellspacing="0"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 34px; vertical-align: top; line-height: 1em; margin: 0; padding: 20px 0 30px;"
|
||||||
|
valign="top">
|
||||||
|
Dear Customer
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 16px; color: #4a4a4a; vertical-align: top; margin: 0; padding: 0 0 20px;"
|
||||||
|
valign="top">
|
||||||
|
您的订阅套餐将于 <strong>24</strong> 小时后到期,请及时续费
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #757575; vertical-align: top; margin: 0; padding: 0 0 20px;"
|
||||||
|
valign="top">
|
||||||
|
(本邮件由系统自动发出,请勿直接回复)
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; text-align: center; vertical-align: top; margin: 0; padding: 0 0 20px;"
|
||||||
|
valign="top">
|
||||||
|
<a href="{{$url}}"
|
||||||
|
class="btn-primary"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; color: #fff; text-decoration: none; line-height: 2em; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; text-transform: capitalize; background-color: #0073ba; margin: 0; border-color: #0073ba; border-style: solid; border-width: 8px 20px;">登录 {{$name}}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="footer"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">
|
||||||
|
<table width="100%"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="aligncenter content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0;"
|
||||||
|
align="center" valign="top">
|
||||||
|
© {{$name}}. All Rights Reserved.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="aligncenter content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0 0 20px;"
|
||||||
|
align="center" valign="top">
|
||||||
|
<a href="{{$url}}/#/subscribe"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: none; margin: 0;">我的订阅</a> |
|
||||||
|
<a href="{{$url}}/#/tutorial"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: none; margin: 0;">使用教程</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"
|
||||||
|
valign="top">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
187
resources/views/mail/classic/remindTraffic.blade.php
Normal file
187
resources/views/mail/classic/remindTraffic.blade.php
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>流量提示</title>
|
||||||
|
<style type="text/css">
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-webkit-text-size-adjust: none;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100%;
|
||||||
|
line-height: 1.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 640px) {
|
||||||
|
body {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 22px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 18px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrap {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body itemscope itemtype="http://schema.org/EmailMessage"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;"
|
||||||
|
bgcolor="#f6f6f6">
|
||||||
|
<table class="body-wrap"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background-color: #f6f6f6; margin: 0;"
|
||||||
|
bgcolor="#f6f6f6">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"
|
||||||
|
valign="top">
|
||||||
|
</td>
|
||||||
|
<td class="container" width="600"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto;"
|
||||||
|
valign="top">
|
||||||
|
<div class="content"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;">
|
||||||
|
<table class="main" width="100%" cellpadding="0" cellspacing="0"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;"
|
||||||
|
bgcolor="#fff">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="alert alert-warning"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 22px; font-weight: bold; vertical-align: top; color: #fff; font-weight: 500; text-align: center; border-radius: 3px 3px 0 0; background-color: #0073ba; margin: 0; padding: 20px;"
|
||||||
|
align="center" bgcolor="#0073ba" valign="top">
|
||||||
|
流量提示
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-wrap"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;"
|
||||||
|
valign="top">
|
||||||
|
<table width="100%" cellpadding="0" cellspacing="0"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 34px; vertical-align: top; line-height: 1em; margin: 0; padding: 20px 0 30px;"
|
||||||
|
valign="top">
|
||||||
|
Dear Customer
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 16px; color: #4a4a4a; vertical-align: top; margin: 0; padding: 0 0 20px;"
|
||||||
|
valign="top">
|
||||||
|
您本月的套餐流量已使用 <strong>80%</strong>,请合理安排使用,避免提前耗尽
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #757575; vertical-align: top; margin: 0; padding: 0 0 20px;"
|
||||||
|
valign="top">
|
||||||
|
(本邮件由系统自动发出,请勿直接回复)
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; text-align: center; vertical-align: top; margin: 0; padding: 0 0 20px;"
|
||||||
|
valign="top">
|
||||||
|
<a href="{{$url}}"
|
||||||
|
class="btn-primary"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; color: #fff; text-decoration: none; line-height: 2em; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; text-transform: capitalize; background-color: #0073ba; margin: 0; border-color: #0073ba; border-style: solid; border-width: 8px 20px;">登录 {{$name}}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="footer"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">
|
||||||
|
<table width="100%"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="aligncenter content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0;"
|
||||||
|
align="center" valign="top">
|
||||||
|
© {{$name}}. All Rights Reserved.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="aligncenter content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0 0 20px;"
|
||||||
|
align="center" valign="top">
|
||||||
|
<a href="{{$url}}/#/subscribe"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: none; margin: 0;">我的订阅</a> |
|
||||||
|
<a href="{{$url}}/#/tutorial"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: none; margin: 0;">使用教程</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"
|
||||||
|
valign="top">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
195
resources/views/mail/classic/verify.blade.php
Normal file
195
resources/views/mail/classic/verify.blade.php
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>邮箱验证码</title>
|
||||||
|
<style type="text/css">
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-webkit-text-size-adjust: none;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100%;
|
||||||
|
line-height: 1.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 640px) {
|
||||||
|
body {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-weight: 800 !important;
|
||||||
|
margin: 20px 0 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 22px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 18px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrap {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invoice {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body itemscope itemtype="http://schema.org/EmailMessage"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;"
|
||||||
|
bgcolor="#f6f6f6">
|
||||||
|
<table class="body-wrap"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background-color: #f6f6f6; margin: 0;"
|
||||||
|
bgcolor="#f6f6f6">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"
|
||||||
|
valign="top">
|
||||||
|
</td>
|
||||||
|
<td class="container" width="600"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto;"
|
||||||
|
valign="top">
|
||||||
|
<div class="content"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;">
|
||||||
|
<table class="main" width="100%" cellpadding="0" cellspacing="0"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;"
|
||||||
|
bgcolor="#fff">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="alert alert-warning"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 22px; font-weight: bold; vertical-align: top; color: #fff; font-weight: 500; text-align: center; border-radius: 3px 3px 0 0; background-color: #0073ba; margin: 0; padding: 20px;"
|
||||||
|
align="center" bgcolor="#0073ba" valign="top">
|
||||||
|
邮箱验证码
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-wrap"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;"
|
||||||
|
valign="top">
|
||||||
|
<table width="100%" cellpadding="0" cellspacing="0"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 34px; vertical-align: top; line-height: 1em; margin: 0; padding: 20px 0 30px;"
|
||||||
|
valign="top">
|
||||||
|
Dear Customer
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 16px; color: #4a4a4a; vertical-align: top; margin: 0; padding: 0 0 20px;"
|
||||||
|
valign="top">
|
||||||
|
请填写以下验证码完成邮箱验证 (1分钟内有效)
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 36px; font-weight: bold; text-align: center; color: #4a4a4a; vertical-align: top; line-height: 1.6em; margin: 0; padding: 0 0 20px;"
|
||||||
|
valign="top">
|
||||||
|
{{$code}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #757575; vertical-align: top; margin: 0; padding: 0 0 20px;"
|
||||||
|
valign="top">
|
||||||
|
(本邮件由系统自动发出,请勿直接回复)
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; text-align: center; vertical-align: top; margin: 0; padding: 0 0 20px;"
|
||||||
|
valign="top">
|
||||||
|
<a href="{{$url}}"
|
||||||
|
class="btn-primary"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; color: #fff; text-decoration: none; line-height: 2em; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; text-transform: capitalize; background-color: #0073ba; margin: 0; border-color: #0073ba; border-style: solid; border-width: 8px 20px;">登录 {{$name}}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="footer"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">
|
||||||
|
<table width="100%"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="aligncenter content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0;"
|
||||||
|
align="center" valign="top">
|
||||||
|
© {{$name}}. All Rights Reserved.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
||||||
|
<td class="aligncenter content-block"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0 0 20px;"
|
||||||
|
align="center" valign="top">
|
||||||
|
<a href="{{$url}}/#/subscribe"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: none; margin: 0;">我的订阅</a> |
|
||||||
|
<a href="{{$url}}/#/tutorial"
|
||||||
|
style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: none; margin: 0;">使用教程</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;"
|
||||||
|
valign="top">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
42
resources/views/mail/default/notify.blade.php
Normal file
42
resources/views/mail/default/notify.blade.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<div style="background: #eee">
|
||||||
|
<table width="600" border="0" align="center" cellpadding="0" cellspacing="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div style="background:#fff">
|
||||||
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td valign="middle" style="padding-left:30px;background-color:#415A94;color:#fff;padding:20px 40px;font-size: 21px;">{{$name}}</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr style="padding:40px 40px 0 40px;display:table-cell">
|
||||||
|
<td style="font-size:24px;line-height:1.5;color:#000;margin-top:40px">公告通知</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:14px;color:#333;padding:24px 40px 0 40px">
|
||||||
|
尊敬的用户您好!
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{!! nl2br($content) !!}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="padding:40px;display:table-cell">
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="padding:20px 40px;font-size:12px;color:#999;line-height:20px;background:#f7f7f7"><a href="{{$url}}" style="font-size:14px;color:#929292">返回{{$name}}</a></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
42
resources/views/mail/default/remindExpire.blade.php
Normal file
42
resources/views/mail/default/remindExpire.blade.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<div style="background: #eee">
|
||||||
|
<table width="600" border="0" align="center" cellpadding="0" cellspacing="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div style="background:#fff">
|
||||||
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td valign="middle" style="padding-left:30px;background-color:#415A94;color:#fff;padding:20px 40px;font-size: 21px;">{{$name}}</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr style="padding:40px 40px 0 40px;display:table-cell">
|
||||||
|
<td style="font-size:24px;line-height:1.5;color:#000;margin-top:40px">到期通知</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:14px;color:#333;padding:24px 40px 0 40px">
|
||||||
|
尊敬的用户您好!
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
你的服务将在24小时内到期。为了不造成使用上的影响请尽快续费。如果你已续费请忽略此邮件。
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="padding:40px;display:table-cell">
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="padding:20px 40px;font-size:12px;color:#999;line-height:20px;background:#f7f7f7"><a href="{{$url}}" style="font-size:14px;color:#929292">返回{{$name}}</a></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
42
resources/views/mail/default/remindTraffic.blade.php
Normal file
42
resources/views/mail/default/remindTraffic.blade.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<div style="background: #eee">
|
||||||
|
<table width="600" border="0" align="center" cellpadding="0" cellspacing="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div style="background:#fff">
|
||||||
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td valign="middle" style="padding-left:30px;background-color:#415A94;color:#fff;padding:20px 40px;font-size: 21px;">{{$name}}</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr style="padding:40px 40px 0 40px;display:table-cell">
|
||||||
|
<td style="font-size:24px;line-height:1.5;color:#000;margin-top:40px">流量通知</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:14px;color:#333;padding:24px 40px 0 40px">
|
||||||
|
尊敬的用户您好!
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
你的流量已经使用80%。为了不造成使用上的影响请合理安排流量的使用。
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="padding:40px;display:table-cell">
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="padding:20px 40px;font-size:12px;color:#999;line-height:20px;background:#f7f7f7"><a href="{{$url}}" style="font-size:14px;color:#929292">返回{{$name}}</a></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
42
resources/views/mail/default/verify.blade.php
Normal file
42
resources/views/mail/default/verify.blade.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<div style="background: #eee">
|
||||||
|
<table width="600" border="0" align="center" cellpadding="0" cellspacing="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div style="background:#fff">
|
||||||
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td valign="middle" style="padding-left:30px;background-color:#415A94;color:#fff;padding:20px 40px;font-size: 21px;">{{$name}}</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr style="padding:40px 40px 0 40px;display:table-cell">
|
||||||
|
<td style="font-size:24px;line-height:1.5;color:#000;margin-top:40px">邮箱验证码</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:14px;color:#333;padding:24px 40px 0 40px">
|
||||||
|
尊敬的用户您好!
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
您的验证码是:{{$code}},请在 5 分钟内进行验证。如果该验证码不为您本人申请,请无视。
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="padding:40px;display:table-cell">
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="padding:20px 40px;font-size:12px;color:#999;line-height:20px;background:#f7f7f7"><a href="{{$url}}" style="font-size:14px;color:#929292">返回{{$name}}</a></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user