6
0
Fork 0

移除分销

release
李静 2022-04-27 15:22:41 +08:00
parent 6c2dd35acb
commit 0b6d5d7a59
106 changed files with 21 additions and 5119 deletions

View File

@ -1,59 +0,0 @@
<?php
namespace App\Admin\Actions\Grid;
use App\Models\QuotaV1SendJob;
use Dcat\Admin\Actions\Response;
use Dcat\Admin\Grid\RowAction;
use Illuminate\Http\Request;
use Throwable;
class QuotaV1SendJobStart extends RowAction
{
public function title()
{
if ($this->title) {
return $this->title;
}
return '<i class="feather grid-action-icon icon-play-circle"></i> 开始任务&nbsp;&nbsp;';
}
/**
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.quota_v2_send_jobs.start');
}
/**
* Handle the action request.
*
* @param Request $request
*
* @return Response
*/
public function handle(Request $request)
{
try {
QuotaV1SendJob::findOrFail($this->getKey())->update([
'status' => QuotaV1SendJob::STATUS_DOING,
]);
} catch (Throwable $th) {
report($th);
return $this->response()->error('开始失败,'.$th->getMessage())->refresh();
}
return $this->response()->success('操作成功')->refresh();
}
/**
* @return string|array|void
*/
public function confirm()
{
return ['确认开始执行当前任务?', '确认后将针对任务金额开始分红,无法逆转。'];
}
}

View File

@ -1,38 +0,0 @@
<?php
namespace App\Admin\Actions\Grid;
use App\Admin\Forms\UserEditAgent as UserEditAgentForm;
use Dcat\Admin\Grid\RowAction;
use Dcat\Admin\Widgets\Modal;
class UserEditAgent extends RowAction
{
public function title()
{
if ($this->title) {
return $this->title;
}
return '<i class="feather grid-action-icon icon-shuffle"></i> 修改等级&nbsp;&nbsp;';
}
/**
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.users.edit_agent');
}
public function render()
{
$form = UserEditAgentForm::make()->payload(['id'=>$this->getKey()]);
return Modal::make()
->lg()
->title($this->title())
->body($form)
->button($this->title());
}
}

View File

@ -1,77 +0,0 @@
<?php
namespace App\Admin\Actions\Show;
use App\Models\User;
use Dcat\Admin\Show\AbstractTool;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\Request;
use Throwable;
class UserDisableBonus extends AbstractTool
{
/**
* @return string
*/
protected $title = '<i class="fa fa-jpy icon-shuffle"></i>&nbsp;关闭奖金分红';
/**
* 按钮样式定义,默认 btn btn-white waves-effect
*
* @var string
*/
protected $style = 'btn btn-sm btn-danger';
/**
* 权限判断,如不需要可以删除此方法
*
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.users.disable_bonus');
}
/**
* 处理请求,如果不需要接口处理,请直接删除这个方法
*
* @param Request $request
*
* @return Response
*/
public function handle(Request $request)
{
// 获取主键
$key = $this->getKey();
$user = User::findOrFail($key);
try {
$user->userInfo->update([
'bonusable'=>0,
]);
} catch (Throwable $th) {
report($th);
return $this->response()->error('操作失败:'.$th->getMessage());
}
return $this->response()
->success(__('admin.update_succeeded'))
->refresh();
}
public function html()
{
return parent::html().'&nbsp;&nbsp;';
}
/**
* 确认弹窗信息,如不需要可以删除此方法
*
* @return string|array|void
*/
public function confirm()
{
return ['是否关闭该用户奖金分红?', '该操作不可逆,确认后该用户将不再享受奖金分红。'];
}
}

View File

@ -1,77 +0,0 @@
<?php
namespace App\Admin\Actions\Show;
use App\Models\User;
use Dcat\Admin\Show\AbstractTool;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\Request;
use Throwable;
class UserEnableBonus extends AbstractTool
{
/**
* @return string
*/
protected $title = '<i class="fa fa-jpy icon-shuffle"></i>&nbsp;开启奖金分红';
/**
* 按钮样式定义,默认 btn btn-white waves-effect
*
* @var string
*/
protected $style = 'btn btn-sm btn-success';
/**
* 权限判断,如不需要可以删除此方法
*
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.users.enable_bonus');
}
/**
* 处理请求,如果不需要接口处理,请直接删除这个方法
*
* @param Request $request
*
* @return Response
*/
public function handle(Request $request)
{
// 获取主键
$key = $this->getKey();
$user = User::findOrFail($key);
try {
$user->userInfo->update([
'bonusable'=>1,
]);
} catch (Throwable $th) {
report($th);
return $this->response()->error('操作失败:'.$th->getMessage());
}
return $this->response()
->success(__('admin.update_succeeded'))
->refresh();
}
public function html()
{
return parent::html().'&nbsp;&nbsp;';
}
/**
* 确认弹窗信息,如不需要可以删除此方法
*
* @return string|array|void
*/
public function confirm()
{
return ['是否开启该用户奖金分红?', '该操作不可逆,确认后该用户将享受奖金分红。'];
}
}

View File

@ -1,130 +0,0 @@
<?php
namespace App\Admin\Controllers;
use App\Admin\Renderable\DistributionPreIncomeLogTable;
use App\Admin\Repositories\DistributionPreIncome;
use App\Models\DistributionPreIncome as DistributionPreIncomeModel;
use App\Models\UserInfo;
use Dcat\Admin\Admin;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Grid\Column;
use Dcat\Admin\Http\Controllers\AdminController;
use Dcat\Admin\Show;
use Illuminate\Support\Arr;
class DistributionPreIncomeController extends AdminController
{
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
$builder = DistributionPreIncome::with(['user', 'user.userInfo.inviterInfo.user', 'order']);
return Grid::make($builder, function (Grid $grid) {
// $grid->column('id')->sortable();
$grid->column('user.phone')->copyable();
$grid->column('agent_level')->display(function ($value) {
return Arr::get(UserInfo::$agentLevelTexts, $this->agent_level, '未知');
})->label();
$grid->column('user.userInfo.inviterInfo.user.phone', '邀请人手机号')->copyable();
$grid->column('order.sn')->if(function () {
return Admin::user()->can('dcat.admin.orders.show');
})
->then(function (Column $column) {
$column->link(function ($value) {
return admin_url('orders/'.$this->order_id);
});
})
->else(function (Column $column) {
$column->copyable();
});
$grid->column('type')->using(DistributionPreIncomeModel::$typeTexts)->label();
$grid->column('agent_level')->display(function () {
return $this->agent_level_name;
})->label();
$grid->column('total_amount');
$grid->column('total_sales_value');
$grid->column('total_revenue');
$grid->column('logs', '收益详情')->display('详情')->modal(function ($modal) {
$modal->title('收益详情');
return DistributionPreIncomeLogTable::make(['id'=>$this->id]);
});
$grid->column('status')->using(DistributionPreIncomeModel::$statusTexts)->dot([
0=>'danger',
1=>'danger',
2=>'success',
]);
// $grid->column('remarks');
$grid->column('completed_at');
$grid->column('created_at')->sortable();
$grid->model()->orderBy('order_id', 'desc');
$grid->model()->orderBy('agent_level', 'asc');
$grid->model()->orderBy('id', 'asc');
$grid->disableActions();
$grid->filter(function (Grid\Filter $filter) {
$filter->panel(false);
$filter->equal('user.phone')->width(3);
$filter->equal('order.sn')->width(3);
$filter->between('created_at')->dateTime()->width(7);
});
});
}
/**
* Make a show builder.
*
* @param mixed $id
*
* @return Show
*/
protected function detail($id)
{
return Show::make($id, new DistributionPreIncome(), function (Show $show) {
$show->field('id');
$show->field('user_id');
$show->field('order_id');
$show->field('type');
$show->field('agent_level');
$show->field('total_amount');
$show->field('total_sales_value');
$show->field('total_revenue');
$show->field('status');
$show->field('remarks');
$show->field('completed_at');
$show->field('created_at');
$show->field('updated_at');
});
}
/**
* Make a form builder.
*
* @return Form
*/
protected function form()
{
return Form::make(new DistributionPreIncome(), function (Form $form) {
$form->display('id');
$form->text('user_id');
$form->text('order_id');
$form->text('type');
$form->text('agent_level');
$form->text('total_amount');
$form->text('total_sales_value');
$form->text('total_revenue');
$form->text('status');
$form->text('remarks');
$form->text('completed_at');
$form->display('created_at');
$form->display('updated_at');
});
}
}

View File

@ -6,7 +6,6 @@ use App\Admin\Metrics\Dashboard;
use App\Admin\Metrics\NewUsers; use App\Admin\Metrics\NewUsers;
use App\Admin\Metrics\Orders; use App\Admin\Metrics\Orders;
use App\Admin\Metrics\StatisticsTotal; use App\Admin\Metrics\StatisticsTotal;
use App\Admin\Metrics\Users;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Dcat\Admin\Admin; use Dcat\Admin\Admin;
use Dcat\Admin\Layout\Column; use Dcat\Admin\Layout\Column;
@ -26,9 +25,6 @@ class HomeController extends Controller
if (Admin::user()->can('dcat.admin.home.statistics')) { if (Admin::user()->can('dcat.admin.home.statistics')) {
$column->row(new StatisticsTotal()); $column->row(new StatisticsTotal());
} }
if (Admin::user()->can('dcat.admin.home.users')) {
$column->row(new Users());
}
}); });
$row->column(6, function (Column $column) { $row->column(6, function (Column $column) {

View File

@ -1,84 +0,0 @@
<?php
namespace App\Admin\Controllers;
use App\Admin\Widgets\InfoBox;
use App\Enums\PayWay;
use App\Enums\WalletToBankLogStatus;
use App\Http\Controllers\Controller;
use App\Models\Order;
use App\Models\WalletLog;
use App\Models\WalletToBankLog;
use Carbon\Carbon;
use Dcat\Admin\Admin;
use Dcat\Admin\Layout\Column;
use Dcat\Admin\Layout\Content;
use Dcat\Admin\Layout\Row;
use Dcat\Admin\Widgets\Card;
class MonthlyStatisticsController extends Controller
{
public function index(Content $content)
{
Admin::requireAssets(['moment', 'bootstrap-datetimepicker']);
Admin::script(
<<<JS
$('#month-picker').datetimepicker({
locale: 'zh_CN',
viewMode: 'years',
format: 'YYYY-MM'
});
JS
);
return $content
->header('每月统计')
->body(function (Row $row) {
if (blank($date = request('date'))) {
$date = date('Y-m');
}
$start = Carbon::parse($date)->startOfMonth();
$end = $start->copy()->endOfMonth();
$row->column(12, function (Column $column) use ($date) {
$form = <<<HTML
<form class="form-inline">
<div class="form-group">
<label>日期</label>
<div class="input-group mx-1">
<span class="input-group-prepend">
<span class="input-group-text bg-white"><i class="fa fa-calendar fa-fw"></i></span>
</span>
<input type="text" class="form-control" name="date" id='month-picker' placeholder="日期" value="$date" >
</div>
</div>
<button type="submit" class="btn btn-primary">查询</button>
</form>
HTML;
$column->row(new Card(null, $form));
});
$totalPreIncome = WalletLog::where('loggable_type', 'distribution_pre_income')
->whereBetween('created_at', [$start, $end])
->sum('change_balance');
// 提现总额
$withdrawAmount = WalletToBankLog::where('status', WalletToBankLogStatus::Success)
->whereBetween('updated_at', [$start, $end])
->sum('amount');
// 余额支付总额
$totalOrderAmount = Order::where('status', Order::STATUS_COMPLETED)
->whereBetween('completed_at', [$start, $end])
->where('pay_way', PayWay::Balance)
->sum('total_amount');
$row->column(3, new InfoBox('返利总额', bcdiv($totalPreIncome, '100', 2), 'fa fa-cny'));
$row->column(3, new InfoBox('提现总额', bcdiv($withdrawAmount, '100', 2), 'fa fa-cny'));
$row->column(3, new InfoBox('余额支付总额', bcdiv($totalOrderAmount, '100', 2), 'fa fa-cny'));
});
}
}

View File

@ -203,9 +203,6 @@ class OrderController extends AdminController
if (Admin::user()->can('dcat.admin.orders.tags')) { if (Admin::user()->can('dcat.admin.orders.tags')) {
$actions->append(new OrderSetTag()); $actions->append(new OrderSetTag());
} }
if (Admin::user()->can('dcat.admin.distribution_pre_incomes.index')) {
$actions->append('<a href="'.admin_route('distribution_pre_incomes.index', ['order[sn]'=>$actions->row->sn]).'" target="_blank"><i class="fa fa-eye"></i> 预收益明细</a>');
}
}); });
return $grid; return $grid;
@ -290,13 +287,6 @@ class OrderController extends AdminController
}); });
$show->row(function (Show\Row $show) use ($userCouponId) { $show->row(function (Show\Row $show) use ($userCouponId) {
$show->width(6)->field('sales_value', '总销售值'); $show->width(6)->field('sales_value', '总销售值');
$show->field('is_settle', '是否结算')->using([
0=>'未结算',
1=>'已结算',
])->dot([
0=>'danger',
1=>'success',
]);
$show->field('completed_at', '完成时间'); $show->field('completed_at', '完成时间');
$show->width(12)->field('note')->width(10, 1); $show->width(12)->field('note')->width(10, 1);
$show->width(12)->field('remark')->width(10, 1); $show->width(12)->field('remark')->width(10, 1);

View File

@ -122,7 +122,7 @@ class OrderPackageController extends AdminController
} }
//修改发货单商品数量 //修改发货单商品数量
if (!$actions->row->is_settle && Admin::user()->can('dcat.admin.order_packages.edit')) { if (Admin::user()->can('dcat.admin.order_packages.edit')) {
$actions->append(new OrderPackageEdit()); $actions->append(new OrderPackageEdit());
} }
}); });

View File

@ -1,72 +0,0 @@
<?php
namespace App\Admin\Controllers;
use App\Admin\Repositories\QuotaLog;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Http\Controllers\AdminController;
use Dcat\Admin\Show;
class QuotaLogController extends AdminController
{
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
$builder = QuotaLog::with('user');
return Grid::make($builder, function (Grid $grid) {
$grid->column('id')->sortable();
$grid->column('user.phone', '手机号');
$grid->column('change_quota');
$grid->column('remarks');
$grid->column('created_at')->sortable();
// $grid->column('updated_at')->sortable();
$grid->filter(function (Grid\Filter $filter) {
$filter->panel();
$filter->equal('user.phone')->width(3);
});
});
}
/**
* Make a show builder.
*
* @param mixed $id
*
* @return Show
*/
protected function detail($id)
{
return Show::make($id, new QuotaLog(), function (Show $show) {
$show->field('id');
$show->field('user_id');
$show->field('change_quota');
$show->field('remarks');
$show->field('created_at');
$show->field('updated_at');
});
}
/**
* Make a form builder.
*
* @return Form
*/
protected function form()
{
return Form::make(new QuotaLog(), function (Form $form) {
$form->display('id');
$form->text('user_id');
$form->text('change_quota');
$form->text('remarks');
$form->display('created_at');
$form->display('updated_at');
});
}
}

View File

@ -1,87 +0,0 @@
<?php
namespace App\Admin\Controllers;
use App\Admin\Repositories\QuotaV1Log;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Http\Controllers\AdminController;
use Dcat\Admin\Show;
class QuotaV1LogController extends AdminController
{
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
$builder = QuotaV1Log::with(['user', 'user.userInfo']);
return Grid::make($builder, function (Grid $grid) {
$grid->column('id')->sortable();
$grid->column('user.phone', '手机号')->copyable();
$grid->column('user.userInfo.nickname', '昵称');
// $grid->column('loggable_type');
// $grid->column('loggable_id');
// $grid->column('action');
$grid->column('before_balance');
$grid->column('change_balance');
$grid->column('remarks');
$grid->model()->orderBy('created_at', 'desc');
$grid->column('created_at')->sortable();
// $grid->column('updated_at')->sortable();
$grid->disableActions();
$grid->filter(function (Grid\Filter $filter) {
$filter->panel();
$filter->like('user.phone', '手机号')->width(3);
// $filter->equal('id');
});
});
}
/**
* Make a show builder.
*
* @param mixed $id
*
* @return Show
*/
protected function detail($id)
{
return Show::make($id, new QuotaV1Log(), function (Show $show) {
$show->field('id');
$show->field('user_id');
$show->field('loggable_type');
$show->field('loggable_id');
$show->field('action');
$show->field('before_balance');
$show->field('change_balance');
$show->field('remarks');
$show->field('created_at');
$show->field('updated_at');
});
}
/**
* Make a form builder.
*
* @return Form
*/
protected function form()
{
return Form::make(new QuotaV1Log(), function (Form $form) {
$form->display('id');
$form->text('user_id');
$form->text('loggable_type');
$form->text('loggable_id');
$form->text('action');
$form->text('before_balance');
$form->text('change_balance');
$form->text('remarks');
$form->display('created_at');
$form->display('updated_at');
});
}
}

View File

@ -1,140 +0,0 @@
<?php
namespace App\Admin\Controllers;
use App\Admin\Actions\Grid\QuotaV1SendJobStart;
use App\Admin\Extensions\Grid\Tools\QuotaV1\Deduction;
use App\Admin\Extensions\Grid\Tools\QuotaV1\Recharge;
use App\Admin\Renderable\QuotaV1SendLogTable;
use App\Admin\Repositories\QuotaV1SendJob;
use App\Models\QuotaV1SendJob as QuotaV1SendJobModel;
use Dcat\Admin\Admin;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Http\Controllers\AdminController;
use Dcat\Admin\Layout\Content;
use Dcat\Admin\Show;
class QuotaV1SendJobController extends AdminController
{
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
$builder = QuotaV1SendJob::with('administrator');
return Grid::make($builder, function (Grid $grid) {
$grid->column('id')->sortable();
$grid->tools(function (Grid\Tools $tools) {
if (Admin::user()->can('dcat.admin.quota_v1_send_jobs.recharge')) {
$tools->append(new Recharge());
}
if (Admin::user()->can('dcat.admin.quota_v1_send_jobs.deduction')) {
$tools->append(new Deduction());
}
if (Admin::user()->can('dcat.admin.quota_v1_send_jobs.logs_index')) {
$tools->append('<a href="'.admin_route('quota_v1_send_jobs.logs_index').'" target="_blank"> <i class="feather grid-action-icon icon-list"></i>变动记录</a>');
}
});
$grid->column('amount')->display(function ($value) {
return bcdiv($value, 100, 2);
})->prepend('¥');
$grid->column('administrator.name');
$grid->column('status')->using(QuotaV1SendJobModel::$statusText)->dot([
0=>'primary',
1=> 'warning',
2=>'success',
]);
$grid->column('remarks');
$grid->column('created_at')->sortable();
$grid->model()->orderBy('created_at', 'desc');
/** 操作 **/
//新增
if (Admin::user()->can('dcat.admin.quota_v1_send_jobs.create')) {
$grid->disableCreateButton(false);
$grid->enableDialogCreate();
}
//修改
$grid->showQuickEditButton(Admin::user()->can('dcat.admin.quota_v1_send_jobs.edit'));
//删除以及自定义操作
$grid->actions(function (Grid\Displayers\Actions $actions) {
if ($actions->row->status === 0) {
$actions->disableDelete(Admin::user()->cannot('dcat.admin.quota_v1_send_jobs.destroy'));
if (Admin::user()->can('dcat.admin.quota_v1_send_jobs.start')) {
$actions->append(new QuotaV1SendJobStart());
}
} else {
if (Admin::user()->can('dcat.admin.quota_v1_send_jobs.log_list')) {
$actions->append('<a href="'.admin_route('quota_v1_send_jobs.log_list', ['job'=>$actions->row]).'"><i class="fa fa-eye"></i> 发放记录</a>');
}
}
});
/** 查询 **/
$grid->filter(function (Grid\Filter $filter) {
$filter->panel();
});
});
}
/**
* Make a show builder.
*
* @param mixed $id
*
* @return Show
*/
protected function detail($id)
{
return Show::make($id, new QuotaV1SendJob(), function (Show $show) {
$show->field('id');
$show->field('administrator_id');
$show->field('amount');
$show->field('status');
$show->field('remarks');
$show->field('created_at');
$show->field('updated_at');
});
}
/**
* Make a form builder.
*
* @return Form
*/
protected function form()
{
return Form::make(new QuotaV1SendJob(), function (Form $form) {
$form->display('id');
if ($form->isCreating()) {
$form->currency('amount')->symbol('¥')->customFormat(function ($amount) {
return bcdiv($amount, 100, 2);
})->saving(function ($amount) {
return bcmul($amount, 100);
})->required();
} else {
$form->currency('amount')->symbol('¥')->customFormat(function ($amount) {
return bcdiv($amount, 100, 2);
})->saving(function ($amount) {
return bcmul($amount, 100);
})->disable();
}
$form->text('remarks');
$form->display('created_at');
$form->display('updated_at');
});
}
public function logList(Content $content, QuotaV1SendJobModel $job)
{
return $content->header(__('quota-v1-send-job.labels.quota-v1-send-jobs'))
->description($job->id)
->body(QuotaV1SendLogTable::grid($job->id));
}
}

