6
0
Fork 0
release
panliang 2022-05-09 17:52:02 +08:00
parent 81868622fa
commit 44dda50250
17 changed files with 963 additions and 785 deletions

View File

@ -0,0 +1,22 @@
<?php
namespace App\Admin\Actions\Show;
use Dcat\Admin\Show\AbstractTool;
use Dcat\Admin\Widgets\Modal;
use App\Admin\Forms\ProfitSuccessForm;
class ProfitSuccess extends AbstractTool
{
protected $title = '支付';
public function html()
{
$form = ProfitSuccessForm::make()->payload(['id'=>$this->getKey()]);;
return Modal::make()
->lg()
->title($this->title)
->body($form)
->button("<a href=\"javascript:void(0)\" class=\"btn btn-sm btn-success\"><i class=\"feather icon-check\"></i>&nbsp;{$this->title}</a>&nbsp;&nbsp;");
}
}

View File

@ -20,6 +20,7 @@ use App\Models\OrderActivity;
use App\Models\OrderLog;
use App\Models\OrderPackage;
use App\Models\OrderProduct;
use App\Models\OrderProfit;
use App\Models\Tag;
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
use Dcat\Admin\Admin;
@ -278,9 +279,7 @@ class OrderController extends AdminController
$show->field('reduced_amount')->as(function ($v) {
return bcdiv($v, 100, 2);
})->prepend('- ¥');
$show->field('bargain_amount')->as(function ($v) {
return bcdiv($v, 100, 2);
})->prepend('- ¥');
$show->field('profit');
$show->field('total_amount')->as(function ($v) {
return bcdiv($v, 100, 2);
})->prepend('¥');
@ -434,19 +433,38 @@ class OrderController extends AdminController
$column->row($packagesBox->collapsable());
$logsBox = Box::make('操作记录', $orderLogoGrid);
$column->row($logsBox->collapsable());
$activityBuilder = OrderActivity::with('activity')->where('order_id', $id);
$activityBox = Box::make('参与活动', Grid::make($activityBuilder, function (Grid $grid) {
$grid->column('activity.title', '活动名称');
$grid->column('show', '活动详情')->display(function () {
return '查看';
})->link(function () {
return admin_route('activities.show', ['activity' =>$this->activity_id]);
})->setHeaderAttributes(['style' => 'color:#5b69bc']);
// 参与活动
// $activityBuilder = OrderActivity::with('activity')->where('order_id', $id);
// $activityBox = Box::make('参与活动', Grid::make($activityBuilder, function (Grid $grid) {
// $grid->column('activity.title', '活动名称');
// $grid->column('show', '活动详情')->display(function () {
// return '查看';
// })->link(function () {
// return admin_route('activities.show', ['activity' =>$this->activity_id]);
// })->setHeaderAttributes(['style' => 'color:#5b69bc']);
// $grid->disableActions();
// $grid->disablePagination();
// $grid->disableRefreshButton();
// }));
// $column->row($activityBox->collapsable());
// 返利记录
$profitBuilder = OrderProfit::with(['user'])->where('order_id', $id);
$profitBox = Box::make('返利记录', Grid::make($profitBuilder, function (Grid $grid) {
$grid->column('user.phone', '受益人');
$grid->column('role_name', '代理等级');
$grid->column('ratio', '比例')->display(function ($v) {
return $v . '%';
});
$grid->column('money', '金额');
$grid->column('status', '状态')->using(OrderProfit::$statusMap)->dot(OrderProfit::$statusColor);
$grid->disableActions();
$grid->disablePagination();
$grid->disableRefreshButton();
}));
$column->row($activityBox->collapsable());
$column->row($profitBox->collapsable());
});
};
}

View File

