!9 1.4.0
* 调整签约发货 * 调整签约进货设置本地库存问题 * 优化订单商品导出 * 【后台】导出商城订单商品 * Update * 调整云仓库存不足信息提示 * 修改撤销订单发货bug * 调试取消提货单撤回订单已发的本地货 * 微信支付JSAPI * 调整取消支付 * 补充撤销支付,并调整日志排序 * 调整签约 云仓发货 * 调整签约发货订单库存问题 * WIP * 调整经销商发货报错 * 调整签约发货 * 调整签约发货内容 * 添加签约云仓发货 * Fix * 【后台】签约渠道补贴 * 【后台】进货补贴优化 * Update * 经销商商品变更数量格式化 * 【后台】优化管理者津贴和管理津贴 * 【后台】优化支付状态显示 * 【后台】优化管理津贴状态显示 * 【后台】优化管理者津贴状态显示 * 提货单支付回调处理 * 批零商品变更记录 * 【后台】云仓提货单 * 添加圆点扩展 * 云仓运费配置 * 取消提货单 * 更新进货业绩缓存有效期 * 修改支付完成云仓库发货 * WIP * 提货单列表和详情 * 创建提货单,提货单付款 * 处理线下付款增加库存 * 修改经销商配置返回手续费率 * 添加经销商配置返回手续费率 * 完善进货云库存 * 处理合并 * 添加后台操作打款补贴时的支付方式 * 取消批零提现时间间隔限制 * 添加自定义配置管理 * 用户商品托管库存 * 新增用户商品托管库存字段release
parent
aaecfccb78
commit
2d057fac9c
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Actions\Grid;
|
||||
|
||||
use App\Admin\Services\DealerEarningService;
|
||||
use App\Models\DealerEarning;
|
||||
use Dcat\Admin\Grid\BatchAction;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
|
||||
class DealerChannelSubsidyBatchPay extends BatchAction
|
||||
{
|
||||
protected $title = '<i class="feather grid-action-icon icon-stop-circle"></i> 付款';
|
||||
|
||||
/**
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.dealer_channel_subsidies.batch_pay');
|
||||
}
|
||||
|
||||
// 确认弹窗信息
|
||||
public function confirm()
|
||||
{
|
||||
return '您确定要支付选中的渠道补贴吗?';
|
||||
}
|
||||
|
||||
// 处理请求
|
||||
public function handle(Request $request)
|
||||
{
|
||||
try {
|
||||
DB::transaction(function () {
|
||||
foreach ($this->getKey() as $id) {
|
||||
$dealerEarning = DealerEarning::lockForUpdate()->channelSubsidy()->withoutPayer()->find($id);
|
||||
|
||||
if (! $dealerEarning?->isSettled() || ! $dealerEarning?->isPending()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(new DealerEarningService())->pay($dealerEarning);
|
||||
}
|
||||
});
|
||||
} catch (Throwable $e) {
|
||||
return $this->response()->error('操作失败:'.$e->getMessage())->refresh();
|
||||
}
|
||||
|
||||
return $this->response()->success('操作成功')->refresh();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Actions\Grid;
|
||||
|
||||
use App\Admin\Services\DealerEarningService;
|
||||
use App\Models\DealerEarning;
|
||||
use Dcat\Admin\Grid\RowAction;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class DealerChannelSubsidyPay extends RowAction
|
||||
{
|
||||
protected $title = '<i class="feather grid-action-icon icon-stop-circle"></i> 付款';
|
||||
|
||||
/**
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.dealer_channel_subsidies.pay');
|
||||
}
|
||||
|
||||
// 确认弹窗信息
|
||||
public function confirm()
|
||||
{
|
||||
return '您确定要支付选中的渠道补贴吗?';
|
||||
}
|
||||
|
||||
// 处理请求
|
||||
public function handle(Request $request)
|
||||
{
|
||||
DB::transaction(function () {
|
||||
$id = $this->getKey();
|
||||
|
||||
$dealerEarning = DealerEarning::lockForUpdate()->channelSubsidy()->withoutPayer()->find($id);
|
||||
|
||||
(new DealerEarningService())->pay($dealerEarning);
|
||||
});
|
||||
|
||||
return $this->response()->success('操作成功')->refresh();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Admin\Actions\Grid;
|
||||
|
||||
use App\Admin\Services\DealerEarningService;
|
||||
use App\Models\DealerManageSubsidy;
|
||||
use App\Services\Dealer\ManageSubsidyService;
|
||||
use Dcat\Admin\Grid\BatchAction;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
|
@ -38,7 +38,9 @@ class DealerManageSubsidyBatchPay extends BatchAction
|
|||
$dealerManageSubsidy = DealerManageSubsidy::lockForUpdate()->settled()->find($id);
|
||||
|
||||
if ($dealerManageSubsidy?->isPending()) {
|
||||
(new ManageSubsidyService())->pay($dealerManageSubsidy);
|
||||
(new DealerEarningService())->pay(
|
||||
$dealerManageSubsidy->earning->setRelation('earningable', $dealerManageSubsidy)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Admin\Actions\Grid;
|
||||
|
||||
use App\Admin\Services\DealerEarningService;
|
||||
use App\Models\DealerManageSubsidy;
|
||||
use App\Services\Dealer\ManageSubsidyService;
|
||||
use Dcat\Admin\Grid\RowAction;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
|
@ -34,8 +34,10 @@ class DealerManageSubsidyPay extends RowAction
|
|||
DB::transaction(function () {
|
||||
$id = $this->getKey();
|
||||
|
||||
(new ManageSubsidyService())->pay(
|
||||
DealerManageSubsidy::lockForUpdate()->settled()->findOrFail($id)
|
||||
$dealerManageSubsidy = DealerManageSubsidy::lockForUpdate()->settled()->findOrFail($id);
|
||||
|
||||
(new DealerEarningService())->pay(
|
||||
$dealerManageSubsidy->earning->setRelation('earningable', $dealerManageSubsidy)
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Admin\Actions\Grid;
|
||||
|
||||
use App\Admin\Services\DealerEarningService;
|
||||
use App\Models\DealerManagerSubsidy;
|
||||
use App\Services\Dealer\ManagerSubsidyService;
|
||||
use Dcat\Admin\Grid\BatchAction;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
|
@ -38,7 +38,9 @@ class DealerManagerSubsidyBatchPay extends BatchAction
|
|||
$dealerManagerSubsidy = DealerManagerSubsidy::lockForUpdate()->settled()->find($id);
|
||||
|
||||
if ($dealerManagerSubsidy?->isPending()) {
|
||||
(new ManagerSubsidyService())->pay($dealerManagerSubsidy);
|
||||
(new DealerEarningService())->pay(
|
||||
$dealerManagerSubsidy->earning->setRelation('earningable', $dealerManagerSubsidy)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace App\Admin\Actions\Grid;
|
||||
|
||||
use App\Admin\Services\DealerEarningService;
|
||||
use App\Models\DealerManagerSubsidy;
|
||||
use App\Services\Dealer\ManagerSubsidyService;
|
||||
use Dcat\Admin\Grid\RowAction;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
|
@ -34,8 +34,10 @@ class DealerManagerSubsidyPay extends RowAction
|
|||
DB::transaction(function () {
|
||||
$id = $this->getKey();
|
||||
|
||||
(new ManagerSubsidyService())->pay(
|
||||
DealerManagerSubsidy::lockForUpdate()->settled()->findOrFail($id)
|
||||
$dealerManagerSubsidy = DealerManagerSubsidy::lockForUpdate()->settled()->findOrFail($id);
|
||||
|
||||
(new DealerEarningService())->pay(
|
||||
$dealerManagerSubsidy->earning->setRelation('earningable', $dealerManagerSubsidy)
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Actions\Grid;
|
||||
|
||||
use App\Admin\Services\DealerEarningService;
|
||||
use App\Models\DealerPurchaseSubsidy;
|
||||
use Dcat\Admin\Grid\BatchAction;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
|
||||
class DealerPurchaseSubsidyBatchPay extends BatchAction
|
||||
{
|
||||
protected $title = '<i class="feather grid-action-icon icon-stop-circle"></i> 付款';
|
||||
|
||||
/**
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.dealer_purchase_subsidies.batch_pay');
|
||||
}
|
||||
|
||||
// 确认弹窗信息
|
||||
public function confirm()
|
||||
{
|
||||
return '您确定要支付选中的进货补贴吗?';
|
||||
}
|
||||
|
||||
// 处理请求
|
||||
public function handle(Request $request)
|
||||
{
|
||||
try {
|
||||
DB::transaction(function () {
|
||||
foreach ($this->getKey() as $id) {
|
||||
$dealerPurchaseSubsidy = DealerPurchaseSubsidy::lockForUpdate()->settleCompleted()->find($id);
|
||||
|
||||
if ($dealerPurchaseSubsidy?->isPending()) {
|
||||
(new DealerEarningService())->pay(
|
||||
$dealerPurchaseSubsidy->earning->setRelation('earningable', $dealerPurchaseSubsidy)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Throwable $e) {
|
||||
return $this->response()->error('操作失败:'.$e->getMessage())->refresh();
|
||||
}
|
||||
|
||||
return $this->response()->success('操作成功')->refresh();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Actions\Grid;
|
||||
|
||||
use App\Admin\Services\DealerEarningService;
|
||||
use App\Models\DealerPurchaseSubsidy;
|
||||
use Dcat\Admin\Grid\RowAction;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class DealerPurchaseSubsidyPay extends RowAction
|
||||
{
|
||||
protected $title = '<i class="feather grid-action-icon icon-stop-circle"></i> 付款';
|
||||
|
||||
/**
|
||||
* @param Model|Authenticatable|HasPermissions|null $user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.dealer_purchase_subsidies.pay');
|
||||
}
|
||||
|
||||
// 确认弹窗信息
|
||||
public function confirm()
|
||||
{
|
||||
return '您确定要支付选中的进货补贴吗?';
|
||||
}
|
||||
|
||||
// 处理请求
|
||||
public function handle(Request $request)
|
||||
{
|
||||
DB::transaction(function () {
|
||||
$id = $this->getKey();
|
||||
|
||||
$dealerPurchaseSubsidy = DealerPurchaseSubsidy::lockForUpdate()->settleCompleted()->findOrFail($id);
|
||||
|
||||
(new DealerEarningService())->pay(
|
||||
$dealerPurchaseSubsidy->earning->setRelation('earningable', $dealerPurchaseSubsidy)
|
||||
);
|
||||
});
|
||||
|
||||
return $this->response()->success('操作成功')->refresh();
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,8 @@ use Illuminate\Http\Request;
|
|||
|
||||
class ShippingOrder extends RowAction
|
||||
{
|
||||
protected $htmlClasses = ['btn', 'btn-primary'];
|
||||
|
||||
public function title()
|
||||
{
|
||||
if ($this->title) {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ class DealerEarningPay extends AbstractTool
|
|||
DB::beginTransaction();
|
||||
$earning = DealerEarning::findOrFail($key);
|
||||
$earning->update([
|
||||
'pay_way' => DealerEarning::PAY_WAY_WALLET,
|
||||
'pay_info' => $earning->getPayInfo(),
|
||||
'pay_at' => now(),
|
||||
'status' => DealerEarningStatus::Completed,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Actions\Grid\DealerChannelSubsidyBatchPay;
|
||||
use App\Admin\Actions\Grid\DealerChannelSubsidyPay;
|
||||
use App\Admin\Repositories\DealerEarning;
|
||||
use App\Admin\Widgets\InfoBox;
|
||||
use App\Enums\DealerEarningStatus;
|
||||
use App\Models\DealerEarning as DealerEarningModel;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Layout\Row;
|
||||
|
||||
class DealerChannelSubsidyController extends AdminController
|
||||
{
|
||||
protected $title = '签约渠道补贴';
|
||||
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
* @return Grid
|
||||
*/
|
||||
protected function grid()
|
||||
{
|
||||
Admin::style(
|
||||
<<<CSS
|
||||
.card-header {
|
||||
margin-top: 1.5rem !important;
|
||||
margin-bottom: -1rem !important;
|
||||
}
|
||||
CSS
|
||||
);
|
||||
|
||||
$builder = DealerEarning::with(['user.userInfo']);
|
||||
|
||||
return Grid::make($builder, function (Grid $grid) {
|
||||
$grid->model()->channelSubsidy()->withoutPayer()->orderBy('id', 'desc');
|
||||
|
||||
$grid->column('id')->sortable();
|
||||
$grid->column('user.phone', '手机号');
|
||||
$grid->column('user.userInfo.nickname', '昵称');
|
||||
$grid->column('lvl', '经销商等级')->display(function () {
|
||||
return $this->lvl->text();
|
||||
});
|
||||
$grid->column('total_amount', '补贴金额')->prepend('¥');
|
||||
$grid->column('fee', '手续费')->prepend('¥')->help('手续费=补贴金额*手续费率');
|
||||
$grid->column('fee_rate', '手续费率')->append('%');
|
||||
$grid->column('total_earnings', '总收入')->prepend('¥')->help('总收入=补贴金额-手续费');
|
||||
$grid->column('remark', '备注')->display('查看')->modal(function ($modal) {
|
||||
$modal->title('备注');
|
||||
return '<div>'.nl2br($this->remark).'</div>';
|
||||
});
|
||||
$grid->column('settle_at', '结算时间')->display(function () {
|
||||
return $this->settle_at?->toDateTimeString();
|
||||
})->sortable();
|
||||
$grid->column('status', '状态')->display(function ($v) {
|
||||
if (! $this->isSettled()) {
|
||||
return "<i class='fa fa-circle' style='font-size: 13px;color: #b9c3cd'></i> 待结算";
|
||||
}
|
||||
|
||||
return "<i class='fa fa-circle' style='font-size: 13px;color: {$v->color()}'></i> {$v->text()}";
|
||||
});
|
||||
$grid->column('pay_at', '付款时间')->display(function () {
|
||||
return $this->pay_at?->toDateTimeString();
|
||||
})->sortable();
|
||||
$grid->column('created_at', '创建时间')->display(function () {
|
||||
return $this->created_at?->toDateTimeString();
|
||||
});
|
||||
|
||||
$grid->showRowSelector();
|
||||
|
||||
$grid->tools(function ($tools) {
|
||||
$tools->batch(function ($batch) {
|
||||
$batch->disableDelete();
|
||||
|
||||
if (Admin::user()->can('dcat.admin.dealer_channel_subsidies.batch_pay')) {
|
||||
$batch->add(new DealerChannelSubsidyBatchPay());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
if (
|
||||
$actions->row->isSettled() &&
|
||||
$actions->row->isPending() &&
|
||||
Admin::user()->can('dcat.admin.dealer_channel_subsidies.pay')
|
||||
) {
|
||||
$actions->append(new DealerChannelSubsidyPay());
|
||||
}
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
|
||||
$filter->equal('user.phone', '手机号')->width(3);
|
||||
$filter->where('status', function ($query) {
|
||||
switch ($this->input) {
|
||||
case 'pending':
|
||||
$query->whereNull('settle_at')->where('status', DealerEarningStatus::Pending);
|
||||
break;
|
||||
|
||||
case 'paying':
|
||||
$query->whereNotNull('settle_at')->where('status', DealerEarningStatus::Pending);
|
||||
break;
|
||||
|
||||
case 'completed':
|
||||
$query->where('status', DealerEarningStatus::Completed);
|
||||
break;
|
||||
}
|
||||
}, '状态')->select([
|
||||
'pending' => '待结算',
|
||||
'paying' => '待付款',
|
||||
'completed' => '已完成',
|
||||
])->width(3);
|
||||
$filter->between('settle_at', '结算时间')->datetime()->width(6);
|
||||
});
|
||||
|
||||
$grid->header(function ($collection) use ($grid) {
|
||||
return tap(new Row(), function ($row) use ($grid) {
|
||||
$query = DealerEarningModel::query();
|
||||
|
||||
$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'] ?? []);
|
||||
});
|
||||
|
||||
$totalAmount = (clone $query)->sum('total_amount');
|
||||
$totalFee = (clone $query)->sum('fee');
|
||||
|
||||
$row->column(3, new InfoBox('补贴金额', $totalAmount, 'fa fa-cny'));
|
||||
$row->column(3, new InfoBox('手续费', $totalFee, 'fa fa-cny'));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -188,7 +188,8 @@ class DealerController extends AdminController
|
|||
$productGrid = Grid::make($builder, function (Grid $grid) {
|
||||
$grid->column('product.name', '商品名称');
|
||||
$grid->column('product.cover', '商品封面')->image(80, 80);
|
||||
$grid->column('stock', '剩余库存');
|
||||
$grid->column('stock', '库存');
|
||||
$grid->column('deposit_stock', '云库存');
|
||||
$grid->column('created_at', '创建时间');
|
||||
$grid->column('logs', '库存记录')->display('查看')->modal(function ($modal) {
|
||||
$modal->title('商品');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Repositories\DealerDeliveryBill;
|
||||
use App\Admin\Repositories\DealerDeliveryProduct;
|
||||
use App\Enums\DealerDeliveryBillStatus;
|
||||
use App\Enums\PayWay;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Layout\Row;
|
||||
use Dcat\Admin\Show;
|
||||
use Dcat\Admin\Widgets\Box;
|
||||
|
||||
class DealerDeliveryBillController extends AdminController
|
||||
{
|
||||
protected $title = '云仓提货单';
|
||||
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
* @return Grid
|
||||
*/
|
||||
protected function grid()
|
||||
{
|
||||
$repository = DealerDeliveryBill::with(['user.userInfo']);
|
||||
|
||||
return Grid::make($repository, function (Grid $grid) {
|
||||
$grid->model()->orderBy('id', 'desc');
|
||||
|
||||
$grid->column('id')->sortable();
|
||||
$grid->column('sn', '提货单号');
|
||||
$grid->column('user.phone', '手机号');
|
||||
$grid->column('user.userInfo.nickname', '昵称');
|
||||
$grid->column('shipping_fee', '运费')->prepend('¥');
|
||||
$grid->column('pay_way', '支付方式')->display(function ($v) {
|
||||
return $v?->text();
|
||||
})->circleDot(PayWay::colors());
|
||||
$grid->column('pay_at', '付款时间')->display(function ($v) {
|
||||
return $v?->toDateTimeString();
|
||||
});
|
||||
$grid->column('status', '状态')->display(function ($v) {
|
||||
return $v?->text();
|
||||
})->circleDot(DealerDeliveryBillStatus::colors());
|
||||
$grid->column('created_at', '创建时间')->display(function ($v) {
|
||||
return $v?->toDateTimeString();
|
||||
});
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
if (Admin::user()->can('dcat.admin.dealer_orders.show')) {
|
||||
$actions->append('<a style="cursor: pointer;" target="_blank" href="'.admin_route('dealer_delivery_bills.show', [$actions->row]).'"><i class="feather icon-eye"></i> 显示 </a>');
|
||||
}
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->like('sn', '提货单号')->width(4);
|
||||
$filter->like('user.phone', '手机号')->width(4);
|
||||
$filter->equal('status', '状态')->select(DealerDeliveryBillStatus::texts())->width(4);
|
||||
$filter->between('pay_at', '付款时间')->dateTime()->width(4);
|
||||
$filter->between('created_at', '创建时间')->dateTime()->width(4);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a show builder.
|
||||
*
|
||||
* @param mixed $id
|
||||
*
|
||||
* @return Show
|
||||
*/
|
||||
protected function detail($id)
|
||||
{
|
||||
return function (Row $row) use ($id) {
|
||||
$row->column(5, function ($column) use ($id) {
|
||||
$builder = DealerDeliveryBill::with(['user.userInfo']);
|
||||
|
||||
$column->row(Show::make($id, $builder, function (Show $show) {
|
||||
$show->field('sn', '提货单号');
|
||||
$show->field('user.phone', '手机号');
|
||||
$show->field('user.user_info.nickname', '昵称');
|
||||
$show->field('shipping_fee', '运费');
|
||||
$show->field('remark', '备注');
|
||||
$show->field('status', '状态')->as(function () {
|
||||
return $this->status?->text();
|
||||
})->circleDot(DealerDeliveryBillStatus::colors());
|
||||
$show->field('created_at')->as(function ($v) {
|
||||
return $this->created_at->toDateTimeString();
|
||||
});
|
||||
|
||||
$show->divider();
|
||||
$show->field('consignee_name', '收货人');
|
||||
$show->field('consignee_telephone', '联系方式');
|
||||
$show->field('consignee', '收货地址')->as(function () {
|
||||
return $this->consignee_zone . ' '. $this->consignee_address;
|
||||
});
|
||||
|
||||
$show->divider();
|
||||
$show->field('pay_sn', '支付单号');
|
||||
$show->field('pay_way', '支付方式')->as(function () {
|
||||
return $this->pay_way?->text();
|
||||
})->circleDot(PayWay::colors());
|
||||
$show->field('pay_at', '付款时间')->as(function () {
|
||||
return $this->pay_at?->toDateTimeString();
|
||||
});
|
||||
$show->field('out_trade_no', '外部交易号');
|
||||
|
||||
|
||||
$show->panel()
|
||||
->tools(function (Show\Tools $tools) use ($show) {
|
||||
$tools->disableEdit();
|
||||
$tools->disableDelete();
|
||||
});
|
||||
}));
|
||||
});
|
||||
$row->column(7, function ($column) use ($id) {
|
||||
$repository = DealerDeliveryProduct::with(['product']);
|
||||
|
||||
$column->row(Box::make('提货单商品', Grid::make($repository, function (Grid $grid) use ($id) {
|
||||
$grid->model()->where('delivery_bill_id', $id);
|
||||
|
||||
$grid->column('product.name', '名称');
|
||||
$grid->column('product.cover', '封面')->image(50, 50);
|
||||
$grid->column('qty', '数量');
|
||||
$grid->disableActions();
|
||||
$grid->disablePagination();
|
||||
$grid->disableRefreshButton();
|
||||
})));
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -62,8 +62,8 @@ class DealerManageSubsidyController extends AdminController
|
|||
return "<div style='padding:10px'>".nl2br($this->remark).'</div>';
|
||||
});
|
||||
$grid->column('status', '状态')->display(function ($v) {
|
||||
return '<i class="fa fa-circle" style="font-size: 13px; color: '.$v->color().';"></i> '.$v->text();
|
||||
});
|
||||
return $v->text();
|
||||
})->circleDot(DealerManageSubsidyStatus::colors());
|
||||
$grid->column('earning.pay_at', '付款时间');
|
||||
|
||||
$grid->showRowSelector();
|
||||
|
|
@ -123,45 +123,5 @@ class DealerManageSubsidyController extends AdminController
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
return Grid::make($builder, function (Grid $grid) {
|
||||
$grid->model()->orderBy('id', 'desc');//默认ID倒叙
|
||||
$grid->column('id')->sortable();
|
||||
$grid->column('user.phone', '手机号')->copyable();
|
||||
$grid->column('lvl', '等级')->display(function () {
|
||||
return $this->lvl->text();
|
||||
});
|
||||
$grid->column('order.sn', '订单编号');
|
||||
$grid->column('product.name', '商品名称');
|
||||
$grid->column('sales_volume', '销量');
|
||||
$grid->column('total_amount', '金额');
|
||||
$grid->column('order_completed_at', '结算时间')->sortable();
|
||||
$grid->column('created_at')->sortable();
|
||||
|
||||
$grid->disableCreateButton();
|
||||
$grid->disableActions();
|
||||
$grid->header(function ($collection) use ($grid) {
|
||||
$query = DealerManageSubsidyLogModel::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'] ?? []);
|
||||
});
|
||||
|
||||
// 查出统计数据
|
||||
$totalAmount = (clone $query)->sum('total_amount');
|
||||
// 自定义组件
|
||||
return "<div style='padding: 10px;'>金额:".$totalAmount.' 元</div>';
|
||||
});
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel(false);
|
||||
$filter->equal('user.phone', '手机号')->width(3);
|
||||
$filter->between('order_completed_at', '结算时间')->dateTime()->width(7);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ class DealerManagerSubsidyController extends AdminController
|
|||
return "<div style='padding:10px'>".nl2br($this->remark).'</div>';
|
||||
});
|
||||
$grid->column('status', '状态')->display(function ($v) {
|
||||
return '<i class="fa fa-circle" style="font-size: 13px; color: '.$v->color().';"></i> '.$v->text();
|
||||
});
|
||||
return $v->text();
|
||||
})->circleDot(DealerManagerSubsidyStatus::colors());
|
||||
$grid->column('earning.pay_at', '付款时间');
|
||||
|
||||
$grid->showRowSelector();
|
||||
|
|
|
|||
|
|
@ -52,11 +52,12 @@ class DealerOrderController extends AdminController
|
|||
$statusTexts = DealerOrderStatus::texts();
|
||||
|
||||
$grid->column('pay_way')->display(function ($v) {
|
||||
if ($v) {
|
||||
return '<i class="fa fa-circle" style="font-size: 13px;color: '.$v->color().'"></i> '.$v->getDealerOrderText();
|
||||
}
|
||||
return '';
|
||||
})->filter(DealerOrderPayWayIn::make(PayWay::dealerOrderTexts()));
|
||||
return $v?->text();
|
||||
})->circleDot(PayWay::colors())->filter(DealerOrderPayWayIn::make([
|
||||
PayWay::Offline->value => '线下',
|
||||
PayWay::Wallet->value => '钱包',
|
||||
PayWay::WxpayH5->value => '微信支付',
|
||||
]));
|
||||
|
||||
$grid->column('order_status')->display(function ($v) {
|
||||
return $this->order_status;
|
||||
|
|
@ -89,7 +90,7 @@ class DealerOrderController extends AdminController
|
|||
$actions->append(new DealerOrderAllocate());
|
||||
}
|
||||
|
||||
if ((empty($actions->row->consignor) || $actions->row->consignor_id == 1)) {
|
||||
if ((empty($actions->row->consignor))) {
|
||||
if ($actions->row->isPay() && Admin::user()->can('dcat.admin.dealer_orders.paid')) {
|
||||
$actions->append(new DealerOrderPaid());
|
||||
}
|
||||
|
|
@ -157,27 +158,9 @@ class DealerOrderController extends AdminController
|
|||
$show->field('consignor.phone')->as(function ($value) {
|
||||
return $value ?? '系统';
|
||||
});
|
||||
$show->html(function () {
|
||||
$content = '';
|
||||
|
||||
if ($this->pay_way) {
|
||||
$content = '<i class="fa fa-circle" style="font-size: 13px;color: '.$this->pay_way->color().'"></i> '.$this->pay_way->getDealerOrderText();
|
||||
}
|
||||
|
||||
return <<<HTML
|
||||
<div class="show-field form-group row">
|
||||
<div class="col-sm-2 control-label">
|
||||
<span>支付方式</span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-8">
|
||||
<div class="box box-solid box-default no-margin box-show">
|
||||
<div class="box-body">{$content} </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
HTML;
|
||||
});
|
||||
$show->field('pay_way', '支付方式')->as(function () {
|
||||
return $this->pay_way?->text();
|
||||
})->circleDot(PayWay::colors());
|
||||
$show->field('pay_sn', '支付流水号');
|
||||
$show->field('pay_time', '支付时间');
|
||||
$show->field('paied_time');
|
||||
|
|
@ -263,6 +246,7 @@ HTML;
|
|||
$grid->column('price', '标价')->prepend('¥');
|
||||
$grid->column('sale_price', '实际售价')->prepend('¥');
|
||||
$grid->column('qty', '数量');
|
||||
$grid->column('deposit_qty', '云数量');
|
||||
$grid->disableActions();
|
||||
$grid->disablePagination();
|
||||
$grid->disableRefreshButton();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,186 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Actions\Grid\DealerPurchaseSubsidyBatchPay;
|
||||
use App\Admin\Actions\Grid\DealerPurchaseSubsidyPay;
|
||||
use App\Admin\Repositories\DealerPurchaseSubsidy;
|
||||
use App\Admin\Repositories\DealerPurchaseSubsidyLog;
|
||||
use App\Admin\Widgets\InfoBox;
|
||||
use App\Enums\DealerPurchaseSubsidyStatus;
|
||||
use App\Models\DealerPurchaseSubsidy as DealerPurchaseSubsidyModel;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Layout\Row;
|
||||
use Dcat\Admin\Show;
|
||||
use Dcat\Admin\Widgets\Box;
|
||||
|
||||
class DealerPurchaseSubsidyController extends AdminController
|
||||
{
|
||||
protected $title = '进货补贴';
|
||||
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
* @return Grid
|
||||
*/
|
||||
protected function grid()
|
||||
{
|
||||
Admin::style(
|
||||
<<<CSS
|
||||
.card-header {
|
||||
margin-top: 1.5rem !important;
|
||||
margin-bottom: -1rem !important;
|
||||
}
|
||||
CSS
|
||||
);
|
||||
|
||||
$builder = DealerPurchaseSubsidy::with(['user.userInfo']);
|
||||
|
||||
return Grid::make($builder, function (Grid $grid) {
|
||||
$grid->model()->settleCompleted()->orderBy('id', 'desc');//默认ID倒叙
|
||||
|
||||
$grid->column('settle_period', '结算周期')->display(function () {
|
||||
return $this->start_at->rawFormat('Y/m/d') . '-' . $this->end_at->rawFormat('Y/m/d');
|
||||
})->link(function () {
|
||||
return admin_route('dealer_purchase_logs.index', [
|
||||
'user_phone' => $this->user?->phone,
|
||||
'order_completed_at[start]' => $this->start_at->toDateTimeString(),
|
||||
'order_completed_at[end]' => $this->end_at->toDateTimeString(),
|
||||
]);
|
||||
});
|
||||
$grid->column('user.phone', '手机号')->copyable();
|
||||
$grid->column('user.userInfo.nickname', '昵称');
|
||||
$grid->column('lvl', '等级')->display(function () {
|
||||
return $this->lvl->text();
|
||||
});
|
||||
$grid->column('total_purchase_amount', '进货业绩')->prepend('¥');
|
||||
$grid->column('subsidy_rate', '补贴比例')->append('%');
|
||||
$grid->column('total_subsidy', '补贴总额')->prepend('¥')->help('补贴总额=进货业绩*补贴比例');
|
||||
$grid->column('total_amount', '应得补贴')->prepend('¥');
|
||||
$grid->column('fee_rate', '手续费率')->append('%');
|
||||
$grid->column('fee', '手续费')->prepend('¥')->help('手续费=应得补贴*手续费率');
|
||||
$grid->column('status', '状态')->display(function ($v) {
|
||||
return $v->text();
|
||||
})->circleDot(DealerPurchaseSubsidyStatus::colors());
|
||||
|
||||
$grid->showRowSelector();
|
||||
$grid->tools(function ($tools) {
|
||||
$tools->batch(function ($batch) {
|
||||
$batch->disableDelete();
|
||||
|
||||
if (Admin::user()->can('dcat.admin.dealer_purchase_subsidies.batch_pay')) {
|
||||
$batch->add(new DealerPurchaseSubsidyBatchPay());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
if (Admin::user()->can('dcat.admin.dealer_purchase_subsidies.show')) {
|
||||
$actions->append('<a style="cursor: pointer;" target="_blank" href="'.admin_route('dealer_purchase_subsidies.show', ['dealer_purchase_subsidy' => $actions->row]).'"><i class="feather icon-eye"></i> 显示 </a>');
|
||||
}
|
||||
|
||||
if ($actions->row->isPending() && Admin::user()->can('dcat.admin.dealer_purchase_subsidies.pay')) {
|
||||
$actions->append(new DealerPurchaseSubsidyPay());
|
||||
}
|
||||
});
|
||||
|
||||
$grid->header(function ($collection) use ($grid) {
|
||||
return tap(new Row(), function ($row) use ($grid) {
|
||||
$query = DealerPurchaseSubsidyModel::query();
|
||||
|
||||
$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'] ?? []);
|
||||
});
|
||||
|
||||
$row->column(3, new InfoBox('进货业绩', (clone $query)->sum('total_purchase_amount'), 'fa fa-cny'));
|
||||
});
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
|
||||
$filter->equal('user.phone', '手机号')->width(3);
|
||||
$filter->equal('status', '状态')->select(DealerPurchaseSubsidyStatus::texts())->width(3);
|
||||
$filter->whereBetween('settle_period', function ($query) {
|
||||
$start = $this->input['start'] ?? null;
|
||||
$end = $this->input['end'] ?? null;
|
||||
|
||||
$query->when($start, function ($query, $start) {
|
||||
$query->where('start_at', '>=', "{$start} 00:00:00");
|
||||
});
|
||||
|
||||
$query->when($end, function ($query, $end) {
|
||||
$query->where('end_at', '<=', "{$end} 23:59:59");
|
||||
});
|
||||
}, '结算周期')->date()->width(6);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a show builder.
|
||||
*
|
||||
* @param mixed $id
|
||||
*
|
||||
* @return Show
|
||||
*/
|
||||
protected function detail($id)
|
||||
{
|
||||
$row = new Row();
|
||||
|
||||
$row->column(5, function ($column) use ($id) {
|
||||
$builder = DealerPurchaseSubsidy::with(['user.userInfo']);
|
||||
|
||||
$column->row(Show::make($id, $builder, function (Show $show) {
|
||||
$show->field('id');
|
||||
$show->field('settle_period', '结算周期')->as(function () {
|
||||
return $this->start_at->rawFormat('Y/m/d') . '-' . $this->end_at->rawFormat('Y/m/d');
|
||||
});
|
||||
$show->field('user.phone', '手机号');
|
||||
$show->field('user.user_info.nickname', '昵称');
|
||||
$show->field('lvl', '经销商等级')->as(function () {
|
||||
return $this->lvl->text();
|
||||
});
|
||||
$show->field('total_purchase_amount', '进货业绩')->prepend('¥');
|
||||
$show->field('subsidy_rate', '补贴比例')->append('%');
|
||||
$show->field('total_subsidy', '补贴总额')->prepend('¥');
|
||||
$show->field('total_amount', '应得补贴')->prepend('¥');
|
||||
$show->field('fee_rate', '手续费率')->append('%');
|
||||
$show->field('fee', '手续费')->prepend('¥');
|
||||
$show->field('real_amount', '实得补贴')->prepend('¥');
|
||||
$show->field('status', '状态')->as(function () {
|
||||
return $this->status?->text();
|
||||
})->circleDot(DealerPurchaseSubsidyStatus::colors());
|
||||
|
||||
$show->panel()
|
||||
->tools(function (Show\Tools $tools) use ($show) {
|
||||
$tools->disableEdit();
|
||||
$tools->disableDelete();
|
||||
});
|
||||
}));
|
||||
});
|
||||
$row->column(7, function ($column) use ($id) {
|
||||
$dealerPurchaseSubsidyLogBox = Box::make('补贴明细', Grid::make(DealerPurchaseSubsidyLog::class, function (Grid $grid) use ($id) {
|
||||
$grid->model()->where('purchase_subsidy_id', $id);
|
||||
|
||||
$grid->column('id');
|
||||
$grid->column('change_amount', '变更金额');
|
||||
$grid->column('remark', '备注');
|
||||
$grid->column('created_at', '结算时间');
|
||||
$grid->disableCreateButton();
|
||||
$grid->disableActions();
|
||||
$grid->disableRefreshButton();
|
||||
}));
|
||||
|
||||
$column->row($dealerPurchaseSubsidyLogBox);
|
||||
});
|
||||
|
||||
return $row;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Actions\Grid\CreateOrderPackage;
|
||||
use App\Admin\Actions\Grid\Exports\ShippingOrder as ExportShippingOrder;
|
||||
use App\Admin\Actions\Grid\KuaidiInfo;
|
||||
use App\Admin\Actions\Grid\OrderSetTag;
|
||||
|
|
@ -11,9 +10,11 @@ use App\Admin\Actions\Show\OrderCreatePackage;
|
|||
use App\Admin\Actions\Show\OrderPay;
|
||||
use App\Admin\Actions\Show\OrderReduce;
|
||||
use App\Admin\Actions\Show\OrderRemark;
|
||||
use App\Admin\Extensions\Grid\Tools\Order\ExportProduct;
|
||||
use App\Admin\Renderable\Grid\Filter\OrderStatusIn;
|
||||
use App\Admin\Renderable\PackageProductSimpleTable;
|
||||
use App\Admin\Repositories\Order;
|
||||
use App\Enums\PayWay;
|
||||
use App\Models\Order as OrderModel;
|
||||
use App\Models\OrderLog;
|
||||
use App\Models\OrderPackage;
|
||||
|
|
@ -25,13 +26,93 @@ use Dcat\Admin\Form;
|
|||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Grid\Column;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Layout\Content;
|
||||
use Dcat\Admin\Layout\Row;
|
||||
use Dcat\Admin\Show;
|
||||
use Dcat\Admin\Widgets\Box;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class OrderController extends AdminController
|
||||
{
|
||||
/**
|
||||
* Index interface.
|
||||
*
|
||||
* @param Content $content
|
||||
* @return Content
|
||||
*/
|
||||
public function index(Content $content)
|
||||
{
|
||||
switch (request()->query('_export')) {
|
||||
case 'product':
|
||||
if (! Admin::user()->can('dcat.admin.orders.export_order_products')) {
|
||||
throw new AuthorizationException('没有操作权限');
|
||||
}
|
||||
|
||||
$query = OrderModel::with(['user.userInfo', 'products']);
|
||||
|
||||
$grid = $this->grid();
|
||||
$grid->processFilter();
|
||||
|
||||
foreach ($grid->model()->getQueries() as $condition) {
|
||||
if (in_array($condition['method'], ['paginate', 'get', 'orderBy', 'orderByDesc'], true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
call_user_func_array([$query, $condition['method']], $condition['arguments'] ?? []);
|
||||
}
|
||||
|
||||
return response()->streamDownload(function () use ($query) {
|
||||
$writer = WriterEntityFactory::createXLSXWriter();
|
||||
$writer->openToBrowser('订单商品'.time().'.xlsx');
|
||||
|
||||
$writer->addRow(WriterEntityFactory::createRowFromArray([
|
||||
'商品ID',
|
||||
'商品名称',
|
||||
'数量',
|
||||
'价格',
|
||||
'金额',
|
||||
'待发货数量',
|
||||
'所属订单',
|
||||
'下单手机',
|
||||
'支付方式',
|
||||
'付款时间',
|
||||
'订单状态',
|
||||
'下单时间',
|
||||
'是否换货',
|
||||
]));
|
||||
|
||||
$query->lazyById()->each(function ($order) use ($writer) {
|
||||
foreach ($order->products as $product) {
|
||||
$writer->addRow(
|
||||
WriterEntityFactory::createRowFromArray([
|
||||
$product->sku_id,
|
||||
$product->name,
|
||||
$product->quantity,
|
||||
bcdiv($product->sell_price, '100', 2),
|
||||
bcdiv($product->total_amount, '100', 2),
|
||||
$product->remain_quantity,
|
||||
$order->sn,
|
||||
$order->user->phone,
|
||||
$order->pay_way?->text(),
|
||||
$order->pay_at?->toDateTimeString(),
|
||||
$order->order_status_text,
|
||||
$order->created_at?->toDateTimeString(),
|
||||
$order->is_change ? '是' : '否',
|
||||
])
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
$writer->close();
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return parent::index($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
|
|
@ -39,106 +120,94 @@ class OrderController extends AdminController
|
|||
*/
|
||||
protected function grid()
|
||||
{
|
||||
$builder = Order::with(['user', 'tags']);
|
||||
$grid = new Grid(Order::with(['user', 'tags']));
|
||||
|
||||
return Grid::make($builder, function (Grid $grid) {
|
||||
$grid->column('id')->sortable()->if(function () {
|
||||
return Admin::user()->can('dcat.admin.orders.show');
|
||||
})->then(function (Column $column) {
|
||||
$column->link(function ($value) {
|
||||
return admin_route('orders.show', ['order' => $value]);
|
||||
});
|
||||
});
|
||||
$grid->setResource('orders');
|
||||
$grid->model()->orderBy('id', 'desc');
|
||||
|
||||
$grid->tools(function (Grid\Tools $tools) {
|
||||
//设置规格
|
||||
if (Admin::user()->can('dcat.admin.orders.export_shipping_orders')) {
|
||||
$tools->append(new ExportShippingOrder());
|
||||
}
|
||||
$grid->column('id')->sortable()->if(function () {
|
||||
return Admin::user()->can('dcat.admin.orders.show');
|
||||
})->then(function (Column $column) {
|
||||
$column->link(function ($value) {
|
||||
return admin_route('orders.show', ['order' => $value]);
|
||||
});
|
||||
$grid->column('sn')->copyable();
|
||||
$grid->column('tags', '标签')->display(function ($tags) {
|
||||
$array = [];
|
||||
foreach ($this->tags as $key => $tag) {
|
||||
$array[] = $tag->name;
|
||||
}
|
||||
return $array;
|
||||
})->label();
|
||||
$grid->column('user.phone')->copyable();
|
||||
$grid->column('total_amount')->display(function ($value) {
|
||||
return bcdiv($value, 100, 2);
|
||||
})->prepend('¥');
|
||||
$grid->column('order_status')->display(function ($value) {
|
||||
return $this->order_status;
|
||||
})->using([
|
||||
});
|
||||
$grid->column('sn')->copyable();
|
||||
$grid->column('tags', '标签')->display(function ($tags) {
|
||||
return $tags->implode('name');
|
||||
})->label();
|
||||
$grid->column('user.phone')->copyable();
|
||||
$grid->column('total_amount')->display(function ($value) {
|
||||
return bcdiv($value, 100, 2);
|
||||
})->prepend('¥');
|
||||
$grid->column('order_status')->display(function ($value) {
|
||||
return $this->order_status;
|
||||
})->using([
|
||||
0=>'待付款',
|
||||
1=>'待发货',
|
||||
2=>'发货中',
|
||||
3=>'已发货',
|
||||
9=>'已完成',
|
||||
10=>'已取消',
|
||||
])->dot([
|
||||
0=>'primary',
|
||||
1=>'warning',
|
||||
2=>'danger',
|
||||
3=>'success',
|
||||
9=>'success',
|
||||
10=>'#b3b9bf',
|
||||
])->filter(
|
||||
OrderStatusIn::make([
|
||||
0=>'待付款',
|
||||
1=>'待发货',
|
||||
2=>'发货中',
|
||||
3=>'已发货',
|
||||
9=>'已完成',
|
||||
10=>'已取消',
|
||||
])->dot([
|
||||
0=>'primary',
|
||||
1=>'warning',
|
||||
2=>'danger',
|
||||
3=>'success',
|
||||
9=>'success',
|
||||
10=>'#b3b9bf',
|
||||
])->filter(
|
||||
OrderStatusIn::make([
|
||||
0=>'待付款',
|
||||
1=>'待发货',
|
||||
2=>'发货中',
|
||||
3=>'已发货',
|
||||
9=>'已完成',
|
||||
10=>'已取消',
|
||||
])
|
||||
);
|
||||
$grid->column('pay_way')->display(function ($v) {
|
||||
if ($v) {
|
||||
return '<i class="fa fa-circle" style="font-size: 13px;color: '.$v->color().'"></i> '.$v->getMallOrderText();
|
||||
}
|
||||
])
|
||||
);
|
||||
$grid->column('pay_way')->display(function ($v) {
|
||||
return $v?->mallText();
|
||||
})->circleDot(PayWay::colors());
|
||||
$grid->column('pay_at');
|
||||
$grid->column('created_at')->sortable();
|
||||
|
||||
return '';
|
||||
});
|
||||
$grid->column('pay_at');
|
||||
// $grid->column('consignee_name');
|
||||
// $grid->column('consignee_telephone');
|
||||
// $grid->column('consignee_zone');
|
||||
// $grid->column('consignee_address');
|
||||
|
||||
$grid->column('created_at')->sortable();
|
||||
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
if (Admin::user()->can('dcat.admin.orders.show')) {
|
||||
$actions->disableView(false);
|
||||
}
|
||||
|
||||
if (Admin::user()->can('dcat.admin.orders.tags')) {
|
||||
$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>');
|
||||
}
|
||||
// $actions->append(new CreateOrderPackage());
|
||||
});
|
||||
|
||||
$grid->setResource('orders');
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->like('sn')->width(3);
|
||||
$filter->like('user.phone')->width(3);
|
||||
$filter->where('tags', function ($query) {
|
||||
$query->whereHas('tags', function ($q) {
|
||||
$q->whereIn('tags.id', $this->input);
|
||||
});
|
||||
}, '标签')->multipleSelect(Tag::orderTag()->pluck('name', 'id'))->width(3);
|
||||
$filter->between('created_at')->dateTime()->width(7);
|
||||
});
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->like('sn')->width(3);
|
||||
$filter->like('user.phone')->width(3);
|
||||
$filter->where('tags', function ($query) {
|
||||
$query->whereHas('tags', function ($q) {
|
||||
$q->whereIn('tags.id', $this->input);
|
||||
});
|
||||
}, '标签')->multipleSelect(Tag::orderTag()->pluck('name', 'id'))->width(3);
|
||||
$filter->between('created_at')->dateTime()->width(7);
|
||||
});
|
||||
|
||||
$grid->tools(function (Grid\Tools $tools) {
|
||||
if (Admin::user()->can('dcat.admin.orders.export_shipping_orders')) {
|
||||
$tools->append(new ExportShippingOrder());
|
||||
}
|
||||
|
||||
if (Admin::user()->can('dcat.admin.orders.export_order_products')) {
|
||||
$tools->append(new ExportProduct());
|
||||
}
|
||||
});
|
||||
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
if (Admin::user()->can('dcat.admin.orders.show')) {
|
||||
$actions->disableView(false);
|
||||
}
|
||||
|
||||
if (Admin::user()->can('dcat.admin.orders.tags')) {
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -180,15 +249,9 @@ class OrderController extends AdminController
|
|||
return $this->tags->pluck('name');
|
||||
})->label();
|
||||
$show->field('pay_at');
|
||||
$show->field('pay_way')->unescape()->as(function () {
|
||||
$content = '';
|
||||
|
||||
if ($this->pay_way) {
|
||||
$content = '<i class="fa fa-circle" style="font-size: 13px;color: '.$this->pay_way->color().'"></i> '.$this->pay_way->getMallOrderText();
|
||||
}
|
||||
|
||||
return $content;
|
||||
});
|
||||
$show->field('pay_way', '支付方式')->as(function () {
|
||||
return $this->pay_way?->text();
|
||||
})->circleDot(PayWay::colors());
|
||||
});
|
||||
$show->row(function (Show\Row $show) {
|
||||
$show->width(6)->field('consignee_name');
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace App\Admin\Controllers;
|
|||
|
||||
use App\Admin\Forms\Settings\Android;
|
||||
use App\Admin\Forms\Settings\App;
|
||||
use App\Admin\Forms\Settings\Custom;
|
||||
use App\Admin\Forms\Settings\Dealer;
|
||||
use App\Admin\Forms\Settings\Distribution;
|
||||
use App\Admin\Forms\Settings\Ios;
|
||||
|
|
@ -118,6 +119,7 @@ class SettingController extends AdminController
|
|||
$tab->addLink('Android配置', admin_route('settings.index', ['type'=>'ios']));
|
||||
$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 'distribution':
|
||||
$tab->addLink('系统配置', admin_route('settings.index', ['type'=>'app']));
|
||||
|
|
@ -128,6 +130,7 @@ class SettingController extends AdminController
|
|||
$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 'dealer':
|
||||
$tab->addLink('系统配置', admin_route('settings.index', ['type'=>'app']));
|
||||
|
|
@ -138,6 +141,7 @@ class SettingController extends AdminController
|
|||
$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':
|
||||
$tab->addLink('系统配置', admin_route('settings.index', ['type'=>'app']));
|
||||
|
|
@ -148,6 +152,7 @@ class SettingController extends AdminController
|
|||
$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 'ios':
|
||||
$tab->addLink('系统配置', admin_route('settings.index', ['type'=>'app']));
|
||||
|
|
@ -158,6 +163,7 @@ class SettingController extends AdminController
|
|||
$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 'android':
|
||||
$tab->addLink('系统配置', admin_route('settings.index', ['type'=>'app']));
|
||||
|
|
@ -168,6 +174,7 @@ class SettingController extends AdminController
|
|||
$tab->add('Android配置', new Android(), true);
|
||||
$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 'kuaidi100':
|
||||
$tab->addLink('系统配置', admin_route('settings.index', ['type'=>'app']));
|
||||
|
|
@ -178,6 +185,7 @@ class SettingController extends AdminController
|
|||
$tab->addLink('Android配置', admin_route('settings.index', ['type'=>'android']));
|
||||
$tab->add('快递100配置', new Kuaidi100(), true);
|
||||
$tab->addLink('Uni-push配置', admin_route('settings.index', ['type'=>'unipush']));
|
||||
$tab->addLink('自定义配置', admin_route('settings.index', ['type'=>'custom']));
|
||||
break;
|
||||
case 'unipush':
|
||||
$tab->addLink('系统配置', admin_route('settings.index', ['type'=>'app']));
|
||||
|
|
@ -188,6 +196,18 @@ class SettingController extends AdminController
|
|||
$tab->addLink('Android配置', admin_route('settings.index', ['type'=>'android']));
|
||||
$tab->addLink('快递100配置', admin_route('settings.index', ['type'=>'kuaidi100']));
|
||||
$tab->add('Uni-push配置', new Unipush(), true);
|
||||
$tab->addLink('自定义配置', admin_route('settings.index', ['type'=>'custom']));
|
||||
break;
|
||||
case 'custom':
|
||||
$tab->addLink('系统配置', admin_route('settings.index', ['type'=>'app']));
|
||||
// $tab->addLink('会员奖励配置', admin_route('settings.index', ['type'=>'distribution']));
|
||||
$tab->addLink('经销商配置', admin_route('settings.index', ['type'=>'dealer']));
|
||||
$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->add('自定义配置', new Custom(), true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Extensions\Column;
|
||||
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Grid\Displayers\AbstractDisplayer;
|
||||
use Illuminate\Support\Arr;
|
||||
use UnitEnum;
|
||||
|
||||
class CircleDot extends AbstractDisplayer
|
||||
{
|
||||
public function display(array $options = [], string $default = 'default')
|
||||
{
|
||||
if (is_null($value = $this->value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($value instanceof UnitEnum) {
|
||||
$value = $value->value;
|
||||
}
|
||||
|
||||
$background = $this->background($options, $default);
|
||||
|
||||
return "<i class='fa fa-circle' style='font-size: 13px;color: {$background}'></i> {$value}";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取圆点的背景色
|
||||
*
|
||||
* @param array $options
|
||||
* @param string $default
|
||||
* @return string
|
||||
*/
|
||||
protected function background(array $options, string $default = 'default'): string
|
||||
{
|
||||
$original = $this->column->getOriginal();
|
||||
|
||||
$style = is_null($original) ? $default : Arr::get(
|
||||
$options,
|
||||
$original instanceof UnitEnum
|
||||
? $original->value
|
||||
: $original,
|
||||
$default
|
||||
);
|
||||
|
||||
$style = $style === 'default' ? 'dark70' : $style;
|
||||
|
||||
return Admin::color()->get($style, $style);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Extensions\Grid\Tools\Order;
|
||||
|
||||
use Dcat\Admin\Grid\Tools\AbstractTool;
|
||||
|
||||
class ExportProduct extends AbstractTool
|
||||
{
|
||||
protected function authorize($user): bool
|
||||
{
|
||||
return $user->can('dcat.admin.orders.export_order_products');
|
||||
}
|
||||
|
||||
/**
|
||||
* 按钮样式定义,默认 btn btn-white waves-effect
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $style = 'btn btn-primary';
|
||||
|
||||
/**
|
||||
* 按钮文本
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function title()
|
||||
{
|
||||
return '<i class="feather grid-action-icon icon-download"></i>导出商品';
|
||||
}
|
||||
|
||||
protected function script()
|
||||
{
|
||||
$this->setHtmlAttribute('data-role', 'order-products-exporter');
|
||||
|
||||
$url = request()->fullUrlWithQuery(['_export' => 'product']);
|
||||
|
||||
return <<<JS
|
||||
$('button[data-role=order-products-exporter]').click(function () {
|
||||
window.location.href="$url";
|
||||
});
|
||||
JS;
|
||||
}
|
||||
}
|
||||
|
|
@ -45,8 +45,9 @@ class DealerEarningPay extends Form implements LazyRenderable
|
|||
DB::beginTransaction();
|
||||
$earning = DealerEarning::findOrFail($id);
|
||||
$earning->update([
|
||||
'pay_way' => DealerEarning::PAY_WAY_WALLET,
|
||||
'pay_info' => $earning->getPayInfo(),
|
||||
'pay_image' => $input['pay_image']??null,
|
||||
'pay_image' => $input['pay_image'] ?? null,
|
||||
'pay_at' => now(),
|
||||
'status' => DealerEarningStatus::Completed,
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Forms\Settings;
|
||||
|
||||
use App\Models\Setting;
|
||||
use App\Services\SettingService;
|
||||
use Dcat\Admin\Widgets\Form;
|
||||
|
||||
class Custom extends Form
|
||||
{
|
||||
/**
|
||||
* Handle the form request.
|
||||
*
|
||||
* @param array $input
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(array $input)
|
||||
{
|
||||
Setting::where('key', 'custom')->updateOrCreate([
|
||||
'key' => 'custom',
|
||||
], ['value' => $input]);
|
||||
|
||||
//清配置缓存
|
||||
app(SettingService::class)->cleanCache('custom');
|
||||
|
||||
return $this
|
||||
->response()
|
||||
->success('配置更新成功!')
|
||||
->refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a form here.
|
||||
*/
|
||||
public function form()
|
||||
{
|
||||
$this->keyValue('key_value', '配置')->setKeyLabel('键名')->setValueLabel('键值');
|
||||
}
|
||||
|
||||
public function default()
|
||||
{
|
||||
$appSettings = Setting::where('key', 'custom')->value('value');
|
||||
return [
|
||||
'key_value' => $appSettings['key_value'] ?? [],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,7 @@ class Dealer extends Form
|
|||
public function form()
|
||||
{
|
||||
$this->switch('wxpay_switch', '微信支付');
|
||||
$this->currency('delivery_bill_shipping_fee', '云仓运费')->symbol('¥');
|
||||
$this->currency('fee_rate', '手续费比例(百分比)')->symbol('%');
|
||||
$this->number('withdraw_threshold_amount', '起提金额(元)');
|
||||
$this->currency('withdraw_fee_rate', '提现费率')->symbol('%');
|
||||
|
|
@ -139,6 +140,7 @@ class Dealer extends Form
|
|||
$dealerSettings = (array) Setting::where('key', 'dealer')->value('value');
|
||||
return [
|
||||
'wxpay_switch'=> $dealerSettings['wxpay_switch'] ?? 1,
|
||||
'delivery_bill_shipping_fee'=> $dealerSettings['delivery_bill_shipping_fee'] ?? 0,
|
||||
'fee_rate'=> $dealerSettings['fee_rate'] ?? '',
|
||||
'withdraw_threshold_amount'=> $dealerSettings['withdraw_threshold_amount'] ?? 0,
|
||||
'withdraw_fee_rate'=> $dealerSettings['withdraw_fee_rate'] ?? 0,
|
||||
|
|
|
|||
|
|
@ -18,16 +18,17 @@ class DealerUserProductLogSimpleTable extends LazyRenderable
|
|||
return Grid::make($builder, function (Grid $grid) {
|
||||
$grid->column('product.name', '商品名称');
|
||||
$grid->column('remark', '备注');
|
||||
$grid->column('is_deposit', '范围')->using([
|
||||
0=>'本地库存',
|
||||
1=>'云库存',
|
||||
]);
|
||||
$grid->column('qty', '变动数量')->display(function () {
|
||||
return (in_array($this->type, [
|
||||
DealerUserProductLog::TYPE_ORDER_IN,
|
||||
DealerUserProductLog::TYPE_ADMIN_IN,
|
||||
]) ? '+' : '-').$this->qty.$this->product?->unit;
|
||||
return $this->qty_format.$this->product?->unit;
|
||||
});
|
||||
$grid->column('created_at', '创建时间');
|
||||
|
||||
// $grid->withBorder();
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
$grid->model()->orderBy('id', 'desc');
|
||||
$grid->disableRefreshButton();
|
||||
$grid->disableActions();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Repositories;
|
||||
|
||||
use App\Models\DealerDeliveryBill as Model;
|
||||
use Dcat\Admin\Repositories\EloquentRepository;
|
||||
|
||||
class DealerDeliveryBill extends EloquentRepository
|
||||
{
|
||||
/**
|
||||
* Model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eloquentClass = Model::class;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Repositories;
|
||||
|
||||
use App\Models\DealerDeliveryProduct as Model;
|
||||
use Dcat\Admin\Repositories\EloquentRepository;
|
||||
|
||||
class DealerDeliveryProduct extends EloquentRepository
|
||||
{
|
||||
/**
|
||||
* Model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eloquentClass = Model::class;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Repositories;
|
||||
|
||||
use App\Models\DealerPurchaseSubsidy as Model;
|
||||
use Dcat\Admin\Repositories\EloquentRepository;
|
||||
|
||||
class DealerPurchaseSubsidy extends EloquentRepository
|
||||
{
|
||||
/**
|
||||
* Model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eloquentClass = Model::class;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Repositories;
|
||||
|
||||
use App\Models\DealerPurchaseSubsidyLog as Model;
|
||||
use Dcat\Admin\Repositories\EloquentRepository;
|
||||
|
||||
class DealerPurchaseSubsidyLog extends EloquentRepository
|
||||
{
|
||||
/**
|
||||
* Model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eloquentClass = Model::class;
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Services;
|
||||
|
||||
use App\Enums\DealerEarningStatus;
|
||||
use App\Enums\DealerManagerSubsidyStatus;
|
||||
use App\Enums\DealerManageSubsidyStatus;
|
||||
use App\Enums\DealerPurchaseSubsidyStatus;
|
||||
use App\Enums\DealerWalletAction;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\DealerChannelSubsidyLog;
|
||||
use App\Models\DealerEarning;
|
||||
use App\Models\DealerManagerSubsidy;
|
||||
use App\Models\DealerManageSubsidy;
|
||||
use App\Models\DealerPurchaseSubsidy;
|
||||
use App\Services\Dealer\WalletService;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
|
||||
class DealerEarningService
|
||||
{
|
||||
public function pay(DealerEarning $dealerEarning)
|
||||
{
|
||||
if (! $dealerEarning->isSettled()) {
|
||||
throw new BizException('经销商收益还未结算');
|
||||
}
|
||||
|
||||
if (! $dealerEarning->isPending()) {
|
||||
throw new BizException('经销商收益状态不是待付款');
|
||||
}
|
||||
|
||||
switch (Relation::getMorphedModel($dealerEarning->earningable_type)) {
|
||||
// 管理津贴
|
||||
case DealerManageSubsidy::class:
|
||||
if (! $dealerEarning->earningable->isPending()) {
|
||||
throw new BizException('管理津贴状态不是待付款');
|
||||
}
|
||||
|
||||
$dealerEarning->earningable->update([
|
||||
'status' => DealerManageSubsidyStatus::Completed,
|
||||
]);
|
||||
|
||||
(new WalletService())->changeBalance(
|
||||
$dealerEarning->user,
|
||||
$dealerEarning->total_earnings,
|
||||
DealerWalletAction::ManageSubsidyIn,
|
||||
'收入-管理津贴',
|
||||
$dealerEarning
|
||||
);
|
||||
break;
|
||||
|
||||
// 管理者津贴
|
||||
case DealerManagerSubsidy::class:
|
||||
if (! $dealerEarning->earningable->isPending()) {
|
||||
throw new BizException('管理者津贴状态不是待付款');
|
||||
}
|
||||
|
||||
$dealerEarning->earningable->update([
|
||||
'status' => DealerManagerSubsidyStatus::Completed,
|
||||
]);
|
||||
|
||||
(new WalletService())->changeBalance(
|
||||
$dealerEarning->user,
|
||||
$dealerEarning->total_earnings,
|
||||
DealerWalletAction::ManagerSubsidyIn,
|
||||
'收入-管理者津贴',
|
||||
$dealerEarning
|
||||
);
|
||||
break;
|
||||
|
||||
// 管理者津贴
|
||||
case DealerPurchaseSubsidy::class:
|
||||
if (! $dealerEarning->earningable->isPending()) {
|
||||
throw new BizException('进货补贴状态不是待付款');
|
||||
}
|
||||
|
||||
$dealerEarning->earningable->update([
|
||||
'status' => DealerPurchaseSubsidyStatus::Completed,
|
||||
]);
|
||||
|
||||
(new WalletService())->changeBalance(
|
||||
$dealerEarning->user,
|
||||
$dealerEarning->total_earnings,
|
||||
DealerWalletAction::PurchaseSubsidyIn,
|
||||
'收入-进货补贴',
|
||||
$dealerEarning
|
||||
);
|
||||
break;
|
||||
|
||||
case DealerChannelSubsidyLog::class:
|
||||
(new WalletService())->changeBalance(
|
||||
$dealerEarning->user,
|
||||
$dealerEarning->total_earnings,
|
||||
DealerWalletAction::ChannelSubsidyIn,
|
||||
'收入-渠道补贴',
|
||||
$dealerEarning
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new BizException('经销商收入异常');
|
||||
break;
|
||||
}
|
||||
|
||||
$dealerEarning->update([
|
||||
'pay_way' => DealerEarning::PAY_WAY_WALLET,
|
||||
'pay_at' => now(),
|
||||
'pay_info' => null,
|
||||
'status' => DealerEarningStatus::Completed,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use App\Admin\Extensions\Column\CircleDot;
|
||||
use App\Admin\Extensions\Column\Modal;
|
||||
use App\Admin\Extensions\Form\Product\SelectAttr;
|
||||
use App\Admin\Extensions\Form\Product\SelectSpec;
|
||||
|
|
@ -10,6 +11,7 @@ use Dcat\Admin\Form\Field\Editor;
|
|||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Grid\Column;
|
||||
use Dcat\Admin\Show\Field as ShowField;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
/**
|
||||
* Dcat-admin - admin builder based on Laravel.
|
||||
|
|
@ -33,6 +35,7 @@ use Dcat\Admin\Show\Field as ShowField;
|
|||
Admin::css('/dist/admin/css/app.css');
|
||||
|
||||
Column::extend('modal', Modal::class);
|
||||
Column::extend('circleDot', CircleDot::class);
|
||||
|
||||
Grid::resolving(function (Grid $grid) {
|
||||
$grid->disableRowSelector();
|
||||
|
|
@ -60,6 +63,27 @@ Editor::resolving(function (Editor $editor) {
|
|||
});
|
||||
|
||||
ShowField::extend('showLabel', Label::class);
|
||||
ShowField::macro('circleDot', function ($options = [], $default = 'default') {
|
||||
return $this->unescape()->prepend(function ($_, $original) use ($options, $default) {
|
||||
if (is_null($original)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$style = Arr::get(
|
||||
$options,
|
||||
$original instanceof UnitEnum
|
||||
? $original->value
|
||||
: $original,
|
||||
$default
|
||||
);
|
||||
|
||||
$style = $style === 'default' ? 'dark70' : $style;
|
||||
|
||||
$background = Admin::color()->get($style, $style);
|
||||
|
||||
return "<i class='fa fa-circle' style='font-size: 13px;color: {$background}'></i> ";
|
||||
});
|
||||
});
|
||||
|
||||
Admin::style(
|
||||
<<<'CSS'
|
||||
|
|
|
|||
|
|
@ -186,6 +186,9 @@ Route::group([
|
|||
$router->get('dealer-earnings-manager', 'DealerEarningController@index')->name('dealer_earnings.manager');
|
||||
$router->get('dealer-earnings-purchase', 'DealerEarningController@index')->name('dealer_earnings.purchase');
|
||||
|
||||
// 签约渠道补贴
|
||||
$router->get('dealer-channel-subsidies', 'DealerChannelSubsidyController@index')->name('dealer_channel_subsidies.index');
|
||||
|
||||
// 管理者津贴
|
||||
$router->get('dealer-manager-subsidies', 'DealerManagerSubsidyController@index')->name('dealer_manager_subsidies.index');
|
||||
$router->get('dealer-manager-sales-logs', 'DealerManagerSalesLogController@index')->name('dealer_manager_sales_logs.index');
|
||||
|
|
@ -194,6 +197,8 @@ Route::group([
|
|||
$router->get('dealer-manage-subsidies', 'DealerManageSubsidyController@index')->name('dealer_manage_subsidies.index');
|
||||
$router->get('dealer-manage-subsidy-logs', 'DealerManageSubsidyLogController@index')->name('dealer_manage_subsidy_logs.index');
|
||||
|
||||
$router->get('dealer-purchase-subsidies', 'DealerPurchaseSubsidyController@index')->name('dealer_purchase_subsidies.index');
|
||||
$router->get('dealer-purchase-subsidies/{dealer_purchase_subsidy}', 'DealerPurchaseSubsidyController@show')->name('dealer_purchase_subsidies.show');
|
||||
$router->get('dealer-purchase-logs', 'DealerPurchaseLogController@index')->name('dealer_purchase_logs.index');
|
||||
|
||||
//批零余额提现
|
||||
|
|
@ -202,6 +207,10 @@ Route::group([
|
|||
'index', 'show',
|
||||
])->names('dealer_wallet_to_bank_logs');
|
||||
|
||||
//
|
||||
$router->get('dealer-delivery-bills', 'DealerDeliveryBillController@index')->name('dealer_delivery_bills.index');
|
||||
$router->get('dealer-delivery-bills/{dealer_delivery_bill}', 'DealerDeliveryBillController@show')->name('dealer_delivery_bills.show');
|
||||
|
||||
/** api接口 **/
|
||||
$router->get('api/product-categories', 'ProductCategoryController@categories')->name('api.product_categories');
|
||||
$router->get('api/product-group-details', 'ProductGroupController@details')->name('api.product_group_details');
|
||||
|
|
|
|||
|
|
@ -11,4 +11,14 @@ class OrderStatus
|
|||
public const SHIPPED = 3; // 已发货/待收货
|
||||
public const COMPLETED = 9; // 已完成
|
||||
public const CANCELLED = 10; // 已取消
|
||||
|
||||
public static $statusTexts = [
|
||||
self::UNKNOWN => '其它',
|
||||
self::PENDING => '待付款',
|
||||
self::WAIT_SHIPPING => '待发货',
|
||||
self::SHIPPING => '发货中',
|
||||
self::SHIPPED => '待收货',
|
||||
self::COMPLETED => '已完成',
|
||||
self::CANCELLED => '已取消',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Filters;
|
||||
|
||||
use App\Enums\DealerDeliveryBillStatus;
|
||||
use EloquentFilter\ModelFilter;
|
||||
|
||||
class DealerDeliveryBillFilter extends ModelFilter
|
||||
{
|
||||
public function status($status)
|
||||
{
|
||||
switch ($status) {
|
||||
case 'pending':
|
||||
$this->where('status', DealerDeliveryBillStatus::Pending);
|
||||
break;
|
||||
|
||||
case 'paid':
|
||||
$this->where('status', DealerDeliveryBillStatus::Paid);
|
||||
break;
|
||||
|
||||
case 'cancelled':
|
||||
$this->where('status', DealerDeliveryBillStatus::Cancelled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,8 @@ class ConfigurationController extends Controller
|
|||
{
|
||||
return response()->json([
|
||||
'wxpay_switch' => app_settings('dealer.wxpay_switch', 0),
|
||||
'delivery_bill_shipping_fee' => app_settings('dealer.delivery_bill_shipping_fee', 0),
|
||||
'withdraw_fee_rate' => app_settings('dealer.withdraw_fee_rate', 0),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,178 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Http\Controllers\Dealer;
|
||||
|
||||
use App\Endpoint\Api\Http\Controllers\Controller;
|
||||
use App\Endpoint\Api\Http\Resources\Dealer\DealerDeliveryBillResource;
|
||||
use App\Enums\PayWay;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Exceptions\PayPasswordIncorrectException;
|
||||
use App\Helpers\Paginator;
|
||||
use App\Services\Dealer\DealerDeliveryBillService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
|
||||
class DealerDeliveryBillController extends Controller
|
||||
{
|
||||
/**
|
||||
* 提货单列表
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$perPage = Paginator::resolvePerPage('per_page', 20, 50);
|
||||
|
||||
$deliveryBills = $request->user()->dealerDeliveryBills()
|
||||
->filter($request->all())
|
||||
->latest('id')
|
||||
->simplePaginate($perPage);
|
||||
|
||||
return DealerDeliveryBillResource::collection($deliveryBills);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建提货单
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Services\Dealer\DealerDeliveryBillService $dealerDeliveryBillService
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function store(Request $request, DealerDeliveryBillService $dealerDeliveryBillService)
|
||||
{
|
||||
$input = $request->validate([
|
||||
'shipping_address_id' => ['bail', 'required'],
|
||||
'products' => ['bail', 'required', 'array'],
|
||||
'products.*.id' => ['bail', 'required', 'int'],
|
||||
'products.*.qty' => ['bail', 'required', 'int', 'min:1'],
|
||||
'remark' => ['bail', 'nullable', 'string', 'max:255'],
|
||||
], [], [
|
||||
'shipping_address_id' => '收货地址',
|
||||
'products' => '商品',
|
||||
'remark' => '备注',
|
||||
]);
|
||||
|
||||
$user = $request->user();
|
||||
|
||||
$shippingAddress = $user->shippingAddresses()->findOrFail($input['shipping_address_id']);
|
||||
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$deliveryBill = $dealerDeliveryBillService->create(
|
||||
$user,
|
||||
$input['products'],
|
||||
[
|
||||
'name' => $shippingAddress->consignee,
|
||||
'telephone' => $shippingAddress->telephone,
|
||||
'zone' => $shippingAddress->zone,
|
||||
'address' => $shippingAddress->address,
|
||||
],
|
||||
$input['remark'] ?? null
|
||||
);
|
||||
|
||||
DB::commit();
|
||||
} catch (Throwable $e) {
|
||||
DB::rollBack();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$deliveryBill->load(['deliveryProducts.product']);
|
||||
|
||||
return DealerDeliveryBillResource::make($deliveryBill);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提货单详情
|
||||
*
|
||||
* @param int $id
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function show($id, Request $request)
|
||||
{
|
||||
$deliveryBill = $request->user()->dealerDeliveryBills()->findOrFail($id);
|
||||
$deliveryBill->load(['deliveryProducts.product']);
|
||||
|
||||
return DealerDeliveryBillResource::make($deliveryBill);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提货单支付
|
||||
*
|
||||
* @param int $id
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Services\Dealer\DealerDeliveryBillService $dealerDeliveryBillService
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function pay($id, Request $request, DealerDeliveryBillService $dealerDeliveryBillService)
|
||||
{
|
||||
$input = $request->validate([
|
||||
'pay_way' => ['bail', 'required', 'string'],
|
||||
'pay_password' => ['bail', 'required_if:pay_way,wallet'],
|
||||
'products'=> ['array'],
|
||||
], [
|
||||
'pay_password.required_if' => '支付密码 不能为空。',
|
||||
], [
|
||||
'pay_way' => '支付方式',
|
||||
'pay_password' => '支付密码',
|
||||
]);
|
||||
|
||||
$payWay = PayWay::tryFrom($input['pay_way']);
|
||||
|
||||
if (! in_array($payWay, [PayWay::Wallet, PayWay::WxpayH5, PayWay::WxpayJsApi])) {
|
||||
throw new BizException('支付方式 非法');
|
||||
}
|
||||
|
||||
$user = $request->user();
|
||||
|
||||
$deliveryBill = $user->dealerDeliveryBills()->findOrFail($id);
|
||||
|
||||
if ($payWay === PayWay::Wallet && !$user->wallet?->verifyPassword($input['pay_password'])) {
|
||||
throw new PayPasswordIncorrectException();
|
||||
}
|
||||
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$data = $dealerDeliveryBillService->pay($deliveryBill, $payWay);
|
||||
|
||||
DB::commit();
|
||||
} catch (BizException $e) {
|
||||
DB::rollBack();
|
||||
|
||||
throw $e;
|
||||
} catch (Throwable $e) {
|
||||
DB::rollBack();
|
||||
|
||||
report($e);
|
||||
|
||||
throw new BizException('支付失败,请重试');
|
||||
}
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消提货单
|
||||
*
|
||||
* @param int $id
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function cancel($id, Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
DB::transaction(function () use ($id, $user) {
|
||||
(new DealerDeliveryBillService())->cancel(
|
||||
$user->dealerDeliveryBills()->lockForUpdate()->findOrFail($id)
|
||||
);
|
||||
});
|
||||
|
||||
return response()->noContent();
|
||||
}
|
||||
}
|
||||
|
|
@ -5,11 +5,13 @@ namespace App\Endpoint\Api\Http\Controllers\Dealer;
|
|||
use App\Endpoint\Api\Http\Controllers\Controller;
|
||||
use App\Endpoint\Api\Http\Resources\Dealer\OrderResource;
|
||||
use App\Endpoint\Api\Http\Resources\Dealer\OrderSimpleResource;
|
||||
use App\Enums\DealerLvl;
|
||||
use App\Enums\PayWay;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Exceptions\PayPasswordIncorrectException;
|
||||
use App\Helpers\Paginator as PaginatorHelper;
|
||||
use App\Models\DealerOrder;
|
||||
use App\Models\DealerOrderProduct;
|
||||
use App\Models\DealerProduct;
|
||||
use App\Services\Dealer\OrderService;
|
||||
use Illuminate\Database\QueryException;
|
||||
|
|
@ -217,6 +219,7 @@ class OrderController extends Controller
|
|||
'pay_image' => ['bail', 'string'],
|
||||
'pay_way' => ['bail', 'string'],
|
||||
'pay_password' => ['bail', 'required_if:pay_way,wallet'],
|
||||
'products'=> ['array'],
|
||||
], [
|
||||
'pay_password.required_if' => '支付密码 不能为空。',
|
||||
], [
|
||||
|
|
@ -224,10 +227,9 @@ class OrderController extends Controller
|
|||
'pay_way' => '支付方式',
|
||||
'pay_password' => '支付密码',
|
||||
]);
|
||||
|
||||
$payWay = PayWay::tryFrom($input['pay_way'] ?? 'offline');
|
||||
|
||||
if (! in_array($payWay, [PayWay::Offline, PayWay::Wallet, PayWay::WxpayH5])) {
|
||||
if (! in_array($payWay, [PayWay::Offline, PayWay::Wallet, PayWay::WxpayH5, PayWay::WxpayJsApi])) {
|
||||
throw new BizException('支付方式 非法');
|
||||
}
|
||||
|
||||
|
|
@ -244,6 +246,7 @@ class OrderController extends Controller
|
|||
break;
|
||||
|
||||
case PayWay::WxpayH5:
|
||||
case PayWay::WxpayJsApi:
|
||||
if ($order->consignor !== null) {
|
||||
throw new BizException('订单不是签约订单');
|
||||
}
|
||||
|
|
@ -254,6 +257,29 @@ class OrderController extends Controller
|
|||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
|
||||
//签约单-处理云库存
|
||||
if ($order->consignor === null) {
|
||||
//处理云库存设置,如果没有设置则默认云仓库为0。
|
||||
$products = $input['products'] ?? [];
|
||||
if ($products) {
|
||||
$num = 0;
|
||||
foreach ($order->products as $product) {
|
||||
//更新云库存
|
||||
if (isset($products[$product->id]) && ($product->qty + $product->deposit_qty) >= $products[$product->id]) {
|
||||
DealerOrderProduct::where('id', $product->id)->update([
|
||||
'qty' => $products[$product->id],
|
||||
'deposit_qty' =>($product->qty + $product->deposit_qty) - $products[$product->id],
|
||||
]);
|
||||
$num += $products[$product->id];
|
||||
}
|
||||
}
|
||||
if ($num < 20) {
|
||||
throw new BizException('首次发货最少20盒');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$data = $orderService->pay($order, $payWay, $input['pay_image'] ?? null);
|
||||
|
||||
DB::commit();
|
||||
|
|
@ -273,7 +299,7 @@ class OrderController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* 确认收款+发货
|
||||
* 确认收款
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
|
@ -288,7 +314,8 @@ class OrderController extends Controller
|
|||
try {
|
||||
DB::beginTransaction();
|
||||
$orderService->paidOrder($order);//确认收款
|
||||
$orderService->shippingOrder($order);//确认发货
|
||||
//3-14号取消确认收款后自动发货
|
||||
// $orderService->shippingOrder($order);//确认发货
|
||||
DB::commit();
|
||||
} catch (QueryException $e) {
|
||||
DB::rollBack();
|
||||
|
|
@ -315,15 +342,32 @@ class OrderController extends Controller
|
|||
public function shippingOrder($id, Request $request, OrderService $orderService)
|
||||
{
|
||||
$order = DealerOrder::findOrFail($id);
|
||||
$userId = $request->user()->id;
|
||||
$user = $request->user();
|
||||
//不是发货人
|
||||
if (!$order->isConsignor($userId)) {
|
||||
if (!$order->isConsignor($user->id)) {
|
||||
throw new BizException('订单未找到');
|
||||
}
|
||||
$deliveryBill = null;
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$orderService->shippingOrder($order);//确认发货
|
||||
//如果发货人是签约经销商, 则可以使用云仓库发货
|
||||
if ($user->dealer->lvl?->value >= DealerLvl::Contracted->value) {
|
||||
$deliveryBill = $orderService->shippingOrderByDeposit($order);
|
||||
if ($deliveryBill) {
|
||||
$order->refresh();
|
||||
//扣除本地库存
|
||||
$orderService->orderOutQty($order);
|
||||
} else {
|
||||
$orderService->shippingOrder($order);//确认发货
|
||||
}
|
||||
} else {
|
||||
$orderService->shippingOrder($order);//确认发货
|
||||
}
|
||||
DB::commit();
|
||||
} catch (BizException $e) {
|
||||
DB::rollBack();
|
||||
$e = new BizException($e->getMessage());
|
||||
throw $e;
|
||||
} catch (QueryException $e) {
|
||||
DB::rollBack();
|
||||
if (strpos($e->getMessage(), 'Numeric value out of range') !== false) {
|
||||
|
|
@ -335,7 +379,10 @@ class OrderController extends Controller
|
|||
report($th);
|
||||
throw new BizException('操作失败,请刷新后再试');
|
||||
}
|
||||
return response()->noContent();
|
||||
|
||||
return response()->json([
|
||||
'delivery_bill_id'=>$deliveryBill?->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -346,9 +393,9 @@ class OrderController extends Controller
|
|||
public function shippingedOrder($id, Request $request, OrderService $orderService)
|
||||
{
|
||||
$order = DealerOrder::findOrFail($id);
|
||||
$userId = $request->user()->id;
|
||||
$user = $request->user();
|
||||
//不是收货人
|
||||
if (!$order->isUser($userId)) {
|
||||
if (!$order->isUser($user->id)) {
|
||||
throw new BizException('订单未找到');
|
||||
}
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class UserProductController extends Controller
|
|||
{
|
||||
$list = $request->user()->dealerProductLogs()->filter($request->all())
|
||||
->with('product')
|
||||
->orderBy('created_at', 'desc')
|
||||
->orderBy('id', 'desc')
|
||||
->simplePaginate(Paginator::resolvePerPage('per_page', 20, 50));
|
||||
return UserProductLogResource::collection($list);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,4 +20,17 @@ class SettingController extends Controller
|
|||
'withdraw'=>app_settings('withdraw'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function custom(Request $request)
|
||||
{
|
||||
$keys = (array) $request->input('keys');
|
||||
$custom = app_settings('custom.key_value');
|
||||
$keyValue = [];
|
||||
foreach ($keys as $key) {
|
||||
$keyValue[$key] = $custom[$key] ?? '';
|
||||
}
|
||||
return response()->json([
|
||||
'values'=>$keyValue,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Http\Resources\Dealer;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class DealerDeliveryBillResource 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,
|
||||
'sn' => $this->sn,
|
||||
'shipping_fee' => $this->shipping_fee,
|
||||
'remark' => $this->remark,
|
||||
'consignee_name' => $this->consignee_name,
|
||||
'consignee_telephone' => $this->consignee_telephone,
|
||||
'consignee_zone' => $this->consignee_zone,
|
||||
'consignee_address' => $this->consignee_address,
|
||||
'delivery_products' => DealerDeliveryProductResource::collection($this->whenLoaded('deliveryProducts')),
|
||||
'pay_sn' => $this->pay_sn,
|
||||
'pay_way' => $this->pay_way,
|
||||
'pay_at' => $this->pay_at?->toDateTimeString(),
|
||||
'status' => $this->status,
|
||||
'created_at' => $this->created_at->toDateTimeString(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Endpoint\Api\Http\Resources\Dealer;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class DealerDeliveryProductResource 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->product->id,
|
||||
'name' => $this->product->name,
|
||||
'cover' => $this->product->cover,
|
||||
'qty' => $this->qty,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -15,11 +15,13 @@ class OrderProductResource extends JsonResource
|
|||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'cover'=> $this->cover,
|
||||
'price'=>$this->price,
|
||||
'sale_price' =>$this->sale_price,
|
||||
'qty' =>$this->qty,
|
||||
'deposit_qty'=> $this->deposit_qty,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Endpoint\Api\Http\Resources\Dealer;
|
||||
|
||||
use App\Models\DealerUserProductLog;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class UserProductLogResource extends JsonResource
|
||||
|
|
@ -19,11 +18,8 @@ class UserProductLogResource extends JsonResource
|
|||
'id' => $this->id,
|
||||
'product_name'=> $this->product?->name,
|
||||
'remark' => $this->remark,
|
||||
'qty' => (in_array($this->type, [
|
||||
DealerUserProductLog::TYPE_ORDER_IN,
|
||||
DealerUserProductLog::TYPE_ADMIN_IN,
|
||||
DealerUserProductLog::TYPE_REVOKE_IN,
|
||||
]) ? '+' : '-').$this->qty.$this->product?->unit,
|
||||
'is_deposit' => $this->is_deposit,
|
||||
'qty' => $this->qty_format.$this->product?->unit,
|
||||
'created_at' => $this->created_at->toDateTimeString(),
|
||||
'can_revoke' => $this->canRevoke(),
|
||||
];
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ class UserProductResource extends JsonResource
|
|||
'cover' => (string) $this->product?->cover,
|
||||
'price' => (string) $this->product?->price,
|
||||
'stock' => (int) $this->stock,
|
||||
'deposit_stock'=> (int) $this->deposit_stock,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ Route::group([
|
|||
|
||||
//获取配置
|
||||
Route::get('configs', [SettingController::class, 'index']);
|
||||
Route::get('configs-custom', [SettingController::class, 'custom']);
|
||||
|
||||
//三方登录聚合
|
||||
Route::group([
|
||||
|
|
@ -299,5 +300,12 @@ Route::group([
|
|||
Route::get('purchase-subsidies', [Dealer\PurchaseSubsidyController::class, 'index']);
|
||||
// 进货补贴流水
|
||||
Route::get('purchase-subsidies/{purchase_subsidy}/logs', [Dealer\PurchaseSubsidyLogController::class, 'index']);
|
||||
|
||||
// 云仓库
|
||||
Route::get('delivery-bills', [Dealer\DealerDeliveryBillController::class, 'index']);
|
||||
Route::post('delivery-bills', [Dealer\DealerDeliveryBillController::class, 'store']);
|
||||
Route::get('delivery-bills/{delivery_bill}', [Dealer\DealerDeliveryBillController::class, 'show']);
|
||||
Route::post('delivery-bills/{delivery_bill}/pay', [Dealer\DealerDeliveryBillController::class, 'pay']);
|
||||
Route::post('delivery-bills/{delivery_bill}/cancel', [Dealer\DealerDeliveryBillController::class, 'cancel']);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum DealerDeliveryBillStatus: int {
|
||||
case Pending = 0; // 待付款
|
||||
case Paid = 1; // 已付款
|
||||
case Cancelled = 10; // 已取消
|
||||
|
||||
public function text()
|
||||
{
|
||||
return static::texts()[$this->value];
|
||||
}
|
||||
|
||||
public static function colors()
|
||||
{
|
||||
return [
|
||||
static::Pending->value => '#5b69bc',
|
||||
static::Paid->value => '#21b978',
|
||||
static::Cancelled->value => '#b3b9bf',
|
||||
];
|
||||
}
|
||||
|
||||
public static function texts()
|
||||
{
|
||||
return [
|
||||
static::Pending->value => '待付款',
|
||||
static::Paid->value => '已付款',
|
||||
static::Cancelled->value => '已取消',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -7,15 +7,31 @@ enum DealerEarningStatus: int {
|
|||
case Paid = 1;//已打款
|
||||
case Completed = 5;//已完成
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function color()
|
||||
{
|
||||
return static::colors()[$this->value] ?? '#5b69bc';
|
||||
}
|
||||
|
||||
public function text()
|
||||
{
|
||||
return match ($this) {
|
||||
static::Pending => '待打款',
|
||||
static::Paid => '待收款',
|
||||
static::Completed => '已完成',
|
||||
};
|
||||
return static::texts()[$this->value];
|
||||
}
|
||||
|
||||
public static function colors()
|
||||
{
|
||||
return [
|
||||
static::Pending->value => '#5b69bc',
|
||||
static::Paid->value => '#3085d6',
|
||||
static::Completed->value => '#21b978',
|
||||
];
|
||||
}
|
||||
|
||||
public static function texts()
|
||||
{
|
||||
return [
|
||||
static::Pending->value => '待打款',
|
||||
static::Paid->value => '待收款',
|
||||
static::Completed->value => '已完成',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,19 +6,19 @@ enum DealerManageSubsidyStatus: int {
|
|||
case Pending = 0;
|
||||
case Completed = 5;
|
||||
|
||||
public function color(): string
|
||||
{
|
||||
return match ($this) {
|
||||
static::Pending => '#5b69bc',
|
||||
static::Completed => '#21b978',
|
||||
};
|
||||
}
|
||||
|
||||
public function text(): string
|
||||
{
|
||||
return static::texts()[$this->value] ?? 'Unknown';
|
||||
}
|
||||
|
||||
public static function colors(): array
|
||||
{
|
||||
return [
|
||||
static::Pending->value => '#5b69bc',
|
||||
static::Completed->value => '#21b978',
|
||||
];
|
||||
}
|
||||
|
||||
public static function texts(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -19,6 +19,14 @@ enum DealerManagerSubsidyStatus: int {
|
|||
return static::texts()[$this->value] ?? 'Unknown';
|
||||
}
|
||||
|
||||
public static function colors(): array
|
||||
{
|
||||
return [
|
||||
static::Pending->value => '#5b69bc',
|
||||
static::Completed->value => '#21b978',
|
||||
];
|
||||
}
|
||||
|
||||
public static function texts(): array
|
||||
{
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -5,4 +5,25 @@ namespace App\Enums;
|
|||
enum DealerPurchaseSubsidyStatus: int {
|
||||
case Pending = 0;
|
||||
case Completed = 5;
|
||||
|
||||
public function text(): string
|
||||
{
|
||||
return static::texts()[$this->value] ?? 'Unknown';
|
||||
}
|
||||
|
||||
public static function colors(): array
|
||||
{
|
||||
return [
|
||||
static::Pending->value => '#5b69bc',
|
||||
static::Completed->value => '#21b978',
|
||||
];
|
||||
}
|
||||
|
||||
public static function texts(): array
|
||||
{
|
||||
return [
|
||||
static::Pending->value => '待付款',
|
||||
static::Completed->value => '已完成',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,4 +15,5 @@ enum DealerWalletAction: int {
|
|||
case TransferOut = 10;
|
||||
case EarningIn = 11;
|
||||
case EarningOut = 12;
|
||||
case DeliveryBillPaid = 13;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ enum PayWay: string {
|
|||
};
|
||||
}
|
||||
|
||||
public function getMallOrderText()
|
||||
public function mallText()
|
||||
{
|
||||
return match ($this) {
|
||||
static::Offline => '线下',
|
||||
|
|
@ -49,25 +49,40 @@ enum PayWay: string {
|
|||
};
|
||||
}
|
||||
|
||||
public function getDealerOrderText()
|
||||
/**
|
||||
* 支付方式文本
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function text(): string
|
||||
{
|
||||
return match ($this) {
|
||||
static::Offline => '线下打款',
|
||||
static::Wallet => '余额支付',
|
||||
static::WxpayH5 => '微信支付',
|
||||
default => 'Unknown',
|
||||
static::Offline => '线下',
|
||||
static::Balance => '余额',
|
||||
static::Wallet => '钱包',
|
||||
static::WxpayApp, static::WxpayH5, static::WxpayJsApi, static::WxpayMiniProgram => '微信支付',
|
||||
static::AlipayApp => '支付宝',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* 支付方式对应的颜色
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function dealerOrderTexts(): array
|
||||
public static function colors(): array
|
||||
{
|
||||
return [
|
||||
static::Offline->value => '线下打款',
|
||||
static::Wallet->value => '余额支付',
|
||||
static::WxpayH5->value => '微信支付',
|
||||
static::Offline->value => '#5b69bc',
|
||||
static::Balance->value => '#dda451',
|
||||
static::Wallet->value => '#ff8acc',
|
||||
// 微信支付
|
||||
static::WxpayApp->value => '#21b978',
|
||||
static::WxpayH5->value => '#21b978',
|
||||
static::WxpayJsApi->value => '#21b978',
|
||||
static::WxpayMiniProgram->value => '#21b978',
|
||||
// 支付宝
|
||||
static::AlipayApp->value => '#3085d6',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -355,7 +355,8 @@ class Dealer extends Model
|
|||
|
||||
public function canWithdraw()
|
||||
{
|
||||
$days = app_settings('dealer.withdraw_days', 7);
|
||||
return DealerWalletToBankLog::where('user_id', $this->user_id)->where('created_at', '>', now()->subDays($days))->doesntExist();
|
||||
return true;
|
||||
// $days = app_settings('dealer.withdraw_days', 7);
|
||||
// return DealerWalletToBankLog::where('user_id', $this->user_id)->where('created_at', '>', now()->subDays($days))->doesntExist();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\DealerDeliveryBillStatus;
|
||||
use App\Enums\PayWay;
|
||||
use EloquentFilter\Filterable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class DealerDeliveryBill extends Model
|
||||
{
|
||||
use Filterable;
|
||||
|
||||
protected $attributes = [
|
||||
'status' => DealerDeliveryBillStatus::Pending,
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'status' => DealerDeliveryBillStatus::class,
|
||||
'pay_way' => PayWay::class,
|
||||
'pay_at' => 'datetime',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'sn',
|
||||
'user_id',
|
||||
'order_id',
|
||||
'shipping_fee',
|
||||
'remark',
|
||||
'consignee_name',
|
||||
'consignee_telephone',
|
||||
'consignee_zone',
|
||||
'consignee_address',
|
||||
'pay_sn',
|
||||
'pay_way',
|
||||
'out_trade_no',
|
||||
'pay_at',
|
||||
'status',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
parent::creating(function ($bill) {
|
||||
if ($bill->sn === null) {
|
||||
do {
|
||||
$bill->sn = serial_number();
|
||||
} while (static::where('sn', $bill->sn)->exists());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->hasOne(DealerOrder::class, 'order_id');
|
||||
}
|
||||
|
||||
public function payLogs()
|
||||
{
|
||||
return $this->morphMany(PayLog::class, 'payable');
|
||||
}
|
||||
|
||||
public function deliveryProducts()
|
||||
{
|
||||
return $this->hasMany(DealerDeliveryProduct::class, 'delivery_bill_id');
|
||||
}
|
||||
|
||||
public function isPending()
|
||||
{
|
||||
return $this->status === DealerDeliveryBillStatus::Pending;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class DealerDeliveryProduct extends Model
|
||||
{
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo(DealerProduct::class, 'product_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -68,6 +68,28 @@ class DealerEarning extends Model
|
|||
return $this->morphTo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅查询渠道补贴收益
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeWithoutPayer($query)
|
||||
{
|
||||
return $query->whereNull('payer_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅查询渠道补贴收益
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeChannelSubsidy($query)
|
||||
{
|
||||
return $query->where('earningable_type', (new DealerChannelSubsidyLog())->getMorphClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* 待打款
|
||||
*
|
||||
|
|
@ -92,6 +114,16 @@ class DealerEarning extends Model
|
|||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认此收益是否结算
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isSettled(): bool
|
||||
{
|
||||
return $this->settle_at !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 待打款状态
|
||||
*
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ class DealerOrder extends Model
|
|||
'remark',
|
||||
'pay_sn',
|
||||
'out_trade_no',
|
||||
'local_status',
|
||||
'deposit_status',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -126,6 +128,11 @@ class DealerOrder extends Model
|
|||
return $query->where('status', DealerOrderStatus::Cancelled);
|
||||
}
|
||||
|
||||
public function dealerDeliveryBill()
|
||||
{
|
||||
return $this->belongsTo(DealerDeliveryBill::class, 'order_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 此订单所属的用户的信息
|
||||
*/
|
||||
|
|
@ -277,6 +284,7 @@ class DealerOrder extends Model
|
|||
{
|
||||
return in_array($this->pay_way, [
|
||||
PayWay::WxpayH5,
|
||||
PayWay::WxpayJsApi,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class DealerOrderProduct extends Model
|
|||
'price',
|
||||
'sale_price',
|
||||
'qty',
|
||||
'deposit_qty',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -49,6 +49,11 @@ class DealerPurchaseSubsidy extends Model
|
|||
return $query->where('settle_state', DealerPurchaseSubsidySettleState::Completed);
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function dealer()
|
||||
{
|
||||
return $this->belongsTo(Dealer::class, 'user_id', 'user_id');
|
||||
|
|
@ -64,8 +69,20 @@ class DealerPurchaseSubsidy extends Model
|
|||
return $this->morphOne(DealerEarning::class, 'earningable');
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅查询待付款的管理津贴
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPending(): bool
|
||||
{
|
||||
return $this->settle_state === DealerPurchaseSubsidySettleState::Completed
|
||||
&& $this->status === DealerPurchaseSubsidyStatus::Pending;
|
||||
}
|
||||
|
||||
public function isCompleted()
|
||||
{
|
||||
return $this->status === DealerPurchaseSubsidyStatus::Completed;
|
||||
return $this->settle_state === DealerPurchaseSubsidySettleState::Completed
|
||||
&& $this->status === DealerPurchaseSubsidyStatus::Completed;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,16 @@ class DealerUserProduct extends Model
|
|||
use HasFactory;
|
||||
use HasDateTimeFormatter;
|
||||
|
||||
protected $attributes = [
|
||||
'stock' => 0,
|
||||
'deposit_stock' => 0,
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'product_id',
|
||||
'stock',
|
||||
'deposit_stock',
|
||||
];
|
||||
|
||||
public function product()
|
||||
|
|
|
|||
|
|
@ -13,12 +13,27 @@ class DealerUserProductLog extends Model
|
|||
use Filterable;
|
||||
use HasDateTimeFormatter;
|
||||
|
||||
// 本地库存
|
||||
public const TYPE_ORDER_IN = 1; //采购加库存
|
||||
public const TYPE_ORDER_OUT = 2; //发货扣库存
|
||||
public const TYPE_OFFLINE_OUT = 3;//线下去库存
|
||||
public const TYPE_ADMIN_IN = 4;//后台添加库存
|
||||
public const TYPE_ADMIN_OUT = 5;//后台扣减库存
|
||||
public const TYPE_REVOKE_IN = 9;//撤销线下去库存
|
||||
public const TYPE_OFFLINE_OUT = 3; //线下去库存
|
||||
public const TYPE_ADMIN_IN = 4; //后台添加库存
|
||||
public const TYPE_ADMIN_OUT = 5; //后台扣减库存
|
||||
public const TYPE_REVOKE_IN = 9; //撤销线下去库存
|
||||
public const TYPE_TRANSFER_IN = 6; // 云库存转本地库存
|
||||
|
||||
// 云库存
|
||||
public const TYPE_DEPOSIT_TRANSFER_OUT = 10; // 云库存转本地库存
|
||||
public const TYPE_DEPOSIT_TRANSFER_REVOKE = 11; // 撤销云库存转本地库存
|
||||
public const TYPE_ORDER_OUT_REVOKE = 12;//撤销发货扣库存
|
||||
|
||||
protected $attributes = [
|
||||
'is_deposit' => false,
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_deposit' => 'bool',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
|
|
@ -27,6 +42,7 @@ class DealerUserProductLog extends Model
|
|||
'qty',
|
||||
'remark',
|
||||
'revoke_id',
|
||||
'is_deposit',
|
||||
];
|
||||
|
||||
public function product()
|
||||
|
|
@ -38,4 +54,18 @@ class DealerUserProductLog extends Model
|
|||
{
|
||||
return ($this->type == static::TYPE_OFFLINE_OUT) && ($this->revoke_id == 0);
|
||||
}
|
||||
|
||||
public function getQtyFormatAttribute()
|
||||
{
|
||||
$symbok = in_array($this->type, [
|
||||
DealerUserProductLog::TYPE_ORDER_IN,
|
||||
DealerUserProductLog::TYPE_ADMIN_IN,
|
||||
DealerUserProductLog::TYPE_REVOKE_IN,
|
||||
DealerUserProductLog::TYPE_TRANSFER_IN,
|
||||
DealerUserProductLog::TYPE_DEPOSIT_TRANSFER_REVOKE,
|
||||
DealerUserProductLog::TYPE_ORDER_OUT_REVOKE,
|
||||
]) ? '+' : '-';
|
||||
|
||||
return $symbok . $this->attributes['qty'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -417,4 +417,14 @@ class Order extends Model
|
|||
// 其它
|
||||
return OrderStatus::UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单状态
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOrderStatusTextAttribute(): string
|
||||
{
|
||||
return OrderStatus::$statusTexts[$this->order_status] ?? OrderStatus::$statusTexts[OrderStatus::UNKNOWN];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,20 @@ class PayLog extends Model
|
|||
'failed_reason',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
parent::creating(function ($payLog) {
|
||||
if ($payLog->pay_sn === null) {
|
||||
do {
|
||||
$payLog->pay_sn = serial_number();
|
||||
} while (static::where('pay_sn', $payLog->pay_sn)->exists());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付记录所属的模型
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -197,6 +197,15 @@ class User extends Model implements AuthorizableContract, AuthenticatableContrac
|
|||
return $this->hasMany(DealerOrder::class, 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 经销商提货单
|
||||
*
|
||||
*/
|
||||
public function dealerDeliveryBills()
|
||||
{
|
||||
return $this->hasMany(DealerDeliveryBill::class, 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 经销商的发货订单
|
||||
*
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ class AppServiceProvider extends ServiceProvider
|
|||
'dealer_wallet_to_bank_log' => \App\Models\DealerWalletToBankLog::class,
|
||||
'dealer_earnings'=> \App\Models\DealerEarning::class,
|
||||
'dealer_wallet_log'=> \App\Models\DealerWalletLog::class,
|
||||
'dealer_delivery_bill'=> \App\Models\DealerDeliveryBill::class,
|
||||
]);
|
||||
|
||||
JsonResource::withoutWrapping();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,259 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Dealer;
|
||||
|
||||
use App\Enums\DealerDeliveryBillStatus;
|
||||
use App\Enums\DealerWalletAction;
|
||||
use App\Enums\PayWay;
|
||||
use App\Enums\WxpayTradeType;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\DealerDeliveryBill;
|
||||
use App\Models\DealerDeliveryProduct;
|
||||
use App\Models\DealerOrder;
|
||||
use App\Models\DealerOrderProduct;
|
||||
use App\Models\DealerProduct;
|
||||
use App\Models\DealerUserProduct;
|
||||
use App\Models\DealerUserProductLog;
|
||||
use App\Models\PayLog;
|
||||
use App\Models\User;
|
||||
use App\Services\Payment\WxpayService;
|
||||
use App\Services\PayService;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class DealerDeliveryBillService
|
||||
{
|
||||
/**
|
||||
* 创建提货单
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param array $deliveryProducts
|
||||
* @param array $consignee
|
||||
* @param string|null $remark
|
||||
* @param int|null $DealerOrder
|
||||
* @return \App\Models\DealerDeliveryBill
|
||||
*/
|
||||
public function create(User $user, array $deliveryProducts, array $consignee, ?string $remark = null, ?DealerOrder $dealerOrder = null): DealerDeliveryBill
|
||||
{
|
||||
$deliveryProductIds = Arr::pluck($deliveryProducts, 'id');
|
||||
|
||||
// 批零商品
|
||||
$products = DealerProduct::findMany($deliveryProductIds);
|
||||
|
||||
if (count($deliveryProducts) !== $products->count()) {
|
||||
throw new BizException('提货单商品已丢失');
|
||||
}
|
||||
|
||||
// 经销商的商品库存
|
||||
$dealerProducts = $user->dealerProducts()
|
||||
->whereIn('product_id', $deliveryProductIds)
|
||||
->get();
|
||||
|
||||
// 创建提货单
|
||||
$deliveryBill = DealerDeliveryBill::create([
|
||||
'user_id' => $user->id,
|
||||
'shipping_fee' => app_settings('dealer.delivery_bill_shipping_fee', 0),
|
||||
'remark' => $remark,
|
||||
'consignee_name' => $consignee['name'],
|
||||
'consignee_telephone' => $consignee['telephone'],
|
||||
'consignee_zone' => $consignee['zone'],
|
||||
'consignee_address' => $consignee['address'],
|
||||
'status' => DealerDeliveryBillStatus::Pending,
|
||||
'order_id' => $dealerOrder?->id,
|
||||
]);
|
||||
|
||||
$mapProducts = $products->keyBy('id');
|
||||
$mapDealerProducts = $dealerProducts->keyBy('product_id');
|
||||
|
||||
$dealerProductLogs = [];
|
||||
$deliveryBillProducts = [];
|
||||
|
||||
foreach ($deliveryProducts as $deliveryProduct) {
|
||||
$product = Arr::get($mapProducts, $deliveryProduct['id']);
|
||||
$dealerProduct = Arr::get($mapDealerProducts, $product->id);
|
||||
|
||||
if ($dealerProduct?->deposit_stock < $deliveryProduct['qty']) {
|
||||
throw new BizException("{$product->name} 库存不足");
|
||||
}
|
||||
|
||||
$dealerProduct->decrement('deposit_stock', $deliveryProduct['qty']);
|
||||
|
||||
$dealerProductLogs[] = [
|
||||
'user_id' => $dealerProduct->user_id,
|
||||
'product_id' => $dealerProduct->product_id,
|
||||
'type' => DealerUserProductLog::TYPE_DEPOSIT_TRANSFER_OUT,
|
||||
'qty' => $deliveryProduct['qty'],
|
||||
'remark' => "提货单【{$deliveryBill->sn}】",
|
||||
'is_deposit' => true,
|
||||
'created_at' => $deliveryBill->created_at,
|
||||
'updated_at' => $deliveryBill->updated_at,
|
||||
];
|
||||
|
||||
$deliveryBillProducts[] = [
|
||||
'delivery_bill_id' => $deliveryBill->id,
|
||||
'product_id' => $product->id,
|
||||
'qty' => $deliveryProduct['qty'],
|
||||
'created_at' => $deliveryBill->created_at,
|
||||
'updated_at' => $deliveryBill->updated_at,
|
||||
];
|
||||
}
|
||||
|
||||
DealerUserProductLog::insert($dealerProductLogs);
|
||||
|
||||
DealerDeliveryProduct::insert($deliveryBillProducts);
|
||||
|
||||
return $deliveryBill;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提货单付款
|
||||
*
|
||||
* @param \App\Models\DealerDeliveryBill $deliveryBill
|
||||
* @param \App\Enums\PayWay $payWay
|
||||
* @return array
|
||||
*
|
||||
* @throws \App\Exceptions\BizException
|
||||
*/
|
||||
public function pay(DealerDeliveryBill $deliveryBill, PayWay $payWay): array
|
||||
{
|
||||
if (! $deliveryBill->isPending()) {
|
||||
throw new BizException('提货单状态不是待付款');
|
||||
}
|
||||
|
||||
$method = match ($payWay) {
|
||||
PayWay::Wallet => 'payUsingWallet',
|
||||
PayWay::WxpayH5, PayWay::WxpayJsApi => 'payUsingWxpay',
|
||||
default => 'payUsingDefault',
|
||||
};
|
||||
|
||||
if (! method_exists($this, $method)) {
|
||||
throw new BizException('交易非法');
|
||||
}
|
||||
|
||||
$payLog = $deliveryBill->payLogs()->create([
|
||||
'pay_way' => $payWay,
|
||||
]);
|
||||
|
||||
return [
|
||||
'pay_way' => $payLog->pay_way,
|
||||
'data' => $this->{$method}($deliveryBill, $payLog),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消提货单
|
||||
*
|
||||
* @param DealerDeliveryBill $deliveryBill
|
||||
* @return void
|
||||
*/
|
||||
public function cancel(DealerDeliveryBill $deliveryBill)
|
||||
{
|
||||
if (! $deliveryBill->isPending()) {
|
||||
throw new BizException('提货单状态不是待付款');
|
||||
}
|
||||
|
||||
$deliveryBill->update([
|
||||
'status' => DealerDeliveryBillStatus::Cancelled,
|
||||
]);
|
||||
|
||||
$dealerProductLogs = [];
|
||||
|
||||
foreach ($deliveryBill->deliveryProducts as $deliveryProduct) {
|
||||
DealerUserProduct::where([
|
||||
'user_id' => $deliveryBill->user_id,
|
||||
'product_id' => $deliveryProduct->product_id,
|
||||
])->update([
|
||||
'deposit_stock' => DB::raw("deposit_stock + {$deliveryProduct->qty}"),
|
||||
]);
|
||||
|
||||
$dealerProductLogs[] = [
|
||||
'user_id' => $deliveryBill->user_id,
|
||||
'product_id' => $deliveryProduct->product_id,
|
||||
'type' => DealerUserProductLog::TYPE_DEPOSIT_TRANSFER_REVOKE,
|
||||
'qty' => $deliveryProduct->qty,
|
||||
'remark' => "撤销提货单【{$deliveryBill->sn}】",
|
||||
'is_deposit' => true,
|
||||
'created_at' => $deliveryBill->updated_at,
|
||||
'updated_at' => $deliveryBill->updated_at,
|
||||
];
|
||||
}
|
||||
|
||||
//撤回已发货的本地库存
|
||||
if ($deliveryBill->order_id) {
|
||||
$dealerOrder = DealerOrder::with('products')->find($deliveryBill->order_id);
|
||||
foreach ($dealerOrder->products as $product) {
|
||||
if ($product->qty > 0 && $dealerOrder->local_status == 1) {
|
||||
$userProduct = $dealerOrder->consignor->dealerProducts()->firstOrCreate([
|
||||
'product_id'=> $product->product_id,
|
||||
]);
|
||||
$userProduct->increment('stock', $product->qty);
|
||||
$dealerProductLogs[] = [
|
||||
'user_id' => $dealerOrder->consignor_id,
|
||||
'product_id' => $product->product_id,
|
||||
'type' => DealerUserProductLog::TYPE_ORDER_OUT_REVOKE,
|
||||
'qty' => $product->qty,
|
||||
'remark' => "撤销订单发货【{$dealerOrder->sn}】",
|
||||
'is_deposit' => false,
|
||||
'created_at' => $deliveryBill->updated_at,
|
||||
'updated_at' => $deliveryBill->updated_at,
|
||||
];
|
||||
}
|
||||
//将云仓发货的数量挪回来
|
||||
DealerOrderProduct::where('id', $product->id)->update([
|
||||
'qty' => $product->qty + $product->deposit_qty,
|
||||
'deposit_qty' => 0,
|
||||
]);
|
||||
}
|
||||
$dealerOrder->update([
|
||||
'local_status'=>0,
|
||||
]);
|
||||
}
|
||||
|
||||
DealerUserProductLog::insert($dealerProductLogs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用余额支付
|
||||
*
|
||||
* @param \App\Models\DealerDeliveryBill $deliveryBill
|
||||
* @param \App\Models\PayLog $payLog
|
||||
* @return void
|
||||
*/
|
||||
protected function payUsingWallet(DealerDeliveryBill $deliveryBill, PayLog $payLog)
|
||||
{
|
||||
(new WalletService())->changeBalance(
|
||||
$deliveryBill->user,
|
||||
bcmul($deliveryBill->shipping_fee, '-1', 2),
|
||||
DealerWalletAction::DeliveryBillPaid,
|
||||
"提货单号:{$deliveryBill->sn}",
|
||||
$deliveryBill
|
||||
);
|
||||
|
||||
(new PayService())->handleSuccess($payLog, [
|
||||
'pay_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用微信支付
|
||||
*
|
||||
* @param \App\Models\DealerDeliveryBill $deliveryBill
|
||||
* @param \App\Models\PayLog $payLog
|
||||
* @return array
|
||||
*/
|
||||
protected function payUsingWxpay(DealerDeliveryBill $deliveryBill, PayLog $payLog): array
|
||||
{
|
||||
if (is_null($tradeType = WxpayTradeType::tryFromPayWay($payLog->pay_way))) {
|
||||
throw new BizException('支付方式 非法');
|
||||
}
|
||||
|
||||
$params = [
|
||||
'body' => app_settings('app.app_name').'-批零订单',
|
||||
'out_trade_no' => $payLog->pay_sn,
|
||||
'total_fee' => bcmul($deliveryBill->shipping_fee, '100'),
|
||||
'trade_type' => $tradeType->value,
|
||||
];
|
||||
|
||||
return (new WxpayService())->pay($params, 'yzk_h5');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Dealer;
|
||||
|
||||
use App\Enums\DealerEarningStatus;
|
||||
use App\Enums\DealerManageSubsidyStatus;
|
||||
use App\Enums\DealerWalletAction;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\DealerEarning;
|
||||
use App\Models\DealerManageSubsidy;
|
||||
|
||||
class ManageSubsidyService
|
||||
{
|
||||
/**
|
||||
* @param \App\Models\DealerManageSubsidy $dealerManageSubsidy
|
||||
* @return void
|
||||
*/
|
||||
public function pay(DealerManageSubsidy $dealerManageSubsidy)
|
||||
{
|
||||
if (! $dealerManageSubsidy->isPending()) {
|
||||
throw new BizException('管理津贴 不是待付款状态');
|
||||
}
|
||||
|
||||
$dealerManageSubsidy->update([
|
||||
'status' => DealerManageSubsidyStatus::Completed,
|
||||
]);
|
||||
|
||||
$dealerManageSubsidy->earning->update([
|
||||
'pay_way' => DealerEarning::PAY_WAY_WALLET,
|
||||
'pay_at' => now(),
|
||||
'pay_info' => null,
|
||||
'status' => DealerEarningStatus::Completed,
|
||||
]);
|
||||
|
||||
(new WalletService())->changeBalance(
|
||||
$dealerManageSubsidy->user,
|
||||
$dealerManageSubsidy->real_amount,
|
||||
DealerWalletAction::ManageSubsidyIn,
|
||||
'收入-管理津贴',
|
||||
$dealerManageSubsidy
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\Dealer;
|
||||
|
||||
use App\Enums\DealerEarningStatus;
|
||||
use App\Enums\DealerManagerSubsidyStatus;
|
||||
use App\Enums\DealerWalletAction;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\DealerEarning;
|
||||
use App\Models\DealerManagerSubsidy;
|
||||
|
||||
class ManagerSubsidyService
|
||||
{
|
||||
/**
|
||||
* @param \App\Models\DealerManagerSubsidy $dealerManagerSubsidy
|
||||
* @return void
|
||||
*/
|
||||
public function pay(DealerManagerSubsidy $dealerManagerSubsidy)
|
||||
{
|
||||
if (! $dealerManagerSubsidy->isPending()) {
|
||||
throw new BizException('管理者津贴 不是待付款状态');
|
||||
}
|
||||
|
||||
$dealerManagerSubsidy->update([
|
||||
'status' => DealerManagerSubsidyStatus::Completed,
|
||||
]);
|
||||
|
||||
$dealerManagerSubsidy->earning->update([
|
||||
'pay_way' => DealerEarning::PAY_WAY_WALLET,
|
||||
'pay_at' => now(),
|
||||
'pay_info' => null,
|
||||
'status' => DealerEarningStatus::Completed,
|
||||
]);
|
||||
|
||||
(new WalletService())->changeBalance(
|
||||
$dealerManagerSubsidy->user,
|
||||
$dealerManagerSubsidy->real_amount,
|
||||
DealerWalletAction::ManagerSubsidyIn,
|
||||
'收入-管理者津贴',
|
||||
$dealerManagerSubsidy
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,16 +2,19 @@
|
|||
|
||||
namespace App\Services\Dealer;
|
||||
|
||||
use App\Enums\DealerDeliveryBillStatus;
|
||||
use App\Enums\DealerLvl;
|
||||
use App\Enums\DealerOrderStatus;
|
||||
use App\Enums\DealerWalletAction;
|
||||
use App\Enums\PayWay;
|
||||
use App\Enums\WxpayTradeType;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\DealerDeliveryBill;
|
||||
use App\Models\DealerOrder;
|
||||
use App\Models\DealerOrderAllocateLog;
|
||||
use App\Models\DealerOrderProduct;
|
||||
use App\Models\DealerProduct;
|
||||
use App\Models\DealerUserProduct;
|
||||
use App\Models\DealerUserProductLog;
|
||||
use App\Models\ShippingAddress;
|
||||
use App\Models\User;
|
||||
|
|
@ -283,20 +286,9 @@ class OrderService
|
|||
throw new BizException('订单状态不是待付款');
|
||||
}
|
||||
|
||||
do {
|
||||
$payLog = null;
|
||||
|
||||
try {
|
||||
$payLog = $order->payLogs()->create([
|
||||
'pay_sn' => serial_number(),
|
||||
'pay_way' => $payWay,
|
||||
]);
|
||||
} catch (QueryException $e) {
|
||||
if (strpos($e->getMessage(), 'Duplicate entry') === false) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
} while ($payLog === null);
|
||||
$payLog = $order->payLogs()->create([
|
||||
'pay_way' => $payWay,
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'pay_sn' => $payLog->pay_sn,
|
||||
|
|
@ -346,6 +338,7 @@ class OrderService
|
|||
break;
|
||||
|
||||
case PayWay::WxpayH5:
|
||||
case PayWay::WxpayJsApi:
|
||||
if (is_null($tradeType = WxpayTradeType::tryFromPayWay($payLog->pay_way))) {
|
||||
throw new BizException('支付方式 非法');
|
||||
}
|
||||
|
|
@ -387,6 +380,10 @@ class OrderService
|
|||
'status' => DealerOrderStatus::Paid,
|
||||
'paied_time' => now(),
|
||||
]);
|
||||
//签约单,云库存直接发货
|
||||
if ($order->consignor === null) {
|
||||
$this->orderInDepositstock($order);
|
||||
}
|
||||
return $order;
|
||||
}
|
||||
|
||||
|
|
@ -394,16 +391,21 @@ class OrderService
|
|||
* 确认发货
|
||||
*
|
||||
* @param DealerOrder $order
|
||||
* @param string $action
|
||||
* @return DealerOrder $order
|
||||
*/
|
||||
public function shippingOrder(DealerOrder $order)
|
||||
public function shippingOrder(DealerOrder $order, ?string $action = 'qty')
|
||||
{
|
||||
if (!$order->isPaid()) {
|
||||
throw new BizException('无法发货:订单状态异常,请刷新后再试');
|
||||
}
|
||||
//扣减发货人库存
|
||||
if ($order->consignor) {
|
||||
$this->orderOutQty($order);
|
||||
if ($action == 'deposit_qty') {
|
||||
$this->orderOutDepositQty($order);
|
||||
} else {
|
||||
$this->orderOutQty($order);
|
||||
}
|
||||
}
|
||||
|
||||
$order->update([
|
||||
|
|
@ -413,7 +415,67 @@ class OrderService
|
|||
return $order;
|
||||
}
|
||||
|
||||
public function shippingedOrder(DealerOrder $order)
|
||||
/**
|
||||
* 使用云仓发货
|
||||
*/
|
||||
public function shippingOrderByDeposit(DealerOrder $order)
|
||||
{
|
||||
$depositProducts = [];
|
||||
$deliveryBill = null;
|
||||
//判断这个订单是否已经有待支付的云仓发货单
|
||||
if ($deliveryBill = DealerDeliveryBill::where([
|
||||
'user_id' => $order->consignor_id,
|
||||
'order_id' => $order->id,
|
||||
'status' => DealerDeliveryBillStatus::Pending,
|
||||
])->first()) {
|
||||
return $deliveryBill;
|
||||
}
|
||||
//判断本地库存是否足够,不足则生成云仓提货单,并唤起支付。
|
||||
foreach ($order->products as $product) {
|
||||
//记录需要生成云仓发货单的商品信息以及数量
|
||||
if ($_userProduct = DealerUserProduct::where([
|
||||
'user_id'=>$order->consignor_id,
|
||||
'product_id'=>$product->product_id,
|
||||
])->first()) {
|
||||
if ($product->qty > $_userProduct->stock) {
|
||||
if ($product->qty > $_userProduct->stock + $_userProduct->deposit_stock) {
|
||||
throw new BizException('当前可发货库存不足');
|
||||
}
|
||||
//记录
|
||||
$depositProducts[$product->id] = [
|
||||
'id'=> $product->product_id,
|
||||
'qty'=> $product->qty - $_userProduct->stock,
|
||||
];
|
||||
}
|
||||
} else {
|
||||
throw new BizException('当前可发货库存不足');
|
||||
}
|
||||
}
|
||||
|
||||
if ($depositProducts) {
|
||||
$dealerDeliveryBillService = new DealerDeliveryBillService();
|
||||
$deliveryBill = $dealerDeliveryBillService->create($order->consignor, $depositProducts, [
|
||||
'name'=>$order->consignee_name,
|
||||
'telephone'=>$order->consignee_telephone,
|
||||
'zone'=>$order->consignee_zone,
|
||||
'address'=>$order->consignee_address,
|
||||
], '订单发货:【'.$order->sn.'】', $order);
|
||||
//更新订单相关的库存发货情况
|
||||
if ($order) {
|
||||
foreach ($order->products as $product) {
|
||||
if (isset($depositProducts[$product->id])) {
|
||||
DealerOrderProduct::where('id', $product->id)->update([
|
||||
'qty' => $product->qty - $depositProducts[$product->id]['qty'],
|
||||
'deposit_qty' => $depositProducts[$product->id]['qty'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $deliveryBill;
|
||||
}
|
||||
|
||||
public function shippingedOrder(DealerOrder $order, ?string $action = 'qty')
|
||||
{
|
||||
if (!$order->isShipping()) {
|
||||
throw new BizException('无法收货:订单状态异常,请刷新后再试');
|
||||
|
|
@ -490,42 +552,145 @@ class OrderService
|
|||
protected function orderInQty(DealerOrder $order)
|
||||
{
|
||||
foreach ($order->products as $product) {
|
||||
//增加本地库存
|
||||
$userProduct = $order->user->dealerProducts()->firstOrCreate([
|
||||
'product_id'=> $product->product_id,
|
||||
]);
|
||||
$userProduct->increment('stock', $product->qty);
|
||||
//如果云仓已收货
|
||||
if ($order->local_status < 2 && $order->deposit_status !== 1) {
|
||||
$userProduct->increment('stock', $product->qty);
|
||||
|
||||
DealerUserProductLog::create([
|
||||
'user_id'=> $order->user_id,
|
||||
'product_id'=> $product->product_id,
|
||||
'type' => DealerUserProductLog::TYPE_ORDER_IN,
|
||||
'qty'=>$product->qty,
|
||||
'remark'=>'订单:'.$order->sn,
|
||||
]);
|
||||
} else {
|
||||
$userProduct->increment('stock', $product->qty + $product->deposit_qty);
|
||||
|
||||
DealerUserProductLog::create([
|
||||
'user_id'=> $order->user_id,
|
||||
'product_id'=> $product->product_id,
|
||||
'type' => DealerUserProductLog::TYPE_ORDER_IN,
|
||||
'qty'=>$product->qty + $product->deposit_qty,
|
||||
'remark'=>'订单:'.$order->sn,
|
||||
]);
|
||||
}
|
||||
}
|
||||
$order->update([
|
||||
'local_status' => 2,
|
||||
'deposit_status'=> 2,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户通过订单云仓库增加本地库存
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function orderInAllQty(DealerOrder $order)
|
||||
{
|
||||
foreach ($order->products as $product) {
|
||||
$userProduct = $order->user->dealerProducts()->firstOrCreate([
|
||||
'product_id'=> $product->product_id,
|
||||
]);
|
||||
$userProduct->increment('stock', $product->qty + $product->deposit_qty);
|
||||
|
||||
DealerUserProductLog::create([
|
||||
'user_id'=> $order->user_id,
|
||||
'product_id'=> $product->product_id,
|
||||
'type' => DealerUserProductLog::TYPE_ORDER_IN,
|
||||
'qty'=>$product->qty,
|
||||
'qty'=>$product->qty + $product->deposit_qty,
|
||||
'remark'=>'订单:'.$order->sn,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户通过订单扣减库存
|
||||
* 用户通过订单扣减本地库存发货
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function orderOutQty(DealerOrder $order)
|
||||
public function orderOutQty(DealerOrder $order)
|
||||
{
|
||||
foreach ($order->products as $product) {
|
||||
$userProduct = $order->consignor->dealerProducts()->firstOrCreate([
|
||||
'product_id'=> $product->product_id,
|
||||
]);
|
||||
$userProduct->decrement('stock', $product->qty);
|
||||
|
||||
DealerUserProductLog::create([
|
||||
'user_id'=> $order->consignor_id,
|
||||
'product_id'=> $product->product_id,
|
||||
'type' => DealerUserProductLog::TYPE_ORDER_OUT,
|
||||
'qty'=>$product->qty,
|
||||
'remark' =>'订单:'.$order->sn,
|
||||
]);
|
||||
if ($product->qty > 0 && $order->local_status == 0) {
|
||||
$userProduct = $order->consignor->dealerProducts()->firstOrCreate([
|
||||
'product_id'=> $product->product_id,
|
||||
]);
|
||||
$userProduct->decrement('stock', $product->qty);
|
||||
DealerUserProductLog::create([
|
||||
'user_id'=> $order->consignor_id,
|
||||
'product_id'=> $product->product_id,
|
||||
'type' => DealerUserProductLog::TYPE_ORDER_OUT,
|
||||
'qty'=>$product->qty,
|
||||
'remark' =>'订单:'.$order->sn,
|
||||
]);
|
||||
}
|
||||
}
|
||||
$order->update([
|
||||
'local_status'=>1,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户通过订单扣减云库存发货
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function orderOutDepositQty(DealerOrder $order)
|
||||
{
|
||||
foreach ($order->products as $product) {
|
||||
if ($product->deposit_qty > 0 && $order->deposit_status == 0) {
|
||||
$userProduct = $order->consignor->dealerProducts()->firstOrCreate([
|
||||
'product_id'=> $product->product_id,
|
||||
]);
|
||||
$userProduct->decrement('stock', $product->deposit_qty);
|
||||
|
||||
DealerUserProductLog::create([
|
||||
'user_id'=> $order->consignor_id,
|
||||
'product_id'=> $product->product_id,
|
||||
'type' => DealerUserProductLog::TYPE_ORDER_OUT,
|
||||
'qty'=>$product->deposit_qty,
|
||||
'remark' =>'订单:'.$order->sn,
|
||||
]);
|
||||
}
|
||||
}
|
||||
$order->update([
|
||||
'deposit_status'=>1,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户通过订单获取云库存
|
||||
*
|
||||
* @param DealerOrder $order
|
||||
* @return void
|
||||
*/
|
||||
public function orderInDepositstock(DealerOrder $order)
|
||||
{
|
||||
foreach ($order->products as $product) {
|
||||
if ($product->deposit_qty > 0 && $order->deposit_status == 0) {
|
||||
$userProduct = $order->user->dealerProducts()->firstOrCreate([
|
||||
'product_id'=> $product->product_id,
|
||||
]);
|
||||
$userProduct->increment('deposit_stock', $product->deposit_qty);
|
||||
|
||||
DealerUserProductLog::create([
|
||||
'is_deposit'=>true,
|
||||
'user_id'=> $order->user_id,
|
||||
'product_id'=> $product->product_id,
|
||||
'type' => DealerUserProductLog::TYPE_ORDER_IN,
|
||||
'qty'=>$product->deposit_qty,
|
||||
'remark' =>'订单:'.$order->sn,
|
||||
]);
|
||||
}
|
||||
}
|
||||
$order->update([
|
||||
'deposit_status'=>2,
|
||||
]);
|
||||
}
|
||||
|
||||
private function getConsignor(User $user, $totalAmount, ?User $lastConsignor = null)
|
||||
|
|
|
|||
|
|
@ -2,13 +2,19 @@
|
|||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Enums\DealerDeliveryBillStatus;
|
||||
use App\Enums\DealerOrderStatus;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Exceptions\InvalidPaySerialNumberException;
|
||||
use App\Models\DealerDeliveryBill;
|
||||
use App\Models\DealerOrder;
|
||||
use App\Models\DealerUserProduct;
|
||||
use App\Models\DealerUserProductLog;
|
||||
use App\Models\DistributionPreIncomeJob;
|
||||
use App\Models\Order;
|
||||
use App\Models\PayLog;
|
||||
use App\Services\Dealer\OrderService;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class PayService
|
||||
{
|
||||
|
|
@ -99,9 +105,55 @@ class PayService
|
|||
} else {
|
||||
$payable->paied_time = $payLog->pay_at;
|
||||
$payable->status = DealerOrderStatus::Paid;
|
||||
//签约单,云库存直接发货
|
||||
if ($payable->consignor === null) {
|
||||
(new OrderService())->orderInDepositstock($payable);
|
||||
}
|
||||
}
|
||||
|
||||
$payable->save();
|
||||
} elseif ($payable instanceof DealerDeliveryBill) {
|
||||
if (! $payable->isPending()) {
|
||||
throw new BizException('提货单状态不是待打款');
|
||||
}
|
||||
|
||||
$payable->pay_sn = $payLog->pay_sn;
|
||||
$payable->pay_at = $payLog->pay_at;
|
||||
$payable->out_trade_no = $payLog->out_trade_no;
|
||||
$payable->pay_way = $payLog->pay_way;
|
||||
$payable->status = DealerDeliveryBillStatus::Paid;
|
||||
$payable->save();
|
||||
|
||||
// 将云仓库存变更为本地库存
|
||||
$dealerProductLogs = [];
|
||||
|
||||
foreach ($payable->deliveryProducts as $deliveryProduct) {
|
||||
DealerUserProduct::where([
|
||||
'user_id' => $payable->user_id,
|
||||
'product_id' => $deliveryProduct->product_id,
|
||||
])->update([
|
||||
'stock' => DB::raw("stock + {$deliveryProduct->qty}"),
|
||||
]);
|
||||
|
||||
$dealerProductLogs[] = [
|
||||
'user_id' => $payable->user_id,
|
||||
'product_id' => $deliveryProduct->product_id,
|
||||
'type' => DealerUserProductLog::TYPE_TRANSFER_IN,
|
||||
'qty' => $deliveryProduct->qty,
|
||||
'remark' => "云库存转本地库存,提货单【{$payable->sn}】",
|
||||
'is_deposit' => false,
|
||||
'created_at' => $payable->updated_at,
|
||||
'updated_at' => $payable->updated_at,
|
||||
];
|
||||
}
|
||||
|
||||
DealerUserProductLog::insert($dealerProductLogs);
|
||||
|
||||
//如果云仓库提货单存在关联订单,则该订单直接处理云仓部分的发货
|
||||
if ($payable->order_id) {
|
||||
$dealerOrder = DealerOrder::find($payable->order_id);
|
||||
(new OrderService())->shippingOrder($dealerOrder, 'deposit_qty');
|
||||
}
|
||||
}
|
||||
|
||||
return $payLog;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddDepositStockToDealerUserProductsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('dealer_user_products', function (Blueprint $table) {
|
||||
$table->unsignedBigInteger('deposit_stock')->default(0)->comment('托管库存');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('dealer_user_products', function (Blueprint $table) {
|
||||
$table->dropColumn(['deposit_stock']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddDepositQtyToDealerOrderProductsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('dealer_order_products', function (Blueprint $table) {
|
||||
$table->unsignedBigInteger('deposit_qty')->default(0)->comment('托管数量');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('dealer_order_products', function (Blueprint $table) {
|
||||
$table->dropColumn(['deposit_qty']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateDealerDeliveryBillsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('dealer_delivery_bills', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('sn')->unique();
|
||||
$table->unsignedBigInteger('user_id');
|
||||
$table->unsignedBigInteger('order_id')->nullable();
|
||||
$table->unsignedDecimal('shipping_fee', 18, 2)->default(0)->comment('运费');
|
||||
$table->string('remark')->nullable()->comment('备注');
|
||||
|
||||
// 收货人信息
|
||||
$table->string('consignee_name')->nullable()->comment('收货人-姓名');
|
||||
$table->string('consignee_telephone')->nullable()->comment('收货人-联系方式');
|
||||
$table->string('consignee_zone')->nullable()->comment('收货人-所在地区');
|
||||
$table->string('consignee_address')->nullable()->comment('收货人-详细地址');
|
||||
|
||||
// 支付信息
|
||||
$table->string('pay_sn')->nullable()->comment('支付单号');
|
||||
$table->string('pay_way')->nullable()->comment('支付方式');
|
||||
$table->string('out_trade_no')->nullable()->comment('外部交易号');
|
||||
$table->timestamp('pay_at')->nullable()->comment('付款时间');
|
||||
|
||||
$table->tinyInteger('status')->default(0)->comment('状态');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('dealer_delivery_bills');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateDealerDeliveryProductsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('dealer_delivery_products', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('delivery_bill_id');
|
||||
$table->unsignedBigInteger('product_id');
|
||||
$table->unsignedBigInteger('qty');
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['delivery_bill_id', 'product_id']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('dealer_delivery_products');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddIsDepositToDealerUserProductLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('dealer_user_product_logs', function (Blueprint $table) {
|
||||
//
|
||||
$table->boolean('is_deposit')->default(false)->comment('是否云库存');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('dealer_user_product_logs', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn(['is_deposit']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddDepositStatusToDealerOrdersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('dealer_orders', function (Blueprint $table) {
|
||||
//
|
||||
$table->unsignedTinyInteger('local_status')->nullable()->default(0)->comment('本地仓发货状态');
|
||||
$table->unsignedTinyInteger('deposit_status')->nullable()->default(0)->comment('云仓发货状态');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('dealer_orders', function (Blueprint $table) {
|
||||
//
|
||||
$table->dropColumn(['local_status', 'deposit_status']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -309,6 +309,11 @@ class AdminMenuSeeder extends Seeder
|
|||
'icon' => '',
|
||||
'uri' => 'dealer-manager-orders?type=manager&filter-status[]=2&filter-status[]=3',
|
||||
],
|
||||
[
|
||||
'title' => '云仓提货单',
|
||||
'icon' => '',
|
||||
'uri' => 'dealer-delivery-bills',
|
||||
],
|
||||
// [
|
||||
// 'title' =>'用户资金',
|
||||
// 'icon'=>'',
|
||||
|
|
@ -319,10 +324,16 @@ class AdminMenuSeeder extends Seeder
|
|||
'icon'=>'',
|
||||
'uri' => 'dealer-earnings-channel?filter-earningable_type[]=dealer_channel_subsidy_log',
|
||||
],
|
||||
// [
|
||||
// 'title' =>'签约渠道补贴',
|
||||
// 'icon'=>'',
|
||||
// 'uri' => 'dealer-channel-subsidies',
|
||||
// ],
|
||||
[
|
||||
'title' =>'进货补贴',
|
||||
'icon' => '',
|
||||
'uri' => 'dealer-earnings-purchase?filter-earningable_type[]=dealer_purchase_subsidy',
|
||||
// 'uri' => 'dealer-purchase-subsidies',
|
||||
],
|
||||
[
|
||||
'title' =>'进货补贴明细',
|
||||
|
|
@ -333,6 +344,7 @@ class AdminMenuSeeder extends Seeder
|
|||
'title'=>'管理津贴',
|
||||
'icon' => '',
|
||||
'uri' => 'dealer-earnings-manage?filter-earningable_type[]=dealer_manage_subsidy',
|
||||
// 'uri' => 'dealer-manage-subsidies',
|
||||
],
|
||||
[
|
||||
'title' =>'管理津贴明细',
|
||||
|
|
@ -343,6 +355,7 @@ class AdminMenuSeeder extends Seeder
|
|||
'title'=>'管理者津贴',
|
||||
'icon' => '',
|
||||
'uri' => 'dealer-earnings-manage?filter-earningable_type[]=dealer_manager_subsidy',
|
||||
// 'uri' => 'dealer-manager-subsidies',
|
||||
],
|
||||
[
|
||||
'title'=>'管理者津贴明细',
|
||||
|
|
|
|||
|
|
@ -213,6 +213,7 @@ class AdminPermissionSeeder extends Seeder
|
|||
'curd' => ['index', 'show'],
|
||||
'children'=>[
|
||||
'export_shipping_orders'=>['name' =>'导出发货单'],
|
||||
'export_order_products'=>['name' =>'导出商品'],
|
||||
'tags'=>['name' =>'标签设置'],
|
||||
'pay'=>['name' =>'支付订单'],
|
||||
'reduce'=>['name' =>'订单改价'],
|
||||
|
|
@ -341,6 +342,11 @@ class AdminPermissionSeeder extends Seeder
|
|||
'cancel'=>['name' =>'取消订单'],
|
||||
],
|
||||
],
|
||||
'dealer_delivery_bills' => [
|
||||
'name' =>'云仓提货单',
|
||||
'curd' => ['index', 'show'],
|
||||
'children' =>[],
|
||||
],
|
||||
'dealer_earnings'=>[
|
||||
'name' =>'资金管理',
|
||||
'curd' => ['index', 'show'],
|
||||
|
|
@ -352,6 +358,22 @@ class AdminPermissionSeeder extends Seeder
|
|||
'pay'=>['name' =>'确认打款'],
|
||||
],
|
||||
],
|
||||
'dealer_channel_subsidies' => [
|
||||
'name' =>'签约渠道补贴',
|
||||
'curd' => ['index'],
|
||||
'children' => [
|
||||
'pay' => ['name' => '付款'],
|
||||
'batch_pay' => ['name' => '批量付款'],
|
||||
],
|
||||
],
|
||||
'dealer_purchase_subsidies' => [
|
||||
'name' =>'进货补贴',
|
||||
'curd' => ['index', 'show'],
|
||||
'children' => [
|
||||
'pay' => ['name' => '付款'],
|
||||
'batch_pay' => ['name' => '批量付款'],
|
||||
],
|
||||
],
|
||||
'dealer_manager_subsidies' => [
|
||||
'name' =>'管理者津贴',
|
||||
'curd' => ['index'],
|
||||
|
|
|
|||
Loading…
Reference in New Issue