View File

@ -24,10 +24,6 @@ class SalesValueLogController extends AdminController
$grid->column('user.userInfo.nickname'); $grid->column('user.userInfo.nickname');
// $grid->column('order_id'); // $grid->column('order_id');
// $grid->column('order_user_id'); // $grid->column('order_user_id');
$grid->column('type')->using([
1=>'个人',
2=>'团队',
]);
$grid->column('change_sales_value'); $grid->column('change_sales_value');
$grid->column('remarks'); $grid->column('remarks');
$grid->column('created_at'); $grid->column('created_at');

View File

@ -117,15 +117,6 @@ class SettingController extends AdminController
$tab->addLink('Uni-push配置', admin_route('settings.index', ['type'=>'unipush'])); $tab->addLink('Uni-push配置', admin_route('settings.index', ['type'=>'unipush']));
$tab->addLink('自定义配置', admin_route('settings.index', ['type'=>'custom'])); $tab->addLink('自定义配置', admin_route('settings.index', ['type'=>'custom']));
break; break;
case 'distribution':
$tab->addLink('系统配置', admin_route('settings.index', ['type'=>'app']));
$tab->addLink('提现配置', admin_route('settings.index', ['type'=>'withdraw']));
$tab->addLink('Ios配置', admin_route('settings.index', ['type'=>'ios']));
$tab->addLink('Android配置', admin_route('settings.index', ['type'=>'android']));
$tab->addLink('快递100配置', admin_route('settings.index', ['type'=>'kuaidi100']));
$tab->addLink('Uni-push配置', admin_route('settings.index', ['type'=>'unipush']));
$tab->addLink('自定义配置', admin_route('settings.index', ['type'=>'custom']));
break;
case 'withdraw': case 'withdraw':
$tab->addLink('系统配置', admin_route('settings.index', ['type'=>'app'])); $tab->addLink('系统配置', admin_route('settings.index', ['type'=>'app']));
$tab->add('提现配置', new Withdraw(), true); $tab->add('提现配置', new Withdraw(), true);

View File

@ -5,14 +5,10 @@ namespace App\Admin\Controllers;
use App\Admin\Actions\Grid\DisableUser; use App\Admin\Actions\Grid\DisableUser;
use App\Admin\Actions\Grid\EnableUser; use App\Admin\Actions\Grid\EnableUser;
use App\Admin\Actions\Grid\Frozen; use App\Admin\Actions\Grid\Frozen;
use App\Admin\Actions\Grid\UserEditAgent;
use App\Admin\Actions\Grid\UserResetAccountPassword; use App\Admin\Actions\Grid\UserResetAccountPassword;
use App\Admin\Actions\Grid\UserResetPassword; use App\Admin\Actions\Grid\UserResetPassword;
use App\Admin\Actions\Show\UserDisableBonus;
use App\Admin\Actions\Show\UserEditBank; use App\Admin\Actions\Show\UserEditBank;
use App\Admin\Actions\Show\UserEditPhone; use App\Admin\Actions\Show\UserEditPhone;
use App\Admin\Actions\Show\UserEnableBonus;
use App\Admin\Renderable\DistributionPreIncomeSimpleTable;
use App\Admin\Renderable\Grid\Filter\PriceBetween; use App\Admin\Renderable\Grid\Filter\PriceBetween;
use App\Admin\Renderable\UserBalanceLogSimpleTable; use App\Admin\Renderable\UserBalanceLogSimpleTable;
use App\Admin\Renderable\UserFansSimpleTable; use App\Admin\Renderable\UserFansSimpleTable;
@ -58,11 +54,6 @@ class UserController extends AdminController
$grid->column('phone')->copyable(); $grid->column('phone')->copyable();
$grid->column('userInfo.nickname'); $grid->column('userInfo.nickname');
$grid->column('userInfo.code')->copyable(); $grid->column('userInfo.code')->copyable();
$grid->column('userInfo.agent_level')->display(function ($value) {
return $this->userInfo?->agent_level_name ?? '未知';
})->label()->filter(Grid\Column\Filter\In::make(UserInfo::$agentLevelTexts));
$grid->column('userInfo.inviterInfo.user.phone')->copyable(); $grid->column('userInfo.inviterInfo.user.phone')->copyable();
$grid->column('userInfo.growth_value')->filter( $grid->column('userInfo.growth_value')->filter(
Grid\Column\Filter\Between::make() Grid\Column\Filter\Between::make()
@ -70,9 +61,6 @@ class UserController extends AdminController
$modal->title('消费值'); $modal->title('消费值');
return UserSalesValueLogSimpleTable::make(['id'=>$this->id]); return UserSalesValueLogSimpleTable::make(['id'=>$this->id]);
})->setHeaderAttributes(['style' => 'color:#5b69bc']); })->setHeaderAttributes(['style' => 'color:#5b69bc']);
$grid->column('userInfo.group_sales_value')->filter(
Grid\Column\Filter\Between::make()
);
$grid->column('wallet.balance')->display(function ($value) { $grid->column('wallet.balance')->display(function ($value) {
$value = bcdiv($value, 100, 2); $value = bcdiv($value, 100, 2);
if ($this->wallet?->is_frozen) { if ($this->wallet?->is_frozen) {
@ -128,11 +116,6 @@ class UserController extends AdminController
$actions->append(new Frozen()); $actions->append(new Frozen());
} }
//调整等级
if (Admin::user()->can('dcat.admin.users.edit_agent')) {
$actions->append(new UserEditAgent());
}
// 重置用户密码 // 重置用户密码
if (Admin::user()->can('dcat.admin.users.reset_password')) { if (Admin::user()->can('dcat.admin.users.reset_password')) {
$actions->append(new UserResetPassword()); $actions->append(new UserResetPassword());
@ -148,14 +131,7 @@ class UserController extends AdminController
$filter->panel(); $filter->panel();
$filter->like('phone')->width(3); $filter->like('phone')->width(3);
$filter->like('userInfo.nickname')->width(3); $filter->like('userInfo.nickname')->width(3);
// $filter->equal('userInfo.agent_level')->select(UserInfo::$agentLevelTexts)->width(3);
$filter->between('created_at')->dateTime()->width(7); $filter->between('created_at')->dateTime()->width(7);
// $filter->between('userInfo.growth_value')->width(6);
// $filter->between('userInfo.group_sales_value')->width(6);
// $filter->between('wallet.balance')->width(6);
// $filter->between('balance.balance')->width(6);
// $filter->equal('id');
}); });
}); });
} }
@ -180,12 +156,8 @@ class UserController extends AdminController
$show->field('user_info.nickname'); $show->field('user_info.nickname');
$show->field('user_info.gender')->using(UserInfo::$genderTexts)->label(); $show->field('user_info.gender')->using(UserInfo::$genderTexts)->label();
$show->field('user_info.birthday'); $show->field('user_info.birthday');
$show->field('user_info.agent_level')->as(function ($value) {
return $this->userInfo?->agent_level_name ?? '未知';
})->label();
$show->field('user_info.growth_value'); $show->field('user_info.growth_value');
$show->field('user_info.group_sales_value');
$show->field('wallet.balance')->as(function ($value) { $show->field('wallet.balance')->as(function ($value) {
$value = bcdiv($value, 100, 2); $value = bcdiv($value, 100, 2);
@ -195,8 +167,6 @@ class UserController extends AdminController
$value = bcdiv($value, 100, 2); $value = bcdiv($value, 100, 2);
return $value; return $value;
})->prepend('¥'); })->prepend('¥');
$show->field('user_info.quota_v2');
$show->field('user_info.quota_v1');
$show->field('user_info.points'); $show->field('user_info.points');
}); });
$show->row(function (Show\Row $show) { $show->row(function (Show\Row $show) {
@ -218,21 +188,11 @@ class UserController extends AdminController
if (Admin::user()->can('dcat.admin.users.edit_bank')) { if (Admin::user()->can('dcat.admin.users.edit_bank')) {
$tools->append(new UserEditBank()); $tools->append(new UserEditBank());
} }
// 开启奖金分红
if (!$show->model()->userInfo->bonusable && Admin::user()->can('dcat.admin.users.enable_bonus')) {
$tools->append(new UserEnableBonus());
}
// 关闭奖金分红
if ($show->model()->userInfo->bonusable && Admin::user()->can('dcat.admin.users.disable_bonus')) {
$tools->append(new UserDisableBonus());
}
}); });
})); }));
}); });
$row->column(7, function ($column) use ($id) { $row->column(7, function ($column) use ($id) {
$tab = Tab::make(); $tab = Tab::make();
// 预收益明细
$tab->add('预收益明细', DistributionPreIncomeSimpleTable::make(['id'=>$id]));
// 可提明细 // 可提明细
$tab->add('可提明细', UserWalletLogSimpleTable::make(['id'=>$id])); $tab->add('可提明细', UserWalletLogSimpleTable::make(['id'=>$id]));
// 余额明细 // 余额明细

View File

@ -1,54 +0,0 @@
<?php
namespace App\Admin\Extensions\Grid\Tools\QuotaV1;
use App\Admin\Forms\QuotaV1Deduction;
use Dcat\Admin\Grid\Tools\AbstractTool;
use Dcat\Admin\Widgets\Modal;
class Deduction extends AbstractTool
{
protected function authorize($user): bool
{
return $user->can('dcat.admin.quota_v1_send_jobs.deduction');
}
/**
* 按钮样式定义,默认 btn btn-white waves-effect
*
* @var string
*/
protected $style = 'btn btn btn-danger';
/**
* 按钮文本
*
* @return string|void
*/
public function title()
{
return '扣减';
}
public function render()
{
$form = QuotaV1Deduction::make();
return Modal::make()
->lg()
->title($this->title())
->body($form)
->button($this->html());
}
/**
* 设置请求参数
*
* @return array|void
*/
public function parameters()
{
return [
];
}
}

View File

@ -1,54 +0,0 @@
<?php
namespace App\Admin\Extensions\Grid\Tools\QuotaV1;
use App\Admin\Forms\QuotaV1Recharge;
use Dcat\Admin\Grid\Tools\AbstractTool;
use Dcat\Admin\Widgets\Modal;
class Recharge extends AbstractTool
{
protected function authorize($user): bool
{
return $user->can('dcat.admin.quota_v1_send_jobs.recharge');
}
/**
* 按钮样式定义,默认 btn btn-white waves-effect
*
* @var string
*/
protected $style = 'btn btn btn-warning';
/**
* 按钮文本
*
* @return string|void
*/
public function title()
{
return '增加';
}
public function render()
{
$form = QuotaV1Recharge::make();
return Modal::make()
->lg()
->title($this->title())
->body($form)
->button($this->html());
}
/**
* 设置请求参数
*
* @return array|void
*/
public function parameters()
{
return [
];
}
}

View File

@ -40,10 +40,6 @@ class OrderPackageEdit extends Form implements LazyRenderable
$quantity = $input['quantity'] ?? 0; $quantity = $input['quantity'] ?? 0;
$orderPackage = OrderPackage::with('order')->findOrFail($id); $orderPackage = OrderPackage::with('order')->findOrFail($id);
//如果订单已分润则不处理
if ($orderPackage->order->is_settle) {
throw new BizException('该发货单已无法修改数量');
}
//修改的数量不能大于当前数量,只能变小 //修改的数量不能大于当前数量,只能变小
$packageProduct = OrderPackageProduct::findOrFail($packageProductId); $packageProduct = OrderPackageProduct::findOrFail($packageProductId);
if ($quantity == 0) { if ($quantity == 0) {

View File

@ -1,69 +0,0 @@
<?php
namespace App\Admin\Forms;
use App\Models\QuotaV1Log;
use App\Models\User;
use App\Services\QuotaV1Service;
use Dcat\Admin\Admin;
use Dcat\Admin\Contracts\LazyRenderable;
use Dcat\Admin\Traits\LazyWidget;
use Dcat\Admin\Widgets\Form;
use Illuminate\Support\Facades\DB;
use Throwable;
class QuotaV1Deduction extends Form implements LazyRenderable
{
use LazyWidget;
/**
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.quota_v1_send_jobs.deduction');
}
/**
* Handle the form request.
*
* @param array $input
*
* @return mixed
*/
public function handle(array $input)
{
if (($input['change_balance'] ?? 0) <= 0) {
return $this->response()->error('扣减配额必须大于0');
}
try {
DB::beginTransaction();
//获取当前操作人;
$adminUser = Admin::user();
$user = User::findOrFail($input['user_id'] ?? 0);
$quotaV1Service = new QuotaV1Service();
$quotaV1Service->changeBalance($user, -($input['change_balance'] ?? 0), QuotaV1Log::ACTION_ADMIN_DEDUCTION, '后台扣减', $adminUser);
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
return $this->response()->error('操作失败:'.$th->getMessage());
}
return $this->response()
->success(__('admin.update_succeeded'))
->refresh();
}
/**
* Build a form here.
*/
public function form()
{
$this->select('user_id', '用户手机号')->ajax(admin_route('api.users'))->required();
$this->currency('change_balance', '扣减配额')->digits(3)->symbol('¥')->required();
$this->confirm('是否确认扣减?', '提交后该动作无法逆转');
}
}

View File

@ -1,69 +0,0 @@
<?php
namespace App\Admin\Forms;
use App\Models\QuotaV1Log;
use App\Models\User;
use App\Services\QuotaV1Service;
use Dcat\Admin\Admin;
use Dcat\Admin\Contracts\LazyRenderable;
use Dcat\Admin\Traits\LazyWidget;
use Dcat\Admin\Widgets\Form;
use Illuminate\Support\Facades\DB;
use Throwable;
class QuotaV1Recharge extends Form implements LazyRenderable
{
use LazyWidget;
/**
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.quota_v1_send_jobs.recharge');
}
/**
* Handle the form request.
*
* @param array $input
*
* @return mixed
*/
public function handle(array $input)
{
if (($input['change_balance'] ?? 0) <= 0) {
return $this->response()->error('增加配额必须大于0');
}
try {
DB::beginTransaction();
//获取当前操作人;
$adminUser = Admin::user();
$user = User::findOrFail($input['user_id'] ?? 0);
$quotaV1Service = new QuotaV1Service();
$quotaV1Service->changeBalance($user, $input['change_balance'] ?? 0, QuotaV1Log::ACTION_ADMIN_RECHARGE, '后台增加', $adminUser);
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
return $this->response()->error('操作失败:'.$th->getMessage());
}
return $this->response()
->success(__('admin.update_succeeded'))
->refresh();
}
/**
* Build a form here.
*/
public function form()
{
$this->select('user_id', '用户手机号')->ajax(admin_route('api.users'))->required();
$this->currency('change_balance', '增加配额')->digits(3)->required();
$this->confirm('是否确认增加老配额?', '提交后该动作无法逆转');
}
}

View File

@ -63,6 +63,5 @@ class App extends Form
$this->text('article_about_us', '关于我们文章指定(链接)')->value($appSettings['article_about_us'] ?? ''); $this->text('article_about_us', '关于我们文章指定(链接)')->value($appSettings['article_about_us'] ?? '');
$this->text('article_user_promotion_agreement', '服务协议文章指定(链接)')->value($appSettings['article_user_promotion_agreement'] ?? ''); $this->text('article_user_promotion_agreement', '服务协议文章指定(链接)')->value($appSettings['article_user_promotion_agreement'] ?? '');
$this->text('article_user_hide_agreement', '隐私协议文章指定(链接)')->value($appSettings['article_user_hide_agreement'] ?? ''); $this->text('article_user_hide_agreement', '隐私协议文章指定(链接)')->value($appSettings['article_user_hide_agreement'] ?? '');
$this->text('article_user_agent_agreement', '升级规则文章指定(链接)')->value($appSettings['article_user_agent_agreement'] ?? '');
} }
} }

View File

@ -1,132 +0,0 @@
<?php
namespace App\Admin\Forms\Settings;
use App\Models\Setting;
use App\Services\SettingService;
use Dcat\Admin\Widgets\Form;
class Distribution extends Form
{
/**
* Handle the form request.
*
* @param array $input
*
* @return mixed
*/
public function handle(array $input)
{
Setting::where('key', 'distribution')->updateOrCreate([
'key' => 'distribution',
], ['value' => $input]);
//清配置缓存
app(SettingService::class)->cleanCache('distribution');
return $this
->response()
->success('配置更新成功!')
->refresh();
}
/**
* Build a form here.
*/
public function form()
{
$appSettings = (array) Setting::where('key', 'distribution')->value('value');
// dd($appSettings, app_settings('distribution'));
$this->number('quota_v1_receive', '老配额分红领取时间(小时)')
->min(0)->value($appSettings['quota_v1_receive'] ?? 0)
->help('从发放配额分红开始后N小时内可以领取');
$this->text('settle_days', '订单结算时间(天)')
->value($appSettings['settle_days'] ?? 0)
->rules('required|numeric|min:0')
->help('从订单完成到结算收益的间隔天数');
$this->text('price_diff_fee_rate', '会员差价手续费')
->prepend('%')
->value($appSettings['price_diff_fee_rate'] ?? 0)
->rules('required|int|min:0|max:100')
->saving(function ($value) {
return bcdiv($value, 100, 2);
})
->customFormat(function ($value) {
return bcmul($value, 100);
});
$this->text('lvl_same_bonus_fee_rate', '平级奖励手续费')
->prepend('%')
->value($appSettings['lvl_same_bonus_fee_rate'] ?? 0)
->rules('required|int|min:0|max:100')
->saving(function ($value) {
return bcdiv($value, 100, 2);
})
->customFormat(function ($value) {
return bcmul($value, 100);
});
$this->text('lvl_diff_bonus_fee_rate', '级差奖励手续费')
->prepend('%')
->value($appSettings['lvl_diff_bonus_fee_rate'] ?? 0)
->rules('required|int|min:0|max:100')
->saving(function ($value) {
return bcdiv($value, 100, 2);
})
->customFormat(function ($value) {
return bcmul($value, 100);
});
$this->text('quota_v2_rate', '获得配额比例')
->prepend('%')
->value($appSettings['quota_v2_rate'] ?? 0)
->rules('required|int|min:0|max:100')
->saving(function ($value) {
return bcdiv($value, 100, 2);
})
->customFormat(function ($value) {
return bcmul($value, 100);
});
// $this->divider();
$this->table('rules', '规则', function ($table) {
$table->hidden('lv_key');
$table->text('lv_name_show', '等级名称')->disable();
$table->hidden('lv_name');
$table->text('lvl_same_bonus_rate', '平级奖励比例')
->prepend('%')
->rules('required|int|min:0|max:100')
->saving(function ($value) {
return bcdiv($value, 100, 2);
})
->customFormat(function ($value) {
return bcmul($value, 100);
});
$table->text('lvl_diff_bonus_rate', '级差奖励比例')
->prepend('%')
->rules('required|int|min:0|max:100')
->saving(function ($value) {
return bcdiv($value, 100, 2);
})
->customFormat(function ($value) {
return bcmul($value, 100);
});
})->customFormat(function ($v) use ($appSettings) {
$_rules = $appSettings['rules'] ?? [];
if ($_rules) {
foreach ($_rules as $key => &$rule) {
$rule['lv_key'] = $key;
$rule['lv_name_show'] = $rule['lv_name'];
}
}
return $_rules;
})->saving(function ($v) {
return collect($v)->keyBy('lv_key')->toArray();
})->disableCreate()->disableDelete();
}
}

View File

@ -1,87 +0,0 @@
<?php
namespace App\Admin\Forms;
use App\Exceptions\BizException;
use App\Models\User;
use App\Models\UserInfo;
use Dcat\Admin\Contracts\LazyRenderable;
use Dcat\Admin\Traits\LazyWidget;
use Dcat\Admin\Widgets\Form;
use Illuminate\Support\Facades\DB;
use Throwable;
class UserEditAgent extends Form implements LazyRenderable
{
use LazyWidget;
/**
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.users.edit_agent');
}
/**
* Handle the form request.
*
* @param array $input
*
* @return mixed
*/
public function handle(array $input)
{
$id = $this->payload['id'] ?? 0;
$user = User::findOrFail($id);
// dd($user->userInfo->agent_level, $input['agent_level'], $user->userInfo->agent_level >= $input['agent_level']);
if ($user->userInfo->agent_level >= $input['agent_level']) {
throw new BizException('请选择大于当前的等级');
}
try {
DB::beginTransaction();
//执行自己升级
$user->userInfo->update([
'agent_level'=>$input['agent_level'],
]);
//给自己的上级依次升级
if (count($pids = $user->userInfo->parent_ids) > 0) {
$ancestors = UserInfo::whereIn('user_id', $pids)->latest('depth')->get();
foreach ($ancestors as $ancestor) {
$ancestor->attemptUpgradeAgentLevel();
}
}
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
return $this->response()->error('操作失败:'.$th->getMessage());
}
return $this->response()
->success(__('admin.update_succeeded'))
->refresh();
}
/**
* Build a form here.
*/
public function form()
{
// dd(UserInfo::$agentLevelTexts);
$this->select('agent_level', '身份')->options(UserInfo::$agentLevelTexts)->required();
}
public function default()
{
$id = $this->payload['id'] ?? 0;
$user = User::with('userInfo')->findOrFail($id);
return [
'agent_level' => $user->userInfo->agent_level,
];
}
}

View File

@ -3,7 +3,6 @@
namespace App\Admin\Metrics; namespace App\Admin\Metrics;
use App\Models\Balance; use App\Models\Balance;
use App\Models\DistributionPreIncome;
use App\Models\UserInfo; use App\Models\UserInfo;
use App\Models\Wallet; use App\Models\Wallet;
use Dcat\Admin\Widgets\Metrics\RadialBar; use Dcat\Admin\Widgets\Metrics\RadialBar;
@ -37,9 +36,6 @@ class StatisticsTotal extends RadialBar
'total_points'=> UserInfo::sum('points'), 'total_points'=> UserInfo::sum('points'),
'total_wallet'=> bcdiv(Wallet::sum('balance'), 100, 2), 'total_wallet'=> bcdiv(Wallet::sum('balance'), 100, 2),
'total_balance'=> bcdiv(Balance::sum('balance'), 100, 2), 'total_balance'=> bcdiv(Balance::sum('balance'), 100, 2),
'total_distribution'=> DistributionPreIncome::unsettlement()->sum('total_revenue'),
'total_quota_v2' => UserInfo::sum('quota_v2'),
'total_quota_v1' => UserInfo::sum('quota_v1'),
]); ]);
} }
@ -55,10 +51,9 @@ class StatisticsTotal extends RadialBar
return $this->content( return $this->content(
<<<HTML <<<HTML
<div class="d-flex row text-center align-items-center justify-content-center" > <div class="d-flex row text-center align-items-center justify-content-center" >
<div class="col-sm-4"> <div class="col-sm-4">
<h1 class="font-lg-1 mt-2 mb-0">{$content['total_distribution']}</h1> <h1 class="font-lg-1 mt-2 mb-0">{$content['total_points']}</h1>
当前预收益 总积分
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
<h1 class="font-lg-1 mt-2 mb-0">{$content['total_wallet']}</h1> <h1 class="font-lg-1 mt-2 mb-0">{$content['total_wallet']}</h1>
@ -69,20 +64,6 @@ class StatisticsTotal extends RadialBar
总余额 总余额
</div> </div>
</div> </div>
<div class="d-flex row text-center align-items-center justify-content-center" >
<div class="col-sm-4">
<h1 class="font-lg-1 mt-2 mb-0">{$content['total_points']}</h1>
总积分
</div>
<div class="col-sm-4">
<h1 class="font-lg-1 mt-2 mb-0">{$content['total_quota_v2']}</h1>
新配额
</div>
<div class="col-sm-4">
<h1 class="font-lg-1 mt-2 mb-0">{$content['total_quota_v1']}</h1>
老配额
</div>
</div>
HTML HTML
); );
} }