@ -0,0 +1,110 @@
<?php
namespace App\Admin\Controllers;
use App\Models\OrderProfit;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Show;
use Dcat\Admin\Http\Controllers\AdminController;
use App\Admin\Extensions\Grid\Tools\ProfitBatchSuccess;
use App\Admin\Actions\Show\ProfitSuccess;
class OrderProfitController extends AdminController
{
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
return Grid::make(OrderProfit::with(['order', 'user']), function (Grid $grid) {
$grid->disableViewButton(false);
$grid->column('order.sn');
$grid->column('user.phone');
$grid->column('role_name');
$grid->column('growth_value');
$grid->column('ratio')->display(function ($v) {
return $v . '%';
});
$grid->column('money');
$grid->column('status')->using(OrderProfit::$statusMap)->dot(OrderProfit::$statusColor);
$grid->column('created_at');
$grid->filter(function (Grid\Filter $filter) {
$filter->panel();
$filter->like('order.sn')->width(3);
$filter->like('user.phone')->width(3);
});
// $grid->showRowSelector();
// $grid->batchActions(function (Grid\Tools\BatchActions $batch) {
// $batch->disableDelete();
// $batch->add(new ProfitBatchSuccess());
// });
});
}
/**
* Make a show builder.
*
* @param mixed $id
*
* @return Show
*/
protected function detail($id)
{
return Show::make($id, OrderProfit::with(['order', 'user']), function (Show $show) {
$show->field('id');
$show->field('order.sn');
$show->field('user.phone');
$show->field('role_name');
$show->field('growth_value');
$show->field('ratio')->as(function ($v) {
return $v . '%';
});
$show->field('money');
$show->field('status')->using(OrderProfit::$statusMap)->dot(OrderProfit::$statusColor);
$show->field('paid_at');
$show->field('remarks');
$show->field('created_at');
$show->field('updated_at');
$show->panel()->tools(function (Show\Tools $tools) use ($show) {
$tools->disableEdit();
$tools->disableDelete();
});
$show->tools(function (Show\Tools $tools) {
$tools->append(new ProfitSuccess());
});
});
}
/**
* Make a form builder.
*
* @return Form
*/
protected function form()
{
return Form::make(new OrderProfit(), function (Form $form) {
$form->display('id');
$form->text('order_id');
$form->text('from_user_id');
$form->text('user_id');
$form->text('role');
$form->text('role_name');
$form->text('growth_value');
$form->text('ratio');
$form->text('money');
$form->text('status');
$form->display('created_at');
$form->display('updated_at');
});
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Admin\Extensions\Grid\Tools;
use App\Models\Profit;
use Dcat\Admin\Grid\BatchAction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Throwable;
class ProfitBatchSuccess extends BatchAction
{
protected $title = '支付成功';
protected function authorize($user): bool
{
return $user->can('dcat.admin.profit.pay');
}
public function confirm()
{
return '是否确认?';
}
// 处理请求
public function handle(Request $request)
{
// 获取选中的ID数组
$keys = $this->getKey();
try {
DB::beginTransaction();
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
return $this->response()->error('操作失败,'.$th->getMessage())->refresh();
}
return $this->response()->success('操作成功')->refresh();
}
}

View File

@ -0,0 +1,67 @@
<?php
namespace App\Admin\Forms;
use App\Services\DistributeService;
use App\Exceptions\BizException;
use App\Models\OrderProfit;
use Dcat\Admin\Contracts\LazyRenderable;
use Dcat\Admin\Traits\LazyWidget;
use Dcat\Admin\Widgets\Form;
use Illuminate\Support\Facades\DB;
use Throwable;
class ProfitSuccessForm extends Form implements LazyRenderable
{
use LazyWidget;
/**
* 权限判断,如不需要可以删除此方法
*
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.profit.pay');
}
/**
* Handle the form request.
*
* @param array $input
*
* @return mixed
*/
public function handle(array $input)
{
$order = OrderProfit::findOrFail($this->payload['id']);
$service = new DistributeService();
try {
DB::beginTransaction();
$service->success($order, $input);
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('操作失败:'.$th->getMessage());
}
return $this->response()->success('操作成功')->refresh();
}
/**
* Build a form here.
*/
public function form()
{
$order = OrderProfit::findOrFail($this->payload['id']);
$this->datetime('paid_at')->value(now());
$this->text('pay_way');
$this->text('pay_no');
$this->text('remarks')->value($order->remark);
$this->disableResetButton();
}
}

View File

@ -177,4 +177,6 @@ Route::group([
// $router->get('test', 'HomeController@test');
$router->resource('store', 'StoreController');
$router->resource('profit', 'OrderProfitController');
});

View File

@ -48,6 +48,7 @@ class DistributeOrder extends Command
$service->storeByOrder($order);
} catch (Throwable $th) {
DB::rollBack();
$this->line($th);
}
return 0;
}

View File

@ -0,0 +1,47 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Schema;
class ModelFillable extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'model:fillable {table}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'get model fillable ';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
*/
public function handle()
{
$table = $this->argument('table');
if (Schema::hasTable($table)) {
$list = Schema::getColumnListing($table);
$this->info("protected \$fillable = ['".implode('\', \'', $list)."'];");
}
}
}

View File

