diff --git a/app/Admin/Actions/Grid/DealerChannelSubsidyBatchPay.php b/app/Admin/Actions/Grid/DealerChannelSubsidyBatchPay.php
new file mode 100644
index 00000000..372217f9
--- /dev/null
+++ b/app/Admin/Actions/Grid/DealerChannelSubsidyBatchPay.php
@@ -0,0 +1,53 @@
+ 付款';
+
+ /**
+ * @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();
+ }
+}
diff --git a/app/Admin/Actions/Grid/DealerChannelSubsidyPay.php b/app/Admin/Actions/Grid/DealerChannelSubsidyPay.php
new file mode 100644
index 00000000..4566557f
--- /dev/null
+++ b/app/Admin/Actions/Grid/DealerChannelSubsidyPay.php
@@ -0,0 +1,44 @@
+ 付款';
+
+ /**
+ * @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();
+ }
+}
diff --git a/app/Admin/Actions/Grid/DealerManageSubsidyBatchPay.php b/app/Admin/Actions/Grid/DealerManageSubsidyBatchPay.php
index caa4546d..de1253db 100644
--- a/app/Admin/Actions/Grid/DealerManageSubsidyBatchPay.php
+++ b/app/Admin/Actions/Grid/DealerManageSubsidyBatchPay.php
@@ -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)
+ );
}
}
});
diff --git a/app/Admin/Actions/Grid/DealerManageSubsidyPay.php b/app/Admin/Actions/Grid/DealerManageSubsidyPay.php
index 6f21ea8d..b4300891 100644
--- a/app/Admin/Actions/Grid/DealerManageSubsidyPay.php
+++ b/app/Admin/Actions/Grid/DealerManageSubsidyPay.php
@@ -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)
);
});
diff --git a/app/Admin/Actions/Grid/DealerManagerSubsidyBatchPay.php b/app/Admin/Actions/Grid/DealerManagerSubsidyBatchPay.php
index 39365184..10457f03 100644
--- a/app/Admin/Actions/Grid/DealerManagerSubsidyBatchPay.php
+++ b/app/Admin/Actions/Grid/DealerManagerSubsidyBatchPay.php
@@ -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)
+ );
}
}
});
diff --git a/app/Admin/Actions/Grid/DealerManagerSubsidyPay.php b/app/Admin/Actions/Grid/DealerManagerSubsidyPay.php
index 0c706e8c..b0dfb63b 100644
--- a/app/Admin/Actions/Grid/DealerManagerSubsidyPay.php
+++ b/app/Admin/Actions/Grid/DealerManagerSubsidyPay.php
@@ -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)
);
});
diff --git a/app/Admin/Actions/Grid/DealerPurchaseSubsidyBatchPay.php b/app/Admin/Actions/Grid/DealerPurchaseSubsidyBatchPay.php
new file mode 100644
index 00000000..59d95980
--- /dev/null
+++ b/app/Admin/Actions/Grid/DealerPurchaseSubsidyBatchPay.php
@@ -0,0 +1,53 @@
+ 付款';
+
+ /**
+ * @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();
+ }
+}
diff --git a/app/Admin/Actions/Grid/DealerPurchaseSubsidyPay.php b/app/Admin/Actions/Grid/DealerPurchaseSubsidyPay.php
new file mode 100644
index 00000000..5f3f714b
--- /dev/null
+++ b/app/Admin/Actions/Grid/DealerPurchaseSubsidyPay.php
@@ -0,0 +1,46 @@
+ 付款';
+
+ /**
+ * @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();
+ }
+}
diff --git a/app/Admin/Actions/Grid/Exports/ShippingOrder.php b/app/Admin/Actions/Grid/Exports/ShippingOrder.php
index c936d863..aaf94628 100644
--- a/app/Admin/Actions/Grid/Exports/ShippingOrder.php
+++ b/app/Admin/Actions/Grid/Exports/ShippingOrder.php
@@ -12,6 +12,8 @@ use Illuminate\Http\Request;
class ShippingOrder extends RowAction
{
+ protected $htmlClasses = ['btn', 'btn-primary'];
+
public function title()
{
if ($this->title) {
diff --git a/app/Admin/Actions/Show/DealerEarningPay.php b/app/Admin/Actions/Show/DealerEarningPay.php
index 804e08e7..6ab63a0b 100644
--- a/app/Admin/Actions/Show/DealerEarningPay.php
+++ b/app/Admin/Actions/Show/DealerEarningPay.php
@@ -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,
diff --git a/app/Admin/Controllers/DealerChannelSubsidyController.php b/app/Admin/Controllers/DealerChannelSubsidyController.php
new file mode 100644
index 00000000..75efaafa
--- /dev/null
+++ b/app/Admin/Controllers/DealerChannelSubsidyController.php
@@ -0,0 +1,141 @@
+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 '
'.nl2br($this->remark).'
';
+ });
+ $grid->column('settle_at', '结算时间')->display(function () {
+ return $this->settle_at?->toDateTimeString();
+ })->sortable();
+ $grid->column('status', '状态')->display(function ($v) {
+ if (! $this->isSettled()) {
+ return " 待结算";
+ }
+
+ return " {$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'));
+ });
+ });
+ });
+ }
+}
diff --git a/app/Admin/Controllers/DealerController.php b/app/Admin/Controllers/DealerController.php
index 48eabee1..f6b3ad39 100644
--- a/app/Admin/Controllers/DealerController.php
+++ b/app/Admin/Controllers/DealerController.php
@@ -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('商品');
diff --git a/app/Admin/Controllers/DealerDeliveryBillController.php b/app/Admin/Controllers/DealerDeliveryBillController.php
new file mode 100644
index 00000000..ec402590
--- /dev/null
+++ b/app/Admin/Controllers/DealerDeliveryBillController.php
@@ -0,0 +1,134 @@
+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(' 显示 ');
+ }
+ });
+
+ $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();
+ })));
+ });
+ };
+ }
+}
diff --git a/app/Admin/Controllers/DealerManageSubsidyController.php b/app/Admin/Controllers/DealerManageSubsidyController.php
index e643f44e..dc445223 100644
--- a/app/Admin/Controllers/DealerManageSubsidyController.php
+++ b/app/Admin/Controllers/DealerManageSubsidyController.php
@@ -62,8 +62,8 @@ class DealerManageSubsidyController extends AdminController
return "".nl2br($this->remark).'
';
});
$grid->column('status', '状态')->display(function ($v) {
- return ' '.$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 "金额:".$totalAmount.' 元
';
- });
- $grid->filter(function (Grid\Filter $filter) {
- $filter->panel(false);
- $filter->equal('user.phone', '手机号')->width(3);
- $filter->between('order_completed_at', '结算时间')->dateTime()->width(7);
- });
- });
}
}
diff --git a/app/Admin/Controllers/DealerManagerSubsidyController.php b/app/Admin/Controllers/DealerManagerSubsidyController.php
index ffa4f236..701e7de5 100644
--- a/app/Admin/Controllers/DealerManagerSubsidyController.php
+++ b/app/Admin/Controllers/DealerManagerSubsidyController.php
@@ -63,8 +63,8 @@ class DealerManagerSubsidyController extends AdminController
return "".nl2br($this->remark).'
';
});
$grid->column('status', '状态')->display(function ($v) {
- return ' '.$v->text();
- });
+ return $v->text();
+ })->circleDot(DealerManagerSubsidyStatus::colors());
$grid->column('earning.pay_at', '付款时间');
$grid->showRowSelector();
diff --git a/app/Admin/Controllers/DealerOrderController.php b/app/Admin/Controllers/DealerOrderController.php
index 5c004b67..1d121d5b 100644
--- a/app/Admin/Controllers/DealerOrderController.php
+++ b/app/Admin/Controllers/DealerOrderController.php
@@ -52,11 +52,12 @@ class DealerOrderController extends AdminController
$statusTexts = DealerOrderStatus::texts();
$grid->column('pay_way')->display(function ($v) {
- if ($v) {
- return ' '.$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 = ' '.$this->pay_way->getDealerOrderText();
- }
-
- return <<
-
- 支付方式
-
-
-
-
-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();
diff --git a/app/Admin/Controllers/DealerPurchaseSubsidyController.php b/app/Admin/Controllers/DealerPurchaseSubsidyController.php
new file mode 100644
index 00000000..c15f12ee
--- /dev/null
+++ b/app/Admin/Controllers/DealerPurchaseSubsidyController.php
@@ -0,0 +1,186 @@
+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(' 显示 ');
+ }
+
+ 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;
+ }
+}
diff --git a/app/Admin/Controllers/OrderController.php b/app/Admin/Controllers/OrderController.php
index 86a857ce..cb32b8da 100644
--- a/app/Admin/Controllers/OrderController.php
+++ b/app/Admin/Controllers/OrderController.php
@@ -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 ' '.$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(' 预收益明细');
- }
- // $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(' 预收益明细');
+ }
+ });
+
+ 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 = ' '.$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');
diff --git a/app/Admin/Controllers/SettingController.php b/app/Admin/Controllers/SettingController.php
index 58b3237c..045c6c9f 100644
--- a/app/Admin/Controllers/SettingController.php
+++ b/app/Admin/Controllers/SettingController.php
@@ -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;
diff --git a/app/Admin/Extensions/Column/CircleDot.php b/app/Admin/Extensions/Column/CircleDot.php
new file mode 100644
index 00000000..33c6dad9
--- /dev/null
+++ b/app/Admin/Extensions/Column/CircleDot.php
@@ -0,0 +1,50 @@
+value)) {
+ return;
+ }
+
+ if ($value instanceof UnitEnum) {
+ $value = $value->value;
+ }
+
+ $background = $this->background($options, $default);
+
+ return " {$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);
+ }
+}
diff --git a/app/Admin/Extensions/Grid/Tools/Order/ExportProduct.php b/app/Admin/Extensions/Grid/Tools/Order/ExportProduct.php
new file mode 100644
index 00000000..b092dbdc
--- /dev/null
+++ b/app/Admin/Extensions/Grid/Tools/Order/ExportProduct.php
@@ -0,0 +1,43 @@
+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 '导出商品';
+ }
+
+ protected function script()
+ {
+ $this->setHtmlAttribute('data-role', 'order-products-exporter');
+
+ $url = request()->fullUrlWithQuery(['_export' => 'product']);
+
+ return <<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,
]);
diff --git a/app/Admin/Forms/Settings/Custom.php b/app/Admin/Forms/Settings/Custom.php
new file mode 100644
index 00000000..f781b6c7
--- /dev/null
+++ b/app/Admin/Forms/Settings/Custom.php
@@ -0,0 +1,48 @@
+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'] ?? [],
+ ];
+ }
+}
diff --git a/app/Admin/Forms/Settings/Dealer.php b/app/Admin/Forms/Settings/Dealer.php
index 0253b089..46ffb3e3 100644
--- a/app/Admin/Forms/Settings/Dealer.php
+++ b/app/Admin/Forms/Settings/Dealer.php
@@ -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,
diff --git a/app/Admin/Renderable/DealerUserProductLogSimpleTable.php b/app/Admin/Renderable/DealerUserProductLogSimpleTable.php
index a0500170..f64a63e6 100644
--- a/app/Admin/Renderable/DealerUserProductLogSimpleTable.php
+++ b/app/Admin/Renderable/DealerUserProductLogSimpleTable.php
@@ -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();
});
diff --git a/app/Admin/Repositories/DealerDeliveryBill.php b/app/Admin/Repositories/DealerDeliveryBill.php
new file mode 100644
index 00000000..347fe149
--- /dev/null
+++ b/app/Admin/Repositories/DealerDeliveryBill.php
@@ -0,0 +1,16 @@
+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,
+ ]);
+ }
+}
diff --git a/app/Admin/bootstrap.php b/app/Admin/bootstrap.php
index d69d8032..4a3f1977 100644
--- a/app/Admin/bootstrap.php
+++ b/app/Admin/bootstrap.php
@@ -1,5 +1,6 @@
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 " ";
+ });
+});
Admin::style(
<<<'CSS'
diff --git a/app/Admin/routes.php b/app/Admin/routes.php
index ae1aa6fa..a679fc24 100644
--- a/app/Admin/routes.php
+++ b/app/Admin/routes.php
@@ -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');
diff --git a/app/Constants/OrderStatus.php b/app/Constants/OrderStatus.php
index 8d10077e..ab61ff4f 100644
--- a/app/Constants/OrderStatus.php
+++ b/app/Constants/OrderStatus.php
@@ -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 => '已取消',
+ ];
}
diff --git a/app/Endpoint/Api/Filters/DealerDeliveryBillFilter.php b/app/Endpoint/Api/Filters/DealerDeliveryBillFilter.php
new file mode 100644
index 00000000..52c8eef3
--- /dev/null
+++ b/app/Endpoint/Api/Filters/DealerDeliveryBillFilter.php
@@ -0,0 +1,26 @@
+where('status', DealerDeliveryBillStatus::Pending);
+ break;
+
+ case 'paid':
+ $this->where('status', DealerDeliveryBillStatus::Paid);
+ break;
+
+ case 'cancelled':
+ $this->where('status', DealerDeliveryBillStatus::Cancelled);
+ break;
+ }
+ }
+}
diff --git a/app/Endpoint/Api/Http/Controllers/Dealer/ConfigurationController.php b/app/Endpoint/Api/Http/Controllers/Dealer/ConfigurationController.php
index 644a9cec..043e88b9 100644
--- a/app/Endpoint/Api/Http/Controllers/Dealer/ConfigurationController.php
+++ b/app/Endpoint/Api/Http/Controllers/Dealer/ConfigurationController.php
@@ -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),
]);
}
}
diff --git a/app/Endpoint/Api/Http/Controllers/Dealer/DealerDeliveryBillController.php b/app/Endpoint/Api/Http/Controllers/Dealer/DealerDeliveryBillController.php
new file mode 100644
index 00000000..49240e0b
--- /dev/null
+++ b/app/Endpoint/Api/Http/Controllers/Dealer/DealerDeliveryBillController.php
@@ -0,0 +1,178 @@
+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();
+ }
+}
diff --git a/app/Endpoint/Api/Http/Controllers/Dealer/OrderController.php b/app/Endpoint/Api/Http/Controllers/Dealer/OrderController.php
index 82339896..a64f7ba9 100644
--- a/app/Endpoint/Api/Http/Controllers/Dealer/OrderController.php
+++ b/app/Endpoint/Api/Http/Controllers/Dealer/OrderController.php
@@ -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 {
diff --git a/app/Endpoint/Api/Http/Controllers/Dealer/UserProductController.php b/app/Endpoint/Api/Http/Controllers/Dealer/UserProductController.php
index 702736a9..693fd92b 100644
--- a/app/Endpoint/Api/Http/Controllers/Dealer/UserProductController.php
+++ b/app/Endpoint/Api/Http/Controllers/Dealer/UserProductController.php
@@ -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);
}
diff --git a/app/Endpoint/Api/Http/Controllers/SettingController.php b/app/Endpoint/Api/Http/Controllers/SettingController.php
index cf9d476d..feaa74ad 100644
--- a/app/Endpoint/Api/Http/Controllers/SettingController.php
+++ b/app/Endpoint/Api/Http/Controllers/SettingController.php
@@ -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,
+ ]);
+ }
}
diff --git a/app/Endpoint/Api/Http/Resources/Dealer/DealerDeliveryBillResource.php b/app/Endpoint/Api/Http/Resources/Dealer/DealerDeliveryBillResource.php
new file mode 100644
index 00000000..83089e86
--- /dev/null
+++ b/app/Endpoint/Api/Http/Resources/Dealer/DealerDeliveryBillResource.php
@@ -0,0 +1,34 @@
+ $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(),
+ ];
+ }
+}
diff --git a/app/Endpoint/Api/Http/Resources/Dealer/DealerDeliveryProductResource.php b/app/Endpoint/Api/Http/Resources/Dealer/DealerDeliveryProductResource.php
new file mode 100644
index 00000000..dee14701
--- /dev/null
+++ b/app/Endpoint/Api/Http/Resources/Dealer/DealerDeliveryProductResource.php
@@ -0,0 +1,24 @@
+ $this->product->id,
+ 'name' => $this->product->name,
+ 'cover' => $this->product->cover,
+ 'qty' => $this->qty,
+ ];
+ }
+}
diff --git a/app/Endpoint/Api/Http/Resources/Dealer/OrderProductResource.php b/app/Endpoint/Api/Http/Resources/Dealer/OrderProductResource.php
index 2ede93b9..727db3a9 100644
--- a/app/Endpoint/Api/Http/Resources/Dealer/OrderProductResource.php
+++ b/app/Endpoint/Api/Http/Resources/Dealer/OrderProductResource.php
@@ -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,
];
}
}
diff --git a/app/Endpoint/Api/Http/Resources/Dealer/UserProductLogResource.php b/app/Endpoint/Api/Http/Resources/Dealer/UserProductLogResource.php
index e5d39a51..5d0e44ef 100644
--- a/app/Endpoint/Api/Http/Resources/Dealer/UserProductLogResource.php
+++ b/app/Endpoint/Api/Http/Resources/Dealer/UserProductLogResource.php
@@ -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(),
];
diff --git a/app/Endpoint/Api/Http/Resources/Dealer/UserProductResource.php b/app/Endpoint/Api/Http/Resources/Dealer/UserProductResource.php
index f0a4e8f6..16aa30eb 100644
--- a/app/Endpoint/Api/Http/Resources/Dealer/UserProductResource.php
+++ b/app/Endpoint/Api/Http/Resources/Dealer/UserProductResource.php
@@ -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,
];
}
}
diff --git a/app/Endpoint/Api/routes.php b/app/Endpoint/Api/routes.php
index ee6afac7..0a994d12 100644
--- a/app/Endpoint/Api/routes.php
+++ b/app/Endpoint/Api/routes.php
@@ -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']);
});
});
diff --git a/app/Enums/DealerDeliveryBillStatus.php b/app/Enums/DealerDeliveryBillStatus.php
new file mode 100644
index 00000000..a042d81c
--- /dev/null
+++ b/app/Enums/DealerDeliveryBillStatus.php
@@ -0,0 +1,32 @@
+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 => '已取消',
+ ];
+ }
+}
diff --git a/app/Enums/DealerEarningStatus.php b/app/Enums/DealerEarningStatus.php
index 8a0e722f..2b8a9b5e 100644
--- a/app/Enums/DealerEarningStatus.php
+++ b/app/Enums/DealerEarningStatus.php
@@ -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 => '已完成',
+ ];
}
}
diff --git a/app/Enums/DealerManageSubsidyStatus.php b/app/Enums/DealerManageSubsidyStatus.php
index 3dac0ed1..51367fcc 100644
--- a/app/Enums/DealerManageSubsidyStatus.php
+++ b/app/Enums/DealerManageSubsidyStatus.php
@@ -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 [
diff --git a/app/Enums/DealerManagerSubsidyStatus.php b/app/Enums/DealerManagerSubsidyStatus.php
index e18c013c..8ee0229a 100644
--- a/app/Enums/DealerManagerSubsidyStatus.php
+++ b/app/Enums/DealerManagerSubsidyStatus.php
@@ -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 [
diff --git a/app/Enums/DealerPurchaseSubsidyStatus.php b/app/Enums/DealerPurchaseSubsidyStatus.php
index d93bab55..fd7987d3 100644
--- a/app/Enums/DealerPurchaseSubsidyStatus.php
+++ b/app/Enums/DealerPurchaseSubsidyStatus.php
@@ -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 => '已完成',
+ ];
+ }
}
diff --git a/app/Enums/DealerWalletAction.php b/app/Enums/DealerWalletAction.php
index 6eae5c51..1bacc3a6 100644
--- a/app/Enums/DealerWalletAction.php
+++ b/app/Enums/DealerWalletAction.php
@@ -15,4 +15,5 @@ enum DealerWalletAction: int {
case TransferOut = 10;
case EarningIn = 11;
case EarningOut = 12;
+ case DeliveryBillPaid = 13;
}
diff --git a/app/Enums/PayWay.php b/app/Enums/PayWay.php
index d296c6e9..c51f70d5 100644
--- a/app/Enums/PayWay.php
+++ b/app/Enums/PayWay.php
@@ -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',
];
}
}
diff --git a/app/Models/Dealer.php b/app/Models/Dealer.php
index 72c4e097..5acc6e50 100644
--- a/app/Models/Dealer.php
+++ b/app/Models/Dealer.php
@@ -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();
}
}
diff --git a/app/Models/DealerDeliveryBill.php b/app/Models/DealerDeliveryBill.php
new file mode 100644
index 00000000..39e3c99c
--- /dev/null
+++ b/app/Models/DealerDeliveryBill.php
@@ -0,0 +1,79 @@
+ 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;
+ }
+}
diff --git a/app/Models/DealerDeliveryProduct.php b/app/Models/DealerDeliveryProduct.php
new file mode 100644
index 00000000..6917bd4e
--- /dev/null
+++ b/app/Models/DealerDeliveryProduct.php
@@ -0,0 +1,13 @@
+belongsTo(DealerProduct::class, 'product_id');
+ }
+}
diff --git a/app/Models/DealerEarning.php b/app/Models/DealerEarning.php
index 93765683..b53befe9 100644
--- a/app/Models/DealerEarning.php
+++ b/app/Models/DealerEarning.php
@@ -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;
+ }
+
/**
* 待打款状态
*
diff --git a/app/Models/DealerOrder.php b/app/Models/DealerOrder.php
index 4d22d0fc..647eba28 100644
--- a/app/Models/DealerOrder.php
+++ b/app/Models/DealerOrder.php
@@ -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,
]);
}
diff --git a/app/Models/DealerOrderProduct.php b/app/Models/DealerOrderProduct.php
index 2175e63d..39a009c5 100644
--- a/app/Models/DealerOrderProduct.php
+++ b/app/Models/DealerOrderProduct.php
@@ -15,6 +15,7 @@ class DealerOrderProduct extends Model
'price',
'sale_price',
'qty',
+ 'deposit_qty',
];
/**
diff --git a/app/Models/DealerPurchaseSubsidy.php b/app/Models/DealerPurchaseSubsidy.php
index 3017bd07..bf0b3089 100644
--- a/app/Models/DealerPurchaseSubsidy.php
+++ b/app/Models/DealerPurchaseSubsidy.php
@@ -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;
}
}
diff --git a/app/Models/DealerUserProduct.php b/app/Models/DealerUserProduct.php
index 65d494a3..b7cb17b5 100644
--- a/app/Models/DealerUserProduct.php
+++ b/app/Models/DealerUserProduct.php
@@ -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()
diff --git a/app/Models/DealerUserProductLog.php b/app/Models/DealerUserProductLog.php
index 8805dd81..4b869ad0 100644
--- a/app/Models/DealerUserProductLog.php
+++ b/app/Models/DealerUserProductLog.php
@@ -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'];
+ }
}
diff --git a/app/Models/Order.php b/app/Models/Order.php
index 6521458e..fb703acc 100644
--- a/app/Models/Order.php
+++ b/app/Models/Order.php
@@ -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];
+ }
}
diff --git a/app/Models/PayLog.php b/app/Models/PayLog.php
index 8d4bda76..0658395a 100644
--- a/app/Models/PayLog.php
+++ b/app/Models/PayLog.php
@@ -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());
+ }
+ });
+ }
+
/**
* 获取支付记录所属的模型
*/
diff --git a/app/Models/User.php b/app/Models/User.php
index f793e61f..4e481af9 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -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');
+ }
+
/**
* 经销商的发货订单
*
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index be546720..e7d0002d 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -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();
diff --git a/app/Services/Dealer/DealerDeliveryBillService.php b/app/Services/Dealer/DealerDeliveryBillService.php
new file mode 100644
index 00000000..dca2a9dc
--- /dev/null
+++ b/app/Services/Dealer/DealerDeliveryBillService.php
@@ -0,0 +1,259 @@
+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');
+ }
+}
diff --git a/app/Services/Dealer/ManageSubsidyService.php b/app/Services/Dealer/ManageSubsidyService.php
deleted file mode 100644
index 24a50bdd..00000000
--- a/app/Services/Dealer/ManageSubsidyService.php
+++ /dev/null
@@ -1,43 +0,0 @@
-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
- );
- }
-}
diff --git a/app/Services/Dealer/ManagerSubsidyService.php b/app/Services/Dealer/ManagerSubsidyService.php
deleted file mode 100644
index ab766710..00000000
--- a/app/Services/Dealer/ManagerSubsidyService.php
+++ /dev/null
@@ -1,43 +0,0 @@
-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
- );
- }
-}
diff --git a/app/Services/Dealer/OrderService.php b/app/Services/Dealer/OrderService.php
index 558b586e..1dbf30ea 100644
--- a/app/Services/Dealer/OrderService.php
+++ b/app/Services/Dealer/OrderService.php
@@ -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)
diff --git a/app/Services/PayService.php b/app/Services/PayService.php
index fb7e4183..9de2c686 100644
--- a/app/Services/PayService.php
+++ b/app/Services/PayService.php
@@ -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;
diff --git a/database/migrations/2022_03_08_100618_add_deposit_stock_to_dealer_user_products_table.php b/database/migrations/2022_03_08_100618_add_deposit_stock_to_dealer_user_products_table.php
new file mode 100644
index 00000000..ad487abc
--- /dev/null
+++ b/database/migrations/2022_03_08_100618_add_deposit_stock_to_dealer_user_products_table.php
@@ -0,0 +1,32 @@
+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']);
+ });
+ }
+}
diff --git a/database/migrations/2022_03_08_103158_add_deposit_qty_to_dealer_order_products_table.php b/database/migrations/2022_03_08_103158_add_deposit_qty_to_dealer_order_products_table.php
new file mode 100644
index 00000000..5c669c25
--- /dev/null
+++ b/database/migrations/2022_03_08_103158_add_deposit_qty_to_dealer_order_products_table.php
@@ -0,0 +1,32 @@
+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']);
+ });
+ }
+}
diff --git a/database/migrations/2022_03_08_105741_create_dealer_delivery_bills_table.php b/database/migrations/2022_03_08_105741_create_dealer_delivery_bills_table.php
new file mode 100644
index 00000000..bfea05d8
--- /dev/null
+++ b/database/migrations/2022_03_08_105741_create_dealer_delivery_bills_table.php
@@ -0,0 +1,50 @@
+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');
+ }
+}
diff --git a/database/migrations/2022_03_08_105753_create_dealer_delivery_products_table.php b/database/migrations/2022_03_08_105753_create_dealer_delivery_products_table.php
new file mode 100644
index 00000000..13f901a6
--- /dev/null
+++ b/database/migrations/2022_03_08_105753_create_dealer_delivery_products_table.php
@@ -0,0 +1,36 @@
+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');
+ }
+}
diff --git a/database/migrations/2022_03_08_145732_add_is_deposit_to_dealer_user_product_logs_table.php b/database/migrations/2022_03_08_145732_add_is_deposit_to_dealer_user_product_logs_table.php
new file mode 100644
index 00000000..387a7162
--- /dev/null
+++ b/database/migrations/2022_03_08_145732_add_is_deposit_to_dealer_user_product_logs_table.php
@@ -0,0 +1,34 @@
+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']);
+ });
+ }
+}
diff --git a/database/migrations/2022_03_14_113838_add_deposit_status_to_dealer_orders_table.php b/database/migrations/2022_03_14_113838_add_deposit_status_to_dealer_orders_table.php
new file mode 100644
index 00000000..6dce48aa
--- /dev/null
+++ b/database/migrations/2022_03_14_113838_add_deposit_status_to_dealer_orders_table.php
@@ -0,0 +1,35 @@
+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']);
+ });
+ }
+}
diff --git a/database/seeders/AdminMenuSeeder.php b/database/seeders/AdminMenuSeeder.php
index 3b2a3654..dc141fb4 100644
--- a/database/seeders/AdminMenuSeeder.php
+++ b/database/seeders/AdminMenuSeeder.php
@@ -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'=>'管理者津贴明细',
diff --git a/database/seeders/AdminPermissionSeeder.php b/database/seeders/AdminPermissionSeeder.php
index 6589ac4c..c52c47c2 100644
--- a/database/seeders/AdminPermissionSeeder.php
+++ b/database/seeders/AdminPermissionSeeder.php
@@ -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'],