View File

@ -1,209 +0,0 @@
<?php
namespace App\Admin\Metrics;
use App\Models\UserInfo;
use Dcat\Admin\Admin;
use Dcat\Admin\Widgets\Metrics\Donut;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
class Users extends Donut
{
/**
* 初始化卡片内容
*/
protected function init()
{
parent::init();
$this->title('累计会员');
$this->contentWidth(5, 7);
$this->chartLabels(UserInfo::$agentLevelTexts);
$this->chartHeight(300);
$this->chartOption('chart.width', '300');
$this->chartOption('dataLabels.enabled', true);
// $this->chartOption('plotOptions.pie.donut.total.show', true);
$this->chartMarginBottom(50);
$this->chart->style('float: none;');
$color = Admin::color();
// $dark35 = $color->dark35();
$this->chartColors([
$color->primary(),
$color->warning(),
$color->danger(),
$color->info(),
$color->primary(),
$color->warning(),
$color->danger(),
$color->info(),
]);
}
/**
* 处理请求
*
* @param Request $request
*
* @return mixed|void
*/
public function handle(Request $request)
{
// 卡片内容
$nums = UserInfo::selectRaw('count(1) as num, agent_level')->groupBy('agent_level')->pluck('num', 'agent_level')->toArray();
$this->withContent($nums);
// dd($nums);
foreach (UserInfo::$agentLevelRanks as $rank) {
if (!isset($nums[$rank])) {
$nums[$rank] = 0;
}
}
// 图表数据
ksort($nums);
$this->withChart($nums);
}
/**
* 设置图表数据.
*
* @param array $data
*
* @return $this
*/
public function withChart(array $data)
{
// dd($data);
return $this->chart([
'series' => array_values($data),
'plotOptions' => [
'pie' => [
'donut' => [
'labels'=>[
'show'=>'true',
'total' => [
'show' => true,
'label'=>'会员总数',
],
],
],
],
],
]);
}
/**
* 卡片内容.
*
* @param int $finished
* @param int $pending
* @param int $rejected
* @param int $finished
* @param int $pending
* @param int $rejected
* @param int $rejected
*
* @return $this
*/
public function withContent($userCount)
{
$civilian = Arr::get($userCount, UserInfo::AGENT_LEVEL_CIVILIAN, 0);
$vip = Arr::get($userCount, UserInfo::AGENT_LEVEL_VIP, 0);
$community = Arr::get($userCount, UserInfo::AGENT_LEVEL_COMMUNITY, 0);
$district = Arr::get($userCount, UserInfo::AGENT_LEVEL_DISTRICT, 0);
$city = Arr::get($userCount, UserInfo::AGENT_LEVEL_CITY, 0);
$province = Arr::get($userCount, UserInfo::AGENT_LEVEL_PROVINCE, 0);
$branch = Arr::get($userCount, UserInfo::AGENT_LEVEL_BRANCH, 0);
$director = Arr::get($userCount, UserInfo::AGENT_LEVEL_DIRECTOR, 0);
$totalNum = array_sum($userCount);
return $this->content(
<<<HTML
<div class="col-12 d-flex flex-column flex-wrap text-center" style="max-width: 220px">
<div class="chart-info d-flex justify-content-between mt-1">
<div class="series-info d-flex align-items-center">
<span class="text-bold-600 ml-50">会员总数</span>
</div>
<div class="product-result">
<span>{$totalNum}</span>
</div>
</div>
<div class="chart-info d-flex justify-content-between mb-1 mt-1" >
<div class="series-info d-flex align-items-center">
<i class="fa fa-circle-o text-bold-700 text-primary"></i>
<span class="text-bold-600 ml-50">粉丝</span>
</div>
<div class="product-result">
<span>{$civilian}</span>
</div>
</div>
<div class="chart-info d-flex justify-content-between mb-1">
<div class="series-info d-flex align-items-center">
<i class="fa fa-circle-o text-bold-700 text-warning"></i>
<span class="text-bold-600 ml-50">会员</span>
</div>
<div class="product-result">
<span>{$vip}</span>
</div>
</div>
<div class="chart-info d-flex justify-content-between mb-1">
<div class="series-info d-flex align-items-center">
<i class="fa fa-circle-o text-bold-700 text-danger"></i>
<span class="text-bold-600 ml-50">铁牌会员</span>
</div>
<div class="product-result">
<span>{$community}</span>
</div>
</div>
<div class="chart-info d-flex justify-content-between mb-1" >
<div class="series-info d-flex align-items-center">
<i class="fa fa-circle-o text-bold-700 text-info"></i>
<span class="text-bold-600 ml-50">铜牌会员</span>
</div>
<div class="product-result">
<span>{$district}</span>
</div>
</div>
<div class="chart-info d-flex justify-content-between mb-1">
<div class="series-info d-flex align-items-center">
<i class="fa fa-circle-o text-bold-700 text-primary"></i>
<span class="text-bold-600 ml-50">银牌会员</span>
</div>
<div class="product-result">
<span>{$city}</span>
</div>
</div>
<div class="chart-info d-flex justify-content-between mb-1">
<div class="series-info d-flex align-items-center">
<i class="fa fa-circle-o text-bold-700 text-warning"></i>
<span class="text-bold-600 ml-50">金牌会员</span>
</div>
<div class="product-result">
<span>{$province}</span>
</div>
</div>
<div class="chart-info d-flex justify-content-between mb-1">
<div class="series-info d-flex align-items-center">
<i class="fa fa-circle-o text-bold-700 text-danger"></i>
<span class="text-bold-600 ml-50">钻石会员</span>
</div>
<div class="product-result">
<span>{$branch}</span>
</div>
</div>
<div class="chart-info d-flex justify-content-between mb-1">
<div class="series-info d-flex align-items-center">
<i class="fa fa-circle-o text-bold-700 text-info"></i>
<span class="text-bold-600 ml-50">默认用户</span>
</div>
<div class="product-result">
<span>{$director}</span>
</div>
</div>
</div>
HTML
);
}
}

View File

@ -1,30 +0,0 @@
<?php
namespace App\Admin\Renderable;
use App\Models\DistributionPreIncomeLog as DistributionPreIncomeLogModel;
use Dcat\Admin\Grid;
use Dcat\Admin\Support\LazyRenderable;
class DistributionPreIncomeLogTable extends LazyRenderable
{
public function render()
{
// 获取ID
$id = $this->key;
$builder = DistributionPreIncomeLogModel::where('pre_income_id', $id);
$grid = Grid::make($builder, function (Grid $grid) {
$grid->column('remarks', '备注');
$grid->column('change_amount', '变动金额');
$grid->column('change_sales_value', '变动消费值');
$grid->column('change_revenue', '变动收益');
$grid->column('created_at', '发生时间');
$grid->disableActions();
$grid->disableCreateButton();
$grid->disablePagination();
// $grid->async();
});
return $grid;
}
}

View File

@ -1,37 +0,0 @@
<?php
namespace App\Admin\Renderable;
use App\Models\DistributionPreIncome;
use Dcat\Admin\Grid;
use Dcat\Admin\Grid\LazyRenderable;
class DistributionPreIncomeSimpleTable extends LazyRenderable
{
public function grid(): Grid
{
$userId = $this->payload['id']??0;
$builder = DistributionPreIncome::query();
$builder->with('logs')->where('user_id', $userId);
return Grid::make($builder, function (Grid $grid) {
$grid->column('remarks', '备注');
$grid->column('status', '状态')->using(DistributionPreIncome::$statusTexts)->dot([
0=>'danger',
1=>'danger',
2=>'success',
]);
$grid->column('total_amount', '金额');
$grid->column('total_sales_value', '消费值');
$grid->column('total_revenue', '收益');
$grid->column('logs', '收益详情')->display('详情')->modal(function ($modal) {
$modal->title('收益详情');
return DistributionPreIncomeLogTable::make(['id'=>$this->id]);
});
$grid->column('created_at', '创建时间');
// $grid->withBorder();
$grid->model()->orderBy('created_at', 'desc');
$grid->disableRefreshButton();
$grid->disableActions();
});
}
}

View File

@ -1,58 +0,0 @@
<?php
namespace App\Admin\Renderable;
use App\Models\QuotaV1SendLog;
use Dcat\Admin\Grid;
class QuotaV1SendLogTable extends Grid
{
public static function grid(int $jobId = null)
{
$builder = QuotaV1SendLog::with(['user']);
$grid = parent::make($builder, function (Grid $grid) {
$grid->column('user.phone', '手机号');
$grid->column('amount', '分红金额')->display(function ($value) {
return bcdiv($value, 100, 2);
})->prepend('¥');
$grid->column('status', '状态')->using(QuotaV1SendLog::$statusText)->dot([
0=>'warning',
1=>'success',
]);
$grid->column('created_at', '发放时间')->sortable();
$grid->model()->orderBy('created_at', 'desc');
$grid->filter(function (Grid\Filter $filter) {
$filter->panel();
$filter->equal('user.phone', '手机号')->width(3);
});
$grid->disableActions();
$grid->disableCreateButton();
});
if ($jobId) {
$grid->model()->where('job_id', $jobId);
}
$grid->header(function ($collection) use ($grid) {
$query = QuotaV1SendLog::query();
// 拿到表格筛选 where 条件数组进行遍历
$grid->model()->getQueries()->unique()->each(function ($value) use (&$query) {
if (in_array($value['method'], ['paginate', 'get', 'orderBy', 'orderByDesc'], true)) {
return;
}
$query = call_user_func_array([$query, $value['method']], $value['arguments'] ?? []);
});
// 查出统计数据
$receivedAmount = (clone $query)->where('status', QuotaV1SendLog::STATUS_SUCCESS)->sum('amount');
$failedAmount = (clone $query)->where('status', QuotaV1SendLog::STATUS_FAILED)->sum('amount');
$totalAmount = (clone $query)->sum('amount');
// 自定义组件
return "<div style='padding: 10px;'>已领取:".bcdiv($receivedAmount, 100, 2).' 元 | 未领取:'.bcdiv($failedAmount, 100, 2).' 元 | 共计:'.bcdiv($totalAmount, 100, 2).' 元</div>';
});
return $grid;
}
}

View File

@ -17,13 +17,7 @@ class UserFansSimpleTable extends LazyRenderable
$grid->column('user.phone', '手机号')->link(function ($value) { $grid->column('user.phone', '手机号')->link(function ($value) {
return admin_url('users/'.$this->user_id); return admin_url('users/'.$this->user_id);
}); });
$grid->column('agent_level', '身份')->display(function ($value) {
return $this->agent_level_name??'未知';
})->label();
$grid->column('growth_value', '消费值'); $grid->column('growth_value', '消费值');
$grid->column('group_sales_value', '业绩');
$grid->column('created_at', '注册时间'); $grid->column('created_at', '注册时间');
// $grid->withBorder(); // $grid->withBorder();
$grid->model()->orderBy('created_at', 'desc'); $grid->model()->orderBy('created_at', 'desc');

View File

@ -18,14 +18,10 @@ class UserInviterSimpleTable extends LazyRenderable
$grid->column('user.phone', '手机号')->link(function ($value) { $grid->column('user.phone', '手机号')->link(function ($value) {
return admin_url('users/'.$this->user_id); return admin_url('users/'.$this->user_id);
}); });
$grid->column('agent_level', '身份')->display(function ($value) {
return $this->agent_level_name??'未知';
})->label();
$grid->column('depth', '层级'); $grid->column('depth', '层级');
$grid->column('growth_value', '消费值'); $grid->column('growth_value', '消费值');
$grid->column('group_sales_value', '业绩');
$grid->column('created_at', '注册时间'); $grid->column('created_at', '注册时间');
// $grid->withBorder(); // $grid->withBorder();

View File

@ -21,10 +21,6 @@ class UserSalesValueLogSimpleTable extends LazyRenderable
// if (empty($timeZone)) { // if (empty($timeZone)) {
// $grid->model()->whereBetween('created_at', [$start, $end]); // $grid->model()->whereBetween('created_at', [$start, $end]);
// } // }
$grid->column('type')->using([
1=>'个人',
2=>'团队',
]);
$grid->column('change_sales_value', '变动'); $grid->column('change_sales_value', '变动');
$grid->column('remarks', '备注'); $grid->column('remarks', '备注');
$grid->column('created_at', '创建时间')->sortable(); $grid->column('created_at', '创建时间')->sortable();

View File

@ -1,16 +0,0 @@
<?php
namespace App\Admin\Repositories;
use App\Models\DistributionPreIncome as Model;
use Dcat\Admin\Repositories\EloquentRepository;
class DistributionPreIncome extends EloquentRepository
{
/**
* Model.
*
* @var string
*/
protected $eloquentClass = Model::class;
}

View File

@ -1,16 +0,0 @@
<?php
namespace App\Admin\Repositories;
use App\Models\QuotaLog as Model;
use Dcat\Admin\Repositories\EloquentRepository;
class QuotaLog extends EloquentRepository
{
/**
* Model.
*
* @var string
*/
protected $eloquentClass = Model::class;
}

View File

@ -1,16 +0,0 @@
<?php
namespace App\Admin\Repositories;
use App\Models\QuotaV1Log as Model;
use Dcat\Admin\Repositories\EloquentRepository;
class QuotaV1Log extends EloquentRepository
{
/**
* Model.
*
* @var string
*/
protected $eloquentClass = Model::class;
}

