fisrt
This commit is contained in:
20
app/Admin/Actions/LinkCreateAddress.php
Normal file
20
app/Admin/Actions/LinkCreateAddress.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Actions;
|
||||
|
||||
use Encore\Admin\Actions\RowAction;
|
||||
|
||||
class LinkCreateAddress extends RowAction
|
||||
{
|
||||
|
||||
public $name = '添加收货地址';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function href(): string
|
||||
{
|
||||
return admin_url("mall/addresses/create?user_id=".$this->row->id);
|
||||
}
|
||||
|
||||
}
|
||||
20
app/Admin/Actions/LinkStockOrderDeliver.php
Normal file
20
app/Admin/Actions/LinkStockOrderDeliver.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Actions;
|
||||
|
||||
use Encore\Admin\Actions\RowAction;
|
||||
|
||||
class LinkStockOrderDeliver extends RowAction
|
||||
{
|
||||
|
||||
public $name = '发货';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function href(): string
|
||||
{
|
||||
return admin_url('mall/stock_orders?user_id='.$this->row->user->id);
|
||||
}
|
||||
|
||||
}
|
||||
20
app/Admin/Actions/LinkVipOrderRefund.php
Normal file
20
app/Admin/Actions/LinkVipOrderRefund.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Actions;
|
||||
|
||||
use Encore\Admin\Actions\RowAction;
|
||||
|
||||
class LinkVipOrderRefund extends RowAction
|
||||
{
|
||||
|
||||
public $name = '体验官退款';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function href(): string
|
||||
{
|
||||
return admin_url("platform/vip_orders?user[username]=".$this->row->user->username);
|
||||
}
|
||||
|
||||
}
|
||||
10
app/Admin/Controllers/AuthController.php
Normal file
10
app/Admin/Controllers/AuthController.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use Encore\Admin\Controllers\AuthController as BaseAuthController;
|
||||
|
||||
class AuthController extends BaseAuthController
|
||||
{
|
||||
|
||||
}
|
||||
259
app/Admin/Controllers/HomeController.php
Normal file
259
app/Admin/Controllers/HomeController.php
Normal file
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Encore\Admin\Auth\Permission;
|
||||
use Encore\Admin\Facades\Admin;
|
||||
use Encore\Admin\Layout\Column;
|
||||
use Encore\Admin\Layout\Content;
|
||||
use Encore\Admin\Layout\Row;
|
||||
use Encore\Admin\Widgets\InfoBox;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Modules\Mall\Models\Order;
|
||||
use Modules\Mall\Models\OrderItem;
|
||||
use Modules\User\Models\User;
|
||||
use Modules\User\Models\UserStock;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
public $content;
|
||||
|
||||
/**
|
||||
* Notes : 数据看板
|
||||
*
|
||||
* @Date : 2021/3/10 5:12 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param Content $content
|
||||
* @return Content
|
||||
*/
|
||||
public function index(Content $content)
|
||||
{
|
||||
$this->content = $content->title('数据看板')->description('Description...');
|
||||
$admin = Admin::user();
|
||||
if ($admin->id == 1) {
|
||||
$this->getUserData();
|
||||
$this->getUserStockData();
|
||||
$this->getUserStockOrderData();
|
||||
} else {
|
||||
$this->content->row($this->setDivider('您没有权限查看数据'));
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取用户数据
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/11/17 11:24
|
||||
*/
|
||||
public function getUserData()
|
||||
{
|
||||
$this->content->row($this->setDivider('用户统计'));
|
||||
|
||||
$users = [
|
||||
'all' => [
|
||||
'name' => '用户总数',
|
||||
'color' => 'blue',
|
||||
'count' => User::count()
|
||||
],
|
||||
'ty' => [
|
||||
'name' => '月卡',
|
||||
'color' => 'green',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 2);
|
||||
})->count()
|
||||
],
|
||||
'jk' => [
|
||||
'name' => '季卡用户数',
|
||||
'color' => 'red',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 3);
|
||||
})->count()
|
||||
],
|
||||
'nk' => [
|
||||
'name' => '年卡用户数',
|
||||
'color' => 'yellow',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 4);
|
||||
})->count(),
|
||||
],
|
||||
];
|
||||
|
||||
$this->content->row(function (Row $row) use ($users) {
|
||||
foreach ($users as $user) {
|
||||
$row->column(2, function (Column $column) use ($user) {
|
||||
$column->append(new InfoBox(
|
||||
$user['name'],
|
||||
'users',
|
||||
$user['color'],
|
||||
'/admin/users',
|
||||
$user['count'],
|
||||
));
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 用户水数量
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/9/1 13:35
|
||||
* @return mixed
|
||||
*/
|
||||
public function getUserStockData()
|
||||
{
|
||||
$this->content->row($this->setDivider('会员水库存数'));
|
||||
|
||||
$all = UserStock::query()->sum('stock');
|
||||
$holds = UserStock::query()->sum('hold');
|
||||
$sy = bcsub($all, $holds);
|
||||
|
||||
$users = [
|
||||
'all' => [
|
||||
'name' => '总数',
|
||||
'color' => 'blue',
|
||||
'count' => UserStock::query()->sum('stock')
|
||||
],
|
||||
'stock' => [
|
||||
'name' => '已提货数',
|
||||
'color' => 'green',
|
||||
'count' => UserStock::query()->sum('hold')
|
||||
],
|
||||
'sy' => [
|
||||
'name' => '待提货数',
|
||||
'color' => 'green',
|
||||
'count' => $sy
|
||||
],
|
||||
];
|
||||
|
||||
$this->content->row(function (Row $row) use ($users) {
|
||||
foreach ($users as $user) {
|
||||
$row->column(2, function (Column $column) use ($user) {
|
||||
$column->append(new InfoBox(
|
||||
$user['name'],
|
||||
'goods',
|
||||
$user['color'],
|
||||
'/admin/stocks',
|
||||
$user['count'],
|
||||
));
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 提货订单数量
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/9/1 13:51
|
||||
*/
|
||||
public function getUserStockOrderData()
|
||||
{
|
||||
$this->content->row($this->setDivider('会员提货订单'));
|
||||
|
||||
|
||||
$deliver = OrderItem::query()
|
||||
->whereHas('order', function ($q) {
|
||||
$q->paid();
|
||||
})->sum('qty');
|
||||
|
||||
$deliverd = OrderItem::query()
|
||||
->whereHas('order', function ($q) {
|
||||
$q->whereIn('state', [
|
||||
Order::STATUS_SIGNED,
|
||||
Order::STATUS_DELIVERED,
|
||||
]);
|
||||
})->sum('qty');
|
||||
|
||||
$users = [
|
||||
'all' => [
|
||||
'name' => '订单总数',
|
||||
'color' => 'blue',
|
||||
'count' => Order::query()->where('type', Order::TYPE_SAMPLE)->count()
|
||||
],
|
||||
'deliver' => [
|
||||
'name' => '待发货',
|
||||
'color' => 'green',
|
||||
'count' => Order::query()
|
||||
->where('type', Order::TYPE_SAMPLE)
|
||||
->paid()
|
||||
->count()
|
||||
],
|
||||
'deliverd' => [
|
||||
'name' => '已发货',
|
||||
'color' => 'green',
|
||||
'count' => Order::query()
|
||||
->where('type', Order::TYPE_SAMPLE)
|
||||
->whereIn('state', [
|
||||
Order::STATUS_DELIVERED,
|
||||
])
|
||||
->count(),
|
||||
],
|
||||
'signed' => [
|
||||
'name' => '已签收',
|
||||
'color' => 'green',
|
||||
'count' => Order::query()
|
||||
->where('type', Order::TYPE_SAMPLE)
|
||||
->whereIn('state', [
|
||||
Order::STATUS_SIGNED,
|
||||
])
|
||||
->count()
|
||||
],
|
||||
];
|
||||
|
||||
$this->content->row(function (Row $row) use ($users) {
|
||||
foreach ($users as $user) {
|
||||
$row->column(2, function (Column $column) use ($user) {
|
||||
$column->append(new InfoBox(
|
||||
$user['name'],
|
||||
'goods',
|
||||
$user['color'],
|
||||
'/admin/stocks',
|
||||
$user['count'],
|
||||
));
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 清理模型缓存
|
||||
*
|
||||
* @Date : 2021/6/8 10:51 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
public function cleanCache(): string
|
||||
{
|
||||
Artisan::call('modelCache:clear');
|
||||
|
||||
return '缓存清理成功';
|
||||
}
|
||||
|
||||
public function setDivider($title)
|
||||
{
|
||||
return <<<HTML
|
||||
<div style="height: 20px; border-bottom: 1px solid #eee; text-align: center;margin-top: 20px;margin-bottom: 20px;">
|
||||
<span style="font-size: 18px; padding: 0 10px;">
|
||||
{$title}
|
||||
</span>
|
||||
</div>
|
||||
HTML;
|
||||
}
|
||||
|
||||
}
|
||||
17
app/Admin/Controllers/LeadyController.php
Normal file
17
app/Admin/Controllers/LeadyController.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Bouns;
|
||||
use Modules\User\Models\Order;
|
||||
|
||||
class LeadyController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$order = Order::find(1);
|
||||
Bouns::addBouns($order, $order->price);
|
||||
dd(111);
|
||||
}
|
||||
}
|
||||
54
app/Admin/Controllers/Material/IndexController.php
Normal file
54
app/Admin/Controllers/Material/IndexController.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Controllers\Material;
|
||||
|
||||
use App\Models\Material;
|
||||
use Encore\Admin\Controllers\AdminController;
|
||||
use Encore\Admin\Form;
|
||||
use Encore\Admin\Grid;
|
||||
|
||||
class IndexController extends AdminController
|
||||
{
|
||||
|
||||
/**
|
||||
* Title for current resource.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $title = '物料/素材';
|
||||
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
* @return Grid
|
||||
*/
|
||||
protected function grid()
|
||||
{
|
||||
$grid = new Grid(new Material());
|
||||
|
||||
$grid->column('id', '编号');
|
||||
$grid->column('title', '名称');
|
||||
$grid->column('地址')->display(function () {
|
||||
return $this->cover_url;
|
||||
});
|
||||
$grid->column('created_at', '创建时间');
|
||||
|
||||
return $grid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a form builder.
|
||||
*
|
||||
* @return Form
|
||||
*/
|
||||
protected function form(): Form
|
||||
{
|
||||
$form = new Form(new Material());
|
||||
$form->text('title', '名称');
|
||||
|
||||
$form->image('cover', '图片1')->move('materials/'.date('Y/m/d'));
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
}
|
||||
100
app/Admin/Controllers/ModuleController.php
Normal file
100
app/Admin/Controllers/ModuleController.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Models\Module;
|
||||
use Encore\Admin\Controllers\AdminController;
|
||||
use Encore\Admin\Grid;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Nwidart\Modules\Facades\Module as ModuleManager;
|
||||
|
||||
class ModuleController extends AdminController
|
||||
{
|
||||
|
||||
protected $title = '模块管理';
|
||||
|
||||
protected function grid(): Grid
|
||||
{
|
||||
$grid = new Grid(new Module());
|
||||
|
||||
$grid->disableBatchActions();
|
||||
$grid->disableFilter();
|
||||
$grid->disableCreateButton();
|
||||
$grid->disablePagination();
|
||||
$grid->disableActions();
|
||||
|
||||
$grid->column('name', '模块名称');
|
||||
$grid->column('alias', '别名');
|
||||
$grid->column('version', '版本');
|
||||
$grid->column('author', '作者');
|
||||
$grid->column('description', '模块简介');
|
||||
$grid->column('enabled', '状态')->bool();
|
||||
$grid->column('id', '操作')->display(function () {
|
||||
if ($this->enabled) {
|
||||
return sprintf('<a href="%s">%s</a>', route('admin.module.disable', $this->name), '禁用');
|
||||
} else {
|
||||
return sprintf('<a href="%s">%s</a>', route('admin.module.enable', $this->name), '启用');
|
||||
}
|
||||
});
|
||||
|
||||
return $grid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 禁用模块
|
||||
* @Date : 2021/3/11 1:13 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param $name
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function disable($name): RedirectResponse
|
||||
{
|
||||
try {
|
||||
$module = ModuleManager::find($name);
|
||||
|
||||
$module->disable();
|
||||
|
||||
$class = sprintf('\\%s\\%s\\%s', config('modules.namespace'), $module->getName(), $module->getName());
|
||||
|
||||
if (class_exists($class)) {
|
||||
call_user_func([$class, 'uninstall']);
|
||||
}
|
||||
|
||||
admin_success('Success', $name . '模块禁用成功');
|
||||
} catch (\Exception $exception) {
|
||||
admin_error('Error', $exception->getMessage());
|
||||
}
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 启用模块
|
||||
* @Date : 2021/3/11 1:13 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param $name
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function enable($name): RedirectResponse
|
||||
{
|
||||
try {
|
||||
$module = ModuleManager::find($name);
|
||||
|
||||
$module->enable();
|
||||
|
||||
$class = sprintf('\\%s\\%s\\%s', config('modules.namespace'), $module->getName(), $module->getName());
|
||||
|
||||
if (class_exists($class)) {
|
||||
call_user_func([$class, 'install']);
|
||||
}
|
||||
|
||||
admin_success('Success', $name . '模块启用成功');
|
||||
} catch (\Exception $exception) {
|
||||
admin_error('Error', $exception->getMessage());
|
||||
}
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
}
|
||||
291
app/Admin/Controllers/Platform/DashboardController.php
Normal file
291
app/Admin/Controllers/Platform/DashboardController.php
Normal file
@@ -0,0 +1,291 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Controllers\Platform;
|
||||
|
||||
use Encore\Admin\Layout\Column;
|
||||
use Encore\Admin\Layout\Content;
|
||||
use Encore\Admin\Layout\Row;
|
||||
use Encore\Admin\Widgets\InfoBox;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Modules\Mall\Models\Order;
|
||||
use Modules\Mall\Models\OrderItem;
|
||||
use Modules\User\Models\User;
|
||||
use Modules\User\Models\UserChannel;
|
||||
use Modules\User\Models\UserStock;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function index(Content $content): Content
|
||||
{
|
||||
$this->content = $content->title('数据看板')->description('Description...');
|
||||
$this->getVipUserData();
|
||||
$this->getUserStockData();
|
||||
// $this->getChannelData();
|
||||
return $this->content;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取用户数据
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/11/17 11:24
|
||||
*/
|
||||
public function getVipUserData(): Content
|
||||
{
|
||||
$this->content->row($this->setDivider('会员统计'));
|
||||
$users = [
|
||||
'all' => [
|
||||
'name' => '总会员量',
|
||||
'color' => 'blue',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', '>', 1);
|
||||
})->count()
|
||||
],
|
||||
'mo' => [
|
||||
'name' => '月卡会员量',
|
||||
'color' => 'red',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 2);
|
||||
})->count()
|
||||
],
|
||||
'jk' => [
|
||||
'name' => '季卡会员量',
|
||||
'color' => 'red',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 3);
|
||||
})->count()
|
||||
],
|
||||
'nk' => [
|
||||
'name' => '年卡会员量',
|
||||
'color' => 'yellow',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 4);
|
||||
})->count(),
|
||||
],
|
||||
'onlone' => [
|
||||
'name' => '在线会员数',
|
||||
'color' => 'red',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', '>', 1);
|
||||
})
|
||||
->where('status', User::STATUS_INIT)
|
||||
->count(),
|
||||
],
|
||||
'refund' => [
|
||||
'name' => '退费会员数',
|
||||
'color' => 'maroon',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', '>', 1);
|
||||
})
|
||||
->where('status', User::STATUS_REFUND)
|
||||
->count(),
|
||||
],
|
||||
];
|
||||
|
||||
$this->content->row(function (Row $row) use ($users) {
|
||||
foreach ($users as $user) {
|
||||
$row->column(2, function (Column $column) use ($user) {
|
||||
$column->append(new InfoBox(
|
||||
$user['name'],
|
||||
'users',
|
||||
$user['color'],
|
||||
'/admin/platform/vips',
|
||||
$user['count'],
|
||||
));
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取渠道数据
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/10/14 13:55
|
||||
*/
|
||||
public function getChannelData()
|
||||
{
|
||||
$this->content->row($this->setDivider('渠道数据'));
|
||||
$channels = UserChannel::query()->get();
|
||||
|
||||
$users = [
|
||||
'all' => [
|
||||
'name' => '总会员量',
|
||||
'color' => 'blue',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', '>', 2);
|
||||
})
|
||||
],
|
||||
'jk' => [
|
||||
'name' => '季卡会员量',
|
||||
'color' => 'red',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 3);
|
||||
})
|
||||
],
|
||||
'nk' => [
|
||||
'name' => '年卡会员量',
|
||||
'color' => 'yellow',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 4);
|
||||
}),
|
||||
],
|
||||
'cs' => [
|
||||
'name' => '创始会员量',
|
||||
'color' => 'aqua',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 5);
|
||||
}),
|
||||
],
|
||||
'hh' => [
|
||||
'name' => '合伙人量',
|
||||
'color' => 'navy',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 6);
|
||||
}),
|
||||
],
|
||||
// 'onlone' => [
|
||||
// 'name' => '在线会员数',
|
||||
// 'color' => 'red',
|
||||
// 'count' => User::query()
|
||||
// ->whereHas('identities', function ($q) {
|
||||
// $q->where('id', '>', 2);
|
||||
// })
|
||||
// ->where('status', User::STATUS_INIT),
|
||||
// ],
|
||||
'refund' => [
|
||||
'name' => '退费会员数',
|
||||
'color' => 'maroon',
|
||||
'count' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', '>', 2);
|
||||
})
|
||||
->where('status', User::STATUS_REFUND),
|
||||
],
|
||||
];
|
||||
foreach ($channels as $channel) {
|
||||
$this->channel_id = $channel->id;
|
||||
$this->content->row(function (Row $row) use ($channel, $users) {
|
||||
foreach ($users as $user) {
|
||||
$row->column(2, function (Column $column) use ($channel, $user) {
|
||||
$column->append(new InfoBox(
|
||||
$channel->name.'-'.$user['name'],
|
||||
'users',
|
||||
$user['color'],
|
||||
'/admin/platform/vips?channel_id='.$channel->id,
|
||||
(clone $user['count'])->where('channel_id', $channel->id)->count(),
|
||||
));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 用户水数量
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/9/1 13:35
|
||||
* @return mixed
|
||||
*/
|
||||
public function getUserStockData()
|
||||
{
|
||||
$this->content->row($this->setDivider('会员库存数'));
|
||||
|
||||
$all = UserStock::query()->sum('stock');
|
||||
$holds = UserStock::query()->sum('hold');
|
||||
$sy = bcsub($all, $holds);
|
||||
|
||||
$users = [
|
||||
'all' => [
|
||||
'name' => '累计总箱数',
|
||||
'color' => 'blue',
|
||||
'count' => $all
|
||||
],
|
||||
'stock' => [
|
||||
'name' => '累计提货数',
|
||||
'color' => 'green',
|
||||
'count' => $holds
|
||||
],
|
||||
'sy' => [
|
||||
'name' => '累计剩余',
|
||||
'color' => 'green',
|
||||
'count' => $sy
|
||||
],
|
||||
'online' => [
|
||||
'name' => '线上发货',
|
||||
'color' => 'green',
|
||||
'count' => OrderItem::query()
|
||||
->whereHas('order', function ($q) {
|
||||
$q->where('type', Order::TYPE_SAMPLE)
|
||||
->whereIn('state', [
|
||||
Order::STATUS_PAID,
|
||||
Order::STATUS_DELIVERED,
|
||||
Order::STATUS_SIGNED,
|
||||
])->where('channel', Order::CHANNEL_USER);
|
||||
})
|
||||
->sum('qty')
|
||||
],
|
||||
'offline' => [
|
||||
'name' => '线下发货',
|
||||
'color' => 'green',
|
||||
'count' => OrderItem::query()
|
||||
->whereHas('order', function ($q) {
|
||||
$q->where('type', Order::TYPE_SAMPLE)
|
||||
->whereIn('state', [
|
||||
Order::STATUS_PAID,
|
||||
Order::STATUS_DELIVERED,
|
||||
Order::STATUS_SIGNED,
|
||||
])->where('channel', Order::CHANNEL_SYSTEM);
|
||||
})
|
||||
->sum('qty')
|
||||
],
|
||||
];
|
||||
|
||||
$this->content->row(function (Row $row) use ($users) {
|
||||
foreach ($users as $user) {
|
||||
$row->column(2, function (Column $column) use ($user) {
|
||||
$column->append(new InfoBox(
|
||||
$user['name'],
|
||||
'goods',
|
||||
$user['color'],
|
||||
'/admin/users/stocks',
|
||||
$user['count'],
|
||||
));
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function setDivider($title)
|
||||
{
|
||||
return <<<HTML
|
||||
<div style="height: 20px; border-bottom: 1px solid #eee; text-align: center;margin-top: 20px;margin-bottom: 20px;">
|
||||
<span style="font-size: 18px; padding: 0 10px;">
|
||||
{$title}
|
||||
</span>
|
||||
</div>
|
||||
HTML;
|
||||
}
|
||||
|
||||
}
|
||||
140
app/Admin/Controllers/Platform/ExperienceController.php
Normal file
140
app/Admin/Controllers/Platform/ExperienceController.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Controllers\Platform;
|
||||
|
||||
use App\Admin\Actions\LinkStockOrderDeliver;
|
||||
use App\Admin\Actions\LinkVipOrderRefund;
|
||||
use Encore\Admin\Controllers\AdminController;
|
||||
use Encore\Admin\Grid;
|
||||
use Modules\Gout\Http\Controllers\Admin\Action\Audit;
|
||||
use Modules\Gout\Models\GoutCase;
|
||||
use Modules\Gout\Renderable\CaseData;
|
||||
use Modules\Gout\Renderable\CaseSymptoms;
|
||||
use Modules\User\Models\User;
|
||||
use Modules\User\Models\UserStock;
|
||||
|
||||
class ExperienceController extends AdminController
|
||||
{
|
||||
|
||||
protected $title = '体验官审核';
|
||||
|
||||
public function grid(): Grid
|
||||
{
|
||||
$grid = new Grid(new GoutCase());
|
||||
$grid->disableCreateButton();
|
||||
$grid->model()->with(['symptoms', 'user', 'user.sign', 'user.userStock'])
|
||||
->withCount(['logs', 'surveys'])
|
||||
->where('type', GoutCase::TYPE_TY);
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableEdit();
|
||||
$actions->disableDelete();
|
||||
$actions->disableView();
|
||||
|
||||
if ($actions->row->canAudit()) {
|
||||
$actions->add(new Audit());
|
||||
}
|
||||
|
||||
if ($actions->row->manage_status == GoutCase::MANAGE_STATUS_DELIVER) {
|
||||
$actions->add(new LinkStockOrderDeliver());
|
||||
}
|
||||
if ($actions->row->manage_status == GoutCase::MANAGE_STATUS_REFUND) {
|
||||
$actions->add(new LinkVipOrderRefund());
|
||||
}
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->column(1 / 2, function (Grid\Filter $filter) {
|
||||
$filter->like('name', '姓名');
|
||||
$filter->equal('mobile', '手机号');
|
||||
});
|
||||
$filter->column(1 / 2, function (Grid\Filter $filter) {
|
||||
$filter->equal('status', '状态')->select((new GoutCase())->status_map);
|
||||
});
|
||||
});
|
||||
|
||||
$grid->column('id', '#ID#');
|
||||
$grid->column('name', '姓名');
|
||||
$grid->column('mobile', '手机号');
|
||||
$grid->column('建档信息')
|
||||
->display(function ($title, $column) {
|
||||
return '查看';
|
||||
})->modal('建档信息', CaseData::class);
|
||||
|
||||
$grid->column('报告数据')
|
||||
->display(function ($title, $column) {
|
||||
return '查看';
|
||||
})->modal('亚健康数据', CaseSymptoms::class);
|
||||
|
||||
$grid->column('symptoms', '症状')
|
||||
->display(function () {
|
||||
return $this->symptoms->pluck('title');
|
||||
})->label();
|
||||
$grid->column('是否关注')
|
||||
->display(function () {
|
||||
return $this->user->isOfficialSubscribe();
|
||||
})
|
||||
->bool();
|
||||
//
|
||||
$grid->column('缴纳保证金')
|
||||
->display(function () {
|
||||
return $this->user->isExperiencePrice() ? '已缴' : '待缴';
|
||||
})
|
||||
->label([
|
||||
'已缴' => 'primary',
|
||||
'待缴' => 'success',
|
||||
]);
|
||||
|
||||
$grid->column('是否收货')
|
||||
->display(function () {
|
||||
return $this->user->userStock->stock_order_status_text;
|
||||
})
|
||||
->label(UserStock::STOCK_ORDER_STATUS_MAP);
|
||||
|
||||
$grid->column('is_coupon', '是否发券')
|
||||
->using(GoutCase::COUPONS)
|
||||
->label(GoutCase::COUPONS_MAP);
|
||||
|
||||
$grid->column('喝水打卡')
|
||||
->display(function () {
|
||||
return $this->user->sign->counts;
|
||||
});
|
||||
//
|
||||
$grid->column('完结报告')
|
||||
->display(function () {
|
||||
return $this->logs_count > 1 ? '已上传' : '待上传';
|
||||
})
|
||||
->label([
|
||||
'已上传' => 'primary',
|
||||
'待上传' => 'success',
|
||||
]);
|
||||
//
|
||||
$grid->column('是否退保')
|
||||
->display(function () {
|
||||
return $this->user->isExperiencePriceRefund() ? '是' : '否';
|
||||
})
|
||||
->label([
|
||||
'是' => 'primary',
|
||||
'否' => 'success',
|
||||
]);
|
||||
$grid->column('好转反馈')
|
||||
->display(function () {
|
||||
return $this->surveys_count;
|
||||
});
|
||||
|
||||
$grid->column('manage_status', '状态')
|
||||
->using((new GoutCase())->manage_status_map)
|
||||
->label([
|
||||
GoutCase::MANAGE_STATUS_INIT => 'primary',
|
||||
GoutCase::MANAGE_STATUS_DELIVER => 'success',
|
||||
GoutCase::MANAGE_STATUS_REFUND => 'danger',
|
||||
GoutCase::MANAGE_STATUS_PASS => 'info',
|
||||
GoutCase::MANAGE_STATUS_FINISH => 'warning',
|
||||
]);
|
||||
|
||||
$grid->column('created_at', '创建时间');
|
||||
|
||||
return $grid;
|
||||
}
|
||||
|
||||
}
|
||||
257
app/Admin/Controllers/Platform/VipController.php
Normal file
257
app/Admin/Controllers/Platform/VipController.php
Normal file
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Controllers\Platform;
|
||||
|
||||
use App\Admin\Actions\LinkCreateAddress;
|
||||
use Carbon\Carbon;
|
||||
use Encore\Admin\Controllers\AdminController;
|
||||
use Encore\Admin\Facades\Admin;
|
||||
use Encore\Admin\Form;
|
||||
use Encore\Admin\Grid;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Modules\User\Http\Controllers\Admin\Actions\AddUserRemark;
|
||||
use Modules\User\Http\Controllers\Admin\Actions\JoinIdentity;
|
||||
use Modules\User\Http\Controllers\Admin\Actions\UserStatusInit;
|
||||
use Modules\User\Http\Controllers\Admin\Actions\UserStatusRefund;
|
||||
use Modules\User\Models\Identity;
|
||||
use Modules\User\Models\IdentityLog;
|
||||
use Modules\User\Models\IdentityMiddle;
|
||||
use Modules\User\Models\User;
|
||||
use Modules\User\Models\UserChannel;
|
||||
use Modules\User\Renderable\UserLog;
|
||||
|
||||
class VipController extends AdminController
|
||||
{
|
||||
|
||||
protected $title = '会员管理';
|
||||
|
||||
/**
|
||||
* Notes : 用户管理列表
|
||||
*
|
||||
* @Date : 2021/3/11 1:59 下午
|
||||
* @Author : <Jason.C>
|
||||
* @return Grid
|
||||
*/
|
||||
public function grid(): Grid
|
||||
{
|
||||
$grid = new Grid(new User());
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableEdit();
|
||||
$actions->disableDelete();
|
||||
$actions->disableView();
|
||||
if ($actions->row->status == User::STATUS_INIT) {
|
||||
$actions->add(new UserStatusRefund());
|
||||
}
|
||||
if ($actions->row->status == User::STATUS_REFUND) {
|
||||
$actions->add(new UserStatusInit());
|
||||
}
|
||||
|
||||
$actions->add(new JoinIdentity());
|
||||
$actions->add(new AddUserRemark());
|
||||
$actions->add(new LinkCreateAddress());
|
||||
|
||||
});
|
||||
|
||||
$grid->quickSearch('username')->placeholder('快速搜索用户名');
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->column(1 / 3, function (Grid\Filter $filter) {
|
||||
$filter->like('username', '用户名');
|
||||
$filter->equal('channel_id', '渠道')->select(UserChannel::pluck('name', 'id'));
|
||||
});
|
||||
|
||||
$filter->column(1 / 3, function (Grid\Filter $filter) {
|
||||
$filter->like('info.nickname', '用户昵称');
|
||||
});
|
||||
$filter->column(1 / 3, function (Grid\Filter $filter) {
|
||||
$filter->equal('identities.id', '身份')
|
||||
->select(Identity::query()->where('id', '>', 1)->pluck('name', 'id'));
|
||||
});
|
||||
});
|
||||
|
||||
$grid->model()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', '>', 1);
|
||||
})
|
||||
->withCount(['addresses', 'logs'])
|
||||
->with(['info', 'parent', 'identities', 'addresses', 'vipOrders', 'userStock', 'logs']);
|
||||
|
||||
//序号 姓名 手机号 会员类型 会员编号 缴费金额 加入时间 状态(正常,退费) 用箱数 提货箱数 剩余箱数
|
||||
$grid->column('id', '序号');
|
||||
$grid->column('username', '手机号');
|
||||
$grid->column('identities', '会员类型')
|
||||
->display(function () {
|
||||
$data = [];
|
||||
foreach ($this->identities as $identity) {
|
||||
$data[] = $identity->name;
|
||||
}
|
||||
return $data;
|
||||
})
|
||||
->label();
|
||||
$grid->column('serial', '会员编号')
|
||||
->display(function () {
|
||||
$data = [];
|
||||
foreach ($this->identities as $identity) {
|
||||
$data[] = $identity->serial_prefix.$identity->getOriginal('pivot_serial');
|
||||
}
|
||||
return $data;
|
||||
})
|
||||
->label();
|
||||
|
||||
$grid->column('price', '缴费金额')
|
||||
->display(function () {
|
||||
return $this->getOpenVipPrices();
|
||||
})
|
||||
->label();
|
||||
|
||||
$grid->column('created_at', '加入时间');
|
||||
$grid->column('status', '状态')
|
||||
->using(User::STATUS)
|
||||
->label();
|
||||
$grid->column('userStock.stock', '总箱数');
|
||||
$grid->column('userStock.hold', '提货箱数');
|
||||
$grid->column('userStock.residue', '剩余箱数');
|
||||
$grid->column('addresses_count', '收货地址')
|
||||
->link(function () {
|
||||
return route('admin.mall.addresses.index', ['user_id' => $this->id]);
|
||||
}, '_self');
|
||||
$grid->column('logs_count', '备注')
|
||||
->modal('备注信息', UserLog::class);
|
||||
|
||||
$grid->disableExport(false);
|
||||
$grid->export(function ($export) {
|
||||
$export->column('identities', function ($value, $original) {
|
||||
return strip_tags($value);
|
||||
});
|
||||
$export->column('serial', function ($value, $original) {
|
||||
return strip_tags($value);
|
||||
});
|
||||
$export->column('price', function ($value, $original) {
|
||||
return strip_tags($value);
|
||||
});
|
||||
$export->column('status', function ($value, $original) {
|
||||
return strip_tags($value);
|
||||
});
|
||||
|
||||
// $export->column('use_way', function ($value, $original) {
|
||||
// return strip_tags($value);
|
||||
// });
|
||||
// $export->column('所属用户', function ($value, $original) {
|
||||
// return iconv('gb2312//ignore', 'utf-8',
|
||||
// iconv('utf-8', 'gb2312//ignore', strip_tags(str_replace(" ", " ", $value))));
|
||||
// });
|
||||
//
|
||||
// $export->column('couponGrant.code', function ($value, $original) {
|
||||
// return $value."\n";
|
||||
// });
|
||||
|
||||
$export->except(['addresses_count', 'logs_count']);
|
||||
|
||||
$export->filename($this->title.date("YmdHis"));
|
||||
});
|
||||
|
||||
return $grid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 编辑表单
|
||||
*
|
||||
* @Date : 2021/7/15 5:09 下午
|
||||
* @Author : <Jason.C>
|
||||
* @return Form
|
||||
* @throws Exception
|
||||
*/
|
||||
public function form(): Form
|
||||
{
|
||||
// if (! config('user.create_user_by_admin')) {
|
||||
// throw new Exception('不运允许操作用户');
|
||||
// }
|
||||
|
||||
Admin::script(" $(document.body).append(`<script src='/vendor/js/setStock.js'>`); ");
|
||||
$form = new Form(new User());
|
||||
|
||||
//姓名 手机号 身份 编号 (数字从1开始) 缴费金额 加入日期(当天) 总箱数
|
||||
$form->text('info.nickname', '姓名')->required();
|
||||
$form->text('username', '手机号')
|
||||
->required()
|
||||
->rules(['phone:CN,mobile', 'unique:users,username,{{id}}'], [
|
||||
'phone' => '手机号格式错误'
|
||||
]);
|
||||
$form->select('join_identity_id', '加入身份')
|
||||
->options(Identity::where('order', '>', 2)->pluck('name', 'id'))
|
||||
->required();
|
||||
$form->text('serial', '编号')->value($form->model()->getNewSerial(8))->required();
|
||||
$form->number('price', '缴费金额')
|
||||
->default(1)
|
||||
->required();
|
||||
|
||||
$form->date('join_at', '加入时间')->default(now())->required();
|
||||
$form->number('stock', '总箱数')
|
||||
->default(0)
|
||||
->setLabelClass(['identity_stock'])
|
||||
->required();
|
||||
|
||||
$form->ignore(['join_at', 'price', 'serial', 'stock', 'join_identity_id']);
|
||||
|
||||
$form->saving(function (Form $form) {
|
||||
$exists = IdentityMiddle::query()->where('serial', $form->serial)->first();
|
||||
if ($exists) {
|
||||
$error = new MessageBag([
|
||||
'title' => '错误',
|
||||
'message' => '编号已经存在',
|
||||
]);
|
||||
|
||||
return back()->withInput()->with(compact('error'));
|
||||
}
|
||||
});
|
||||
|
||||
$form->saved(function (Form $form) {
|
||||
$user = $form->model();
|
||||
$user->update([
|
||||
'created_at' => Carbon::parse(request()->jion_at)->startOfDay()
|
||||
]);
|
||||
$user->createOrder(request()->join_identity_id, 1, request()->price, request()->stock, [
|
||||
'serial' => request()->serial,
|
||||
'channel' => IdentityLog::CHANNEL_SYSTEM,
|
||||
]);//创建订单
|
||||
});
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : User 列表选择, 这里没有判断,用户是否已经有店铺了,如果判断的情况,可能导致当前用户 无法被选中
|
||||
*
|
||||
* @Date : 2021/5/6 4:35 下午
|
||||
* @Author : <Jason.C>
|
||||
*/
|
||||
public function ajax(Request $request)
|
||||
{
|
||||
$q = $request->get('q');
|
||||
|
||||
return User::leftJoin('user_infos as info', 'users.id', '=', 'info.user_id')
|
||||
->where('username', 'like', "%$q%")
|
||||
->orWhere('info.nickname', 'like', "%$q%")
|
||||
->select('id', DB::raw('CONCAT(username, " [", info.nickname, "]") as text'))
|
||||
->paginate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取库存
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/9/7 15:23
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function stock(Request $request)
|
||||
{
|
||||
$q = $request->get('q');
|
||||
$identity = Identity::find($q);
|
||||
return ['status_code' => 200, 'value' => $identity->stock];
|
||||
}
|
||||
|
||||
}
|
||||
85
app/Admin/Controllers/Platform/VipOrderController.php
Normal file
85
app/Admin/Controllers/Platform/VipOrderController.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Controllers\Platform;
|
||||
|
||||
use Encore\Admin\Controllers\AdminController;
|
||||
use Encore\Admin\Form;
|
||||
use Encore\Admin\Grid;
|
||||
use Exception;
|
||||
use Modules\User\Http\Controllers\Admin\Actions\Pay;
|
||||
use Modules\User\Http\Controllers\Admin\Actions\Refund;
|
||||
use Modules\User\Models\Identity;
|
||||
use Modules\User\Models\Order;
|
||||
|
||||
class VipOrderController extends AdminController
|
||||
{
|
||||
|
||||
protected $title = '体验官退款';
|
||||
|
||||
/**
|
||||
* Notes: 升级订单
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date : 2021/6/7 15:19
|
||||
* @return Grid
|
||||
*/
|
||||
public function grid(): Grid
|
||||
{
|
||||
try {
|
||||
trait_exists('Modules\Payment\Traits\WithPayments');
|
||||
$grid = new Grid(new Order());
|
||||
$grid->model()
|
||||
->whereHas('identity', function ($q) {
|
||||
$q->ty();
|
||||
})
|
||||
->whereIn('state',[Order::STATE_SUCCESS,Order::STATE_REFUND])
|
||||
->latest();
|
||||
|
||||
$grid->disableCreateButton();
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableEdit();
|
||||
$actions->disableDelete();
|
||||
$actions->disableView();
|
||||
if ($actions->row->canRefund()) {
|
||||
$actions->add(new Refund());
|
||||
}
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->column(1 / 2, function (Grid\Filter $filter) {
|
||||
$filter->like('user.username', '用户名');
|
||||
});
|
||||
|
||||
$filter->column(1 / 2, function (Grid\Filter $filter) {
|
||||
$filter->equal('state', '状态')->select(Order::STATES);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$grid->column('id', '用户ID');
|
||||
$grid->column('升级用户')->display(function () {
|
||||
return $this->user->username."({$this->user->info->nickname})";
|
||||
});
|
||||
$grid->column('identity.name', '身份');
|
||||
$grid->column('price', '金额');
|
||||
$grid->column('state', '状态')->using(Order::STATES)->label();
|
||||
$grid->column('type', '类型')->using(Order::TYPES)->label();
|
||||
$grid->column('created_at', '升级时间');
|
||||
|
||||
return $grid;
|
||||
} catch (Exception $exception) {
|
||||
dd('Payment 模块不存在,无法加载订单数据');
|
||||
}
|
||||
}
|
||||
|
||||
public function form(): Form
|
||||
{
|
||||
$form = new Form(new Order());
|
||||
|
||||
$form->decimal('price', '金额')->required();
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
}
|
||||
123
app/Admin/Controllers/TestController.php
Normal file
123
app/Admin/Controllers/TestController.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Bonus\IdentityBonus;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Liuhelong\LaravelAdmin\Wechat\Models\WechatOffiaccountUser;
|
||||
use Modules\Coupon\Models\Coupon;
|
||||
use Modules\Coupon\Traits\WithCoupon;
|
||||
use Modules\User\Models\Identity;
|
||||
use Modules\User\Models\Order;
|
||||
use Modules\User\Models\UserInvite;
|
||||
use Modules\User\Models\UserStockLog;
|
||||
use Modules\User\Models\UserWechat;
|
||||
use Modules\User\Models\UserWechatOfficial;
|
||||
use Modules\User\Traits\RankDataTrait;
|
||||
use Modules\User\Traits\WechatTrait;
|
||||
use Vinkla\Hashids\Facades\Hashids;
|
||||
|
||||
class TestController extends Controller
|
||||
{
|
||||
use WithCoupon, WechatTrait, RankDataTrait;
|
||||
|
||||
public function index()
|
||||
{
|
||||
$identities= Identity::all();
|
||||
dd($identities->toArray());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 清空数据表的操作,为了测试用的
|
||||
*
|
||||
* @Author: <C.Jason>
|
||||
* @Date : 2020/11/23 4:54 下午
|
||||
*/
|
||||
public function truncate(Request $request)
|
||||
{
|
||||
$name = $request->name;
|
||||
$is_test = config('app.is_test');
|
||||
dump('is_test'.$is_test);
|
||||
|
||||
if ($name != 'skyxu') {
|
||||
dd('name不对');
|
||||
}
|
||||
|
||||
if (! $is_test) {
|
||||
dd('不是测试环境');
|
||||
}
|
||||
|
||||
$tables = [
|
||||
'admin_operation_log',
|
||||
'bouns',
|
||||
'bouns_orders',
|
||||
'bouns_user_perves',
|
||||
'coupon_grants',
|
||||
'coupon_item_use_logs',
|
||||
'coupon_use_logs',
|
||||
'failed_jobs',
|
||||
'gout_case_log_symptoms',
|
||||
'gout_case_logs',
|
||||
'gout_case_timelines',
|
||||
'gout_case_symptom',
|
||||
'gout_cases',
|
||||
'gout_surveys',
|
||||
'gout_votes',
|
||||
'jobs',
|
||||
'linker_relations',
|
||||
'linkers',
|
||||
'mall_addresses',
|
||||
'mall_order_expresses',
|
||||
'mall_order_items',
|
||||
'mall_orders',
|
||||
'mall_carts',
|
||||
'mall_refund_items',
|
||||
'mall_refund_logs',
|
||||
'mall_refunds',
|
||||
'mall_refund_expresses',
|
||||
'notifications',
|
||||
'payment_refunds',
|
||||
'payments',
|
||||
'user_account_logs',
|
||||
'user_accounts',
|
||||
'user_identity',
|
||||
'user_identity_logs',
|
||||
'user_identity_coupons',
|
||||
'user_infos',
|
||||
'user_invites',
|
||||
'user_logs',
|
||||
'user_orders',
|
||||
'user_perves',
|
||||
'user_relations',
|
||||
'user_sign_logs',
|
||||
'user_signs',
|
||||
'user_sms',
|
||||
'user_stock_logs',
|
||||
'user_stocks',
|
||||
'user_wechat_apps',
|
||||
'user_wechat_minis',
|
||||
'user_wechat_officials',
|
||||
'user_wechats',
|
||||
'users',
|
||||
'versions',
|
||||
'wechat_offiaccount_event_logs',
|
||||
'withdraw_alipay_accounts',
|
||||
'withdraw_bank_accounts',
|
||||
'withdraw_logs',
|
||||
'withdraws',
|
||||
'personal_access_tokens',
|
||||
];
|
||||
foreach ($tables as $table) {
|
||||
DB::table($table)->truncate();
|
||||
}
|
||||
dd('清理成功');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
29
app/Admin/Extensions/CleanCache.php
Normal file
29
app/Admin/Extensions/CleanCache.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Extensions;
|
||||
|
||||
class CleanCache
|
||||
{
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
$url = route('admin.cleanCache');
|
||||
|
||||
return <<<HTML
|
||||
<li data-toggle="tooltip" data-placement="bottom" title="清除缓存">
|
||||
<a href="javascript:void(0);" class="clean-cache">
|
||||
<i class="fa fa-trash-o"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<script>
|
||||
$('.clean-cache').click(function () {
|
||||
$.get('{$url}', function (data) {
|
||||
toastr.success(data)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
HTML;
|
||||
}
|
||||
|
||||
}
|
||||
10
app/Admin/Routes/material.php
Normal file
10
app/Admin/Routes/material.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Routing\Router;
|
||||
|
||||
Route::group([
|
||||
'namespace' => 'Material',
|
||||
], function (Router $router) {
|
||||
$router->resource('materials', 'IndexController');
|
||||
|
||||
});
|
||||
12
app/Admin/Routes/modules.php
Normal file
12
app/Admin/Routes/modules.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::group([
|
||||
'prefix' => 'modules',
|
||||
], function (Router $router) {
|
||||
$router->get('', 'ModuleController@index');
|
||||
$router->get('{name}/disable', 'ModuleController@disable')->name('module.disable');
|
||||
$router->get('{name}/enable', 'ModuleController@enable')->name('module.enable');
|
||||
});
|
||||
15
app/Admin/Routes/platform.php
Normal file
15
app/Admin/Routes/platform.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Routing\Router;
|
||||
|
||||
Route::group([
|
||||
'namespace' => 'Platform',
|
||||
'prefix' => 'platform',
|
||||
], function (Router $router) {
|
||||
$router->resource('experiences', 'ExperienceController');//体验官审核
|
||||
$router->resource('vip_orders', 'VipOrderController');//体验官审核
|
||||
$router->resource('vips', 'VipController');//会员管理
|
||||
$router->get('identity_stock', 'VipController@stock')->name('platform.identity_stock');;//会员管理
|
||||
$router->get('dashboard', 'DashboardController@index');
|
||||
|
||||
});
|
||||
12
app/Admin/Routes/test.php
Normal file
12
app/Admin/Routes/test.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::group([
|
||||
'prefix' => 'test',
|
||||
], function (Router $router) {
|
||||
$router->get('', 'TestController@index');
|
||||
$router->get('truncate', 'TestController@truncate');
|
||||
$router->get('leady', 'LeadyController@index');
|
||||
});
|
||||
103
app/Admin/Traits/WithUploads.php
Normal file
103
app/Admin/Traits/WithUploads.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace App\Admin\Traits;
|
||||
|
||||
use Illuminate\Contracts\Support\Renderable;
|
||||
|
||||
trait WithUploads
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes : 单张封面图上传
|
||||
*
|
||||
* @Date : 2021/4/25 2:06 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param \Encore\Admin\Form $form
|
||||
* @param string $filed
|
||||
* @param string $label
|
||||
*/
|
||||
public function cover(Renderable $form, string $filed = 'cover', string $label = '封面图片')
|
||||
{
|
||||
$cover = $form->image($filed, $label)
|
||||
->move('images/'.date('Y/m/d'))
|
||||
->uniqueName()
|
||||
->removable()
|
||||
->retainable();
|
||||
|
||||
$waterConfig = config('admin.image_water');
|
||||
|
||||
if (! empty($waterConfig)) {
|
||||
$cover->insert(...$waterConfig);
|
||||
}
|
||||
|
||||
$coverThumb = config('admin.cover_thumb');
|
||||
|
||||
if (! empty($coverThumb)) {
|
||||
$cover->thumbnail($coverThumb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 上传视频
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/9/30 9:44
|
||||
* @param Renderable $form
|
||||
* @param string $filed
|
||||
* @param string $label
|
||||
*/
|
||||
public function video(Renderable $form, string $filed = 'path', string $label = '视频')
|
||||
{
|
||||
$form->file($filed, $label)
|
||||
->move('videos/'.date('Y/m/d'))
|
||||
->uniqueName()
|
||||
->removable()
|
||||
->downloadable()
|
||||
->retainable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 统一的多图上传
|
||||
*
|
||||
* @Date : 2021/4/25 2:06 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param \Encore\Admin\Form $form
|
||||
* @param string $filed
|
||||
* @param string $label
|
||||
*/
|
||||
public function pictures(Renderable $form, string $filed = 'pictures', string $label = '多图轮播')
|
||||
{
|
||||
$pictures = $form->multipleImage($filed, $label)
|
||||
->move('images/'.date('Y/m/d'))
|
||||
->uniqueName()
|
||||
->removable()
|
||||
->retainable();
|
||||
|
||||
// 多图如果开启排序的话,会报错,暂时没由解决办法 ->sortable()
|
||||
$waterConfig = config('admin.image_water');
|
||||
|
||||
if (! empty($waterConfig)) {
|
||||
$pictures->insert(...$waterConfig);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 统一的附件上传
|
||||
*
|
||||
* @Date : 2021/4/25 3:03 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param \Illuminate\Contracts\Support\Renderable $form
|
||||
* @param string $filed
|
||||
* @param string $label
|
||||
*/
|
||||
public function attachments(Renderable $form, string $filed = 'attachments', string $label = '内容附件')
|
||||
{
|
||||
$form->multipleFile($filed, $label)
|
||||
->move('attachments/'.date('Y/m/d'))
|
||||
->uniqueName()
|
||||
->removable()
|
||||
->retainable()
|
||||
->sortable();
|
||||
}
|
||||
|
||||
}
|
||||
62
app/Admin/bootstrap.php
Normal file
62
app/Admin/bootstrap.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Laravel-admin - admin builder based on Laravel.
|
||||
* @author z-song <https://github.com/z-song>
|
||||
* Bootstraper for Admin.
|
||||
* Here you can remove builtin form field:
|
||||
* Encore\Admin\Form::forget(['map', 'editor']);
|
||||
* Or extend custom form field:
|
||||
* Encore\Admin\Form::extend('php', PHPEditor::class);
|
||||
* Or require js and css assets:
|
||||
* Admin::css('/packages/prettydocs/css/styles.css');
|
||||
* Admin::js('/packages/prettydocs/js/main.js');
|
||||
*/
|
||||
|
||||
use App\Admin\Extensions\CleanCache;
|
||||
use Encore\Admin\Facades\Admin;
|
||||
use Encore\Admin\Form;
|
||||
use Encore\Admin\Grid;
|
||||
use Encore\Admin\Show;
|
||||
use Encore\Admin\Widgets\Navbar;
|
||||
|
||||
Form::forget(['map', 'editor']);
|
||||
|
||||
Admin::navbar(function (Navbar $navbar) {
|
||||
$navbar->right(new CleanCache());
|
||||
$navbar->right(new Navbar\Fullscreen());
|
||||
});
|
||||
|
||||
Form::init(function (Form $form) {
|
||||
$form->disableEditingCheck();
|
||||
$form->disableCreatingCheck();
|
||||
$form->disableViewCheck();
|
||||
|
||||
$form->tools(function (Form\Tools $tools) {
|
||||
$tools->disableView();
|
||||
// $tools->disableDelete();
|
||||
// $tools->disableList();
|
||||
});
|
||||
});
|
||||
|
||||
Show::init(function (Show $show) {
|
||||
$show->panel()
|
||||
->tools(function ($tools) {
|
||||
// $tools->disableEdit();
|
||||
// $tools->disableList();
|
||||
$tools->disableDelete();
|
||||
});;
|
||||
});
|
||||
|
||||
Grid::init(function (Grid $grid) {
|
||||
$grid->disableExport();
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableView();
|
||||
});
|
||||
$grid->disableBatchActions();
|
||||
$grid->filter(function ($filter) {
|
||||
$filter->disableIdFilter();
|
||||
});
|
||||
// $grid->expandFilter();
|
||||
});
|
||||
|
||||
24
app/Admin/routes.php
Normal file
24
app/Admin/routes.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use Encore\Admin\Facades\Admin;
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Admin::routes();
|
||||
|
||||
Route::group([
|
||||
'prefix' => config('admin.route.prefix'),
|
||||
'namespace' => config('admin.route.namespace'),
|
||||
'middleware' => config('admin.route.middleware'),
|
||||
'as' => config('admin.route.as'),
|
||||
], function (Router $router) {
|
||||
|
||||
$router->get('/', 'HomeController@index')->name('home');
|
||||
|
||||
$router->get('clean_cache', 'HomeController@cleanCache')->name('cleanCache');
|
||||
|
||||
foreach (glob(admin_path('Routes') . '/*.php') as $routeFile) {
|
||||
require $routeFile;
|
||||
}
|
||||
|
||||
});
|
||||
12
app/Api/Controllers/Controller.php
Normal file
12
app/Api/Controllers/Controller.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\Controllers;
|
||||
|
||||
use Jason\Api\Traits\ApiResponse;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
|
||||
use ApiResponse;
|
||||
}
|
||||
159
app/Api/Controllers/Data/IndexController.php
Normal file
159
app/Api/Controllers/Data/IndexController.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\Controllers\Data;
|
||||
|
||||
use App\Api\Controllers\Controller;
|
||||
use App\Api\Resources\Order\OrderDataCollection;
|
||||
use App\Api\Resources\User\UserDataCollection;
|
||||
use App\Api\Resources\User\UserDataResource;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\Coupon\Http\Resources\User\UserBaseResource;
|
||||
use Modules\Mall\Models\Order;
|
||||
use Modules\User\Models\User;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
$all = 1000;
|
||||
$sold = Order::query()
|
||||
->whereIn('state', [
|
||||
Order::STATUS_PAID,
|
||||
Order::STATUS_DELIVERED,
|
||||
Order::STATUS_SIGNED,
|
||||
Order::STATUS_COMPLETED,
|
||||
])
|
||||
->count();
|
||||
$donate = (new User())->getALlJzCount();
|
||||
|
||||
$orderQuery = Order::query()->where('type', Order::TYPE_NORMAL);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
$amount = (clone $orderQuery)->whereIn('state', [
|
||||
Order::STATUS_PAID,
|
||||
Order::STATUS_DELIVERED,
|
||||
Order::STATUS_SIGNED,
|
||||
Order::STATUS_COMPLETED,
|
||||
])->sum('amount');
|
||||
|
||||
$data = [
|
||||
'activities' => [
|
||||
'all' => $all,
|
||||
'donate' => $donate,
|
||||
'residue' => bcsub($all, $donate),
|
||||
],
|
||||
'orders' => [
|
||||
'users' => User::query()->whereHas('orders', function ($q) {
|
||||
$q->whereIn('state', [
|
||||
Order::STATUS_PAID,
|
||||
Order::STATUS_DELIVERED,
|
||||
Order::STATUS_SIGNED,
|
||||
Order::STATUS_COMPLETED,
|
||||
])->where('type', Order::TYPE_NORMAL);
|
||||
})->count(),
|
||||
|
||||
'all' => (clone $orderQuery)
|
||||
->whereIn('state', [
|
||||
Order::STATUS_PAID,
|
||||
Order::STATUS_DELIVERED,
|
||||
Order::STATUS_SIGNED,
|
||||
Order::STATUS_COMPLETED,
|
||||
])->count(),
|
||||
'paid' => (clone $orderQuery)->where('state', Order::STATUS_PAID)->count(),
|
||||
'delivered' => (clone $orderQuery)->where('state', Order::STATUS_DELIVERED)->count(),
|
||||
'signed' => (clone $orderQuery)->where('state', Order::STATUS_SIGNED)->count(),
|
||||
'completed' => (clone $orderQuery)->where('state', Order::STATUS_COMPLETED)->count(),
|
||||
'amount' => floatval($amount),
|
||||
],
|
||||
'users' => [
|
||||
'all' => User::count(),
|
||||
'yk' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 2);
|
||||
})->count(),
|
||||
'jk' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 3);
|
||||
})->count(),
|
||||
'nk' => User::query()
|
||||
->whereHas('identities', function ($q) {
|
||||
$q->where('id', 4);
|
||||
})->count(),
|
||||
]
|
||||
];
|
||||
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: description
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2023/1/5 13:50
|
||||
*/
|
||||
public function orders(Request $request)
|
||||
{
|
||||
$status = $request->status ?? 'all';
|
||||
|
||||
$orders = Order::query()
|
||||
->where('type', Order::TYPE_NORMAL)
|
||||
->when($status !== 'all', function ($q) use ($status) {
|
||||
$q->where('state', $status);
|
||||
}, function ($q) {
|
||||
$q->whereIn('state', [
|
||||
Order::STATUS_PAID,
|
||||
Order::STATUS_DELIVERED,
|
||||
Order::STATUS_SIGNED,
|
||||
Order::STATUS_COMPLETED,
|
||||
]);
|
||||
})
|
||||
->paginate();
|
||||
|
||||
return $this->success(new OrderDataCollection($orders));
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: description
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2023/1/5 14:13
|
||||
*/
|
||||
public function users()
|
||||
{
|
||||
$users = User::query()
|
||||
->withCount([
|
||||
'orders' => function ($q) {
|
||||
$q->whereIn('state', [
|
||||
Order::STATUS_PAID,
|
||||
Order::STATUS_DELIVERED,
|
||||
Order::STATUS_SIGNED,
|
||||
Order::STATUS_COMPLETED,
|
||||
]);
|
||||
}
|
||||
])
|
||||
->withSum([
|
||||
'orders' => function ($q) {
|
||||
$q->whereIn('state', [
|
||||
Order::STATUS_PAID,
|
||||
Order::STATUS_DELIVERED,
|
||||
Order::STATUS_SIGNED,
|
||||
Order::STATUS_COMPLETED,
|
||||
]);
|
||||
}
|
||||
], 'amount')
|
||||
->whereHas('orders', function ($q) {
|
||||
$q->whereIn('state', [
|
||||
Order::STATUS_PAID,
|
||||
Order::STATUS_DELIVERED,
|
||||
Order::STATUS_SIGNED,
|
||||
Order::STATUS_COMPLETED,
|
||||
])->where('type', Order::TYPE_NORMAL);
|
||||
})
|
||||
->paginate();
|
||||
return $this->success(new UserDataCollection($users));
|
||||
|
||||
}
|
||||
}
|
||||
12
app/Api/Controllers/IndexController.php
Normal file
12
app/Api/Controllers/IndexController.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\Controllers;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
return $this->success('Json Api is ready');
|
||||
}
|
||||
}
|
||||
63
app/Api/Controllers/Wechat/IndexController.php
Normal file
63
app/Api/Controllers/Wechat/IndexController.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\Controllers\Wechat;
|
||||
|
||||
use App\Api\WechatHandlers\EventMessageHandler;
|
||||
use App\Api\WechatHandlers\FileMessageHandler;
|
||||
use App\Api\WechatHandlers\ImageMessageHandler;
|
||||
use App\Api\WechatHandlers\LinkMessageHandler;
|
||||
use App\Api\WechatHandlers\LocationMessageHandler;
|
||||
use App\Api\WechatHandlers\ShortVideoMessageHandler;
|
||||
use App\Api\WechatHandlers\TextMessageHandler;
|
||||
use App\Api\WechatHandlers\TransferMessageHandler;
|
||||
use App\Api\WechatHandlers\VideoMessageHandler;
|
||||
use App\Api\WechatHandlers\VoiceMessageHandler;
|
||||
use EasyWeChat\Kernel\Messages\Message;
|
||||
use Overtrue\LaravelWeChat\Controllers\Controller;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
|
||||
public function serve()
|
||||
{
|
||||
$app = app('wechat.official_account');
|
||||
|
||||
$app->server->push(function ($message) {
|
||||
switch ($message['MsgType']) {
|
||||
case 'event':
|
||||
return '收到事件消息';
|
||||
break;
|
||||
case 'text':
|
||||
return '收到文字消息';
|
||||
break;
|
||||
case 'image':
|
||||
return '收到图片消息';
|
||||
break;
|
||||
case 'voice':
|
||||
return '收到语音消息';
|
||||
break;
|
||||
case 'video':
|
||||
return '收到视频消息';
|
||||
break;
|
||||
case 'location':
|
||||
return '收到坐标消息';
|
||||
break;
|
||||
case 'link':
|
||||
return '收到链接消息';
|
||||
break;
|
||||
case 'file':
|
||||
return '收到文件消息';
|
||||
// ... 其它消息
|
||||
default:
|
||||
return '收到其它消息';
|
||||
break;
|
||||
}
|
||||
|
||||
// ...
|
||||
});
|
||||
|
||||
$app->server->push(EventMessageHandler::class, Message::EVENT);
|
||||
|
||||
return $app->server->serve();
|
||||
}
|
||||
}
|
||||
21
app/Api/Resources/BaseCollection.php
Normal file
21
app/Api/Resources/BaseCollection.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class BaseCollection extends ResourceCollection
|
||||
{
|
||||
|
||||
protected function page(): array
|
||||
{
|
||||
return [
|
||||
'current' => $this->currentPage(),
|
||||
'total_page' => $this->lastPage(),
|
||||
'per_page' => $this->perPage(),
|
||||
'has_more' => $this->hasMorePages(),
|
||||
'total' => $this->total(),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
32
app/Api/Resources/Order/OrderDataCollection.php
Normal file
32
app/Api/Resources/Order/OrderDataCollection.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\Resources\Order;
|
||||
|
||||
use App\Api\Resources\BaseCollection;
|
||||
use App\Api\Resources\User\UserBaseResource;
|
||||
use Modules\Mall\Http\Resources\Api\Order\OrderExpressResource;
|
||||
|
||||
class OrderDataCollection extends BaseCollection
|
||||
{
|
||||
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'data' => $this->collection->map(function ($order) {
|
||||
return [
|
||||
'order_no' => $order->order_no,
|
||||
'user' => new UserBaseResource($order->user),
|
||||
'express' => new OrderExpressResource($order->express),
|
||||
'qty' => $order->items()->sum('qty'),
|
||||
'amount' => $order->amount,
|
||||
'freight' => $order->freight,
|
||||
'total' => $order->total,
|
||||
'type' => $order->type_text,
|
||||
'state' => $order->state_text,
|
||||
];
|
||||
}),
|
||||
'page' => $this->page(),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
20
app/Api/Resources/User/UserBaseResource.php
Normal file
20
app/Api/Resources/User/UserBaseResource.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\Resources\User;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class UserBaseResource extends JsonResource
|
||||
{
|
||||
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'user_id' => $this->id,
|
||||
'username' => $this->username,
|
||||
'nickname' => $this->info->nickname,
|
||||
'avatar' => $this->info->avatar ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
20
app/Api/Resources/User/UserDataCollection.php
Normal file
20
app/Api/Resources/User/UserDataCollection.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\Resources\User;
|
||||
|
||||
use App\Api\Resources\BaseCollection;
|
||||
|
||||
class UserDataCollection extends BaseCollection
|
||||
{
|
||||
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'data' => $this->collection->map(function ($info) {
|
||||
return new UserDataResource($info);
|
||||
}),
|
||||
'page' => $this->page(),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
22
app/Api/Resources/User/UserDataResource.php
Normal file
22
app/Api/Resources/User/UserDataResource.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\Resources\User;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class UserDataResource extends JsonResource
|
||||
{
|
||||
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'user_id' => $this->id,
|
||||
'username' => $this->username,
|
||||
'nickname' => $this->info->nickname,
|
||||
'orders_count' => $this->orders_count,
|
||||
'orders_sum_amount' => $this->orders_sum_amount,
|
||||
'avatar' => $this->info->avatar ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
14
app/Api/Routes/data.php
Normal file
14
app/Api/Routes/data.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::group([
|
||||
'namespace' => 'Data',
|
||||
'middleware' => config('api.route.middleware'),
|
||||
], function (Router $router) {
|
||||
$router->get('data', 'IndexController@index');
|
||||
$router->get('data/orders', 'IndexController@orders');
|
||||
$router->get('data/users', 'IndexController@users');
|
||||
});
|
||||
|
||||
12
app/Api/Routes/wechat.php
Normal file
12
app/Api/Routes/wechat.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::group([
|
||||
'namespace' => 'Wechat',
|
||||
'middleware' => config('api.route.middleware'),
|
||||
], function (Router $router) {
|
||||
$router->any('wechat', 'IndexController@serve')->name('wechat');
|
||||
});
|
||||
|
||||
142
app/Api/WechatHandlers/EventMessageHandler.php
Normal file
142
app/Api/WechatHandlers/EventMessageHandler.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\WechatHandlers;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
|
||||
use EasyWeChat\Kernel\Messages\Text;
|
||||
use Modules\User\Models\UserWechat;
|
||||
use Modules\User\Models\UserWechatOfficial;
|
||||
use Modules\User\Traits\WechatTrait;
|
||||
|
||||
class EventMessageHandler implements EventHandlerInterface
|
||||
{
|
||||
use WechatTrait;
|
||||
|
||||
private $payload;
|
||||
|
||||
public function handle($payload = null)
|
||||
{
|
||||
if (method_exists($this, $payload->Event)) {
|
||||
$this->payload = $payload;
|
||||
return call_user_func_array([$this, $payload->Event], []);
|
||||
} else {
|
||||
// return '暂不支持的消息类型';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 关注事件
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/7/27 9:41
|
||||
*/
|
||||
private function subscribe()
|
||||
{
|
||||
$app = app('wechat.official_account');
|
||||
$user = $app->user->get($this->payload->FromUserName);
|
||||
|
||||
if ($user->unionid) {
|
||||
$wechatUsers = UserWechat::query()
|
||||
->where('unionid', $user->unionid)
|
||||
->get();
|
||||
if ($wechatUsers->isNotEmpty()) {
|
||||
foreach ($wechatUsers as $wechatUser) {
|
||||
if ($wechatUser->official) {
|
||||
if ($wechatUser->official->subscribe != 1) {
|
||||
$wechatUser->official->update([
|
||||
'subscribe' => 1,
|
||||
'subscribed_at' => Carbon::parse($user->subscribe_time)->toDateTimeString(),
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$wechatUser->official()->create([
|
||||
'openid' => $this->payload->FromUserName,
|
||||
'subscribe' => 1,
|
||||
'subscribed_at' => Carbon::parse($user->subscribe_time)->toDateTimeString(),
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//插入关注数据
|
||||
$this->setUserSubscribe($user->unionid, $this->payload->FromUserName, 1);
|
||||
|
||||
} else {
|
||||
// 先查找用户是否存在,不存在再注册
|
||||
$officialUsers = UserWechatOfficial::query()
|
||||
->where('openid', $this->payload->FromUserName)
|
||||
->get();
|
||||
|
||||
//设置总表uniond
|
||||
if ($officialUsers->isNotEmpty()) {
|
||||
foreach ($officialUsers as $officialUser) {
|
||||
if (! $officialUser->userWechat->unionid && $user->unionid) {
|
||||
$officialUser->userWechat->update([
|
||||
'unionid' => $user->unionid
|
||||
]);
|
||||
}
|
||||
|
||||
if ($officialUser->subscribe != 1) {
|
||||
$officialUser->update([
|
||||
'subscribe' => 1,
|
||||
'subscribed_at' => Carbon::parse($user->subscribe_time)->toDateTimeString(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->firstSubscribeMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 取消关注事件
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/7/27 9:41
|
||||
*/
|
||||
private function unsubscribe()
|
||||
{
|
||||
$officialUsers = UserWechatOfficial::where('openid', $this->payload->FromUserName)->get();
|
||||
if ($officialUsers->isNotEmpty()) {
|
||||
foreach ($officialUsers as $officialUser) {
|
||||
$officialUser->update([
|
||||
'subscribe' => 0,
|
||||
'subscribed_at' => null,
|
||||
]);
|
||||
|
||||
//设置取消关注
|
||||
if ($officialUser->userWechat) {
|
||||
$this->setUserSubscribe($officialUser->userWechat->unionid, $officialUser->openid, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 关注返回的消息
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/8/2 11:37
|
||||
* @return Text
|
||||
*/
|
||||
private function firstSubscribeMessage()
|
||||
{
|
||||
$officialUser = UserWechatOfficial::where('openid', $this->payload->FromUserName)->first();
|
||||
$text = new Text('扎西德勒!感谢关注锶源昆仑。锶源昆仑天然饮用水,水源地位于海拔4300米的昆仑山,水中富含镁离子、锶元素、钙元素等微量元素且氘含量低,稀世罕见,仅供30000人饮用。
|
||||
参与打卡“锶享体验官”活动,请点击公众号菜单上的按钮“锶享体验官”进入活动,来申请喝水体验官吧!');
|
||||
if ($officialUser && $officialUser->userWechat) {
|
||||
$nickname = $officialUser->userWechat->nickname;
|
||||
$text = new Text('扎西德勒!'.$nickname.',感谢关注锶源昆仑。锶源昆仑天然饮用水,水源地位于海拔4300米的昆仑山,水中富含镁离子、锶元素、钙元素等微量元素且氘含量低,稀世罕见,仅供30000人饮用。
|
||||
参与打卡“锶享体验官”活动,请点击公众号菜单上的按钮“锶享体验官”进入活动,来申请喝水体验官吧!');
|
||||
}
|
||||
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
}
|
||||
27
app/Api/WechatHandlers/FileMessageHandler.php
Normal file
27
app/Api/WechatHandlers/FileMessageHandler.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\WechatHandlers;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
|
||||
|
||||
class FileMessageHandler implements EventHandlerInterface
|
||||
{
|
||||
|
||||
public function handle($payload = null)
|
||||
{
|
||||
|
||||
$payload->ToUserName;
|
||||
$payload->FromUserName;
|
||||
$payload->CreateTime;
|
||||
$payload->MsgId;
|
||||
|
||||
$payload->Title;
|
||||
$payload->Description;
|
||||
$payload->FileKey;
|
||||
$payload->FileMd5;
|
||||
$payload->FileTotalLen;
|
||||
|
||||
return '文件消息';
|
||||
}
|
||||
|
||||
}
|
||||
24
app/Api/WechatHandlers/ImageMessageHandler.php
Normal file
24
app/Api/WechatHandlers/ImageMessageHandler.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\WechatHandlers;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
|
||||
|
||||
class ImageMessageHandler implements EventHandlerInterface
|
||||
{
|
||||
|
||||
public function handle($payload = null)
|
||||
{
|
||||
|
||||
// $payload->ToUserName;
|
||||
// $payload->FromUserName;
|
||||
// $payload->CreateTime;
|
||||
// $payload->MsgId;
|
||||
//
|
||||
// $payload->MediaId;
|
||||
// $payload->PicUrl;
|
||||
|
||||
return '图片消息';
|
||||
}
|
||||
|
||||
}
|
||||
25
app/Api/WechatHandlers/LinkMessageHandler.php
Normal file
25
app/Api/WechatHandlers/LinkMessageHandler.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\WechatHandlers;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
|
||||
|
||||
class LinkMessageHandler implements EventHandlerInterface
|
||||
{
|
||||
|
||||
public function handle($payload = null)
|
||||
{
|
||||
|
||||
$payload->ToUserName;
|
||||
$payload->FromUserName;
|
||||
$payload->CreateTime;
|
||||
$payload->MsgId;
|
||||
|
||||
$payload->Title;
|
||||
$payload->Description;
|
||||
$payload->Url;
|
||||
|
||||
return '链接消息';
|
||||
}
|
||||
|
||||
}
|
||||
25
app/Api/WechatHandlers/LocationMessageHandler.php
Normal file
25
app/Api/WechatHandlers/LocationMessageHandler.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\WechatHandlers;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
|
||||
|
||||
class LocationMessageHandler implements EventHandlerInterface
|
||||
{
|
||||
|
||||
public function handle($payload = null)
|
||||
{
|
||||
|
||||
$payload->ToUserName;
|
||||
$payload->FromUserName;
|
||||
$payload->CreateTime;
|
||||
$payload->MsgId;
|
||||
|
||||
$payload->Latitude;
|
||||
$payload->Longitude;
|
||||
$payload->Precision;
|
||||
|
||||
return '上报位置消息';
|
||||
}
|
||||
|
||||
}
|
||||
24
app/Api/WechatHandlers/ShortVideoMessageHandler.php
Normal file
24
app/Api/WechatHandlers/ShortVideoMessageHandler.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\WechatHandlers;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
|
||||
|
||||
class ShortVideoMessageHandler implements EventHandlerInterface
|
||||
{
|
||||
|
||||
public function handle($payload = null)
|
||||
{
|
||||
|
||||
$payload->ToUserName;
|
||||
$payload->FromUserName;
|
||||
$payload->CreateTime;
|
||||
$payload->MsgId;
|
||||
|
||||
$payload->MediaId;
|
||||
$payload->ThumbMediaId;
|
||||
|
||||
return '短视频消息';
|
||||
}
|
||||
|
||||
}
|
||||
16
app/Api/WechatHandlers/TextMessageHandler.php
Normal file
16
app/Api/WechatHandlers/TextMessageHandler.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\WechatHandlers;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
|
||||
use function AlibabaCloud\Client\json;
|
||||
|
||||
class TextMessageHandler implements EventHandlerInterface
|
||||
{
|
||||
|
||||
public function handle($payload = null)
|
||||
{
|
||||
return '您的留言已经收到';
|
||||
}
|
||||
|
||||
}
|
||||
15
app/Api/WechatHandlers/TransferMessageHandler.php
Normal file
15
app/Api/WechatHandlers/TransferMessageHandler.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\WechatHandlers;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
|
||||
|
||||
class TransferMessageHandler implements EventHandlerInterface
|
||||
{
|
||||
|
||||
public function handle($payload = null)
|
||||
{
|
||||
return '客服消息'.json_encode($payload);
|
||||
}
|
||||
|
||||
}
|
||||
24
app/Api/WechatHandlers/VideoMessageHandler.php
Normal file
24
app/Api/WechatHandlers/VideoMessageHandler.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\WechatHandlers;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
|
||||
|
||||
class VideoMessageHandler implements EventHandlerInterface
|
||||
{
|
||||
|
||||
public function handle($payload = null)
|
||||
{
|
||||
|
||||
$payload->ToUserName;
|
||||
$payload->FromUserName;
|
||||
$payload->CreateTime;
|
||||
$payload->MsgId;
|
||||
|
||||
$payload->MediaId;
|
||||
$payload->ThumbMediaId;
|
||||
|
||||
return '视频消息';
|
||||
}
|
||||
|
||||
}
|
||||
25
app/Api/WechatHandlers/VoiceMessageHandler.php
Normal file
25
app/Api/WechatHandlers/VoiceMessageHandler.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Api\WechatHandlers;
|
||||
|
||||
use EasyWeChat\Kernel\Contracts\EventHandlerInterface;
|
||||
|
||||
class VoiceMessageHandler implements EventHandlerInterface
|
||||
{
|
||||
|
||||
public function handle($payload = null)
|
||||
{
|
||||
|
||||
$payload->ToUserName;
|
||||
$payload->FromUserName;
|
||||
$payload->CreateTime;
|
||||
$payload->MsgId;
|
||||
|
||||
$payload->MediaId;
|
||||
$payload->Format;
|
||||
$payload->Recognition;
|
||||
|
||||
return '语音消息';
|
||||
}
|
||||
|
||||
}
|
||||
1
app/Api/bootstrap.php
Normal file
1
app/Api/bootstrap.php
Normal file
@@ -0,0 +1 @@
|
||||
<?php
|
||||
25
app/Api/routes.php
Normal file
25
app/Api/routes.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
//Route::get('/', 'IndexController@index')->name('home');
|
||||
|
||||
/**
|
||||
* 分组的路由示例
|
||||
*/
|
||||
Route::group([
|
||||
// 'as' => '',
|
||||
// 'domain' => '',
|
||||
// 'middleware' => '',
|
||||
// 'namespace' => '',
|
||||
// 'prefix' => '',
|
||||
], function (Router $router) {
|
||||
$router->get('/', 'IndexController@index')->name('home');
|
||||
});
|
||||
/**
|
||||
* 文件夹引入的示例
|
||||
*/
|
||||
foreach (glob(app_path('Api/Routes').'/*.php') as $routeFile) {
|
||||
require $routeFile;
|
||||
}
|
||||
305
app/Bonus/IdentityBonus.php
Normal file
305
app/Bonus/IdentityBonus.php
Normal file
@@ -0,0 +1,305 @@
|
||||
<?php
|
||||
|
||||
namespace App\Bonus;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Modules\Coupon\Models\Coupon;
|
||||
use Modules\Coupon\Models\CouponGrant;
|
||||
use Modules\User\Models\Identity;
|
||||
use Modules\User\Models\Order;
|
||||
use Modules\User\Models\User;
|
||||
|
||||
class IdentityBonus
|
||||
{
|
||||
|
||||
/**
|
||||
* 开通身份
|
||||
*
|
||||
* @param User $user
|
||||
* @param Order $order
|
||||
* @param array $source
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function BuyIdentity(User $user, Order $order, array $source = [])
|
||||
{
|
||||
dd(1);
|
||||
try {
|
||||
$identity = $order->identity;
|
||||
$parent = $user->parent;
|
||||
$parentIdentity = $parent ? $user->parent->identityFirst() : '';
|
||||
|
||||
//开通赠送水滴
|
||||
$crystal = $order->identity->getRule('give_crystal', '0');
|
||||
if ($crystal > 0) {
|
||||
$user->account->rule('open_identity_score', $crystal, true, array_merge($source, [
|
||||
'user_order_id' => $order->id
|
||||
]));
|
||||
}
|
||||
//发券
|
||||
self::grantCoupon($user, $order, $parent, $parentIdentity);
|
||||
|
||||
//是否有上级
|
||||
if ($parent && $parentIdentity && $order->price > 0) {
|
||||
//增加业绩
|
||||
$parent->addPerf($order->price, $order);
|
||||
//开通的是季卡
|
||||
if ($identity->job == Identity::JOB_JK) {
|
||||
|
||||
|
||||
//直推季卡获得水滴
|
||||
$hasRecommend_jk_score = $parentIdentity->getRule('recommend_jk_score', '');
|
||||
if ($hasRecommend_jk_score) {
|
||||
$user->parent->account->rule(
|
||||
'recommend_jk_score',
|
||||
$hasRecommend_jk_score,
|
||||
false,
|
||||
array_merge($source, [
|
||||
'user_order_id' => $order->id
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
//合伙人推荐奖励
|
||||
self::setHhRecommendJk($hasRecommend_jk_score, $user, $order, $source);
|
||||
}
|
||||
|
||||
//开通的是年卡
|
||||
if ($identity->job == Identity::JOB_NK) {
|
||||
//直推年卡获得水滴
|
||||
$hasRecommend_nk_score = $parentIdentity->getRule('recommend_nk_score', '');
|
||||
if ($hasRecommend_nk_score) {
|
||||
$user->parent->account->rule(
|
||||
'recommend_nk_score',
|
||||
$hasRecommend_nk_score,
|
||||
false,
|
||||
array_merge($source, [
|
||||
'user_order_id' => $order->id
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
//合伙人推荐奖励
|
||||
self::setHhRecommendNk($hasRecommend_nk_score, $user, $order, $source);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (\Exception $exception) {
|
||||
return $exception->getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 发券
|
||||
* 推荐会员得优惠券 季卡 年卡 创始
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/8/31 13:53
|
||||
*/
|
||||
public static function grantCoupon($user, $order, $parent, $parentIdentity)
|
||||
{
|
||||
if ($parent && $parentIdentity->job !== Identity::JOB_HH) {
|
||||
$jkIdentity = Identity::query()->Jk()->first();
|
||||
$openJkCount = $parent->getOpenJkCount();//开通季卡次数
|
||||
$recommendUserCoupunCount = $parent->getRecommendUserCouponCount();//推荐季卡得优惠券数
|
||||
$recommend_coupon = $parentIdentity->getRule('recommend_coupon', null);//是否有推荐奖励
|
||||
|
||||
//推荐季卡得优惠券
|
||||
if ($recommend_coupon && $order->type == Order::TYPE_OPEN && $openJkCount > $recommendUserCoupunCount) {
|
||||
$coupon = Coupon::query()
|
||||
->whereHas('items', function ($q) use ($jkIdentity) {
|
||||
$q->withGoods($jkIdentity);
|
||||
})
|
||||
->first();
|
||||
|
||||
$ended_at = Carbon::parse($parentIdentity->pivot->ended_at);
|
||||
if ($coupon && $ended_at->gt(now())) {
|
||||
$days = $ended_at->addMonth()->diffInDays(now());
|
||||
#TODO 推季卡会员得优惠券
|
||||
// $user->parent->getCoupon($coupon->id, CouponGrant::CHANNEL_EXPAND, $days);
|
||||
$user->parent->getCoupon($coupon->id, CouponGrant::CHANNEL_EXPAND);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 合伙人推荐季卡
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/8/19 15:11
|
||||
*/
|
||||
public static function setHhRecommendJk($score, $user, $order, $source)
|
||||
{
|
||||
$hhUsers = $user->getParentHh();//获取所有合伙人
|
||||
$hhIdentity = Identity::query()->where('job', Identity::JOB_HH)->first();
|
||||
$rule_name = 'recommend_indirect_jk_balance';
|
||||
if ($hhIdentity && ! empty($hhUsers)) {
|
||||
//有人获得了推荐水滴就是间推
|
||||
|
||||
$i = 1;
|
||||
foreach ($hhUsers as $hhUser) {
|
||||
$jkChildren = $hhUser->getJkChildrenCount();
|
||||
$amount = 0;
|
||||
|
||||
if ($i > 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
//间接
|
||||
if ($score) {
|
||||
if ($jkChildren > 10) {
|
||||
$rateName = 'recommend_rate_indirect_jk_balance_gt';
|
||||
} else {
|
||||
$rateName = 'recommend_rate_indirect_jk_balance_lte';
|
||||
}
|
||||
} else {//直接
|
||||
if ($jkChildren > 10) {
|
||||
$rateName = 'recommend_rate_jk_balance_gt';
|
||||
} else {
|
||||
$rateName = 'recommend_rate_jk_balance_lte';
|
||||
}
|
||||
|
||||
$rule_name = 'recommend_jk_balance';
|
||||
}
|
||||
|
||||
$hasRate = $hhIdentity->getRule($rateName, 0);//获取比例
|
||||
$rateData = self::getNonZeroRate($hasRate);
|
||||
$amount = bcmul($order->price, $rateData, 2);
|
||||
|
||||
if ($amount) {
|
||||
//执行分润
|
||||
$hhUser->account->rule(
|
||||
$rule_name,
|
||||
$amount,
|
||||
false,
|
||||
array_merge($source, [
|
||||
'user_order_id' => $order->id,
|
||||
'rate' => $rateData
|
||||
])
|
||||
);
|
||||
//培育津贴
|
||||
self::allowance($hhUser, $amount, $source);
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
} else {
|
||||
info('没有找到合伙人');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 合伙人间推季卡
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/8/19 15:13
|
||||
*/
|
||||
public static function setHhRecommendNk($score, $user, $order, $source)
|
||||
{
|
||||
$hhUsers = $user->getParentHh();//获取所有合伙人
|
||||
$hhIdentity = Identity::query()->where('job', Identity::JOB_HH)->first();
|
||||
$rule_name = 'recommend_indirect_nk_balance';
|
||||
if ($hhIdentity && ! empty($hhUsers)) {
|
||||
//有人获得了推荐水滴就是间推
|
||||
$i = 1;
|
||||
foreach ($hhUsers as $hhUser) {
|
||||
$nkChildren = $hhUser->getNkChildrenCount();
|
||||
$amount = 0;
|
||||
if ($i > 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
//间接
|
||||
if ($score) {
|
||||
if ($nkChildren > 10) {
|
||||
$rateName = 'recommend_rate_indirect_nk_balance_gt';
|
||||
} else {
|
||||
$rateName = 'recommend_rate_indirect_nk_balance_lte';
|
||||
}
|
||||
} else {//直接
|
||||
if ($nkChildren > 10) {
|
||||
$rateName = 'recommend_rate_nk_balance_gt';
|
||||
} else {
|
||||
$rateName = 'recommend_rate_nk_balance_lte';
|
||||
}
|
||||
|
||||
$rule_name = 'recommend_nk_balance';
|
||||
}
|
||||
$hasRate = $hhIdentity->getRule($rateName, 0);//获取比例
|
||||
$rateData = self::getNonZeroRate($hasRate);
|
||||
$amount = bcmul($order->price, $rateData, 2);
|
||||
|
||||
|
||||
if ($amount > 0) {
|
||||
//执行分润
|
||||
$hhUser->account->rule(
|
||||
$rule_name,
|
||||
$amount,
|
||||
false,
|
||||
array_merge($source, [
|
||||
'user_order_id' => $order->id,
|
||||
'rate' => $rateData
|
||||
])
|
||||
);
|
||||
|
||||
//培育津贴
|
||||
self::allowance($hhUser, $amount, $source);
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 获取百分比数据
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/8/19 14:56
|
||||
* @param $rate
|
||||
* @param $decimals
|
||||
* @return int|string|null
|
||||
*/
|
||||
public static function getNonZeroRate($rate, $decimals = 2)
|
||||
{
|
||||
return $rate > 0 ? bcdiv($rate, 100, $decimals) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 培育津贴
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/8/30 14:32
|
||||
*/
|
||||
public static function allowance(User $user, $amount, $source)
|
||||
{
|
||||
$UserIdentity = $user->identityFirst();
|
||||
$hasRate = $UserIdentity->getRule('recommend_rate_allowance', 0);//获取培育津贴比例
|
||||
if ($UserIdentity->job == Identity::JOB_HH && $hasRate) {
|
||||
$hhUsers = $user->getParentHh();//获取所有合伙人
|
||||
$rateData = self::getNonZeroRate($hasRate);
|
||||
$amount = bcmul($amount, $rateData, 2);
|
||||
|
||||
$i = 1;
|
||||
if (! empty($hhUsers)) {
|
||||
foreach ($hhUsers as $hhUser) {
|
||||
if ($i > 1) {
|
||||
break;
|
||||
}
|
||||
$hhUser->account->rule(
|
||||
'allowance_balance',
|
||||
$amount,
|
||||
false,
|
||||
$source
|
||||
);
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
15
app/Channels/WechatMiniChannel.php
Normal file
15
app/Channels/WechatMiniChannel.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Channels;
|
||||
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class WechatMiniChannel
|
||||
{
|
||||
|
||||
public function send($notifiable, Notification $notification)
|
||||
{
|
||||
$notification->toWeChat($notifiable);
|
||||
}
|
||||
|
||||
}
|
||||
36
app/Console/Commands/MonthPerfCommand.php
Normal file
36
app/Console/Commands/MonthPerfCommand.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Jobs\Bonus\MonthPerfJob;
|
||||
use Illuminate\Console\Command;
|
||||
use Modules\User\Models\User;
|
||||
|
||||
class MonthPerfCommand extends Command
|
||||
{
|
||||
protected $signature = 'Bonus:MonthPerf {last?}';
|
||||
|
||||
protected $description = '分红:计算用户月度业绩';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$last = $this->argument('last') ?: 0;
|
||||
|
||||
User::whereHas('identities', function ($query) {
|
||||
$query->where('id', 6);
|
||||
})
|
||||
->whereHas('identityMiddle', function ($query) {
|
||||
$query->where('star', '>', 0);
|
||||
})
|
||||
->chunkById(100, function ($users) use ($last) {
|
||||
foreach ($users as $user) {
|
||||
MonthPerfJob::dispatch($user, $last);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
57
app/Console/Commands/StartBounsCommand.php
Normal file
57
app/Console/Commands/StartBounsCommand.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Jobs\Bonus\SendBounsJob;
|
||||
use App\Models\Bouns;
|
||||
use App\Models\BounsUserPerf;
|
||||
use Illuminate\Console\Command;
|
||||
use Exception;
|
||||
|
||||
class StartBounsCommand extends Command
|
||||
{
|
||||
protected $signature = 'Bonus:StartMonth {star} {last?}';
|
||||
|
||||
protected $description = '分红:开始分红 {1-5} {last?}';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$star = $this->argument('star') ?: 0;
|
||||
if (!in_array($star, Bouns::TYPEARRAY)) {
|
||||
throw new Exception('星级参数不正确');
|
||||
}
|
||||
$last = $this->argument('last') ?: 0;
|
||||
|
||||
$time = now()->startOfMonth()->toDateTimeString();
|
||||
if ($last) {
|
||||
$time = now()->subMonth()->startOfMonth()->toDateTimeString();
|
||||
}
|
||||
$bouns = Bouns::where('date', $time)
|
||||
->where('type', $star)
|
||||
->where('status', Bouns::STATUS_INIT)
|
||||
->first();
|
||||
if (!$bouns) {
|
||||
throw new Exception('分红内容不存在或状态不正确');
|
||||
}
|
||||
$bounsUserPerf = BounsUserPerf::where('date', $bouns->date)
|
||||
->where('star', '>=', $bouns->type)
|
||||
->get();
|
||||
if ($bounsUserPerf->count() > 0) {
|
||||
$allOld = bcmul($bounsUserPerf->sum('old_perf'), 0.3, 4);//累计业绩
|
||||
$allNew = bcmul($bounsUserPerf->sum('new_perf'), 0.7, 4);//新增业绩
|
||||
$allPerf = bcadd($allOld, $allNew, 4);//总业绩
|
||||
$price = bcdiv($bouns->total, $allPerf, 6);//单价
|
||||
$bouns->doIng();
|
||||
foreach ($bounsUserPerf as $bounsPerf) {
|
||||
SendBounsJob::dispatch($bounsPerf, $price, $bouns);
|
||||
}
|
||||
} else {
|
||||
$bouns->doEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
66
app/Console/Kernel.php
Normal file
66
app/Console/Kernel.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
use Nwidart\Modules\Facades\Module as ModuleManager;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
* @var array
|
||||
*/
|
||||
protected $commands = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// $schedule->command('inspire')->hourly();
|
||||
$schedule->command('Bonus:MonthPerf 1')->monthlyOn(1, '00:01');
|
||||
$schedule->command('Bonus:StartMonth 1 1')->monthlyOn(1, '00:10');
|
||||
$schedule->command('Bonus:StartMonth 2 1')->monthlyOn(1, '00:15');
|
||||
$schedule->command('Bonus:StartMonth 3 1')->monthlyOn(1, '00:20');
|
||||
$schedule->command('Bonus:StartMonth 4 1')->monthlyOn(1, '00:25');
|
||||
$schedule->command('Bonus:StartMonth 5 1')->monthlyOn(1, '00:30');
|
||||
$this->modules($schedule);
|
||||
}
|
||||
|
||||
/**
|
||||
* 要执行任务的位置增加Console\Kernel类
|
||||
* 类中 runCommand(Schedule $schedule)
|
||||
* 模型中的command在模型的ServiceProvider自行注册
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
*/
|
||||
protected function modules(Schedule $schedule)
|
||||
{
|
||||
$data = ModuleManager::toCollection();
|
||||
foreach ($data as $name => $module) {
|
||||
$nameSpace = "\\Modules\\$name\\Console\\Kernel";
|
||||
if (class_exists($nameSpace)) {
|
||||
$runKernel = resolve($nameSpace);
|
||||
$runKernel->runCommand($schedule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
* @return void
|
||||
*/
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
|
||||
// require base_path('routes/console.php');
|
||||
}
|
||||
|
||||
}
|
||||
43
app/Exceptions/Handler.php
Normal file
43
app/Exceptions/Handler.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Jason\Api\Traits\ApiException;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
|
||||
use ApiException;
|
||||
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
* @var array
|
||||
*/
|
||||
protected $dontReport = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed for validation exceptions.
|
||||
* @var array
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
//
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
29
app/Http/Controllers/Controller.php
Normal file
29
app/Http/Controllers/Controller.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Jason\Api\Traits\ApiResponse;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
|
||||
use ApiResponse;
|
||||
|
||||
/**
|
||||
* Notes : 授权token返回格式
|
||||
* @Date : 2021/3/16 5:00 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param string $token
|
||||
* @return array
|
||||
*/
|
||||
protected function respondWithToken(string $token): array
|
||||
{
|
||||
return [
|
||||
'access_token' => $token,
|
||||
'token_type' => 'Bearer',
|
||||
'expires_in' => auth('api')->factory()->getTTL() * 60,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
18
app/Http/Controllers/ImageController.php
Normal file
18
app/Http/Controllers/ImageController.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Material;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ImageController extends Controller
|
||||
{
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$name = $request->name;
|
||||
$img = Material::query()->where('title', $name)->first();
|
||||
|
||||
return view('image', compact('img'));
|
||||
}
|
||||
}
|
||||
66
app/Http/Kernel.php
Normal file
66
app/Http/Kernel.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Fruitcake\Cors\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
// \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
// 'throttle:api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
];
|
||||
}
|
||||
21
app/Http/Middleware/Authenticate.php
Normal file
21
app/Http/Middleware/Authenticate.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
return route('login');
|
||||
}
|
||||
}
|
||||
}
|
||||
17
app/Http/Middleware/EncryptCookies.php
Normal file
17
app/Http/Middleware/EncryptCookies.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
32
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
32
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null ...$guards
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, ...$guards)
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
19
app/Http/Middleware/TrimStrings.php
Normal file
19
app/Http/Middleware/TrimStrings.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
||||
20
app/Http/Middleware/TrustHosts.php
Normal file
20
app/Http/Middleware/TrustHosts.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
||||
class TrustHosts extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the host patterns that should be trusted.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function hosts()
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
||||
23
app/Http/Middleware/TrustProxies.php
Normal file
23
app/Http/Middleware/TrustProxies.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array|string|null
|
||||
*/
|
||||
protected $proxies;
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
||||
17
app/Http/Middleware/VerifyCsrfToken.php
Normal file
17
app/Http/Middleware/VerifyCsrfToken.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
'wechat'
|
||||
];
|
||||
}
|
||||
43
app/Jobs/Bonus/BuyIdentityJob.php
Normal file
43
app/Jobs/Bonus/BuyIdentityJob.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Bonus;
|
||||
|
||||
use App\Bonus\IdentityBonus;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Modules\User\Models\Order;
|
||||
use Modules\User\Models\User;
|
||||
|
||||
class BuyIdentityJob implements ShouldQueue
|
||||
{
|
||||
|
||||
use Dispatchable, InteractsWithQueue;
|
||||
|
||||
public $queue = 'BONUS';
|
||||
|
||||
public $delay = 0;
|
||||
|
||||
public $tries = 1;
|
||||
|
||||
public $timeout = 30;
|
||||
|
||||
protected $user; //bonus
|
||||
|
||||
protected $order; //bonus
|
||||
|
||||
protected $source;//bonus
|
||||
|
||||
public function __construct(User $user, Order $order, array $source = [])
|
||||
{
|
||||
$this->user = $user->fresh();
|
||||
$this->order = $order->fresh();
|
||||
$this->source = $source;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
IdentityBonus::BuyIdentity($this->user, $this->order, $this->source);
|
||||
}
|
||||
|
||||
}
|
||||
57
app/Jobs/Bonus/MonthPerfJob.php
Normal file
57
app/Jobs/Bonus/MonthPerfJob.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Bonus;
|
||||
|
||||
use App\Models\BounsUserPerf;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Modules\User\Models\User;
|
||||
|
||||
class MonthPerfJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue;
|
||||
|
||||
public $queue = 'BONUS';
|
||||
|
||||
public $delay = 0;
|
||||
|
||||
public $tries = 1;
|
||||
|
||||
public $timeout = 30;
|
||||
|
||||
protected $user; //bonus
|
||||
|
||||
protected $last; //bonus
|
||||
|
||||
/**
|
||||
* @param User $user 用户
|
||||
* @param bool $last 是否上个月
|
||||
*/
|
||||
public function __construct(User $user, bool $last)
|
||||
{
|
||||
$this->user = $user->fresh();
|
||||
$this->last = $last;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$time = [now()->startOfMonth()->toDateTimeString(), now()->endOfMonth()->toDateTimeString()];
|
||||
if ($this->last) {
|
||||
$time = [
|
||||
now()->subMonth()->startOfMonth()->toDateTimeString(),
|
||||
now()->subMonth()->endOfMonth()->toDateTimeString()
|
||||
];
|
||||
}
|
||||
$old = $this->user->allPerf();
|
||||
$new = $this->user->allPerf($time);
|
||||
BounsUserPerf::updateOrCreate([
|
||||
'user_id' => $this->user->id,
|
||||
'date' => $time[0],
|
||||
], [
|
||||
'star' => $this->user->identityFirst()->pivot->star,
|
||||
'old_perf' => $old,
|
||||
'new_perf' => $new,
|
||||
]);
|
||||
}
|
||||
}
|
||||
55
app/Jobs/Bonus/SendBounsJob.php
Normal file
55
app/Jobs/Bonus/SendBounsJob.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Bonus;
|
||||
|
||||
use App\Models\Bouns;
|
||||
use App\Models\BounsUserPerf;
|
||||
use App\Models\Job;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
|
||||
class SendBounsJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue;
|
||||
|
||||
public $queue = 'BONUS';
|
||||
|
||||
public $delay = 0;
|
||||
|
||||
public $tries = 1;
|
||||
|
||||
public $timeout = 30;
|
||||
|
||||
protected BounsUserPerf $bounsPerf; //BounsUserPerf
|
||||
protected float $price;//单价
|
||||
protected Bouns $bouns;//单价
|
||||
|
||||
public function __construct(BounsUserPerf $bounsPerf, float $price, Bouns $bouns)
|
||||
{
|
||||
$this->bounsPerf = $bounsPerf->fresh();
|
||||
$this->price = $price;
|
||||
$this->bouns = $bouns;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
try {
|
||||
$perf = bcadd(bcmul($this->bounsPerf->old_perf, 0.3, 4),
|
||||
bcmul($this->bounsPerf->new_perf, 0.7, 4), 4);
|
||||
|
||||
$this->bounsPerf->price = $this->price;
|
||||
$this->bounsPerf->amount = $this->price * $perf;
|
||||
$this->bounsPerf->user->account->rule('star_balance', $this->bounsPerf->amount, false, [
|
||||
'remark' => Bouns::TYPES[$this->bouns->type],
|
||||
'star' => $this->bouns->type,
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
$this->bounsPerf->status = BounsUserPerf::STATUS_ERROR;
|
||||
}
|
||||
$this->bounsPerf->save();
|
||||
if (Job::where('queue', 'BONUS')->where('payload', 'like', '%SendBounsJob%')->count() <= 1) {
|
||||
$this->bouns->doEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
15
app/Listeners/PaymentPaidListener.php
Normal file
15
app/Listeners/PaymentPaidListener.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Modules\Payment\Events\Paid;
|
||||
|
||||
class PaymentPaidListener implements ShouldQueue
|
||||
{
|
||||
public function handle(Paid $event): void
|
||||
{
|
||||
$payment = $event->payment;
|
||||
|
||||
}
|
||||
}
|
||||
41
app/Listeners/UserOrderPaidListener.php
Normal file
41
app/Listeners/UserOrderPaidListener.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Jobs\Bonus\BuyIdentityJob;
|
||||
use App\Models\Bouns;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Modules\Task\Facades\TaskFacade;
|
||||
use Modules\User\Events\UserOrderPaid;
|
||||
|
||||
class UserOrderPaidListener implements ShouldQueue
|
||||
{
|
||||
|
||||
public function handle(UserOrderPaid $event)
|
||||
{
|
||||
$order = $event->order;
|
||||
$user = $event->order->user;
|
||||
$identity = $event->order->identity;
|
||||
$source = [
|
||||
'identity_id' => $identity->id,
|
||||
'order_id' => $event->order->id,
|
||||
'type' => $event->order->type,
|
||||
];
|
||||
|
||||
// BuyIdentityJob::dispatch($user, $order, $source);//个人赠送水滴
|
||||
// Bouns::addBouns($order, $order->price);
|
||||
|
||||
#TODO 开通会员赠送水滴
|
||||
// TaskFacade::do('open_vip', $user->id, [
|
||||
// 'identity_id' => $event->order->identity_id
|
||||
// ]);
|
||||
|
||||
#TODO 邀请一名健康体验馆 赠送水滴
|
||||
// if ($user->parent) {
|
||||
// TaskFacade::do('recommend_ty', $user->parent->id, [
|
||||
// 'user_id' => $user->id
|
||||
// ]);
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
128
app/Models/Bouns.php
Normal file
128
app/Models/Bouns.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model as BaseModel;
|
||||
|
||||
class Bouns extends Model
|
||||
{
|
||||
protected $dates = ['date'];
|
||||
protected $casts = [
|
||||
'source' => 'array',
|
||||
];
|
||||
const ONE_STAR = 1;
|
||||
const TWO_STAR = 2;
|
||||
const THREE_STAR = 3;
|
||||
const FOUR_STAR = 4;
|
||||
const FIVE_STAR = 5;
|
||||
const TYPES = [
|
||||
self::ONE_STAR => '一星分红',
|
||||
self::TWO_STAR => '二星分红',
|
||||
self::THREE_STAR => '三星分红',
|
||||
self::FOUR_STAR => '四星分红',
|
||||
self::FIVE_STAR => '五星分红',
|
||||
];
|
||||
|
||||
const TYPEARRAY = [self::ONE_STAR, self::TWO_STAR, self::THREE_STAR, self::FOUR_STAR, self::FIVE_STAR];
|
||||
|
||||
const STATUS_INIT = 0;
|
||||
const STATUS_SENDING = 1;
|
||||
const STATUS_SENDED = 2;
|
||||
const STATUS_REJECT = 8;
|
||||
const STATUS_ERROR = 9;
|
||||
const STATUS = [
|
||||
self::STATUS_INIT => '待发放',
|
||||
self::STATUS_SENDING => '发放中',
|
||||
self::STATUS_SENDED => '发放完毕',
|
||||
self::STATUS_REJECT => '停发',
|
||||
self::STATUS_ERROR => '错误',
|
||||
];
|
||||
|
||||
protected function orders()
|
||||
{
|
||||
return $this->hasMany(BounsOrder::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加累计额度,增加对应订单记录
|
||||
* @param BaseModel $order
|
||||
* @param float $total
|
||||
* @param float $rate
|
||||
* @return void
|
||||
*/
|
||||
protected function addAmount(BaseModel $order, float $total, float $rate)
|
||||
{
|
||||
$amount = bcmul($total, bcdiv($rate, 100, 4), 2);
|
||||
if ($this->orders()->create([
|
||||
'order_type' => $order->getMorphClass(),
|
||||
'order_id' => $order->id,
|
||||
'type' => $this->type,
|
||||
'total' => $total,
|
||||
'amount' => $amount,
|
||||
])) {
|
||||
$this->increment('total', $amount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分红模型
|
||||
* @param int $type 类别
|
||||
* @param bool $last 是否上一期
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getBouns(int $type, bool $last = false)
|
||||
{
|
||||
$time = now()->startOfMonth();
|
||||
if ($last) {
|
||||
$time = now()->subMonth()->startOfMonth();
|
||||
}
|
||||
return Bouns::firstOrCreate([
|
||||
'type' => $type,
|
||||
'date' => $time->toDateTimeString(),
|
||||
], [
|
||||
'total' => 0,
|
||||
'status' => self::STATUS_INIT,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加分红
|
||||
* @param BaseModel $order 订单
|
||||
* @param float $total 订单金额(未计算前)
|
||||
* @return void
|
||||
*/
|
||||
public static function addBouns(BaseModel $order, float $total)
|
||||
{
|
||||
$rateArray = [
|
||||
self::ONE_STAR => app('Conf_user')['one_star_balance_rate'] ?? 0,
|
||||
self::TWO_STAR => app('Conf_user')['two_star_balance_rate'] ?? 0,
|
||||
self::THREE_STAR => app('Conf_user')['three_star_balance_rate'] ?? 0,
|
||||
self::FOUR_STAR => app('Conf_user')['four_star_balance_rate'] ?? 0,
|
||||
self::FIVE_STAR => app('Conf_user')['five_star_balance_rate'] ?? 0,
|
||||
];
|
||||
foreach ($rateArray as $key => $rate) {
|
||||
if ($rate > 0) {
|
||||
$model = Bouns::getBouns($key);
|
||||
$model->addAmount($order, $total, $rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function doIng()
|
||||
{
|
||||
$this->status = self::STATUS_SENDING;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
public function doEnd()
|
||||
{
|
||||
$this->status = self::STATUS_SENDED;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
public function doError()
|
||||
{
|
||||
$this->status = self::STATUS_ERROR;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
12
app/Models/BounsOrder.php
Normal file
12
app/Models/BounsOrder.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
|
||||
class BounsOrder extends Model
|
||||
{
|
||||
public function bouns()
|
||||
{
|
||||
return $this->belongsTo(Bouns::class);
|
||||
}
|
||||
}
|
||||
26
app/Models/BounsUserPerf.php
Normal file
26
app/Models/BounsUserPerf.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
|
||||
use Modules\User\Traits\BelongsToUser;
|
||||
|
||||
class BounsUserPerf extends Model
|
||||
{
|
||||
use BelongsToUser;
|
||||
|
||||
const STATUS_INIT = 0;
|
||||
const STATUS_SUCCESS = 1;
|
||||
const STATUS_ERROR = 2;
|
||||
|
||||
const STATUS = [
|
||||
self::STATUS_INIT => '待发放',
|
||||
self::STATUS_SUCCESS => '完成',
|
||||
self::STATUS_ERROR => '失败',
|
||||
];
|
||||
|
||||
public function bouns()
|
||||
{
|
||||
return $this->belongsTo(Bouns::class);
|
||||
}
|
||||
}
|
||||
8
app/Models/Job.php
Normal file
8
app/Models/Job.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
class Job extends Model
|
||||
{
|
||||
|
||||
}
|
||||
11
app/Models/Material.php
Normal file
11
app/Models/Material.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
|
||||
use App\Traits\HasCovers;
|
||||
|
||||
class Material extends Model
|
||||
{
|
||||
use HasCovers;
|
||||
}
|
||||
27
app/Models/Model.php
Normal file
27
app/Models/Model.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Traits\Macroable;
|
||||
use Encore\Admin\Traits\DefaultDatetimeFormat;
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
|
||||
class Model extends Eloquent
|
||||
{
|
||||
|
||||
use DefaultDatetimeFormat,
|
||||
Macroable;
|
||||
|
||||
/**
|
||||
* 进制批量写入的字段
|
||||
* @var array
|
||||
*/
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
* 修改模型默认分页数量
|
||||
* @var int
|
||||
*/
|
||||
protected $perPage = 10;
|
||||
|
||||
}
|
||||
51
app/Models/Module.php
Normal file
51
app/Models/Module.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Nwidart\Modules\Facades\Module as ModuleManager;
|
||||
|
||||
class Module extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes : 自定义返回数据
|
||||
* @Date : 2021/3/11 9:59 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public function paginate(): LengthAwarePaginator
|
||||
{
|
||||
$perPage = Request::get('per_page', 20);
|
||||
// $page = Request::get('page', 1);
|
||||
// $start = ($page - 1) * $perPage;
|
||||
|
||||
$data = ModuleManager::toCollection();
|
||||
|
||||
$movies = $data->map(function ($module) {
|
||||
return [
|
||||
'id' => $module->getName(),
|
||||
'name' => $module->getName(),
|
||||
'alias' => $module->getAlias(),
|
||||
'description' => $module->getDescription(),
|
||||
'priority' => $module->getPriority(),
|
||||
'keywords' => $module->get('keywords'),
|
||||
'requires' => $module->getRequires(),
|
||||
'enabled' => $module->isEnabled(),
|
||||
'version' => $module->get('version'),
|
||||
'author' => $module->get('author'),
|
||||
];
|
||||
});
|
||||
|
||||
$movies = static::hydrate($movies->toArray());
|
||||
|
||||
$paginator = new LengthAwarePaginator($movies, ModuleManager::count(), $perPage);
|
||||
|
||||
$paginator->setPath(url()->current());
|
||||
|
||||
return $paginator;
|
||||
}
|
||||
|
||||
}
|
||||
100
app/Notifications/SystemOpenVip.php
Normal file
100
app/Notifications/SystemOpenVip.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use App\Channels\WechatMiniChannel;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Channels\DatabaseChannel;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Modules\User\Models\Identity;
|
||||
use Modules\User\Models\IdentityMiddle;
|
||||
use Modules\User\Models\User;
|
||||
|
||||
class SystemOpenVip extends Notification
|
||||
{
|
||||
|
||||
use Queueable;
|
||||
|
||||
protected $identityMiddle;
|
||||
protected $identity;
|
||||
protected $title;
|
||||
protected $remark;
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(IdentityMiddle $identityMiddle)
|
||||
{
|
||||
$identity = $identityMiddle->identity;
|
||||
$remark = '赠送'.$identity->stock.'箱水';
|
||||
// if ($identity->job == Identity::JOB_HH) {
|
||||
// $remark = '开启奖金模式';
|
||||
// }
|
||||
|
||||
$this->title = "恭喜您!开通{$identityMiddle->identity->name}成功!";
|
||||
$this->identityMiddle = $identityMiddle;
|
||||
$this->identity = $identity;
|
||||
$this->remark = $remark;
|
||||
$this->url = config('user.web.base');
|
||||
}
|
||||
|
||||
public function via(): array
|
||||
{
|
||||
return [DatabaseChannel::class, WechatMiniChannel::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 开通会员
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/8/9 10:44
|
||||
* @param User $notifiable
|
||||
* @return bool
|
||||
*/
|
||||
public function toWeChat(User $notifiable): bool
|
||||
{
|
||||
if ($notifiable->isOfficialSubscribe()) {
|
||||
$app = app('wechat.official_account');
|
||||
|
||||
$start_at = $this->identityMiddle->started_at ?? '';
|
||||
$end_at = $this->identityMiddle->ended_at ?? '';
|
||||
$time = $start_at.' ~ '.$end_at;
|
||||
if (empty($start_at) || empty($end_at)) {
|
||||
$time = '永久';
|
||||
}
|
||||
|
||||
$app->template_message->send([
|
||||
'touser' => $notifiable->wechat->official_openid,
|
||||
'template_id' => 'gtS1LS9Irw7h2RtQLT5Cxx4p28-k8PrPyH53HBU2oWk',
|
||||
'url' => $this->url,
|
||||
'data' => [
|
||||
'first' => $this->title,
|
||||
'keyword1' => $time,
|
||||
'keyword2' => $this->remark,
|
||||
'remark' => '',
|
||||
],
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送到数据库
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toDatabase(User $notifiable): array
|
||||
{
|
||||
return [
|
||||
'title' => $this->title,
|
||||
'content' => $this->remark,
|
||||
'url' => $this->url,
|
||||
];
|
||||
}
|
||||
}
|
||||
90
app/Notifications/SystemOrderDelivered.php
Normal file
90
app/Notifications/SystemOrderDelivered.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use App\Channels\WechatMiniChannel;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Channels\DatabaseChannel;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Modules\Mall\Models\Order;
|
||||
use Modules\Mall\Models\OrderExpress;
|
||||
use Modules\User\Models\User;
|
||||
|
||||
class SystemOrderDelivered extends Notification
|
||||
{
|
||||
|
||||
use Queueable;
|
||||
|
||||
protected $order;
|
||||
protected $title;
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($title, Order $order, $url = '')
|
||||
{
|
||||
$this->title = $title;
|
||||
$this->order = $order;
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
public function via(): array
|
||||
{
|
||||
return [DatabaseChannel::class, WechatMiniChannel::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 订单发货
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/8/4 16:22
|
||||
* @param User $notifiable
|
||||
* @return bool
|
||||
*/
|
||||
public function toWeChat(User $notifiable): bool
|
||||
{
|
||||
if ($notifiable->isOfficialSubscribe()) {
|
||||
$app = app('wechat.official_account');
|
||||
$remark = '您的宝贝已经发货,请耐心等待';
|
||||
if ($this->order->express->type == OrderExpress::TYPE_LOGISTICS) {
|
||||
$remark .= ',经办人:'.$this->order->express->person;
|
||||
}
|
||||
|
||||
$res = $app->template_message->send([
|
||||
'touser' => $notifiable->wechat->official_openid,
|
||||
'template_id' => 'UvUA6wvPSegvT7i8IVrLipktbtCmyjtdnuKD8EvyOO8',
|
||||
'url' => $this->url,
|
||||
'data' => [
|
||||
'first' => $this->title,
|
||||
'keyword1' => $this->order->order_no,
|
||||
'keyword2' => $this->order->express->deliver_at,
|
||||
'keyword3' => $this->order->express->express_id > 0 ? $this->order->express->express->name : '',
|
||||
'keyword4' => $this->order->express->express_no ?? '',
|
||||
'keyword5' => $this->order->express->getFullAddress(),
|
||||
'remark' => $remark,
|
||||
],
|
||||
]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 数据库
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/8/4 16:38
|
||||
* @param User $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toDatabase(User $notifiable): array
|
||||
{
|
||||
return [
|
||||
'title' => $this->title,
|
||||
'content' => '订单编号:'.$this->order->order_no.' 已发货',
|
||||
'url' => $this->url,
|
||||
];
|
||||
}
|
||||
}
|
||||
81
app/Notifications/SystemRemindUserSign.php
Normal file
81
app/Notifications/SystemRemindUserSign.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use App\Channels\WechatMiniChannel;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Channels\DatabaseChannel;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Modules\User\Models\User;
|
||||
|
||||
class SystemRemindUserSign extends Notification
|
||||
{
|
||||
|
||||
use Queueable;
|
||||
|
||||
protected $content;
|
||||
protected $title;
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->title = '喝水打卡提醒';
|
||||
$this->content = '您今天还没有喝水打卡,请前去打卡';
|
||||
$this->url = config('user.web.base');
|
||||
}
|
||||
|
||||
public function via(): array
|
||||
{
|
||||
return [DatabaseChannel::class, WechatMiniChannel::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 喝水打卡提醒
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/8/8 8:48
|
||||
* @param User $notifiable
|
||||
* @return bool
|
||||
*/
|
||||
public function toWeChat(User $notifiable): bool
|
||||
{
|
||||
if ($notifiable->isOfficialSubscribe()) {
|
||||
$app = app('wechat.official_account');
|
||||
|
||||
$app->template_message->send([
|
||||
'touser' => $notifiable->wechat->official_openid,
|
||||
'template_id' => 'N7-vo1bSYXahw22pplkHtI7WGg96dPf1KdMxbKdx6ao',
|
||||
'url' => $this->url,
|
||||
'data' => [
|
||||
'first' => $this->title,
|
||||
'keyword1' => now(),
|
||||
'keyword2' => $this->content,
|
||||
'remark' => '',
|
||||
],
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送到数据库
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toDatabase(User $notifiable): array
|
||||
{
|
||||
return [
|
||||
'title' => $this->title,
|
||||
'content' => $this->content,
|
||||
'url' => $this->url,
|
||||
];
|
||||
}
|
||||
}
|
||||
81
app/Notifications/SystemUpdateCase.php
Normal file
81
app/Notifications/SystemUpdateCase.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use App\Channels\WechatMiniChannel;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Channels\DatabaseChannel;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Modules\User\Models\IdentityMiddle;
|
||||
use Modules\User\Models\User;
|
||||
|
||||
class SystemUpdateCase extends Notification
|
||||
{
|
||||
|
||||
use Queueable;
|
||||
|
||||
protected $content;
|
||||
protected $title;
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->title = '上传报告提醒';
|
||||
$this->url = config('user.web.base');
|
||||
}
|
||||
|
||||
public function via(): array
|
||||
{
|
||||
return [DatabaseChannel::class, WechatMiniChannel::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 喝水打卡提醒
|
||||
*
|
||||
* @Author: 玄尘
|
||||
* @Date: 2022/8/8 8:48
|
||||
* @param User $notifiable
|
||||
* @return bool
|
||||
*/
|
||||
public function toWeChat(User $notifiable): bool
|
||||
{
|
||||
if ($notifiable->isOfficialSubscribe()) {
|
||||
$app = app('wechat.official_account');
|
||||
|
||||
$app->template_message->send([
|
||||
'touser' => $notifiable->wechat->official_openid,
|
||||
'template_id' => '3sksrHdMTu3k1yderqyP5hOYXWltNf-CvESRG4r3Fnc',
|
||||
'url' => $this->url,
|
||||
'data' => [
|
||||
'first' => $this->title,
|
||||
'keyword1' => now(),
|
||||
'keyword2' => '您已经连续打卡30天,请上传报告',
|
||||
'remark' => '',
|
||||
],
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送到数据库
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toDatabase(User $notifiable): array
|
||||
{
|
||||
return [
|
||||
'title' => $this->title,
|
||||
'content' => '您已经连续打卡30天,请上传报告',
|
||||
'url' => $this->url,
|
||||
];
|
||||
}
|
||||
}
|
||||
28
app/Providers/AppServiceProvider.php
Normal file
28
app/Providers/AppServiceProvider.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
30
app/Providers/AuthServiceProvider.php
Normal file
30
app/Providers/AuthServiceProvider.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The policy mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $policies = [
|
||||
// 'App\Models\Model' => 'App\Policies\ModelPolicy',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->registerPolicies();
|
||||
|
||||
//
|
||||
}
|
||||
}
|
||||
21
app/Providers/BroadcastServiceProvider.php
Normal file
21
app/Providers/BroadcastServiceProvider.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Broadcast;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BroadcastServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
Broadcast::routes();
|
||||
|
||||
require base_path('routes/channels.php');
|
||||
}
|
||||
}
|
||||
32
app/Providers/EventServiceProvider.php
Normal file
32
app/Providers/EventServiceProvider.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Listeners\UserOrderPaidListener;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
use Modules\User\Events\UserOrderPaid;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The event listener mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $listen = [
|
||||
//开通会员
|
||||
UserOrderPaid::class => [
|
||||
UserOrderPaidListener::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any events for your application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
63
app/Providers/RouteServiceProvider.php
Normal file
63
app/Providers/RouteServiceProvider.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The path to the "home" route for your application.
|
||||
*
|
||||
* This is used by Laravel authentication to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const HOME = '/home';
|
||||
|
||||
/**
|
||||
* The controller namespace for the application.
|
||||
*
|
||||
* When present, controller route declarations will automatically be prefixed with this namespace.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
// protected $namespace = 'App\\Http\\Controllers';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, etc.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->configureRateLimiting();
|
||||
|
||||
$this->routes(function () {
|
||||
Route::prefix('api')
|
||||
->middleware('api')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/api.php'));
|
||||
|
||||
Route::middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web.php'));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the rate limiters for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configureRateLimiting()
|
||||
{
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
|
||||
});
|
||||
}
|
||||
}
|
||||
84
app/Traits/HasClicks.php
Normal file
84
app/Traits/HasClicks.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
/**
|
||||
* 预期给所有拥有浏览计数的模型使用
|
||||
* 使用缓存,计算浏览量,定期更新缓存至数据库中
|
||||
*/
|
||||
trait HasClicks
|
||||
{
|
||||
|
||||
protected int $saveRate = 20;
|
||||
|
||||
/**
|
||||
* Notes : 获取点击量的字段
|
||||
* @Date : 2021/3/17 9:39 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
private function getClicksField(): string
|
||||
{
|
||||
return $this->clicks_filed ?? 'clicks';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 获取缓存前缀
|
||||
* @Date : 2021/3/16 5:52 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
private function getClickCachePrefix(): string
|
||||
{
|
||||
return $this->cachePrefix ?? class_basename(__CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 生成一个缓存KEY
|
||||
* @Date : 2021/3/16 5:52 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param string|null $appends
|
||||
* @return string
|
||||
*/
|
||||
private function getCacheKey(string $appends = null): string
|
||||
{
|
||||
return $this->getClickCachePrefix() . ':' . $this->getKey() . ':' . $appends;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 增加点击量
|
||||
* @Date : 2021/3/17 9:20 上午
|
||||
* @Author : < Jason.C >
|
||||
* @param int $step
|
||||
*/
|
||||
public function incrementClicks(int $step = 1): void
|
||||
{
|
||||
Cache::increment($this->getCacheKey('clicks'), $step);
|
||||
|
||||
if (rand(1, $this->saveRate) === 1) {
|
||||
$this->update([$this->getClicksField() => $this->clicks]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 获取缓存的浏览次数
|
||||
* @Date : 2021/3/16 5:52 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return int
|
||||
*/
|
||||
public function getClicksAttribute(): int
|
||||
{
|
||||
$clicks = Cache::get($this->getCacheKey('clicks'));
|
||||
|
||||
if (is_null($clicks)) {
|
||||
return Cache::rememberForever($this->getCacheKey('clicks'), function () {
|
||||
return $this->getAttributes()[$this->getClicksField()];
|
||||
});
|
||||
} else {
|
||||
return $clicks;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
83
app/Traits/HasCovers.php
Normal file
83
app/Traits/HasCovers.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait HasCovers
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes : 获取封面图片字段(单图)
|
||||
* @Date : 2021/3/16 4:34 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
public function getCoverField(): string
|
||||
{
|
||||
return $this->cover_field ?? 'cover';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 获取图片字段(多图)
|
||||
* @Date : 2021/3/16 4:35 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
public function getPicturesField(): string
|
||||
{
|
||||
return $this->pictures_field ?? 'pictures';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 解析单图地址
|
||||
* @Date : 2021/3/16 4:54 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
public function getCoverUrlAttribute(): string
|
||||
{
|
||||
$cover = $this->getAttribute($this->getCoverField());
|
||||
|
||||
return $this->parseImageUrl($cover);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 解析多图地址
|
||||
* @Date : 2021/3/16 4:54 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return array
|
||||
*/
|
||||
public function getPicturesUrlAttribute(): array
|
||||
{
|
||||
$pictures = $this->getAttribute($this->getPicturesField());
|
||||
|
||||
if (empty($pictures)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return collect($pictures)->map(function ($picture) {
|
||||
return $this->parseImageUrl($picture);
|
||||
})->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 解析图片文件的实际展示地址
|
||||
* @Date : 2021/3/16 4:53 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param string|null $image
|
||||
* @return string
|
||||
*/
|
||||
public function parseImageUrl(?string $image): string
|
||||
{
|
||||
if (empty($image)) {
|
||||
return '';
|
||||
} elseif (Str::startsWith($image, 'http')) {
|
||||
return $image;
|
||||
} else {
|
||||
return Storage::url($image);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
87
app/Traits/HasStatus.php
Normal file
87
app/Traits/HasStatus.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
trait HasStatus
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes : 获取状态字段,主模型可配置 $status_field
|
||||
* @Date : 2021/3/16 4:34 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
protected function getStatusField(): string
|
||||
{
|
||||
return $this->status_field ?? 'status';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 获取各状态的名称
|
||||
* @Date : 2021/5/27 11:50 上午
|
||||
* @Author : < Jason.C >
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getStatusMap(): array
|
||||
{
|
||||
return isset($this->status_map) && !empty($this->status_map) ? $this->status_map : [
|
||||
0 => '待审核',
|
||||
1 => '正常',
|
||||
2 => '驳回',
|
||||
3 => '关闭',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 正常显示的数据
|
||||
* @Author:<Mr.Wang>
|
||||
* @Date :2021-04-09
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeShown(Builder $query): Builder
|
||||
{
|
||||
return $query->where($this->getStatusField(), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 不显示的数据
|
||||
* @Author :<Mr.Wang>
|
||||
* @Date :2021-04-09
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeHidden(Builder $query): Builder
|
||||
{
|
||||
return $query->where($this->getStatusField(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 状态查询
|
||||
* @Date : 2021/6/28 10:25 上午
|
||||
* @Author : < Jason.C >
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param int $status
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeOfStatus(Builder $query, int $status): Builder
|
||||
{
|
||||
return $query->where($this->getStatusField(), $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 获取状态的文本信息
|
||||
* @Date : 2021/4/25 2:10 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return string
|
||||
*/
|
||||
public function getStatusTextAttribute(): string
|
||||
{
|
||||
$map = $this->getStatusMap();
|
||||
|
||||
return $map[$this->{$this->getStatusField()}] ?? '未知';
|
||||
}
|
||||
|
||||
}
|
||||
50
app/Traits/Macroable.php
Normal file
50
app/Traits/Macroable.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
trait Macroable
|
||||
{
|
||||
|
||||
use \Illuminate\Support\Traits\Macroable {
|
||||
__call as macroCall;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRelationValue($key)
|
||||
{
|
||||
$relation = parent::getRelationValue($key);
|
||||
if (!$relation && static::hasMacro($key)) {
|
||||
return $this->getRelationshipFromMethod($key);
|
||||
}
|
||||
|
||||
return $relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
if (static::hasMacro($method)) {
|
||||
return $this->macroCall($method, $parameters);
|
||||
}
|
||||
|
||||
return parent::__call($method, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public static function __callStatic($method, $parameters)
|
||||
{
|
||||
return parent::__callStatic($method, $parameters);
|
||||
}
|
||||
|
||||
}
|
||||
22
app/Traits/OrderByIdDesc.php
Normal file
22
app/Traits/OrderByIdDesc.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
trait OrderByIdDesc
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes: 初始化trait,自动在模型中,注入作用域
|
||||
* @Author: <C.Jason>
|
||||
* @Date : 2020/1/19 1:42 下午
|
||||
*/
|
||||
public static function bootOrderByIdDesc(): void
|
||||
{
|
||||
static::addGlobalScope(function (Builder $builder) {
|
||||
$builder->orderByDesc('id');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
22
app/Traits/OrderByOrderAsc.php
Normal file
22
app/Traits/OrderByOrderAsc.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
trait OrderByOrderAsc
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes: 初始化trait,自动在模型中,注入作用域
|
||||
* @Author: <C.Jason>
|
||||
* @Date : 2020/1/19 1:42 下午
|
||||
*/
|
||||
public static function bootOrderByOrderAsc(): void
|
||||
{
|
||||
static::addGlobalScope(function (Builder $builder) {
|
||||
$builder->orderBy('order')->orderByDesc('id');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
65
app/Traits/WithPosition.php
Normal file
65
app/Traits/WithPosition.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
trait WithPosition
|
||||
{
|
||||
|
||||
/**
|
||||
* Notes : 获取定位的数组
|
||||
* @Date : 2021/7/2 11:31 上午
|
||||
* @Author : < Jason.C >
|
||||
*/
|
||||
protected function getPositionMap(): array
|
||||
{
|
||||
return $this->position_map ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 定位查询作用域
|
||||
* @Author: Mr.wang
|
||||
* @Date : 2021/5/11 10:48
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param int $pos
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeOfPosition(Builder $query, int $pos): Builder
|
||||
{
|
||||
return $query->whereRaw('position & ' . $pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 设置定位
|
||||
* @Author: Mr.wang
|
||||
* @Date : 2020/5/11 10:48
|
||||
* @param int $value
|
||||
*/
|
||||
protected function setPositionAttribute($value): void
|
||||
{
|
||||
if (is_array($value) && !blank($value)) {
|
||||
$this->attributes['position'] = array_sum($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 获取定位数据
|
||||
* @Author: Mr.wang
|
||||
* @Date : 2020/5/11 10:48
|
||||
* @param int $value
|
||||
* @return array
|
||||
*/
|
||||
protected function getPositionAttribute(int $value): array
|
||||
{
|
||||
$position = [];
|
||||
foreach ($this->getPositionMap() as $k => $v) {
|
||||
if ($k & $value) {
|
||||
array_push($position, $k);
|
||||
}
|
||||
}
|
||||
|
||||
return $position;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user