@ -88,6 +88,7 @@ class Order extends Model
'is_change',
'sales_value',
'bargain_amount',
'profit',
];
/**
@ -203,6 +204,14 @@ class Order extends Model
return $this->hasMany(AfterSale::class, 'order_id');
}
/**
* 属于此订单的返利记录
*/
public function profits()
{
return $this->hasMany(OrderProfit::class, 'order_id');
}
/**
* 此订单是否待付款
*

View File

@ -0,0 +1,43 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Dcat\Admin\Traits\HasDateTimeFormatter;
class OrderProfit extends Model
{
use HasFactory, HasDateTimeFormatter;
public static $statusMap = [
0 => '待付款',
1 => '付款中',
2 => '已付款',
3 => '付款失败'
];
public static $statusColor = [
0 => 'primary',
1 => 'warning',
2 => 'success',
3 => 'danger'
];
protected $fillable = ['id', 'order_id', 'from_user_id', 'user_id', 'role', 'role_name', 'growth_value', 'ratio', 'money', 'status', 'paid_at', 'pay_data', 'remarks'];
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function fromUser()
{
return $this->belongsTo(User::class, 'from_user_id');
}
public function order()
{
return $this->belongsTo(Order::class, 'order_id');
}
}

View File

@ -2,7 +2,7 @@
namespace App\Services;
use App\Models\{User, Order, SalesValueLog, Vip};
use App\Models\{User, Order, SalesValueLog, Vip, OrderProfit};
/**
* 分销模块
@ -38,23 +38,56 @@ class DistributeService
$parent_ids = array_reverse($user->userInfo->parent_ids);
$parents = User::with(['userInfo', 'userVip.vip'])->whereIn('id', $parent_ids)->get();
// 过滤掉不是代理身份的用户
// 当前等级和下一级的等级相同
$parents->filter(function ($item) {
return $item->userVip ? true : false;
// 过滤掉当前等级 大于 下一级的等级的用户
$filtered = $parents->filter(function ($item, $key) use ($parents) {
if (!$item->userVip) {
return false;
}
$next = $parents->get($key + 1);
if ($next && $next->userVip) {
return $item->userVip->vip->sort < $next->userVip->vip->sort;
}
return true;
});
$user_list = collect();
foreach($parents as $item) {
$user_list->push([
'id' => $item->id,
'vip_name' => $item->userVip->vip->name ?? '',
'vip_id' => $item->userVip->vip_id ?? '',
// 生成返现记录
$profit_list = [];
$money_sum = 0;
foreach($filtered->reverse() as $item) {
$vip = $item->userVip->vip??'';
if (!$vip) {
continue;
}
$money = floor($sales_value * $vip->ratio) / 100 - $money_sum;
array_unshift($profit_list, [
'from_user_id' => $user->id,
'user_id' => $item->id,
'role' => $vip->slug . '-' . $vip->sort,
'role_name' => $vip->name,
'ratio' => $vip->ratio,
'growth_value' => $sales_value,
'money' => $money
]);
$money_sum += $money;
}
$order->update([
'profit' => $money_sum
]);
$order->profits()->createMany($profit_list);
}
// $vip_list = Vip::orderBy('sort', 'desc')->pluk('id');
// foreach($vip_list as $vip_id) {
// }
dd($user_list->all());
/**
* 返现记录支付成功
*
* @param \App\Models\OrderProfit $profit
* @param mixed $data
*/
public function success(OrderProfit $profit, $data = null)
{
$profit->update([
'status' => 2,
'paid_at' => data_get($data, 'paid_at', now()),
'pay_data' => $data,
'remarks' => data_get($data, 'remarks'),
]);
}
}

View File

@ -24,6 +24,7 @@ class CreateOrderProfitsTable extends Migration
$table->integer('ratio')->comment('比例');
$table->decimal('money', 12, 2)->comment('收益金额');
$table->tinyInteger('status')->default(0)->comment('状态(0: 待付款, 1: 付款中, 2: 已付款)');
$table->string('remarks')->nullable()->comment('备注');
$table->timestamp('paid_at')->nullable()->comment('付款时间');
$table->text('pay_data')->nullable()->comment('支付信息{pay_way, pay_sn}');
$table->timestamps();

View File

@ -14,6 +14,7 @@ class AddInvitorIdToOrders extends Migration
public function up()
{
Schema::table('orders', function (Blueprint $table) {
$table->decimal('profit')->default(0)->comment('产生的提成');
$table->unsignedBigInteger('store_id')->nullable()->comment('关联门店');
$table->unsignedBigInteger('inviter_id')->nullable()->comment('关联员工');
});

View File

@ -15,7 +15,7 @@ class AddSlugToVips extends Migration
{
Schema::table('vips', function (Blueprint $table) {
$table->string('slug')->comment('标识');
$table->unsignedInteger('sort')->comment('等级');
$table->unsignedInteger('sort')->unique()->comment('等级');
$table->integer('ratio')->comment('返佣比例, 10 => 10%');
});
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
<?php
return [
'labels' => [
'OrderProfit' => '提成记录',
'order-profit' => '提成记录',
'profit' => '提成记录',
],
'fields' => [
'order_id' => '订单ID',
'from_user_id' => '下单用户',
'user_id' => '用户',
'role_name' => '代理等级',
'growth_value' => '成长值',
'ratio' => '比例',
'money' => '收益金额',
'status' => '状态',
'order' => [
'sn' => '订单号'
],
'user' => [
'phone' => '用户'
],
'remarks' => '备注',
'paid_at' => '付款时间',
'pay_way' => '支付方式',
'pay_no' => '订单号',
],
'options' => [
],
];

View File

@ -53,7 +53,7 @@ return [
'quantity'=>'数量',
'remain_quantity'=>'待发',
'tags'=>'标签',
'profit' => '累计返利',
],
'options' => [
],