View File

@ -1,95 +0,0 @@
<?php
namespace App\Admin\Repositories;
use App\Models\QuotaV1SendJob as Model;
use Dcat\Admin\Admin;
use Dcat\Admin\Form;
use Dcat\Admin\Repositories\EloquentRepository;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
class QuotaV1SendJob extends EloquentRepository
{
/**
* Model.
*
* @var string
*/
protected $eloquentClass = Model::class;
/**
* 新增记录.
*
* @param Form $form
* @return mixed
*/
public function store(Form $form)
{
$result = null;
DB::transaction(function () use ($form, &$result) {
$model = $this->model();
$updates = $form->updates();
[$relations, $relationKeyMap] = $this->getRelationInputs($model, $updates);
if ($relations) {
$updates = Arr::except($updates, array_keys($relationKeyMap));
}
foreach ($updates as $column => $value) {
$model->setAttribute($column, $value);
}
$model->setAttribute('administrator_id', Admin::user()->id);
$result = $model->save();
$this->updateRelation($form, $model, $relations, $relationKeyMap);
});
return $this->model()->getKey();
}
/**
* 更新数据.
*
* @param Form $form
* @return bool
*/
public function update(Form $form)
{
/* @var EloquentModel $builder */
$model = $this->model();
if (! $model->getKey()) {
$model->exists = true;
$model->setAttribute($model->getKeyName(), $form->getKey());
}
$result = null;
DB::transaction(function () use ($form, $model, &$result) {
$updates = $form->updates();
[$relations, $relationKeyMap] = $this->getRelationInputs($model, $updates);
if ($relations) {
$updates = Arr::except($updates, array_keys($relationKeyMap));
}
foreach ($updates as $column => $value) {
/* @var EloquentModel $model */
$model->setAttribute($column, $value);
}
$model->setAttribute('administrator_id', Admin::user()->id);
$result = $model->update();
$this->updateRelation($form, $model, $relations, $relationKeyMap);
});
return $result;
}
}

View File

@ -132,10 +132,6 @@ Route::group([
'index', 'index',
])->names('wallet_to_bank_logs'); ])->names('wallet_to_bank_logs');
$router->resource('distribution-pre-incomes', 'DistributionPreIncomeController')->only([
'index',
])->names('distribution_pre_incomes');
$router->resource('wallet-logs', 'WalletLogController')->only([ $router->resource('wallet-logs', 'WalletLogController')->only([
'index', 'index',
])->names('wallet_logs'); ])->names('wallet_logs');
@ -148,14 +144,6 @@ Route::group([
'index', 'index',
])->names('points_logs'); ])->names('points_logs');
$router->get('quota-logs', 'QuotaLogController@index')->name('quota_logs.index');
$router->resource('quota-v1-send-jobs', 'QuotaV1SendJobController')->only([
'index', 'create', 'store', 'edit', 'update', 'destroy',
])->names('quota_v1_send_jobs');
$router->get('quota-v1-send-jobs/{job}/log-list', 'QuotaV1SendJobController@logList')->name('quota_v1_send_jobs.log_list');
$router->get('quota-v1-send-jobs/logs-index', 'QuotaV1LogController@index')->name('quota_v1_send_jobs.logs_index');
$router->resource('order-refunds', 'OrderRefundLogController')->only([ $router->resource('order-refunds', 'OrderRefundLogController')->only([
'index', 'index',
])->names('order_refunds'); ])->names('order_refunds');
@ -168,8 +156,6 @@ Route::group([
['index'] ['index']
)->names('sales_value_logs'); )->names('sales_value_logs');
$router->get('monthly-statistics', 'MonthlyStatisticsController@index')->name('monthly-statistics.index');
//商城端-砍价活动 //商城端-砍价活动
$router->resource('bargain-activities', 'BargainActivityController')->names('bargain_activities'); $router->resource('bargain-activities', 'BargainActivityController')->names('bargain_activities');
$router->resource('bargain-orders', 'BargainOrderController')->only(['index', 'show'])->names('bargain_orders'); $router->resource('bargain-orders', 'BargainOrderController')->only(['index', 'show'])->names('bargain_orders');

View File

@ -1,94 +0,0 @@
<?php
namespace App\Console\Commands\Distribution;
use App\Models\DistributionPreIncome;
use App\Models\DistributionPreIncomeJob;
use App\Models\MerchantMessage;
use App\Models\Order;
use App\Services\DistributionPreIncomeJobService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Throwable;
class PreIncomeJobCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'distribution:pre-income-job';
/**
* The console command description.
*
* @var string
*/
protected $description = '分销预收益任务';
/**
* Execute the console command.
*
* @param \App\Services\DistributionPreIncomeJobService $jobService
* @return int
*/
public function handle(DistributionPreIncomeJobService $jobService)
{
while (true) {
$page = 0;
DistributionPreIncomeJob::with('jobable')->pending()->chunkById(200, function ($jobs) use ($jobService, &$page) {
foreach ($jobs as $job) {
try {
DB::beginTransaction();
$jobService->run($job);
DB::commit();
} catch (Throwable $e) {
DB::rollBack();
report($e);
}
//发送商家端预收益进帐消息
try {
DB::beginTransaction();
switch (get_class($job->jobable)) {
case Order::class://如果是订单类型,则发送预收益消息
$order = $job->jobable;
$incomesLogs = DistributionPreIncome::where('order_id', $order->id)->get();
foreach ($incomesLogs as $log) {
MerchantMessage::createDistributionMessage($log->user_id, [
'title'=>'恭喜收入'.$log->total_revenue.'元',
'content'=>'您有新的预收益产生,共'.$log->total_revenue.'元。',
]);
}
break;
default:
break;
}
DB::commit();
} catch (Throwable $e) {
DB::rollBack();
report($e);
}
}
$page++;
});
if ($page === 0) {
sleep(60);
} elseif ($page === 1) {
sleep(30);
} else {
sleep(15);
}
}
}
}

View File

@ -1,89 +0,0 @@
<?php
namespace App\Console\Commands\Distribution;
use App\Models\DistributionPreIncome;
use App\Models\WalletLog;
use App\Services\WalletService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Throwable;
class PreIncomeSettleCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'distribution:pre-income-settle';
/**
* The console command description.
*
* @var string
*/
protected $description = '分销预收益结算';
/**
* Execute the console command.
*
* @param \App\Services\WalletService $walletService
* @return int
*/
public function handle(WalletService $walletService)
{
while (true) {
$page = 0;
DistributionPreIncome::processing()->chunkById(200, function ($preIncomes) use ($walletService, &$page) {
$preIncomes->load('user');
foreach ($preIncomes as $preIncome) {
try {
DB::beginTransaction();
$walletService->changeBalance(
$preIncome->user,
bcmul($preIncome->total_revenue, 100),
WalletLog::ACTION_DISTRIBUTION_PRE_INCOME,
$preIncome->remarks,
$preIncome
);
// 计算配额
$changeQuota = bcmul($preIncome->total_revenue, app_settings('distribution.quota_v2_rate', 0), 4);
$changeQuota = round($changeQuota, 3);
$preIncome->user->userInfo()->update([
'quota_v2' => DB::raw("quota_v2+{$changeQuota}"),
]);
$preIncome->user->quotaLogs()->create([
'loggable_id' => $preIncome->id,
'loggable_type' => $preIncome->getMorphClass(),
'change_quota' => $changeQuota,
'remarks' => $preIncome->type_text.'得配额',
]);
// 将预收益标记为已结算
$preIncome->update([
'completed_at' => now(),
'status' => DistributionPreIncome::STATUS_PROCESSED,
]);
DB::commit();
} catch (Throwable $e) {
DB::rollBack();
report($e);
}
}
$page++;
});
sleep(60);
}
}
}

View File

@ -1,160 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Models\DistributionPreIncome;
use App\Models\Order;
use App\Models\SalesValueLog;
use App\Models\UserInfo;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Throwable;
class OrderSettleCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'order:settle';
/**
* The console command description.
*
* @var string
*/
protected $description = '订单结算';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
while (true) {
Order::where(
'completed_at',
'<=',
now()->subDays(app_settings('distribution.settle_days', 7))
)->where([
'status' => Order::STATUS_COMPLETED,
'is_settlable' => false,
'is_settle' => false,
])->chunkById(200, function ($orders) {
foreach ($orders as $order) {
$order->update([
'is_settlable' => true,
]);
}
});
Order::whereDoesntHave('afterSales', function ($query) {
return $query->processing();
})->whereDoesntHave('distributionPreIncomeJobs', function ($query) {
return $query->pending();
})->settlable()->chunkById(200, function ($orders) {
$orders->load(['user', 'afterSales']);
foreach ($orders as $order) {
try {
DB::beginTransaction();
$this->settle($order);
DB::commit();
} catch (Throwable $e) {
DB::rollBack();
report($e);
}
}
});
sleep(60);
}
}
/**
* 结算成长值
*
* @param \App\Models\Order $order
* @return void
*/
protected function settle(Order $order)
{
// 用户可得销售值
$salesValue = $order->sales_value;
foreach ($order->afterSales as $afterSale) {
if ($afterSale->isCancelled()) {
continue;
}
$salesValue = bcsub($salesValue, $afterSale->sales_value, 2);
}
if (bccomp($salesValue, '0', 2) === 1) {
$salesValueLogs = [];
$ts = now()->toDateTimeString();
// 更新下单用户的成长值和预成长值
$order->user->userInfo()->update([
'growth_value' => DB::raw("growth_value+{$salesValue}"),
]);
// 下单用户的销售值日志
$salesValueLogs[] = [
'user_id' => $order->user->id,
'order_id' => $order->id,
'order_user_id' => $order->user->id,
'type' => SalesValueLog::TYPE_INDIVIDUAL,
'change_sales_value' => $salesValue,
'remarks' => '个人消费',
'created_at' => $ts,
'updated_at' => $ts,
];
// 提升下单用户的代理等级
$order->user->userInfo->attemptUpgradeAgentLevel();
if (count($pids = $order->user->userInfo->parent_ids) > 0) {
$ancestors = UserInfo::whereIn('user_id', $pids)->latest('depth')->get();
foreach ($ancestors as $ancestor) {
$ancestor->attemptUpgradeAgentLevel();
$salesValueLogs[] = [
'user_id' => $ancestor->user_id,
'order_id' => $order->id,
'order_user_id' => $order->user_id,
'type' => SalesValueLog::TYPE_TEAM,
'change_sales_value' => $salesValue,
'remarks' => '团队成员消费',
'created_at' => $ts,
'updated_at' => $ts,
];
}
// 更新上级的团队销售值
UserInfo::whereIn('user_id', $pids)->update([
'group_sales_value' => DB::raw("group_sales_value + {$salesValue}"),
]);
}
// 保存销售值日志
SalesValueLog::insert($salesValueLogs);
}
// 将订单标记未已结算
$order->update([
'is_settle' => true,
]);
// 将预收益标记为结算中
DistributionPreIncome::where('order_id', $order->id)->update([
'status' => DistributionPreIncome::STATUS_PROCESSING,
]);
}
}

View File

@ -1,86 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Models\QuotaV1SendJob;
use App\Models\QuotaV1SendLog;
use App\Models\UserInfo;
use App\Models\WalletLog;
use App\Services\WalletService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Throwable;
class QuotaV1SendCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'quota-v1:send';
/**
* The console command description.
*
* @var string
*/
protected $description = '老配额分红';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
foreach (QuotaV1SendJob::where('status', 1)->cursor() as $job) {
$totalQuotaV1 = UserInfo::where('quota_v1', '>', 0)->sum('quota_v1');
if ($totalQuotaV1 > 0) {//总配额大于0才开始分
UserInfo::with('user')->where('quota_v1', '>', 0)->chunkById(100, function ($userInfos) use ($totalQuotaV1, $job) {
$walletService = new WalletService();
//依次分红
$nowTime = now();
$logs = [];
foreach ($userInfos as $userInfo) {
// if ($userInfo->bonusable) {//只针对享受分红的人发放
$quotaV1amount = round(bcmul(bcdiv($job->amount, $totalQuotaV1, 5), $userInfo->quota_v1, 3));
if ($quotaV1amount >0) {
// $log = new QuotaV1SendLog();
// $log->user_id = $userInfo->user_id;
// $log->job_id = $job->id;
// $log->amount = $quotaV1amount;
// $log->save();
// try {
// DB::beginTransaction();
// $log->update(['status'=>1]);
// $walletService->changeBalance($userInfo->user, $log->amount, WalletLog::ACTION_QUOTA_V1, '老配额分红', $log);
// DB::commit();
// } catch (Throwable $th) {
// DB::rollBack();
// report($th);
// }
$_log = [
'user_id'=>$userInfo->user_id,
'job_id' =>$job->id,
'amount' =>$quotaV1amount,
'created_at'=>$nowTime,
'updated_at'=>$nowTime,
];
$logs[] = $_log;
}
// }
}
if (count($logs) > 0) {
QuotaV1SendLog::insert($logs);
}
});
}
$job->update([
'status' => 2,
]);
}
return Command::SUCCESS;
}
}

View File

@ -22,10 +22,6 @@ class FansController extends Controller
return response()->json([ return response()->json([
'fans_num' => $user->fans()->count(), 'fans_num' => $user->fans()->count(),
'growth_value' => $user->userInfo->growth_value, 'growth_value' => $user->userInfo->growth_value,
/**
* @deprecated 1.1.3
*/
'group_sales_value' => $user->userInfo->group_sales_value,
]); ]);
} }

View File

