门店商品库存批量
parent
bd7ad825f8
commit
653bd1cc13
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Admin\Actions\Store;
|
||||||
|
|
||||||
|
use Dcat\Admin\Grid\RowAction;
|
||||||
|
use App\Models\Admin\Administrator;
|
||||||
|
use App\Models\Store\{ProductSku, StockBatch};
|
||||||
|
|
||||||
|
class RowAddStock extends RowAction
|
||||||
|
{
|
||||||
|
protected $title = '确认';
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
// 添加库存记录
|
||||||
|
$list = [];
|
||||||
|
$model = StockBatch::findOrFail($this->getKey());
|
||||||
|
if ($model->status) {
|
||||||
|
return $this->response()->error('已经确认过了');
|
||||||
|
}
|
||||||
|
$type = (new Administrator())->getMorphClass();
|
||||||
|
foreach($model->productSkus()->get() as $item) {
|
||||||
|
$amount = $item->pivot?->amount;
|
||||||
|
if ($amount) {
|
||||||
|
$product = ProductSku::firstOrCreate([
|
||||||
|
'store_id' => $model->store_id,
|
||||||
|
'product_sku_id' => $item->id
|
||||||
|
], [
|
||||||
|
'amount' => 0,
|
||||||
|
'status' => 1,
|
||||||
|
'product_spu_id' => $item->spu_id,
|
||||||
|
]);
|
||||||
|
$balance = $product->amount + $amount;
|
||||||
|
if ($balance < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
array_push($list, [
|
||||||
|
'operator_type' => $type,
|
||||||
|
'operator_id' => $model->admin_user_id,
|
||||||
|
'amount' => $amount,
|
||||||
|
'product_sku_id' => $item->id,
|
||||||
|
'balance' => $balance,
|
||||||
|
'store_id' => $model->store_id,
|
||||||
|
'tag_id' => $model->tag_id,
|
||||||
|
'remarks' => '批次号: ' . $model->sn,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$product->update(['amount' => $balance]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$model->logs()->createMany($list);
|
||||||
|
|
||||||
|
$model->update(['status' => 1]);
|
||||||
|
|
||||||
|
return $this->response()->success('操作成功')->refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function confirm()
|
||||||
|
{
|
||||||
|
return ['是否确定?', '不可恢复'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -4,9 +4,30 @@ namespace App\Admin\Controllers;
|
||||||
|
|
||||||
use Dcat\Admin\Admin;
|
use Dcat\Admin\Admin;
|
||||||
use Dcat\Admin\Http\Controllers\UserController;
|
use Dcat\Admin\Http\Controllers\UserController;
|
||||||
|
use App\Models\Admin\Administrator;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class AdministratorController extends UserController
|
class AdministratorController extends UserController
|
||||||
{
|
{
|
||||||
|
public function list(Request $request)
|
||||||
|
{
|
||||||
|
$query = Administrator::select('id', 'name as text');
|
||||||
|
|
||||||
|
if ($request->filled('q')) {
|
||||||
|
$phone = $request->input('q');
|
||||||
|
$query->where(fn($q) => $q->where('username', 'like', "%$phone%")->orWhere('name', 'like', "%$phone%"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->filled('_paginate')) {
|
||||||
|
$list = $query->paginate();
|
||||||
|
} else {
|
||||||
|
$list = $query->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
public function grid()
|
public function grid()
|
||||||
{
|
{
|
||||||
$grid = parent::grid();
|
$grid = parent::grid();
|
||||||
|
|
|
||||||
|
|
@ -76,11 +76,9 @@ class OrderController extends AdminController
|
||||||
})->prepend('¥');
|
})->prepend('¥');
|
||||||
$grid->column('sales_value');
|
$grid->column('sales_value');
|
||||||
$grid->column('order_status')->using($this->statusMap)->dot($this->statusColor);
|
$grid->column('order_status')->using($this->statusMap)->dot($this->statusColor);
|
||||||
$grid->column('pay_way')->display(function ($v) {
|
|
||||||
return $v?->mallText();
|
|
||||||
})->circleDot(PayWay::colors());
|
|
||||||
$grid->column('pay_at');
|
|
||||||
$grid->column('created_at');
|
$grid->column('created_at');
|
||||||
|
$grid->column('pay_at');
|
||||||
|
$grid->column('completed_at');
|
||||||
|
|
||||||
$grid->showViewButton($user->can('dcat.admin.store.order.show'));
|
$grid->showViewButton($user->can('dcat.admin.store.order.show'));
|
||||||
|
|
||||||
|
|
@ -100,10 +98,10 @@ class OrderController extends AdminController
|
||||||
->orWhereHas('inviterInfo', fn($q) => $q->where('nickname', 'like', '%'.$this->input.'%'));
|
->orWhereHas('inviterInfo', fn($q) => $q->where('nickname', 'like', '%'.$this->input.'%'));
|
||||||
});
|
});
|
||||||
})->width(3)->placeholder('昵称/手机号');
|
})->width(3)->placeholder('昵称/手机号');
|
||||||
$filter->equal('pay_way')->select([
|
// $filter->equal('pay_way')->select([
|
||||||
PayWay::WxpayMiniProgram->value => PayWay::WxpayMiniProgram->text(),
|
// PayWay::WxpayMiniProgram->value => PayWay::WxpayMiniProgram->text(),
|
||||||
PayWay::Offline->value => PayWay::Offline->text(),
|
// PayWay::Offline->value => PayWay::Offline->text(),
|
||||||
])->width(3);
|
// ])->width(3);
|
||||||
$filter->where('order_status', function ($q) {
|
$filter->where('order_status', function ($q) {
|
||||||
switch ($this->input) {
|
switch ($this->input) {
|
||||||
case OrderStatus::PENDING:
|
case OrderStatus::PENDING:
|
||||||
|
|
@ -134,6 +132,7 @@ class OrderController extends AdminController
|
||||||
OrderStatus::CANCELLED => '已取消'
|
OrderStatus::CANCELLED => '已取消'
|
||||||
])->width(3);
|
])->width(3);
|
||||||
$filter->between('created_at')->dateTime()->width(6);
|
$filter->between('created_at')->dateTime()->width(6);
|
||||||
|
$filter->between('completed_at')->dateTime()->width(6);
|
||||||
});
|
});
|
||||||
|
|
||||||
$grid->footer(function ($collection) use ($grid) {
|
$grid->footer(function ($collection) use ($grid) {
|
||||||
|
|
@ -146,10 +145,11 @@ class OrderController extends AdminController
|
||||||
$query = call_user_func_array([$query, $value['method']], $value['arguments'] ?? []);
|
$query = call_user_func_array([$query, $value['method']], $value['arguments'] ?? []);
|
||||||
});
|
});
|
||||||
$count = $query->count();
|
$count = $query->count();
|
||||||
$total_amount = number_format($query->sum('total_amount') / 100);
|
$total_amount = round($query->sum('total_amount') / 100, 2, PHP_ROUND_HALF_DOWN);
|
||||||
$market_price = number_format($query->sum('market_price') / 100);
|
$market_price = round($query->sum('market_price') / 100, 2, PHP_ROUND_HALF_DOWN);
|
||||||
$cost_price = number_format($query->sum('cost_price') / 100);
|
$cost_price = round($query->sum('cost_price') / 100, 2, PHP_ROUND_HALF_DOWN);
|
||||||
$sales_value = number_format($query->sum('sales_value'));
|
$sales_value = round($query->sum('sales_value'), 2, PHP_ROUND_HALF_DOWN);
|
||||||
|
$profit = round($total_amount - $cost_price, 2, PHP_ROUND_HALF_DOWN);
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
@ -157,8 +157,7 @@ class OrderController extends AdminController
|
||||||
<td>统计</td>
|
<td>统计</td>
|
||||||
<td>订单数: $count</td>
|
<td>订单数: $count</td>
|
||||||
<td>订单总额: $total_amount</td>
|
<td>订单总额: $total_amount</td>
|
||||||
<td>市场价: $market_price</td>
|
<td>总毛利: $profit</td>
|
||||||
<td>成本价: $cost_price</td>
|
|
||||||
<td>成长值: $sales_value</td>
|
<td>成长值: $sales_value</td>
|
||||||
<tr>
|
<tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
@ -184,6 +183,10 @@ class OrderController extends AdminController
|
||||||
$show->field('cost_price')->as(function ($value) {
|
$show->field('cost_price')->as(function ($value) {
|
||||||
return bcdiv($value, 100, 2);
|
return bcdiv($value, 100, 2);
|
||||||
});
|
});
|
||||||
|
$show->field('products_total_amount')->as(fn($value) => bcdiv($value, 100, 2));
|
||||||
|
$show->field('coupon_discount_amount')->as(fn($value) => bcdiv($value, 100, 2));
|
||||||
|
// $show->field('vip_discount_amount')->as(fn($value) => bcdiv($value, 100, 2));
|
||||||
|
$show->field('total_amount', '支付金额')->as(fn($value) => bcdiv($value, 100, 2));
|
||||||
$show->field('sales_value');
|
$show->field('sales_value');
|
||||||
$show->field('order_status')->as(function ($v) {
|
$show->field('order_status')->as(function ($v) {
|
||||||
return $this->order_status;
|
return $this->order_status;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use Dcat\Admin\Http\Controllers\AdminController;
|
||||||
use Dcat\Admin\Models\Administrator;
|
use Dcat\Admin\Models\Administrator;
|
||||||
use App\Models\{ProductCategory, ProductSku};
|
use App\Models\{ProductCategory, ProductSku};
|
||||||
use App\Models\Store\{Store, ProductSku as StoreProductSku};
|
use App\Models\Store\{Store, ProductSku as StoreProductSku};
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class ProductController extends AdminController
|
class ProductController extends AdminController
|
||||||
{
|
{
|
||||||
|
|
@ -57,9 +58,22 @@ class ProductController extends AdminController
|
||||||
return bcdiv($value, 100, 2);
|
return bcdiv($value, 100, 2);
|
||||||
});
|
});
|
||||||
$grid->column('productSku.sell_price', '销售价')->display(function ($value) {
|
$grid->column('productSku.sell_price', '销售价')->display(function ($value) {
|
||||||
return bcdiv($value, 100, 2);;
|
return bcdiv($value, 100, 2);
|
||||||
|
});
|
||||||
|
$grid->column('amount', '库存');
|
||||||
|
$grid->column('profit', '毛利')->display(function () {
|
||||||
|
$sell_price = data_get($this->productSku, 'sell_price');
|
||||||
|
$cost_price = data_get($this->productSku, 'cost_price');
|
||||||
|
return round(($sell_price - $cost_price) / 100, 2, PHP_ROUND_HALF_DOWN);
|
||||||
|
});
|
||||||
|
$grid->column('cost', '成本')->display(function () {
|
||||||
|
$cost_price = data_get($this->productSku, 'cost_price');
|
||||||
|
return round($cost_price / 100 * $this->amount, 2, PHP_ROUND_HALF_DOWN);
|
||||||
|
});
|
||||||
|
$grid->column('sell', '销售')->display(function () {
|
||||||
|
$sell_price = data_get($this->productSku, 'sell_price');
|
||||||
|
return round($sell_price / 100 * $this->amount, 2, PHP_ROUND_HALF_DOWN);
|
||||||
});
|
});
|
||||||
$grid->column('amount', '库存')->editable();
|
|
||||||
$grid->column('status', '状态')->switch();
|
$grid->column('status', '状态')->switch();
|
||||||
$grid->paginate(10);
|
$grid->paginate(10);
|
||||||
|
|
||||||
|
|
@ -71,7 +85,10 @@ class ProductController extends AdminController
|
||||||
$grid->filter(function (Grid\Filter $filter) {
|
$grid->filter(function (Grid\Filter $filter) {
|
||||||
$filter->panel();
|
$filter->panel();
|
||||||
$filter->equal('store_id')->select('api/store')->width(3);
|
$filter->equal('store_id')->select('api/store')->width(3);
|
||||||
$filter->equal('productSku.category_id', '分类')->select(admin_route('api.product_categories', ['level' => 2]))->width(3);
|
$filter->where('category_id', function ($q) {
|
||||||
|
$id = $this->input;
|
||||||
|
$q->whereHas('productSku', fn($q1) => $q1->filter(['category' => $id], \App\Endpoint\Api\Filters\ProductSkuFilter::class));
|
||||||
|
}, '分类')->select(ProductCategory::selectOptions())->width(3);
|
||||||
$filter->like('productSku.name', '名称')->width(3);
|
$filter->like('productSku.name', '名称')->width(3);
|
||||||
});
|
});
|
||||||
$grid->tools(function (Grid\Tools $tools) {
|
$grid->tools(function (Grid\Tools $tools) {
|
||||||
|
|
@ -89,22 +106,22 @@ class ProductController extends AdminController
|
||||||
$query = call_user_func_array([$query, $value['method']], $value['arguments'] ?? []);
|
$query = call_user_func_array([$query, $value['method']], $value['arguments'] ?? []);
|
||||||
});
|
});
|
||||||
$count = $query->count();
|
$count = $query->count();
|
||||||
$market_price = 0;
|
$sell_price = round($query->sum('product_skus.sell_price') / 100, 2, PHP_ROUND_HALF_DOWN);
|
||||||
$cost_price = 0;
|
$cost_price = round($query->sum('product_skus.cost_price') / 100, 2, PHP_ROUND_HALF_DOWN);
|
||||||
$market_price = number_format($query->sum('product_skus.market_price') / 100);
|
$stock = round($query->sum('store_product_skus.amount'), 2, PHP_ROUND_HALF_DOWN);
|
||||||
$cost_price = number_format($query->sum('product_skus.cost_price') / 100);
|
$cost = round($query->sum(DB::raw('product_skus.cost_price * amount')) / 100, 2, PHP_ROUND_HALF_DOWN);
|
||||||
$stock = number_format($query->sum('store_product_skus.amount'));
|
$sell = round($query->sum(DB::raw('product_skus.sell_price * amount')) / 100, 2, PHP_ROUND_HALF_DOWN);
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>统计</td>
|
<td>统计</td>
|
||||||
<td>总数: $count</td>
|
<td>总数: $count</td>
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td>成本价: $cost_price</td>
|
<td>成本价: $cost_price</td>
|
||||||
<td>销售价: $market_price</td>
|
<td>销售价: $sell_price</td>
|
||||||
<td>库存: $stock</td>
|
<td>库存: $stock</td>
|
||||||
|
<td>总成本: $cost</td>
|
||||||
|
<td>总销售: $sell</td>
|
||||||
<tr>
|
<tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
@ -120,7 +137,6 @@ class ProductController extends AdminController
|
||||||
$form->select('product_sku_id')->options(ProductSku::class)->ajax('api/product-skus');
|
$form->select('product_sku_id')->options(ProductSku::class)->ajax('api/product-skus');
|
||||||
$form->hidden('product_spu_id');
|
$form->hidden('product_spu_id');
|
||||||
$form->switch('status', '状态')->default(1);
|
$form->switch('status', '状态')->default(1);
|
||||||
$form->number('amount');
|
|
||||||
$form->saving(function (Form $form) {
|
$form->saving(function (Form $form) {
|
||||||
if ($form->isCreating()) {
|
if ($form->isCreating()) {
|
||||||
$store_id = $form->input('store_id');
|
$store_id = $form->input('store_id');
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Admin\Controllers\Store;
|
||||||
|
|
||||||
|
use Dcat\Admin\Http\Controllers\AdminController;
|
||||||
|
use Dcat\Admin\{Form, Grid, Admin, Show};
|
||||||
|
use App\Models\Store\{Store, StockBatch, StockLog};
|
||||||
|
use App\Models\{ProductSku};
|
||||||
|
use Dcat\Admin\Widgets\Table;
|
||||||
|
use App\Models\Admin\Administrator;
|
||||||
|
|
||||||
|
class StockBatchController extends AdminController
|
||||||
|
{
|
||||||
|
protected $translation = 'store-stock-bacth';
|
||||||
|
|
||||||
|
protected function grid()
|
||||||
|
{
|
||||||
|
return Grid::make(StockBatch::with(['store', 'adminUser', 'tag', 'productSkus']), function (Grid $grid) {
|
||||||
|
$grid->model()->orderBy('created_at', 'desc');
|
||||||
|
|
||||||
|
$grid->column('sn');
|
||||||
|
$grid->column('store_id')->display(fn() => data_get($this->store, 'title'));
|
||||||
|
$grid->column('tag_id')->display(fn() => data_get($this->tag, 'name'));
|
||||||
|
$grid->column('admin_user_id')->display(fn() => data_get($this->adminUser, 'name'));
|
||||||
|
$grid->column('status')->using([0 => '未确认', 1 => '已确认'])->label([0 => 'danger', 1 => 'success']);
|
||||||
|
$grid->column('product_sku_id')->display(fn() => '共'.$this->productSkus->count().'件')->modal(function ($modal) {
|
||||||
|
$modal->title('商品记录');
|
||||||
|
$data = $this->productSkus->map(fn($item) => [$item->name, $item->pivot?->amount])->all();
|
||||||
|
return Table::make(['名称', '数量'], $data);
|
||||||
|
});
|
||||||
|
$grid->column('remarks')->editable();
|
||||||
|
$grid->column('created_at');
|
||||||
|
|
||||||
|
$grid->filter(function (Grid\Filter $filter) {
|
||||||
|
$filter->panel();
|
||||||
|
$filter->equal('store_id')->select('api/store')->width(3);
|
||||||
|
$filter->equal('tag_id', '类目')->select(StockLog::tags()->pluck('name', 'id'))->width(3);
|
||||||
|
$filter->equal('admin_user_id')->select()->model(Administrator::class)->ajax('api/administrators?_paginate=1')->width(3);
|
||||||
|
$filter->equal('status')->select([0 => '未确认', 1 => '已确认'])->width(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
$user = Admin::user();
|
||||||
|
$grid->showCreateButton($user->can('dcat.admin.store.batch.create'));
|
||||||
|
$grid->showViewButton($user->can('dcat.admin.store.batch.show'));
|
||||||
|
|
||||||
|
$grid->actions(function (Grid\Displayers\Actions $actions) use ($user) {
|
||||||
|
$row = $actions->row;
|
||||||
|
if (!$row->status) {
|
||||||
|
$actions->append(new \App\Admin\Actions\Store\RowAddStock());
|
||||||
|
}
|
||||||
|
|
||||||
|
$actions->delete($user->can('dcat.admin.store.batch.destroy') && !$row->status);
|
||||||
|
$actions->edit($user->can('dcat.admin.store.batch.edit') && !$row->status);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function form()
|
||||||
|
{
|
||||||
|
return Form::make(StockBatch::with(['productSkus']), function (Form $form) {
|
||||||
|
$fullForm = $form->isCreating() || ($form->isEditing() && $form->model()->status == 0);
|
||||||
|
if ($fullForm) {
|
||||||
|
$form->text('sn')->required();
|
||||||
|
$form->select('store_id')->options(Store::pluck('title', 'id'))->required();
|
||||||
|
$form->select('tag_id')->options(StockLog::tags()->pluck('name', 'id'))->required();
|
||||||
|
$form->text('remarks');
|
||||||
|
$form->hidden('admin_user_id')->value(Admin::user()->id);
|
||||||
|
|
||||||
|
$form->table('productSkus', function (Form\NestedForm $form) {
|
||||||
|
$form->select('product_sku_id')->options(ProductSku::class)->ajax('api/product-skus');
|
||||||
|
$form->text('amount')->help('正数为增加, 负数为减少');
|
||||||
|
})->saving(function ($value) {
|
||||||
|
$result = [];
|
||||||
|
if ($value) {
|
||||||
|
$products = ProductSku::whereIn('id', array_column($value, 'product_sku_id'))->get();
|
||||||
|
foreach($value as $item) {
|
||||||
|
$product = $products->firstWhere('id', $item['product_sku_id']);
|
||||||
|
if ($product) {
|
||||||
|
array_push($result, [
|
||||||
|
'product_sku_id' => $product->id,
|
||||||
|
'product_spu_id' => $product->spu_id,
|
||||||
|
'amount' => $item['amount']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$form->text('sn')->required();
|
||||||
|
$form->text('remarks');
|
||||||
|
}
|
||||||
|
|
||||||
|
$form->disableCreatingCheck();
|
||||||
|
$form->disableEditingCheck();
|
||||||
|
$form->disableResetButton();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function detail($id)
|
||||||
|
{
|
||||||
|
return Show::make($id, StockBatch::with(['store', 'adminUser', 'tag', 'productSkus']), function (Show $show) {
|
||||||
|
$show->field('sn');
|
||||||
|
$show->field('store_id')->as(fn() => $this->store?->title);
|
||||||
|
$show->field('tag_id')->as(fn() => $this->tag?->name);
|
||||||
|
$show->field('admin_user_id')->as(fn() => $this->adminUser?->name);
|
||||||
|
$show->field('remarks');
|
||||||
|
$show->field('product_sku_id')->as(function () {
|
||||||
|
$data = $this->productSkus->map(fn($item) => [$item->name, $item->pivot?->amount])->all();
|
||||||
|
return Table::make(['名称', '数量'], $data);
|
||||||
|
})->unescape();
|
||||||
|
|
||||||
|
$user = Admin::user();
|
||||||
|
$model = $show->model();
|
||||||
|
|
||||||
|
$show->disableEditButton(!$user->can('dcat.admin.store.batch.edit') || $model->status);
|
||||||
|
$show->disableDeleteButton(!$user->can('dcat.admin.store.batch.destroy') || $model->status);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -169,6 +169,7 @@ Route::group([
|
||||||
$router->get('api/product-by-store', 'Store\ProductController@listByStore')->name('api.store_product');
|
$router->get('api/product-by-store', 'Store\ProductController@listByStore')->name('api.store_product');
|
||||||
$router->get('api/store', 'Store\StoreController@list')->name('api.store');
|
$router->get('api/store', 'Store\StoreController@list')->name('api.store');
|
||||||
$router->post('api/wang-editor/upload', 'WangEditoController@upload')->name('api.wang-editor.upload');
|
$router->post('api/wang-editor/upload', 'WangEditoController@upload')->name('api.wang-editor.upload');
|
||||||
|
$router->get('api/administrators', 'AdministratorController@list')->name('api.administrators');
|
||||||
|
|
||||||
// 抽奖管理
|
// 抽奖管理
|
||||||
$router->resource('draw-prizes', 'Draw\DrawPrizeController')->names('draw_prizes');
|
$router->resource('draw-prizes', 'Draw\DrawPrizeController')->names('draw_prizes');
|
||||||
|
|
@ -192,6 +193,7 @@ Route::group([
|
||||||
$router->resource('store/user', 'Store\UserController')->only(['index'])->names('store.user');
|
$router->resource('store/user', 'Store\UserController')->only(['index'])->names('store.user');
|
||||||
$router->resource('store/order', 'Store\OrderController')->only(['index', 'show'])->names('store.order');
|
$router->resource('store/order', 'Store\OrderController')->only(['index', 'show'])->names('store.order');
|
||||||
$router->resource('store/stock', 'Store\StockController')->only(['index', 'create', 'store', 'show'])->names('store.stock');
|
$router->resource('store/stock', 'Store\StockController')->only(['index', 'create', 'store', 'show'])->names('store.stock');
|
||||||
|
$router->resource('store/batch', 'Store\StockBatchController')->names('store.batch');
|
||||||
|
|
||||||
$router->resource('profit', 'OrderProfitController');
|
$router->resource('profit', 'OrderProfitController');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\Store;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||||
|
use App\Models\Tag;
|
||||||
|
use App\Models\Admin\Administrator;
|
||||||
|
|
||||||
|
class StockBatch extends Model
|
||||||
|
{
|
||||||
|
use HasDateTimeFormatter;
|
||||||
|
|
||||||
|
protected $table = 'store_stock_batches';
|
||||||
|
|
||||||
|
protected $fillable = ['admin_user_id', 'store_id', 'remarks', 'sn', 'tag_id', 'status'];
|
||||||
|
|
||||||
|
protected $attributes = [
|
||||||
|
'status' => 0
|
||||||
|
];
|
||||||
|
|
||||||
|
public function store()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Store::class, 'store_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function adminUser()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Administrator::class, 'admin_user_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tag()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Tag::class, 'tag_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function productSkus()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(\App\Models\ProductSku::class, 'store_stock_batch_goods', 'batch_id', 'product_sku_id')->withPivot('amount');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function logs()
|
||||||
|
{
|
||||||
|
return $this->morphMany(StockLog::class, 'source');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -57,6 +57,7 @@ class AppServiceProvider extends ServiceProvider
|
||||||
'admin_users' => \App\Models\Admin\Administrator::class,
|
'admin_users' => \App\Models\Admin\Administrator::class,
|
||||||
'user_vip' => \App\Models\UserVip::class,
|
'user_vip' => \App\Models\UserVip::class,
|
||||||
'draw_log' => \App\Models\DrawLog::class,
|
'draw_log' => \App\Models\DrawLog::class,
|
||||||
|
'store_stock_batch' => \App\Models\Store\StockBatch::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
JsonResource::withoutWrapping();
|
JsonResource::withoutWrapping();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateStoreStockBatchesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('store_stock_batches', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('store_id')->comment('门店');
|
||||||
|
$table->unsignedBigInteger('admin_user_id')->comment('操作人');
|
||||||
|
$table->string('sn')->comment('批次号');
|
||||||
|
$table->unsignedBigInteger('tag_id')->comment('变更类目(tags.id)');
|
||||||
|
$table->string('remarks')->nullable()->comment('备注');
|
||||||
|
$table->unsignedInteger('status')->default(0)->comment('0: 未确认, 1: 已确认');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('store_stock_batch_goods', function (Blueprint $table) {
|
||||||
|
$table->unsignedBigInteger('batch_id');
|
||||||
|
$table->unsignedBigInteger('product_sku_id');
|
||||||
|
$table->unsignedBigInteger('product_spu_id');
|
||||||
|
$table->integer('amount')->comment('数量');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('store_stock_batches');
|
||||||
|
Schema::dropIfExists('store_stock_batch_goods');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -94,6 +94,7 @@ class AdminMenuSeeder extends Seeder
|
||||||
['title' => '员工业绩', 'uri' => 'store/user', 'icon' => ''],
|
['title' => '员工业绩', 'uri' => 'store/user', 'icon' => ''],
|
||||||
['title' => '订单管理', 'uri' => 'store/order', 'icon' => ''],
|
['title' => '订单管理', 'uri' => 'store/order', 'icon' => ''],
|
||||||
['title' => '库存管理', 'uri' => 'store/stock', 'icon' => ''],
|
['title' => '库存管理', 'uri' => 'store/stock', 'icon' => ''],
|
||||||
|
['title' => '库存批次', 'uri' => 'store/batch', 'icon' => ''],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -333,6 +333,7 @@ class AdminPermissionSeeder extends Seeder
|
||||||
'user' => ['name' => '员工业绩', 'curd' => ['index']],
|
'user' => ['name' => '员工业绩', 'curd' => ['index']],
|
||||||
'order' => ['name' => '订单管理', 'curd' => ['index', 'show']],
|
'order' => ['name' => '订单管理', 'curd' => ['index', 'show']],
|
||||||
'stock' => ['name' => '库存管理', 'curd' => ['index', 'create', 'store', 'show']],
|
'stock' => ['name' => '库存管理', 'curd' => ['index', 'create', 'store', 'show']],
|
||||||
|
'batch' => ['name' => '批次管理', 'curd' => true],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'profit' => [
|
'profit' => [
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'labels' => [
|
||||||
|
'store' => '门店管理',
|
||||||
|
'StockBatch' => '库存批次',
|
||||||
|
'batch' => '库存批次',
|
||||||
|
],
|
||||||
|
'fields' => [
|
||||||
|
'sn' => '批次号',
|
||||||
|
'tag_id' => '类目',
|
||||||
|
'remarks' => '备注',
|
||||||
|
'productSkus' => '商品',
|
||||||
|
'store_id' => '门店',
|
||||||
|
'product_sku_id' => '商品',
|
||||||
|
'amount' => '数量',
|
||||||
|
'admin_user_id' => '操作人',
|
||||||
|
'status' => '状态',
|
||||||
|
],
|
||||||
|
'options' => [
|
||||||
|
],
|
||||||
|
];
|
||||||
Loading…
Reference in New Issue