@ -4,7 +4,6 @@ namespace App\Endpoint\Api\Http\Controllers\Account;
use App\Endpoint\Api\Http\Controllers\Controller; use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\BalanceLogResource; use App\Endpoint\Api\Http\Resources\BalanceLogResource;
use App\Endpoint\Api\Http\Resources\DistributionPreIncomeResource;
use App\Endpoint\Api\Http\Resources\WalletLogResource; use App\Endpoint\Api\Http\Resources\WalletLogResource;
use App\Endpoint\Api\Http\Resources\WalletToBankLogResource; use App\Endpoint\Api\Http\Resources\WalletToBankLogResource;
use App\Events\OrderPaid; use App\Events\OrderPaid;
@ -41,31 +40,10 @@ class WalletController extends Controller
public function index(Request $request) public function index(Request $request)
{ {
return response()->json([ return response()->json([
'distribution_pre' => $request->user()->getTotalPreRevenue(),
'wallet_balance'=> $request->user()->wallet?->balance_format ?? 0, 'wallet_balance'=> $request->user()->wallet?->balance_format ?? 0,
]); ]);
} }
/**
* 预收益明细
*
* @param Request $request
* @return void
*/
public function distributionLogs(Request $request)
{
$perPage = PaginatorHelper::resolvePerPage('per_page', 20, 50);
// $sort = $request-
$distributionLogs = $request->user()->distributionPreIncomes()
->with('logs')
->where('created_at', '>', now()->subDays(30))
// ->unsettlement()
->latest('id')
->simplePaginate($perPage);
return DistributionPreIncomeResource::collection($distributionLogs);
}
/** /**
* 可提明细 * 可提明细
* *

View File

@ -31,7 +31,6 @@ class ArticleController extends Controller
'about_us'=>app_settings('app.article_about_us', ''), 'about_us'=>app_settings('app.article_about_us', ''),
'user_promotion_agreement'=> app_settings('app.article_user_promotion_agreement', ''), 'user_promotion_agreement'=> app_settings('app.article_user_promotion_agreement', ''),
'user_hide_agreement' => app_settings('app.article_user_hide_agreement', ''), 'user_hide_agreement' => app_settings('app.article_user_hide_agreement', ''),
'user_agent_agreement' => app_settings('app.article_user_agent_agreement', ''),
]); ]);
} }

View File

@ -7,7 +7,6 @@ use App\Endpoint\Api\Http\Controllers\Controller;
use App\Exceptions\BizException; use App\Exceptions\BizException;
use App\Models\SmsCode; use App\Models\SmsCode;
use App\Models\User; use App\Models\User;
use App\Models\UserInfo;
use App\Services\SmsCodeService; use App\Services\SmsCodeService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Str; use Illuminate\Support\Str;
@ -51,28 +50,11 @@ class LoginController extends Controller
$user->last_login_ip = $request->realIp(); $user->last_login_ip = $request->realIp();
$user->save(); $user->save();
// 获取登录设备
$device = $request->header('client-app', Device::UNIAPP);
switch ($device) {
case Device::MERCHANT:
if ($user->userInfo?->agent_level < UserInfo::AGENT_LEVEL_VIP) {
throw new BizException('账户没有权限');
}
// 清理此用户的商户端令牌
$user->tokens()->where('name', $device)->delete();
// 颁发新的商户端令牌
$token = $user->createToken($device);
break;
default:
$device = Device::UNIAPP; $device = Device::UNIAPP;
// 清理此用户的商城端令牌 // 清理此用户的商城端令牌
$user->tokens()->where('name', $device)->delete(); $user->tokens()->where('name', $device)->delete();
// 颁发新的商城端令牌 // 颁发新的商城端令牌
$token = $user->createToken($device, ['mall']); $token = $user->createToken($device, ['mall']);
break;
}
return response()->json([ return response()->json([
'token' => $token->plainTextToken, 'token' => $token->plainTextToken,

View File

@ -10,7 +10,6 @@ use App\Helpers\PhoneNumber;
use App\Models\SmsCode; use App\Models\SmsCode;
use App\Models\SocialiteUser; use App\Models\SocialiteUser;
use App\Models\User; use App\Models\User;
use App\Models\UserInfo;
use App\Rules\PhoneNumber as PhoneNumberRule; use App\Rules\PhoneNumber as PhoneNumberRule;
use App\Services\SmsCodeService; use App\Services\SmsCodeService;
use EasyWeChat\Factory as EasyWeChatFactory; use EasyWeChat\Factory as EasyWeChatFactory;
@ -269,25 +268,12 @@ class SocialiteAuthController extends Controller
// 获取登录设备 // 获取登录设备
$device = $request->header('client-app', Device::UNIAPP); $device = $request->header('client-app', Device::UNIAPP);
switch ($device) {
case Device::MERCHANT:
if ($user->userInfo?->agent_level < UserInfo::AGENT_LEVEL_VIP) {
throw new BizException('账户没有权限');
}
// 清理此用户的商户端令牌
$user->tokens()->where('name', $device)->delete();
// 颁发新的商户端令牌
$token = $user->createToken($device);
break;
default:
$device = Device::UNIAPP; $device = Device::UNIAPP;
// 清理此用户的商城端令牌 // 清理此用户的商城端令牌
$user->tokens()->where('name', $device)->delete(); $user->tokens()->where('name', $device)->delete();
// 颁发新的商城端令牌 // 颁发新的商城端令牌
$token = $user->createToken($device, ['mall']); $token = $user->createToken($device, ['mall']);
break;
}
return $token; return $token;
} }

View File

@ -1,158 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Controllers\Merchant;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Models\UserInfo;
use Illuminate\Http\Request;
class AgentController extends Controller
{
/**
* 代理晋升条件
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function upgradeConditions(Request $request)
{
$userInfo = $request->user()->userInfo;
// 升级规则
$rules = config('agent.upgrade_rules');
switch ($userInfo->agent_level) {
case UserInfo::AGENT_LEVEL_VIP:
$data = [
// 是否显示
'display' => true,
// 业绩
'team_sales_value' => [
'label' => '业绩',
'current_team_sales_value' => $userInfo->team_sales_value,
'upgrade_team_sales_value' => '-1',
],
// 代理
'agents_count' => [
'label' => '会员',
'current_agents_count' => $userInfo->getVipAgentsCount(),
'upgrade_agents_count' => $rules['community']['vips_agents_count'],
],
];
break;
case UserInfo::AGENT_LEVEL_COMMUNITY:
$data = [
'display' => true,
'team_sales_value' => [
'label' => '业绩',
'current_team_sales_value' => $userInfo->team_sales_value,
'upgrade_team_sales_value' => (string) $rules['district']['team_sales_value'],
],
'agents_count' => [
'label' => '会员',
'current_agents_count' => $userInfo->getVipAgentsCount(),
'upgrade_agents_count' => $rules['district']['vips_agents_count'],
],
];
break;
case UserInfo::AGENT_LEVEL_DISTRICT:
$data = [
'display' => true,
'team_sales_value' => [
'label' => '业绩',
'current_team_sales_value' => $userInfo->team_sales_value,
'upgrade_team_sales_value' => (string) $rules['city']['team_sales_value'],
],
'agents_count' => [
'label' => '铜牌会员',
'current_agents_count' => $userInfo->getDistrictAgentsCountOnDifferentLines(),
'upgrade_agents_count' => $rules['city']['district_agents_count'],
],
];
break;
case UserInfo::AGENT_LEVEL_CITY:
$data = [
'display' => true,
'team_sales_value' => [
'label' => '业绩',
'current_team_sales_value' => $userInfo->team_sales_value,
'upgrade_team_sales_value' => (string) $rules['province']['team_sales_value'],
],
'agents_count' => [
'label' => '银牌会员',
'current_agents_count' => $userInfo->getCityAgentsCountOnDifferentLines(),
'upgrade_agents_count' => $rules['province']['city_agents_count'],
],
];
break;
case UserInfo::AGENT_LEVEL_PROVINCE:
$data = [
'display' => true,
'team_sales_value' => [
'label' => '业绩',
'current_team_sales_value' => $userInfo->team_sales_value,
'upgrade_team_sales_value' => (string) $rules['branch']['team_sales_value'],
],
'agents_count' => [
'label' => '金牌会员',
'current_agents_count' => $userInfo->getProvinceAgentsCountOnDifferentLines(),
'upgrade_agents_count' => $rules['branch']['province_agents_count'],
],
];
break;
default:
$data = [
'display' => false,
'team_sales_value' => [
'label' => '',
'current_team_sales_value' => '0',
'upgrade_team_sales_value' => '-1',
],
'agents_count' => [
'label' => '',
'current_agents_count' => 0,
'upgrade_agents_count' => -1,
],
];
break;
}
return response()->json($data);
}
/**
* 代理统计
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function statistics(Request $request)
{
$path = $request->user()->userInfo->full_path;
$statistics = UserInfo::selectRaw('count(1) as aggregate, agent_level')
->where('agent_level', '>=', 0)
->where('path', 'like', "{$path}%")
->groupBy('agent_level')
->pluck('aggregate', 'agent_level');
$data = [];
foreach ([
UserInfo::AGENT_LEVEL_VIP => 'vip',
UserInfo::AGENT_LEVEL_COMMUNITY => 'community',
UserInfo::AGENT_LEVEL_DISTRICT => 'district',
UserInfo::AGENT_LEVEL_CITY => 'city',
UserInfo::AGENT_LEVEL_PROVINCE => 'province',
UserInfo::AGENT_LEVEL_BRANCH => 'branch',
] as $k => $v) {
$data[$v] = $statistics[$k] ?? 0;
}
return response()->json($data);
}
}

View File

@ -1,47 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Controllers\Merchant;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\Merchant\FanResource;
use App\Helpers\Paginator as PaginatorHelper;
use Illuminate\Http\Request;
class FanController extends Controller
{
/**
* 粉丝列表
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$perPage = PaginatorHelper::resolvePerPage('per_page', 20, 50);
$fans = $request->user()
->fans()
->latest('id')
->simplePaginate($perPage);
$fans->load('userInfo');
return FanResource::collection($fans);
}
/**
* 粉丝统计
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function statistics(Request $request)
{
$user = $request->user();
return response()->json([
'fans_count' => $user->getFansCount(),
'team_sales_value' => $user->userInfo->team_sales_value,
]);
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Controllers\Merchant;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\Merchant\MessageResource;
use App\Helpers\Paginator as PaginatorHelper;
use App\Models\MerchantMessage as Message;
use Illuminate\Http\Request;
class MessageController extends Controller
{
public function index(Request $request)
{
$list = Message::userMessages($request->user())
->orderBy('created_at', 'desc')
->simplePaginate(PaginatorHelper::resolvePerPage('per_page', 20, 50));
return MessageResource::collection($list);
}
}

View File

@ -1,70 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Controllers\Merchant;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\QuotaLogResource;
use App\Endpoint\Api\Http\Resources\QuotaV1LogResource;
use App\Exceptions\BizException;
use App\Helpers\Paginator as PaginatorHelper;
use App\Models\QuotaV1SendLog;
use App\Models\WalletLog;
use App\Services\WalletService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Throwable;
class QuotaLogController extends Controller
{
/**
* 配额日志
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$perPage = PaginatorHelper::resolvePerPage('per_page', 20, 50);
$quotaLogs = $request->user()
->quotaLogs()
->latest('id')
->simplePaginate($perPage);
return QuotaLogResource::collection($quotaLogs);
}
public function quotaV1Logs(Request $request)
{
$perPage = PaginatorHelper::resolvePerPage('per_page', 20, 50);
return QuotaV1LogResource::collection(
QuotaV1SendLog::where('user_id', $request->user()->id)
->receive()->latest('id')
->simplePaginate($perPage));
}
/**
* 领取老配额分红
*
* @return void
*/
public function receiveQuotaV1(Request $request, WalletService $walletService)
{
$user = $request->user();
try {
DB::beginTransaction();
foreach (QuotaV1SendLog::where('user_id', $user->id)->waitReceive()->cursor() as $log) {
$log->update(['status'=>1]);
$walletService->changeBalance($user, $log->amount, WalletLog::ACTION_QUOTA_V1, '老配额分红', $log);
}
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('领取失败,稍后再试');
}
return response()->noContent();
}
}

View File

@ -1,29 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Controllers\Merchant;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\SalesValueLogResource;
use App\Helpers\Paginator as PaginatorHelper;
use Illuminate\Http\Request;
class SalesValueLogController extends Controller
{
/**
* 个人销售值日志
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function index(Request $request)
{
$perPage = PaginatorHelper::resolvePerPage('per_page', 20, 50);
$salesValueLogs = $request->user()
->salesValueLogs()
->latest('id')
->simplePaginate($perPage);
return SalesValueLogResource::collection($salesValueLogs);
}
}

View File

@ -1,29 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Controllers\Merchant;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\SalesValueLogResource;
use App\Helpers\Paginator as PaginatorHelper;
use Illuminate\Http\Request;
class TeamSalesValueLogController extends Controller
{
/**
* 团队销售值日志
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function index(Request $request)
{
$perPage = PaginatorHelper::resolvePerPage('per_page', 20, 50);
$teamSalesValueLogs = $request->user()
->teamSalesValueLogs()
->latest('id')
->simplePaginate($perPage);
return SalesValueLogResource::collection($teamSalesValueLogs);
}
}

View File

@ -1,55 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Controllers\Merchant;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\Merchant\UserInfoResource;
use App\Endpoint\Api\Http\Resources\UserBalanceResource;
use App\Endpoint\Api\Http\Resources\UserWalletResource;
use App\Models\QuotaV1SendLog;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* 个人信息
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function show(Request $request)
{
$user = $request->user();
return response()->json([
'id' => $user->id,
'phone' => $user->phone,
'user_info' => UserInfoResource::make($user->userInfo),
'balance' => bcdiv($user->balance?->balance, '100', 2),
]);
}
/**
* 个人账户信息
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function account(Request $request)
{
$user = $request->user();
return response()->json([
// 余额
'balance' => UserBalanceResource::make($user->balance),
// 可提
'wallet' => UserWalletResource::make($user->wallet),
// 销售值
'sales_value' => $user->userInfo->growth_value,
// 总预收益
'total_pre_revenue' => $user->getTotalPreRevenue(),
// 待领取老配额分红
'wait_receive_quota_v1_amount' => bcdiv(QuotaV1SendLog::where('user_id', $user->id)->waitReceive()->sum('amount'), 100, 2),
]);
}
}

View File

@ -1,25 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class DistributionPreIncomeLogResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'remarks' => $this->remarks,
'change_sales_value' => $this->change_sales_value,
'change_amount' => $this->change_amount,
'change_revenue'=> $this->change_revenue,
'created_at' => $this->created_at->toDateTimeString(),
];
}
}

View File

@ -1,26 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Resources;
use App\Models\DistributionPreIncome;
use Illuminate\Http\Resources\Json\JsonResource;
class DistributionPreIncomeResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'remarks' => $this->remarks,
'logs' => DistributionPreIncomeLogResource::collection($this->whenLoaded('logs')),
'created_at'=> $this->created_at->format('y-m-d H:i'),
'total_revenue' => $this->total_revenue,
'status' => DistributionPreIncome::$statusTexts[$this->status],
];
}
}

View File

@ -25,9 +25,6 @@ class FansResource extends JsonResource
'value' => (string) $this->whenLoaded('userInfo', function () { 'value' => (string) $this->whenLoaded('userInfo', function () {
return $this->userInfo->growth_value; return $this->userInfo->growth_value;
}, 0), }, 0),
'level_name' => (string) $this->whenLoaded('userInfo', function () {
return $this->userInfo->agent_level_name;
}, '未知'),
]; ];
} }
} }

View File

@ -1,26 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Resources\Merchant;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Str;
class FanResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'nickname' => (string) $this->userInfo->nickname,
'avatar' => (string) $this->userInfo->avatar,
'phone' => Str::mask($this->phone, '*', 3, 4),
'agent_level_name' => (string) $this->userInfo->agent_level_name,
'team_sales_value' => $this->userInfo?->team_sales_value,
];
}
}

View File

@ -1,28 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Resources\Merchant;
use Illuminate\Http\Resources\Json\JsonResource;
class MessageResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'content' => $this->content,
'type' => $this->type,
'ext' => $this->ext,
'jump_type' => $this->jump_type,
'jump_link' => (string) $this->jump_link,
'created_at'=> $this->created_at->toDateTimeString(),
];
}
}

View File

@ -1,31 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Resources\Merchant;
use Illuminate\Http\Resources\Json\JsonResource;
class UserInfoResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'nickname' => (string) $this->nickname,
'avatar' => (string) $this->avatar,
'gender' => (string) $this->gender,
'birthday' => (string) $this->birthday?->toDateString(),
'code' => (string) $this->code,
'points' => (int) $this->points,
'quota_v2' => $this->quota_v2,
'quota_v1' => $this->quota_v1,
'agent_level' => $this->agent_level,
'agent_level_icon' => $this->agent_level_icon,
'agent_level_name' => $this->agent_level_name,
];
}
}

View File

@ -1,23 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class QuotaLogResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'change_quota' => $this->change_quota,
'remarks' => (string) $this->remarks,
'created_at' => $this->created_at->toDateTimeString(),
];
}
}

View File

@ -1,23 +0,0 @@
<?php
namespace App\Endpoint\Api\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class QuotaV1LogResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'remarks' => (string) '老配额分红',
'amount' => $this->amount_format,
'created_at' => $this->created_at->toDateTimeString(),
];
}
}

View File

@ -17,7 +17,6 @@ use App\Endpoint\Api\Http\Controllers\Auth\RegisterController;
use App\Endpoint\Api\Http\Controllers\Auth\ResetPasswordController; use App\Endpoint\Api\Http\Controllers\Auth\ResetPasswordController;
use App\Endpoint\Api\Http\Controllers\CaptchaController; use App\Endpoint\Api\Http\Controllers\CaptchaController;
use App\Endpoint\Api\Http\Controllers\ClickController; use App\Endpoint\Api\Http\Controllers\ClickController;
use App\Endpoint\Api\Http\Controllers\Merchant;
use App\Endpoint\Api\Http\Controllers\MessageController; use App\Endpoint\Api\Http\Controllers\MessageController;
use App\Endpoint\Api\Http\Controllers\Order\OrderController; use App\Endpoint\Api\Http\Controllers\Order\OrderController;
use App\Endpoint\Api\Http\Controllers\Order\OrderVerifyController; use App\Endpoint\Api\Http\Controllers\Order\OrderVerifyController;
@ -119,7 +118,6 @@ Route::group([
//我的账户 //我的账户
Route::get('wallet', [WalletController::class, 'index']); Route::get('wallet', [WalletController::class, 'index']);
Route::get('wallet/distribution-logs', [WalletController::class, 'distributionLogs']);
Route::get('wallet/wallet-logs', [WalletController::class, 'walletLogs']); Route::get('wallet/wallet-logs', [WalletController::class, 'walletLogs']);
Route::get('wallet/balance-logs', [WalletController::class, 'balanceLogs']); Route::get('wallet/balance-logs', [WalletController::class, 'balanceLogs']);
Route::get('wallet/wallet-to-bank-logs', [WalletController::class, 'walletToBankLogs']); Route::get('wallet/wallet-to-bank-logs', [WalletController::class, 'walletToBankLogs']);
@ -207,37 +205,4 @@ Route::group([
Route::post('bargains/bargain/{order}', [\App\Endpoint\Api\Http\Controllers\BargainController::class, 'bargain']); Route::post('bargains/bargain/{order}', [\App\Endpoint\Api\Http\Controllers\BargainController::class, 'bargain']);
Route::post('bargains/create-mall-order/{bargainOrder}', [\App\Endpoint\Api\Http\Controllers\BargainController::class, 'createMallOrderByBargainOrder']); Route::post('bargains/create-mall-order/{bargainOrder}', [\App\Endpoint\Api\Http\Controllers\BargainController::class, 'createMallOrderByBargainOrder']);
}); });
Route::group([
'prefix' => 'merchant',
'middleware' => [
'guard:api',
'ability:merchant',
],
], function () {
// 个人信息
Route::get('me', [Merchant\UserController::class, 'show']);
// 个人账户
Route::get('account', [Merchant\UserController::class, 'account']);
// 粉丝列表
Route::get('fans', [Merchant\FanController::class, 'index']);
// 粉丝统计
Route::get('fan-statistics', [Merchant\FanController::class, 'statistics']);
// 配额日志
Route::get('quota-logs', [Merchant\QuotaLogController::class, 'index']);
// 个人销售值日志
Route::get('sales-value-logs', [Merchant\SalesValueLogController::class, 'index']);
// 团队销售值日志
Route::get('team-sales-value-logs', [Merchant\TeamSalesValueLogController::class, 'index']);
// 代理晋升条件
Route::get('agent-upgrade-conditions', [Merchant\AgentController::class, 'upgradeConditions']);
// 代理统计
Route::get('agent-statistics', [Merchant\AgentController::class, 'statistics']);
// 消息列表
Route::get('messages', [Merchant\MessageController::class, 'index']);
// 领取老配额分红
Route::post('receive-quota-v1', [Merchant\QuotaLogController::class, 'receiveQuotaV1']);
// 老配额领取记录
Route::get('quota-v1-logs', [Merchant\QuotaLogController::class, 'quotaV1Logs']);
});
}); });

View File

@ -1,18 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class AgentUpgradeLog extends Model
{
/**
* @var array
*/
protected $fillable = [
'user_id',
'before_agent_level',
'change_agent_level',
'remark',
];
}

View File

@ -1,130 +0,0 @@
<?php
namespace App\Models;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Model;
class DistributionPreIncome extends Model
{
use HasDateTimeFormatter;
public const STATUS_PENDING = 0;
public const STATUS_PROCESSING = 1;
public const STATUS_PROCESSED = 2;
public const TYPE_PRICE_DIFF = 1;
public const TYPE_LEVEL_SAME = 2;
public const TYPE_LEVEL_DIFF = 3;
/**
* @var array
*/
protected $attributes = [
'status' => self::STATUS_PENDING,
];
/**
* @var array
*/
protected $casts = [
'rule' => 'json',
'completed_at' => 'datetime',
];
/**
* @var array
*/
protected $fillable = [
'user_id',
'order_id',
'type',
'agent_level',
'total_amount',
'total_sales_value',
'total_revenue',
'rule',
'status',
'remarks',
'rule',
'completed_at',
];
public static $typeTexts = [
self::TYPE_PRICE_DIFF => '推粉丝赚差价',
self::TYPE_LEVEL_SAME => '平级奖励',
self::TYPE_LEVEL_DIFF => '级差奖励',
];
/**
* @var array
*/
public static $statusTexts = [
self::STATUS_PENDING => '待结算',
self::STATUS_PROCESSING => '结算中',
self::STATUS_PROCESSED => '已结算',
];
/**
* 仅查询未结算的预收益
*/
public function scopeUnsettlement($query)
{
return $query->whereIn('status', [
static::STATUS_PENDING,
static::STATUS_PROCESSING,
]);
}
/**
* 仅查询结算中的预收益
*/
public function scopeProcessing($query)
{
return $query->where('status', static::STATUS_PROCESSING);
}
/**
* 此预收益的所属的用户
*/
public function user()
{
return $this->belongsTo(User::class);
}
/**
* 此预收益的所属订单
*/
public function order()
{
return $this->belongsTo(Order::class);
}
/**
* 此预收益的变更记录
*/
public function logs()
{
return $this->hasMany(DistributionPreIncomeLog::class, 'pre_income_id');
}
/**
* 等级名称
*
* @return void
*/
public function getAgentLevelNameAttribute()
{
return UserInfo::$agentLevelTexts[$this->agent_level] ?? '未知';
}
/**
* 获取类型文本
*
* @return string
*/
public function getTypeTextAttribute(): string
{
return static::$typeTexts[$this->type] ?? '其它';
}
}

View File

@ -1,52 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class DistributionPreIncomeJob extends Model
{
public const STATUS_PENDING = 0;
public const STATUS_SUCCESS = 1;
public const STATUS_FAILED = 2;
/**
* @var array
*/
protected $attributes = [
'status' => self::STATUS_PENDING,
];
/**
* @var array
*/
protected $fillable = [
'jobable_id',
'jobable_type',
'status',
'remarks',
'failed_reason',
];
/**
* @var array
*/
protected $statusTexts = [
self::STATUS_PENDING => '待处理',
self::STATUS_SUCCESS => '成功',
self::STATUS_FAILED => '失败',
];
/**
* 只查询待退款的记录
*/
public function scopePending($query)
{
return $query->where('status', static::STATUS_PENDING);
}
public function jobable()
{
return $this->morphTo();
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace App\Models;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Model;
class DistributionPreIncomeLog extends Model
{
use HasDateTimeFormatter;
/**
* @var array
*/
protected $fillable = [
'pre_income_id',
'pre_income_job_id',
'change_amount',
'change_sales_value',
'change_revenue',
'remarks',
];
}

View File

@ -46,29 +46,6 @@ class MerchantMessage extends Model
}); });
} }
/**
* 发送预收益消息
*
* @return void
*/
public static function createDistributionMessage($userId, $params)
{
$message = self::create([
'type' => 1,
'title' => $params['title'],
'user_id' => $userId,
'content' => $params['content'],
'jump_type'=> self::JUMP_NO,
'is_push' => 1,
]);
if ($message && $message->needPush()) {
$message->pushMessage();
}
return $message;
}
public function needPush() public function needPush()
{ {
return $this->is_push; return $this->is_push;

View File

@ -42,10 +42,8 @@ class Order extends Model
*/ */
protected $attributes = [ protected $attributes = [
'reduced_amount' => 0, 'reduced_amount' => 0,
'is_settle' => false,
'is_change' => false, 'is_change' => false,
'status' => self::STATUS_PENDING, 'status' => self::STATUS_PENDING,
'is_settlable' => false,
]; ];
/** /**
@ -57,9 +55,7 @@ class Order extends Model
'completed_at' => 'datetime', 'completed_at' => 'datetime',
'auto_complete_at' => 'datetime', 'auto_complete_at' => 'datetime',
'status' => 'int', 'status' => 'int',
'is_settle' => 'bool',
'is_change' => 'bool', 'is_change' => 'bool',
'is_settlable' => 'bool',
]; ];
/** /**
@ -90,9 +86,7 @@ class Order extends Model
'completed_at', 'completed_at',
'auto_complete_at', 'auto_complete_at',
'is_change', 'is_change',
'is_settle',
'sales_value', 'sales_value',
'is_settlable',
'bargain_amount', 'bargain_amount',
]; ];
@ -115,16 +109,6 @@ class Order extends Model
->where('auto_complete_at', '<=', now()); ->where('auto_complete_at', '<=', now());
} }
/**
* 仅查询可结算的订单
*/
public function scopeSettlable($query)
{
return $query->where('status', static::STATUS_COMPLETED)
->where('is_settlable', true)
->where('is_settle', false);
}
/** /**
* 仅查询待发货的订单 * 仅查询待发货的订单
*/ */
@ -219,14 +203,6 @@ class Order extends Model
return $this->hasMany(AfterSale::class, 'order_id'); return $this->hasMany(AfterSale::class, 'order_id');
} }
/**
* 属于此订单的预收益任务
*/
public function distributionPreIncomeJobs()
{
return $this->morphMany(DistributionPreIncomeJob::class, 'jobable');
}
/** /**
* 此订单是否待付款 * 此订单是否待付款
* *

View File

@ -113,10 +113,6 @@ class OrderProduct extends Model
{ {
$res = false; $res = false;
if ($this->order->is_settlable) {
return false;
}
// 老判断,有过期时间,且未到过期时间,未发起过售后 // 老判断,有过期时间,且未到过期时间,未发起过售后
// $oldJudge = !is_null($this->after_expire_at) && $this->after_expire_at > now() && $this->after_sale_state == 0; // $oldJudge = !is_null($this->after_expire_at) && $this->after_expire_at > now() && $this->after_sale_state == 0;

View File

@ -1,29 +0,0 @@
<?php
namespace App\Models;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Model;
class QuotaLog extends Model
{
use HasDateTimeFormatter;
/**
* @var array
*/
protected $fillable = [
'user_id',
'loggable_id',
'loggable_type',
'change_quota',
'remarks',
];
/**
* 新配额所属的用户
*/
public function user()
{
return $this->belongsTo(User::class);
}
}

View File

@ -1,34 +0,0 @@
<?php
namespace App\Models;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class QuotaV1Log extends Model
{
use HasFactory;
use HasDateTimeFormatter;
public const ACTION_ADMIN_RECHARGE = 7;
public const ACTION_ADMIN_DEDUCTION = 8;
/**
* @var array
*/
protected $fillable = [
'user_id',
'loggable_id',
'loggable_type',
'action',
'before_balance',
'change_balance',
'remarks',
];
public function user()
{
return $this->belongsTo(User::class);
}
}

View File

@ -1,38 +0,0 @@
<?php
namespace App\Models;
use App\Models\Admin\Administrator;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class QuotaV1SendJob extends Model
{
use HasFactory;
use HasDateTimeFormatter;
public const STATUS_PENDING = 0;
public const STATUS_DOING = 1;
public const STATUS_FINISHED = 2;
protected $fillable = [
'status',
];
public static $statusText = [
self::STATUS_PENDING=>'未开始',
self::STATUS_DOING=>'进行中',
self::STATUS_FINISHED=>'已完成',
];
public function administrator()
{
return $this->belongsTo(Administrator::class, 'administrator_id');
}
public function logs()
{
return $this->hasMany(QuotaV1SendLog::class, 'job_id');
}
}

View File

@ -1,65 +0,0 @@
<?php
namespace App\Models;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class QuotaV1SendLog extends Model
{
use HasFactory;
use HasDateTimeFormatter;
public const STATUS_FAILED = 0;
public const STATUS_SUCCESS = 1;
protected $attributes = [
'status'=>self::STATUS_FAILED,
];
protected $fillable = [
'user_id',
'job_id',
'amount',
'status',
'created_at',
'updated_at',
];
public static $statusText = [
self::STATUS_FAILED=>'未领取',
self::STATUS_SUCCESS=>'已领取',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function scopeReceive($query)
{
return $query->where('status', static::STATUS_SUCCESS);
}
public function scopeWaitReceive($query)
{
$query->where('status', static::STATUS_FAILED);
if ($hours = app_settings('distribution.quota_v1_receive', 0)) {
return $query->where('created_at', '>', now()->subHours($hours));
} else {
return $query;
}
}
/**
* 获取格式化售后金额
*
* @return void
*/
public function getAmountFormatAttribute()
{
return trim_trailing_zeros(bcdiv($this->attributes['amount'], 100, 2));
}
}

View File

@ -10,7 +10,6 @@ class SalesValueLog extends Model
use HasDateTimeFormatter; use HasDateTimeFormatter;
public const TYPE_INDIVIDUAL = 1; public const TYPE_INDIVIDUAL = 1;
public const TYPE_TEAM = 2;
/** /**
* @var array * @var array

View File

@ -152,11 +152,7 @@ class User extends Model implements AuthorizableContract, AuthenticatableContrac
*/ */
public function isVip(): bool public function isVip(): bool
{ {
if ($this->userInfo->agent_level > UserInfo::AGENT_LEVEL_VIP) { return $this->userInfo?->growth_value >= 650;
return true;
}
return $this->userInfo?->growth_value >= config('agent.upgrade_rules.vip.sales_value');
} }
/** /**
@ -243,38 +239,6 @@ class User extends Model implements AuthorizableContract, AuthenticatableContrac
return $this->hasOne(BalanceLog::class, 'user_id'); return $this->hasOne(BalanceLog::class, 'user_id');
} }
/**
* 用户的预收益
*/
public function distributionPreIncomes()
{
return $this->hasMany(DistributionPreIncome::class, 'user_id');
}
/**
* 用户的配额日志
*/
public function quotaLogs()
{
return $this->hasMany(QuotaLog::class);
}
/**
* 用户的配额日志
*/
public function quotaV1Logs()
{
return $this->hasMany(QuotaV1Log::class);
}
/**
* 属于此用户的团队销售值(含自己的销售值)
*/
public function teamSalesValueLogs()
{
return $this->hasMany(SalesValueLog::class);
}
/** /**
* 属于此用户的团队销售值(含自己的销售值) * 属于此用户的团队销售值(含自己的销售值)
*/ */
@ -360,16 +324,6 @@ class User extends Model implements AuthorizableContract, AuthenticatableContrac
$this->attributes['password'] = $value; $this->attributes['password'] = $value;
} }
/**
* 获取此用户的总预收入
*
* @return string
*/
public function getTotalPreRevenue(): string
{
return $this->distributionPreIncomes()->unsettlement()->sum('total_revenue');
}
/** /**
* 确认给定的密码是否正确 * 确认给定的密码是否正确
* *

View File

@ -2,7 +2,6 @@
namespace App\Models; namespace App\Models;
use App\Helpers\Str as StrHelper;
use Dcat\Admin\Traits\HasDateTimeFormatter; use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str; use Illuminate\Support\Str;
@ -15,15 +14,6 @@ class UserInfo extends Model
public const GENDER_MALE = 'male'; // 男性 public const GENDER_MALE = 'male'; // 男性
public const GENDER_FEMALE = 'female'; // 女性 public const GENDER_FEMALE = 'female'; // 女性
public const AGENT_LEVEL_CIVILIAN = 0;
public const AGENT_LEVEL_VIP = 1;
public const AGENT_LEVEL_COMMUNITY = 2;
public const AGENT_LEVEL_DISTRICT = 3;
public const AGENT_LEVEL_CITY = 4;
public const AGENT_LEVEL_PROVINCE = 5;
public const AGENT_LEVEL_BRANCH = 6;
public const AGENT_LEVEL_DIRECTOR = 7;
/** /**
* @var string * @var string
*/ */
@ -39,7 +29,6 @@ class UserInfo extends Model
*/ */
protected $attributes = [ protected $attributes = [
'gender' => self::GENDER_UNKNOWN, 'gender' => self::GENDER_UNKNOWN,
'bonusable' => true,
]; ];
/** /**
@ -51,14 +40,9 @@ class UserInfo extends Model
'avatar', 'avatar',
'gender', 'gender',
'birthday', 'birthday',
'bonusable',
'depth', 'depth',
'path', 'path',
'agent_level',
'quota_v1',
'quota_v2',
'growth_value', 'growth_value',
'group_sales_value',
'real_inviter_id', 'real_inviter_id',
]; ];
@ -67,39 +51,6 @@ class UserInfo extends Model
*/ */
protected $casts = [ protected $casts = [
'birthday' => 'date', 'birthday' => 'date',
'bonusable' => 'bool',
];
/**
* 代理等级排名,从低到高
*
* @var array
*/
public static $agentLevelRanks = [
self::AGENT_LEVEL_CIVILIAN => 1,
self::AGENT_LEVEL_VIP => 2,
self::AGENT_LEVEL_COMMUNITY => 3,
self::AGENT_LEVEL_DISTRICT => 4,
self::AGENT_LEVEL_CITY => 5,
self::AGENT_LEVEL_PROVINCE => 6,
self::AGENT_LEVEL_BRANCH => 7,
self::AGENT_LEVEL_DIRECTOR => 8,
];
/**
* 代理等级配置 key
*
* @var array
*/
public static $agentLevelKeys = [
self::AGENT_LEVEL_CIVILIAN => 'civilian',
self::AGENT_LEVEL_VIP => 'vip',
self::AGENT_LEVEL_COMMUNITY => 'community',
self::AGENT_LEVEL_DISTRICT => 'district',
self::AGENT_LEVEL_CITY => 'city',
self::AGENT_LEVEL_PROVINCE => 'province',
self::AGENT_LEVEL_BRANCH => 'branch',
self::AGENT_LEVEL_DIRECTOR => 'director',
]; ];
public static $genderTexts = [ public static $genderTexts = [
@ -108,35 +59,6 @@ class UserInfo extends Model
self::GENDER_FEMALE => '女性', self::GENDER_FEMALE => '女性',
]; ];
/**
* 代理等级文本
*
* @var array
*/
public static $agentLevelTexts = [
self::AGENT_LEVEL_CIVILIAN => '粉丝',
self::AGENT_LEVEL_VIP => '会员',
self::AGENT_LEVEL_COMMUNITY => '铁牌会员',
self::AGENT_LEVEL_DISTRICT => '铜牌会员',
self::AGENT_LEVEL_CITY => '银牌会员',
self::AGENT_LEVEL_PROVINCE => '金牌会员',
self::AGENT_LEVEL_BRANCH => '钻石会员',
self::AGENT_LEVEL_DIRECTOR => '默认用户',
];
/**
* 代理等级图标
*
* @var array
*/
public static $agentLevelIcons = [
self::AGENT_LEVEL_COMMUNITY => 'https://cdn.zichunsheng.cn/statics/icons/lvl_2.png',
self::AGENT_LEVEL_DISTRICT => 'https://cdn.zichunsheng.cn/statics/icons/lvl_3.png',
self::AGENT_LEVEL_CITY => 'https://cdn.zichunsheng.cn/statics/icons/lvl_4.png',
self::AGENT_LEVEL_PROVINCE => 'https://cdn.zichunsheng.cn/statics/icons/lvl_5.png',
self::AGENT_LEVEL_BRANCH => 'https://cdn.zichunsheng.cn/statics/icons/lvl_6.png',
];
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -146,7 +68,7 @@ class UserInfo extends Model
// 如果没有邀请码,则自动分配邀请码 // 如果没有邀请码,则自动分配邀请码
if ($userInfo->code === null) { if ($userInfo->code === null) {
do { do {
$userInfo->code = strtolower(StrHelper::randomAlpha(6)); $userInfo->code = strtolower(Str::random(6));
} while (static::where('code', $userInfo->code)->exists()); } while (static::where('code', $userInfo->code)->exists());
} elseif ($userInfo->isDirty('code')) { } elseif ($userInfo->isDirty('code')) {
$userInfo->code = strtolower($userInfo->code); $userInfo->code = strtolower($userInfo->code);
@ -180,208 +102,6 @@ class UserInfo extends Model
return $this->belongsTo(UserInfo::class, 'real_inviter_id'); return $this->belongsTo(UserInfo::class, 'real_inviter_id');
} }
/**
* 获取此用户的预收益
*/
public function distributionPreIncomes()
{
return $this->hasMany(DistributionPreIncome::class, 'user_id', 'user_id');
}
/**
* 获取此用户的代理升级日志
*/
public function agentUpgradeLogs()
{
return $this->hasMany(AgentUpgradeLog::class, 'user_id', 'user_id');
}
/**
* 获取此用户的直推店铺总数
*/
public function getVipAgentsCount()
{
return static::where('inviter_id', $this->getKey())
->where('agent_level', '>=', static::AGENT_LEVEL_VIP)
->count();
}
/**
* 获取此用户的不同线上的下级区级代理总数
*/
public function getDistrictAgentsCountOnDifferentLines()
{
$path = $this->full_path;
// 获取所有区级以上的代理
$agents = static::where('agent_level', '>=', static::AGENT_LEVEL_DISTRICT)
->where('path', 'like', "{$path}%")
->get();
$lines = [];
foreach ($agents as $agent) {
preg_match("#\A{$path}\d+-#", $agent->full_path, $matches);
$line = $matches[0];
if (! isset($lines[$line])) {
$lines[$line] = 1;
}
}
return count($lines);
}
/**
* 获取此用户的不同线上的下级市级代理总数
*/
public function getCityAgentsCountOnDifferentLines()
{
$path = $this->full_path;
// 获取所有市级以上的代理
$agents = static::where('agent_level', '>=', static::AGENT_LEVEL_CITY)
->where('path', 'like', "$path%")
->get();
$lines = [];
foreach ($agents as $agent) {
preg_match("#\A{$path}\d+-#", $agent->full_path, $matches);
$line = $matches[0];
if (! isset($lines[$line])) {
$lines[$line] = 1;
}
}
return count($lines);
}
/**
* 获取此用户的不同线上的下级省级代理总数
*/
public function getProvinceAgentsCountOnDifferentLines()
{
$path = $this->full_path;
// 获取所有省级以上的代理
$agents = static::where('agent_level', '>=', static::AGENT_LEVEL_PROVINCE)
->where('path', 'like', "$path%")
->get();
$lines = [];
foreach ($agents as $agent) {
preg_match("#\A{$path}\d+-#", $agent->full_path, $matches);
$line = $matches[0];
if (! isset($lines[$line])) {
$lines[$line] = 1;
}
}
return count($lines);
}
/**
* 尝试提升代理等级
*
* @return void
*/
public function attemptUpgradeAgentLevel(): void
{
$lvl = $this->agent_level;
// 如果代理等级是分公司或董事时,不能继续提升代理等级
if (in_array($lvl, [static::AGENT_LEVEL_BRANCH, static::AGENT_LEVEL_DIRECTOR])) {
return;
}
$rules = config('agent.upgrade_rules');
// 如果成长值不足650时不能升级
if (bccomp($this->growth_value, $rules['vip']['sales_value']) < 0) {
return;
}
// 如果代理等级是粉丝,则可升级为店铺
if ($lvl === static::AGENT_LEVEL_CIVILIAN) {
$lvl = static::AGENT_LEVEL_VIP;
}
// 团队销售值
$salesValue = $this->team_sales_value;
if ($lvl === static::AGENT_LEVEL_VIP) {
$vipsCount = $this->getVipAgentsCount();
// 如果直推店铺人数>=6并且团队销售值>=65000则可升级为区级代理
// 或者直推店铺人数>=4则可升级为社区
if (
$vipsCount >= $rules['district']['vips_agents_count']
&& bccomp($salesValue, $rules['district']['team_sales_value']) >= 0
) {
$lvl = static::AGENT_LEVEL_DISTRICT;
} elseif ($vipsCount >= $rules['community']['vips_agents_count']) {
$lvl = static::AGENT_LEVEL_COMMUNITY;
}
} elseif ($lvl === static::AGENT_LEVEL_COMMUNITY && bccomp($salesValue, $rules['district']['team_sales_value']) >= 0) {
if ($this->getVipAgentsCount() >= $rules['district']['vips_agents_count']) {
$lvl = static::AGENT_LEVEL_DISTRICT;
}
}
if ($lvl === static::AGENT_LEVEL_DISTRICT && bccomp($salesValue, $rules['city']['team_sales_value']) >= 0) {
if ($this->getDistrictAgentsCountOnDifferentLines() >= $rules['city']['district_agents_count']) {
$lvl = static::AGENT_LEVEL_CITY;
}
}
if ($lvl === static::AGENT_LEVEL_CITY && bccomp($salesValue, $rules['province']['team_sales_value']) >= 0) {
if ($this->getCityAgentsCountOnDifferentLines() >= $rules['province']['city_agents_count']) {
$lvl = static::AGENT_LEVEL_PROVINCE;
}
}
if ($lvl === static::AGENT_LEVEL_PROVINCE && bccomp($salesValue, $rules['branch']['team_sales_value']) >= 0) {
if ($this->getProvinceAgentsCountOnDifferentLines() >= $rules['branch']['province_agents_count']) {
$lvl = static::AGENT_LEVEL_BRANCH;
}
}
$this->changeAgentLvl($lvl, '达到升级条件');
}
/**
* 变更代理等级
*
* @param int $lvl
* @param string|null $remark
* @return void
*/
public function changeAgentLvl(int $lvl, ?string $remark = null)
{
if ($this->agent_level === $lvl) {
return $lvl;
}
$beforeAgentLevel = $this->agent_level;
$this->update([
'agent_level' => $lvl,
]);
$this->agentUpgradeLogs()->create([
'before_agent_level' => $beforeAgentLevel,
'change_agent_level' => $lvl,
'remark' => $remark,
]);
}
/** /**
* 获取此用户的所有父级ID * 获取此用户的所有父级ID
* *
@ -405,36 +125,6 @@ class UserInfo extends Model
return $rpids; return $rpids;
} }
/**
* 代理等级排名
*
* @return int
*/
public function getAgentLevelRankAttribute(): int
{
return static::$agentLevelRanks[$this->agent_level] ?? 0;
}
/**
* 代理等级配置 key
*
* @return string
*/
public function getAgentLevelKeyAttribute(): string
{
return static::$agentLevelKeys[$this->agent_level] ?? 'unknown';
}
public function getAgentLevelNameAttribute(): string
{
return static::$agentLevelTexts[$this->agent_level] ?? '未知';
}
public function getAgentLevelIconAttribute(): string
{
return static::$agentLevelIcons[$this->agent_level] ?? '';
}
/** /**
* 获取完整的邀请路径 * 获取完整的邀请路径
* *
@ -444,14 +134,4 @@ class UserInfo extends Model
{ {
return Str::finish($this->path.$this->getKey(), '-'); return Str::finish($this->path.$this->getKey(), '-');
} }
/**
* 获团队销售值
*
* @return string
*/
public function getTeamSalesValueAttribute(): string
{
return bcadd($this->growth_value, $this->group_sales_value, 2);
}
} }

View File

@ -20,8 +20,6 @@ class WalletLog extends Model
public const ACTION_WITHDRAW_FAILED = 6; public const ACTION_WITHDRAW_FAILED = 6;
public const ACTION_ADMIN_RECHARGE = 7; public const ACTION_ADMIN_RECHARGE = 7;
public const ACTION_ADMIN_DEDUCTION = 8; public const ACTION_ADMIN_DEDUCTION = 8;
public const ACTION_QUOTA_V1 = 9;
public const ACTION_DISTRIBUTION_PRE_INCOME = 10;
/** /**
* @var array * @var array

View File

@ -54,9 +54,7 @@ class AppServiceProvider extends ServiceProvider
'after_sale' => \App\Models\AfterSale::class, 'after_sale' => \App\Models\AfterSale::class,
'wallet_to_bank_log' => \App\Models\WalletToBankLog::class, 'wallet_to_bank_log' => \App\Models\WalletToBankLog::class,
'balance_log' => \App\Models\BalanceLog::class, 'balance_log' => \App\Models\BalanceLog::class,
'distribution_pre_income' => \App\Models\DistributionPreIncome::class,
'admin_users' => \App\Models\Admin\Administrator::class, 'admin_users' => \App\Models\Admin\Administrator::class,
'quota_v1_send_logs' => \App\Models\QuotaV1SendLog::class,
]); ]);
JsonResource::withoutWrapping(); JsonResource::withoutWrapping();

View File

@ -6,7 +6,6 @@ use App\Admin\Services\OrderService;
use App\Exceptions\BizException; use App\Exceptions\BizException;
use App\Models\AfterSale; use App\Models\AfterSale;
use App\Models\AfterSaleLog; use App\Models\AfterSaleLog;
use App\Models\DistributionPreIncomeJob;
use App\Models\Order; use App\Models\Order;
use App\Models\OrderProduct; use App\Models\OrderProduct;
use App\Models\User; use App\Models\User;
@ -408,6 +407,7 @@ class AfterSaleService
$salesValue = bcmul($afterSaleProduct->sales_value, $qty, 2); $salesValue = bcmul($afterSaleProduct->sales_value, $qty, 2);
} }
$afterSale->logs()->create([ $afterSale->logs()->create([
'name' => '财务审核', 'name' => '财务审核',
'desc' => $remarks, 'desc' => $remarks,
@ -419,25 +419,6 @@ class AfterSaleService
'remarks' => $remarks, 'remarks' => $remarks,
]); ]);
// 1.先扣除预收益(可能会将店铺降级为粉丝)
// 2.生成分销任务
// 3.生成新订单
// 非赠品售后单,且售后单类型是换货、退款、退款退货
if (! $afterSaleProduct->isGift()
&& in_array($afterSale->type, [
AfterSale::TYPE_REFUND_AND_RETURN,
AfterSale::TYPE_REFUND,
AfterSale::TYPE_CHANGE,
])
) {
DistributionPreIncomeJob::create([
'jobable_id' => $afterSale->id,
'jobable_type' => $afterSale->getMorphClass(),
'remarks' => $afterSale->isChange() ? '订单换货' : '订单退货',
]);
}
// 如果是换货单 // 如果是换货单
if ($afterSale->isChange()) { if ($afterSale->isChange()) {
// 如果订单享受了会员折扣,则需计算会员折扣 // 如果订单享受了会员折扣,则需计算会员折扣

View File

@ -1,498 +0,0 @@
<?php
namespace App\Services;
use App\Models\AfterSale;
use App\Models\DistributionPreIncome;
use App\Models\DistributionPreIncomeJob;
use App\Models\DistributionPreIncomeLog;
use App\Models\Order;
use App\Models\OrderRefundLog;
use App\Models\UserInfo;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
class DistributionPreIncomeJobService
{
/**
* 执行分销任务
*
* @param \App\Models\DistributionPreIncomeJob $job
* @return void
*/
public function run(DistributionPreIncomeJob $job)
{
bcscale(18);
switch (get_class($job->jobable)) {
case Order::class:
$this->runOrderJob($job);
break;
case OrderRefundLog::class:
$this->runOrderRefundJob($job);
break;
case AfterSale::class:
$this->runOrderAfterSaleJob($job);
break;
}
$job->update([
'status' => DistributionPreIncomeJob::STATUS_SUCCESS,
]);
}
/**
* 处理订单售后的预收益任务
*
* @param \App\Models\DistributionPreIncomeJob $job
* @return void
*/
protected function runOrderAfterSaleJob(DistributionPreIncomeJob $job)
{
// 售后单
$afterSale = $job->jobable;
// 如果售后单不是退款或换货,则直接结束任务
if (! in_array($afterSale->type, [
AfterSale::TYPE_REFUND,
AfterSale::TYPE_REFUND_AND_RETURN,
AfterSale::TYPE_CHANGE,
])) {
return;
}
// 售后商品
$afterSaleProduct = $afterSale->orderProduct;
// 如果售后商品是赠品,则直接结束任务
if ($afterSaleProduct->isGift()) {
return;
}
$preIncomes = DistributionPreIncome::where('order_id', $afterSale->order_id)->get();
$time = now();
$preIncomeLogs = [];
foreach ($preIncomes as $preIncome) {
$rule = $preIncome->rule;
if ($preIncome->type === DistributionPreIncome::TYPE_PRICE_DIFF) {
// 售后商品的总差价(元)
$totalDiffPrice = 0;
if (! is_null($afterSaleProduct->vip_price) && $afterSaleProduct->vip_discount_amount === 0) {
$diffPrice = $afterSaleProduct->sell_price - $afterSaleProduct->vip_price;
if ($diffPrice > 0) {
$totalDiffPrice = bcdiv($diffPrice * $afterSaleProduct->quantity, '100');
}
}
if (bccomp($totalDiffPrice, '0', 2) <= 0) {
continue;
}
$changeAmount = 0;
if ($afterSaleProduct->total_amount > 0) {
$amount = $afterSale->amount;
if ($amount >= $afterSaleProduct->total_amount) {
$amount = $afterSaleProduct->total_amount;
}
$changeAmount = bcdiv(bcmul($totalDiffPrice, $amount), $afterSaleProduct->total_amount);
} else {
$qty = $afterSale->num;
if ($qty > $afterSaleProduct->quantity) {
$qty = $afterSaleProduct->quantity;
}
$changeAmount = bcdiv(bcmul($totalDiffPrice, $qty), $afterSaleProduct->quantity);
}
// 差价奖励按变更的差价计算
$changeRevenue = bcmul($changeAmount, $rule['bonus_rate']);
$changeRevenue = bcmul($changeRevenue, bcsub('1', $rule['fee_rate']));
$changeRevenue = round($changeRevenue, 2);
// 变更金额
$changeAmount = round($changeAmount, 2);
// 变更成长值
$changeSalesValue = $afterSale->sales_value;
$preIncome->update([
'total_amount' => DB::raw("total_amount-{$changeAmount}"),
'total_revenue' => DB::raw("total_revenue-{$changeRevenue}"),
'total_sales_value' => DB::raw("total_sales_value-{$changeSalesValue}"),
]);
$preIncomeLogs[] = [
'pre_income_id' => $preIncome->id,
'pre_income_job_id' => $job->id,
'change_amount' => bcmul($changeAmount, '-1'),
'change_revenue' => bcmul($changeRevenue, '-1'),
'change_sales_value' => bcmul($changeSalesValue, '-1'),
'remarks' => $afterSale->isChange() ? '订单换货' : '订单退款',
'created_at' => $time,
'updated_at' => $time,
];
} elseif (in_array($preIncome->type, [DistributionPreIncome::TYPE_LEVEL_DIFF, DistributionPreIncome::TYPE_LEVEL_SAME])) {
if (bccomp($afterSale->sales_value, '0', 2) <= 0) {
continue;
}
$changeAmount = $afterSale->amount;
if ($changeAmount > $afterSaleProduct->total_amount) {
$changeAmount = $afterSaleProduct->total_amount;
}
$changeAmount = bcdiv($changeAmount, '100');
$changeSalesValue = $afterSale->sales_value;
// 级差奖励和平级奖励按变更的销售值算收益
$changeRevenue = bcmul($changeSalesValue, $rule['bonus_rate']);
$changeRevenue = bcmul($changeRevenue, bcsub('1', $rule['fee_rate']));
$changeRevenue = round($changeRevenue, 2);
$preIncome->update([
'total_amount' => DB::raw("total_amount-{$changeAmount}"),
'total_revenue' => DB::raw("total_revenue-{$changeRevenue}"),
'total_sales_value' => DB::raw("total_sales_value-{$changeSalesValue}"),
]);
$preIncomeLogs[] = [
'pre_income_id' => $preIncome->id,
'pre_income_job_id' => $job->id,
'change_amount' => bcmul($changeAmount, '-1'),
'change_revenue' => bcmul($changeRevenue, '-1'),
'change_sales_value' => bcmul($changeSalesValue, '-1'),
'remarks' => $afterSale->isChange() ? '订单换货' : '订单退款',
'created_at' => $time,
'updated_at' => $time,
];
}
}
DistributionPreIncomeLog::insert($preIncomeLogs);
}
/**
* 处理取消订单的预收益任务
*
* @param \App\Models\DistributionPreIncomeJob $job
* @return void
*/
protected function runOrderRefundJob(DistributionPreIncomeJob $job)
{
$time = now();
$preIncomeLogs = [];
$orderRefundLog = $job->jobable;
$preIncomes = DistributionPreIncome::where('order_id', $orderRefundLog->order_id)->get();
foreach ($preIncomes as $preIncome) {
$original = $preIncome->replicate();
$preIncome->update([
'total_amount' => 0,
'total_sales_value' => 0,
'total_revenue' => 0,
'status' => DistributionPreIncome::STATUS_PROCESSED,
]);
$preIncomeLogs[] = [
'pre_income_id' => $preIncome->id,
'pre_income_job_id' => $job->id,
'change_amount' => bcmul($original->total_amount, '-1'),
'change_sales_value' => bcmul($original->total_sales_value, '-1'),
'change_revenue' => bcmul($original->total_revenue, '-1'),
'remarks' => '取消订单',
'created_at' => $time,
'updated_at' => $time,
];
}
DistributionPreIncomeLog::insert($preIncomeLogs);
}
/**
* 处理下单预的预收益任务
*
* @param \App\Models\DistributionPreIncomeJob $job
* @return void
*/
protected function runOrderJob(DistributionPreIncomeJob $job)
{
// 订单信息
$order = $job->jobable;
// 下单用户信息
$user = $order->user->userInfo;
// 总销售值
$totalSalesValue = $order->sales_value;
// 总差价
$totalDiffPrice = 0;
if ($order->vip_discount_amount === 0) {
foreach ($order->products as $product) {
// 赠品不算成长值和差价
if ($product->isGift()) {
continue;
}
// 如果订单商品有会员价,并且没有会员折扣时,才计算总差价
if (! is_null($product->vip_price) && $product->vip_discount_amount === 0) {
$diffPrice = $product->sell_price - $product->vip_price;
if ($diffPrice > 0) {
$totalDiffPrice = bcadd($totalDiffPrice, bcmul(bcdiv($diffPrice, '100'), $product->quantity));
}
}
}
}
// 分销配置
$config = $this->getConfig();
$preIncomeLogs = [];
// 推粉丝赚差价
// 1. 总差价必须大于0
// 2. 下单用户必须有邀请人
// 3. 下单用户的邀请人必须可以享受分红
if (
$totalDiffPrice > 0
&& $user->inviter_id
&& $user->inviterInfo->bonusable
) {
// 手续费率
$feeRate = $config['price_diff_fee_rate'] ?? '0';
// 奖励比例
$bonusRate = '1';
// 总收益
$totalRevenue = bcmul($totalDiffPrice, $bonusRate);
// 扣除手续费
$totalRevenue = bcmul($totalRevenue, bcsub('1', $feeRate));
$preIncome = $user->inviterInfo->distributionPreIncomes()->create([
'order_id' => $order->id,
'type' => DistributionPreIncome::TYPE_PRICE_DIFF,
'agent_level' => $user->inviterInfo->agent_level,
'total_amount' => $totalDiffPrice,
'total_sales_value' => $totalSalesValue,
'total_revenue' => round($totalRevenue, 2),
'rule' => [
'fee_rate' => bcmul($feeRate, '1', 2),
'bonus_rate' => bcmul($bonusRate, '1', 2),
],
'remarks' => "订单号: {$order->sn}",
]);
$preIncomeLogs[] = [
'pre_income_id' => $preIncome->id,
'pre_income_job_id' => $job->id,
'change_amount' => bcdiv($totalDiffPrice, 100),
'change_sales_value' => $preIncome->total_sales_value,
'change_revenue' => $preIncome->total_revenue,
'remarks' => "订单号: {$order->sn}",
'created_at' => $preIncome->created_at,
'updated_at' => $preIncome->created_at,
];
}
// 如果总销售值大于0需计算各级代理的奖励
if ($totalSalesValue > 0) {
// 可获取奖励
$agents = $this->getAgentsByUser($user);
$lastAgent = null;
// 已分配的级差奖励比例
$assignedLvlDiffBonusRate = 0;
foreach ($agents as $agent) {
$rule = Arr::get($config, "rules.{$agent->agent_level_key}");
if ($lastAgent && $agent->agent_level === $lastAgent->agent_level) {
/*
|-----------------------------------------------
| 平级奖励
|-----------------------------------------------
*/
if ($agent->bonusable) {
$bonusRate = $rule['lvl_same_bonus_rate'] ?? '0';
if (bccomp($bonusRate, '0') === 1) {
// 手续费率
$feeRate = $config['lvl_same_bonus_fee_rate'] ?? '0';
// 总收益
$totalRevenue = bcmul($totalSalesValue, $bonusRate);
// 扣除手续费
$totalRevenue = bcmul($totalRevenue, bcsub('1', $feeRate));
$preIncome = $agent->distributionPreIncomes()->create([
'order_id' => $order->id,
'type' => DistributionPreIncome::TYPE_LEVEL_SAME,
'agent_level' => $agent->agent_level,
'total_amount' => $this->calculateOrderTotalAmount($order),
'total_sales_value' => $totalSalesValue,
'total_revenue' => round($totalRevenue, 2),
'rule' => [
// 手续费率
'fee_rate' => bcmul($feeRate, '1', 2),
// 实际奖励比例
'bonus_rate' => bcmul($bonusRate, '1', 2),
],
'remarks' => "订单号: {$order->sn}",
]);
$preIncomeLogs[] = [
'pre_income_id' => $preIncome->id,
'pre_income_job_id' => $job->id,
'change_amount' => $preIncome->total_amount,
'change_sales_value' => $preIncome->total_sales_value,
'change_revenue' => $preIncome->total_revenue,
'remarks' => "订单号: {$order->sn}",
'created_at' => $preIncome->created_at,
'updated_at' => $preIncome->created_at,
];
}
}
} else {
/*
|-----------------------------------------------
| 级差奖励
|-----------------------------------------------
*/
$lvlDiffBonusRate = $rule['lvl_diff_bonus_rate'] ?? '0';
if (bccomp($lvlDiffBonusRate, '0') === 1) {
// 可得级差奖励比例 = 当前等级的级差奖励 - 已分配的级差奖励比例
$bonusRate = bcsub($lvlDiffBonusRate, $assignedLvlDiffBonusRate);
// 如果可得级差奖励比例小于或等于0则停止分润
if (bccomp($bonusRate, '0') <= 0) {
break;
}
if ($agent->bonusable) {
// 手续费率
$feeRate = $config['lvl_diff_bonus_fee_rate'] ?? '0';
// 总收益
$totalRevenue = bcmul($totalSalesValue, $bonusRate);
// 扣除手续费
$totalRevenue = bcmul($totalRevenue, bcsub('1', $feeRate));
$preIncome = $agent->distributionPreIncomes()->create([
'order_id' => $order->id,
'type' => DistributionPreIncome::TYPE_LEVEL_DIFF,
'agent_level' => $agent->agent_level,
'total_amount' => $this->calculateOrderTotalAmount($order),
'total_sales_value' => $totalSalesValue,
'total_revenue' => round($totalRevenue, 2),
'rule' => [
// 手续费率
'fee_rate' => bcmul($feeRate, '1', 2),
// 实际奖励比例
'bonus_rate' => bcmul($bonusRate, '1', 2),
// 级差奖励比例
'lvl_diff_bonus_rate' => bcmul($lvlDiffBonusRate, '1', 2),
],
'remarks' => "订单号: {$order->sn}",
]);
$preIncomeLogs[] = [
'pre_income_id' => $preIncome->id,
'pre_income_job_id' => $job->id,
'change_amount' => $preIncome->total_amount,
'change_sales_value' => $preIncome->total_sales_value,
'change_revenue' => $preIncome->total_revenue,
'remarks' => "订单号: {$order->sn}",
'created_at' => $preIncome->created_at,
'updated_at' => $preIncome->created_at,
];
}
$assignedLvlDiffBonusRate = $lvlDiffBonusRate;
}
}
$lastAgent = $agent;
}
}
DistributionPreIncomeLog::insert($preIncomeLogs);
}
/**
* 根据下单用户,获取参与结算的所有代理
*
* @param \App\Models\UserInfo $user
* @return array
*/
protected function getAgentsByUser(UserInfo $user): array
{
// 可参与分销的所有代理
// 代理的等级必须从低到过且同一等级连续出现次数不超过2次
$agents = [
$user,
];
// 如果下单用户没有上级,则只有下单用户参与奖励计算
if (empty($pids = $user->parent_ids)) {
return $agents;
}
// 下单用户的所有上级
$ancestors = UserInfo::whereIn('user_id', $pids)->latest('depth')->get();
// 最后加入分销链的代理
$last = $user;
// 最后加入分销链的代理的前一个代理
$previous = null;
foreach ($ancestors as $ancestor) {
if ($previous && $previous->agent_level_rank >= $ancestor->agent_level_rank) {
continue;
}
if ($ancestor->agent_level_rank >= $last->agent_level_rank) {
$previous = $last;
$last = $ancestor;
$agents[] = $last;
}
}
return $agents;
}
/**
* 订单总金额
*
* @param \App\Models\Order $order
* @return float
*/
protected function calculateOrderTotalAmount(Order $order)
{
$totalAmount = bcadd($order->products_total_amount, $order->shipping_fee);
$totalAmount = bcsub($totalAmount, $order->coupon_discount_amount);
$totalAmount = bcsub($totalAmount, $order->vip_discount_amount);
$totalAmount = bcsub($totalAmount, $order->reduced_amount);
return round(bcdiv($totalAmount, 100), 2);
}
/**
* 分销配置
*
* @return array
*/
protected function getConfig(): array
{
return app_settings('distribution');
}
}

View File

@ -12,7 +12,6 @@ use App\Exceptions\BizException;
use App\Exceptions\ShippingNotSupportedException; use App\Exceptions\ShippingNotSupportedException;
use App\Models\ActivityProductPart; use App\Models\ActivityProductPart;
use App\Models\BargainOrder; use App\Models\BargainOrder;
use App\Models\DistributionPreIncomeJob;
use App\Models\Order; use App\Models\Order;
use App\Models\OrderActivity; use App\Models\OrderActivity;
use App\Models\OrderProduct; use App\Models\OrderProduct;
@ -1050,7 +1049,6 @@ class OrderService
} }
$order->update([ $order->update([
'is_settlable' => $isSettlable,
'status' => Order::STATUS_COMPLETED, 'status' => Order::STATUS_COMPLETED,
'completed_at' => now(), 'completed_at' => now(),
]); ]);
@ -1069,17 +1067,11 @@ class OrderService
} }
if ($order->isWaitShipping()) { if ($order->isWaitShipping()) {
$refundLog = $order->refundLogs()->create([ $order->refundLogs()->create([
'sn' => serial_number(), 'sn' => serial_number(),
'amount' => $order->total_amount, 'amount' => $order->total_amount,
'reason' => '取消订单', 'reason' => '取消订单',
]); ]);
DistributionPreIncomeJob::create([
'jobable_id' => $refundLog->id,
'jobable_type' => $refundLog->getMorphClass(),
'remarks' => '取消订单',
]);
} }
$products = $order->products()->get(); $products = $order->products()->get();

View File

@ -4,7 +4,6 @@ namespace App\Services;
use App\Exceptions\BizException; use App\Exceptions\BizException;
use App\Exceptions\InvalidPaySerialNumberException; use App\Exceptions\InvalidPaySerialNumberException;
use App\Models\DistributionPreIncomeJob;
use App\Models\Order; use App\Models\Order;
use App\Models\PayLog; use App\Models\PayLog;
@ -71,12 +70,6 @@ class PayService
'out_trade_no' => $payLog->out_trade_no, 'out_trade_no' => $payLog->out_trade_no,
'status' => Order::STATUS_PAID, 'status' => Order::STATUS_PAID,
]); ]);
DistributionPreIncomeJob::create([
'jobable_id' => $payable->id,
'jobable_type' => $payable->getMorphClass(),
'remarks' => '支付订单',
]);
} }
return $payLog; return $payLog;

View File

@ -1,57 +0,0 @@
<?php
namespace App\Services;
use App\Exceptions\BizException;
use App\Models\User;
class QuotaV1Service
{
/**
* 变老配额余额
*
* @param \App\Models\User $user
* @param float $changeBalance
* @param int $action
* @param string|null $remarks
* @param mixed $loggable
* @return void
*/
public function changeBalance(User $user, float $changeBalance, int $action, ?string $remarks = null, $loggable = null)
{
if ($changeBalance === 0) {
return;
}
$userInfo = $user->userInfo()->lockForUpdate()->first();
if ($userInfo === null) {
throw new BizException('系统错误');
}
// 变更前余额
$beforeBalance = $userInfo->quota_v1;
$_changeBalance = abs($changeBalance);
if ($changeBalance > 0) {
// 收入
$user->userInfo()->increment('quota_v1', $_changeBalance);
} else {
// 支出
if ($userInfo->quota_v1 < $_changeBalance) {
throw new BizException('老配额不足');
}
$user->userInfo()->decrement('quota_v1', $_changeBalance);
}
$user->quotaV1Logs()->create([
'loggable_id' => $loggable?->id,
'loggable_type' => $loggable?->getMorphClass(),
'before_balance' => $beforeBalance,
'change_balance' => $changeBalance,
'action' => $action,
'remarks' => $remarks,
]);
}
}

View File

@ -1,47 +0,0 @@
<?php
return [
// 升级规则
'upgrade_rules' => [
// 升级到店铺
'vip' => [
// 个人销售值 650
'sales_value' => 650,
],
// 升级到社区
'community' => [
// 个人销售值
'sales_value' => 650,
// 直推店铺数
'vips_agents_count' => 4,
],
// 升级到区级
'district' => [
// 团队销售值
'team_sales_value' => 65000,
// 直推店铺数
'vips_agents_count' => 6,
],
// 升级到市级
'city' => [
// 团队销售值
'team_sales_value' => 780000,
// 不同线上的区代
'district_agents_count' => 3,
],
// 升级到省级
'province' => [
// 团队销售值
'team_sales_value' => 7800000,
// 不同线上的市代
'city_agents_count' => 2,
],
// 升级到分公司
'branch' => [
// 团队销售值
'team_sales_value' => 52000000,
// 不同线上的省代
'province_agents_count' => 2,
],
],
];

View File

@ -1,35 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateDistributionPreIncomeJobsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('distribution_pre_income_jobs', function (Blueprint $table) {
$table->id();
$table->morphs('jobable');
$table->tinyInteger('status')->default(0)->comment('状态');
$table->string('remarks')->nullable()->comment('备注');
$table->text('failed_reason')->nullable()->comment('失败原因');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('distribution_pre_income_jobs');
}
}

View File

@ -1,45 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateDistributionPreIncomesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('distribution_pre_incomes', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->comment('用户ID');
$table->unsignedBigInteger('order_id')->comment('订单ID');
$table->tinyInteger('type')->comment('收益类型: 1 差价奖励2 平级奖励3 级差奖励');
$table->tinyInteger('agent_level')->comment('代理等级');
$table->unsignedDecimal('total_amount', 18, 2)->default(0)->comment('总金额');
$table->unsignedDecimal('total_sales_value', 18, 2)->default(0)->comment('总销售');
$table->unsignedDecimal('total_revenue', 18, 2)->default(0)->comment('总收益');
$table->tinyInteger('status')->default(0)->comment('状态');
$table->string('remarks')->nullable()->comment('备注');
$table->text('rule')->nullable()->comment('分销规则');
$table->timestamp('completed_at')->nullable()->comment('结算完成时间');
$table->timestamps();
$table->index('user_id');
$table->index('order_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('distribution_pre_incomes');
}
}

View File

@ -1,39 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateDistributionPreIncomeLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('distribution_pre_income_logs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('pre_income_id')->comment('预收益ID');
$table->unsignedBigInteger('pre_income_job_id')->nullable()->comment('预收益任务ID');
$table->decimal('change_amount', 18, 2)->default(0)->comment('变更金额');
$table->decimal('change_sales_value', 18, 2)->default(0)->comment('变更销售值');
$table->decimal('change_revenue', 18, 2)->default(0)->comment('变更收益');
$table->string('remarks')->nullable()->comment('备注');
$table->timestamps();
$table->index('pre_income_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('distribution_pre_income_logs');
}
}

View File

@ -14,14 +14,9 @@ class AddDistributionColumnsToUserInfosTable extends Migration
public function up() public function up()
{ {
Schema::table('user_infos', function (Blueprint $table) { Schema::table('user_infos', function (Blueprint $table) {
$table->boolean('bonusable')->default(true)->comment('是否可享受奖励');
$table->unsignedInteger('depth')->comment('分销深度'); $table->unsignedInteger('depth')->comment('分销深度');
$table->text('path')->nullable()->comment('分销路径'); $table->text('path')->nullable()->comment('分销路径');
$table->tinyInteger('agent_level')->default(0)->comment('代理等级');
$table->unsignedDecimal('quota_v2', 18, 3)->default(0)->comment('新配额');
$table->unsignedDecimal('quota_v1', 18, 3)->default(0)->comment('旧配额');
$table->unsignedDecimal('growth_value', 18, 2)->default(0)->comment('成长值'); $table->unsignedDecimal('growth_value', 18, 2)->default(0)->comment('成长值');
$table->unsignedDecimal('group_sales_value', 18, 2)->default(0)->comment('团队销售值');
}); });
} }
@ -34,14 +29,9 @@ class AddDistributionColumnsToUserInfosTable extends Migration
{ {
Schema::table('user_infos', function (Blueprint $table) { Schema::table('user_infos', function (Blueprint $table) {
$table->dropColumn([ $table->dropColumn([
'bonusable',
'depth', 'depth',
'path', 'path',
'agent_level',
'quota_v2',
'quota_v1',
'growth_value', 'growth_value',
'group_sales_value',
]); ]);
}); });
} }

View File

@ -1,34 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAgentUpgradeLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('agent_upgrade_logs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->tinyInteger('before_agent_level')->comment('变更前的代理等级');
$table->tinyInteger('change_agent_level')->comment('变更的代理等级');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('agent_upgrade_logs');
}
}

View File

@ -1,32 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddIsSettleToOrdersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('orders', function (Blueprint $table) {
$table->boolean('is_settle')->default(false)->comment('是否结算');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn(['is_settle']);
});
}
}

View File

@ -1,36 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateQuotaLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('quota_logs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->comment('用户ID');
$table->nullableMorphs('loggable');
$table->decimal('change_quota', 18, 3)->default(0)->comment('变更的配额');
$table->timestamps();
$table->index('user_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('quota_logs');
}
}

View File

@ -1,35 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateQuotaV1SendJobsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('quota_v1_send_jobs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('administrator_id')->comment('管理员ID');
$table->unsignedInteger('amount')->comment('金额(分)');
$table->unsignedTinyInteger('status')->default(0)->comment('0未开始1分配中2分配完成');
$table->string('remarks')->nullable()->comment('备注');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('quota_v1_send_jobs');
}
}

View File

@ -1,36 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateQuotaV1SendLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('quota_v1_send_logs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->comment('用户ID');
$table->unsignedBigInteger('job_id')->comment('任务ID');
$table->unsignedInteger('amount')->default(0)->comment('分红金额');
$table->unsignedTinyInteger('status')->default(0)->comment('0失败1成功');
$table->string('remarks')->nullable()->comment('备注');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('quota_v1_send_logs');
}
}

View File

@ -1,32 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddRemarksToQuotaLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('quota_logs', function (Blueprint $table) {
$table->string('remarks')->nullable()->comment('备注');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('quota_logs', function (Blueprint $table) {
$table->dropColumn(['remarks']);
});
}
}

View File

@ -1,32 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddRemarkToAgentUpgradeLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('agent_upgrade_logs', function (Blueprint $table) {
$table->string('remark')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('agent_upgrade_logs', function (Blueprint $table) {
$table->dropColumn(['remark']);
});
}
}

View File

@ -1,32 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddIsSettlableToOrdersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('orders', function (Blueprint $table) {
$table->boolean('is_settlable')->default(false)->comment('是否完成');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn(['is_settlable']);
});
}
}

View File

@ -1,39 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateQuotaV1LogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('quota_v1_logs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->comment('用户ID');
$table->nullableMorphs('loggable');
$table->tinyInteger('action')->comment('操作类型');
$table->unsignedDecimal('before_balance')->default(0)->comment('变更前的余额');
$table->unsignedDecimal('change_balance', 12, 3)->default(0)->comment('变动余额');
$table->string('remarks')->nullable()->comment('备注');
$table->timestamps();
$table->index('user_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('quota_v1_logs');
}
}

View File

@ -1,33 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class ChangeBeforeBalanceToQuotaV1LogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('quota_v1_logs', function (Blueprint $table) {
$table->decimal('before_balance', 12, 3)->change();
$table->decimal('change_balance', 12, 3)->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('quota_v1_logs', function (Blueprint $table) {
//
});
}
}

View File

@ -247,11 +247,6 @@ class AdminMenuSeeder extends Seeder
'icon' => 'fa fa-jpy', 'icon' => 'fa fa-jpy',
'uri'=> '', 'uri'=> '',
'children'=>[ 'children'=>[
[
'title' =>'预收益',
'icon' => '',
'uri' => 'distribution-pre-incomes',
],
[ [
'title' => '可提账户', 'title' => '可提账户',
'icon'=>'', 'icon'=>'',
@ -267,11 +262,6 @@ class AdminMenuSeeder extends Seeder
'icon' => '', 'icon' => '',
'uri' => 'points-logs', 'uri' => 'points-logs',
], ],
[
'title' => '新配额账户',
'icon' => '',
'uri' => 'quota-logs',
],
[ [
'title' =>'提现审核', 'title' =>'提现审核',
'icon' => '', 'icon' => '',
@ -282,11 +272,6 @@ class AdminMenuSeeder extends Seeder
'icon' => '', 'icon' => '',
'uri' =>'finance-after-sales?state=5', 'uri' =>'finance-after-sales?state=5',
], ],
[
'title' => '老配额分红',
'icon' => '',
'uri' => 'quota-v1-send-jobs',
],
], ],
], ],
[ [

View File

@ -69,7 +69,6 @@ class AdminPermissionSeeder extends Seeder
'curd' => false, 'curd' => false,
'children' =>[ 'children' =>[
'home.statistics'=>['name' =>'统计预览'], 'home.statistics'=>['name' =>'统计预览'],
'home.users'=>['name' =>'累计会员'],
'home.new_users'=>['name' =>'新注册'], 'home.new_users'=>['name' =>'新注册'],
'home.orders'=>['name' =>'订单'], 'home.orders'=>['name' =>'订单'],
], ],
@ -81,13 +80,10 @@ class AdminPermissionSeeder extends Seeder
'disable' =>['name'=>'禁用'], 'disable' =>['name'=>'禁用'],
'enable'=>['name' =>'启用'], 'enable'=>['name' =>'启用'],
'frozen'=>['name' =>'冻结资产'], 'frozen'=>['name' =>'冻结资产'],
'edit_agent'=>['name' =>'修改等级'],
'reset_password'=>['name' =>'修改密码'], 'reset_password'=>['name' =>'修改密码'],
'reset_account_password'=>['name' =>'修改安全密码'], 'reset_account_password'=>['name' =>'修改安全密码'],
'edit_phone'=>['name' =>'修改手机号'], 'edit_phone'=>['name' =>'修改手机号'],
'edit_bank'=>['name'=>'修改银行卡'], 'edit_bank'=>['name'=>'修改银行卡'],
'enable_bonus'=>['name' =>'开启奖金分红'],
'disable_bonus'=>['name' =>'关闭奖金分红'],
], ],
], ],
'article_categories' =>[ 'article_categories' =>[
@ -267,10 +263,6 @@ class AdminPermissionSeeder extends Seeder
'name' =>'配置管理', 'name' =>'配置管理',
'curd' => ['index'], 'curd' => ['index'],
], ],
'distribution_pre_incomes'=>[
'name' =>'预收益',
'curd' => ['index'],
],
'wallet_logs'=>[ 'wallet_logs'=>[
'name' =>'可提账户', 'name' =>'可提账户',
'curd' =>['index'], 'curd' =>['index'],
@ -291,10 +283,6 @@ class AdminPermissionSeeder extends Seeder
'name' =>'积分账户', 'name' =>'积分账户',
'curd' => ['index'], 'curd' => ['index'],
], ],
'quota_logs'=>[
'name' =>'新配额账户',
'curd' => ['index'],
],
'wallet_to_bank_logs' => [ 'wallet_to_bank_logs' => [
'name' => '提现审核', 'name' => '提现审核',
'curd' => ['index'], 'curd' => ['index'],
@ -302,24 +290,10 @@ class AdminPermissionSeeder extends Seeder
'verify'=>['name' =>'审核'], 'verify'=>['name' =>'审核'],
], ],
], ],
'quota_v1_send_jobs'=>[
'name' => '老配额分红',
'curd' => ['index', 'create', 'store', 'edit', 'update', 'destroy'],
'children' => [
'log_list'=>['name' =>'分红记录'],
'recharge'=>['name' =>'增加配额'],
'deduction'=>['name' =>'扣减配额'],
'logs_index'=>['name' =>'变动日志'],
],
],
'activities'=>[ 'activities'=>[
'name' =>'活动管理', 'name' =>'活动管理',
'curd' => true, 'curd' => true,
], ],
'monthly-statistics' => [
'name' => '每月统计',
'curd' => ['index'],
],
'bargain_activities'=>[ 'bargain_activities'=>[
'name' =>'砍价活动', 'name' =>'砍价活动',
'curd'=> true, 'curd'=> true,

View File

@ -34,7 +34,6 @@ class AppSettingSeeder extends Seeder
'article_about_us' => env('APP_URL', '').'/h5/articles/1', 'article_about_us' => env('APP_URL', '').'/h5/articles/1',
'article_user_promotion_agreement' => env('APP_URL', '').'/h5/articles/2', 'article_user_promotion_agreement' => env('APP_URL', '').'/h5/articles/2',
'article_user_hide_agreement' => env('APP_URL', '').'/h5/articles/3', 'article_user_hide_agreement' => env('APP_URL', '').'/h5/articles/3',
'article_user_agent_agreement' => env('APP_URL', '').'/h5/articles/4',
'invite_uri' => '', 'invite_uri' => '',
'search_hot_keys' => '搜索热词,分词1,分词2,分词3', 'search_hot_keys' => '搜索热词,分词1,分词2,分词3',
], ],
@ -100,82 +99,6 @@ class AppSettingSeeder extends Seeder
], ],
'remarks' => '个推配置', 'remarks' => '个推配置',
], ],
'distribution' => [
'value' => [
// 分销结算时间
'settle_days' => '7',
// 新配额比例
'quota_v2_rate' => '0.01',
// 会员差价手续费
'price_diff_fee_rate' => '0.23',
// 平级奖励手续费
'lvl_same_bonus_fee_rate' => '0',
// 级差奖励手续费
'lvl_diff_bonus_fee_rate' => '0.10',
// 老配额分红领取过期时间(小时)
'quota_v1_receive' => 72,
// 代理等级分润规则
'rules' => [
// 平民(粉丝)
'civilian' => [
'lvl_same_bonus_rate' => '0', // 平级奖励比例
'lvl_diff_bonus_rate' => '0', // 级差奖励比例
'lv_name' => '粉丝',
],
// 店铺
'vip' => [
'lvl_same_bonus_rate' => '0', // 平级奖励比例
'lvl_diff_bonus_rate' => '0.02', // 级差奖励比例
'lv_name' => '店铺',
],
// 社区
'community' => [
'lvl_same_bonus_rate' => '0.01', // 平级奖励比例
'lvl_diff_bonus_rate' => '0.10', // 级差奖励比例
'lv_name' => '社区',
],
// 区级
'district' => [
'lvl_same_bonus_rate' => '0.02', // 平级奖励比例
'lvl_diff_bonus_rate' => '0.19', // 级差奖励比例
'lv_name' => '区级',
],
// 市级
'city' => [
'lvl_same_bonus_rate' => '0.01', // 平级奖励比例
'lvl_diff_bonus_rate' => '0.32', // 级差奖励比例
'lv_name' => '市级',
],
// 省级
'province' => [
'lvl_same_bonus_rate' => '0.01', // 平级奖励比例
'lvl_diff_bonus_rate' => '0.42', // 级差奖励比例
'lv_name' => '省级',
],
// 分公司
'branch' => [
'lvl_same_bonus_rate' => '0.01', // 平级奖励比例
'lvl_diff_bonus_rate' => '0.48', // 级差奖励比例
'lv_name' => '分公司',
],
// 董事
'director' => [
'lvl_same_bonus_rate' => '0.01', // 平级奖励比例
'lvl_diff_bonus_rate' => '0.50', // 级差奖励
'lv_name' => '董事',
],
],
],
'remarks' => '会员奖励配置',
],
] as $key => $values) { ] as $key => $values) {
Setting::firstOrCreate(['key' => $key], $values); Setting::firstOrCreate(['key' => $key], $values);
} }

Some files were not shown because too many files have changed in this diff Show More