admin 门店管理
parent
3c5ccf66be
commit
822f64fee9
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers\Store;
|
||||
|
||||
use Dcat\Admin\Form;
|
||||
use App\Models\Store\Store;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Layout\Content;
|
||||
use Dcat\Admin\Models\Administrator;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Dcat\Admin\Traits\HasFormResponse;
|
||||
|
||||
class AdministratorController extends Controller
|
||||
{
|
||||
use HasFormResponse;
|
||||
public function create($store_id)
|
||||
{
|
||||
$store = Store::findOrFail($store_id);
|
||||
$form = Form::make();
|
||||
$form->tree('administrator_id', '选择管理员')
|
||||
->nodes(Administrator::all()->toArray())
|
||||
->value($store->administrators()->select(['admin_users.id', 'admin_users.name', 'admin_users.username'])->pluck('id'))
|
||||
->setTitleColumn('name');
|
||||
return (new Content())->title('新增')->body($form);
|
||||
}
|
||||
|
||||
public function store($store_id, Request $request)
|
||||
{
|
||||
$store = Store::findOrFail($store_id);
|
||||
if ($request->input('administrator_id')) {
|
||||
$admin_ids = explode(',', $request->input('administrator_id'));
|
||||
$store->administrators()->sync($admin_ids);
|
||||
} else {
|
||||
$store->administrators()->detach();
|
||||
}
|
||||
|
||||
return $this->sendResponse($this->response()->success(trans('admin.save_succeeded')));
|
||||
}
|
||||
|
||||
public function destroy($store_id, $id)
|
||||
{
|
||||
$store = Store::findOrFail($store_id);
|
||||
$admin_ids = explode(',', $id);
|
||||
$store->administrators()->detach($admin_ids);
|
||||
return $this->sendResponse($this->response()->success(trans('admin.delete_succeeded')));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers\Store;
|
||||
|
||||
use Dcat\Admin\{Form, Grid, Admin};
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use App\Models\Order;
|
||||
use App\Enums\PayWay;
|
||||
|
||||
class OrderController extends AdminController
|
||||
{
|
||||
protected $translation = 'store-order';
|
||||
protected function grid()
|
||||
{
|
||||
$grid = new Grid(Order::with(['user', 'inviter']));
|
||||
$grid->model()->whereNotNull('inviter_id');
|
||||
|
||||
$grid->column('sn')->copyable();
|
||||
$grid->column('user.phone')->copyable();
|
||||
$grid->column('inviter.phone')->copyable();
|
||||
$grid->column('total_amount')->display(function ($value) {
|
||||
return bcdiv($value, 100, 2);
|
||||
})->prepend('¥');
|
||||
$grid->column('sales_value');
|
||||
$grid->column('order_status')->using([
|
||||
0 => '待付款',
|
||||
1 => '待发货',
|
||||
2 => '发货中',
|
||||
3 => '已发货',
|
||||
9 => '已完成',
|
||||
10 => '已取消',
|
||||
])->dot([
|
||||
0=>'primary',
|
||||
1=>'warning',
|
||||
2=>'danger',
|
||||
3=>'success',
|
||||
9=>'success',
|
||||
10=>'#b3b9bf',
|
||||
]);
|
||||
$grid->column('pay_way')->display(function ($v) {
|
||||
return $v?->mallText();
|
||||
})->circleDot(PayWay::colors());
|
||||
$grid->column('pay_at');
|
||||
$grid->column('created_at');
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->like('sn')->width(3);
|
||||
$filter->like('user.phone')->width(3);
|
||||
$filter->like('inviter.phone')->width(3);
|
||||
$filter->between('created_at')->dateTime()->width(7);
|
||||
});
|
||||
return $grid;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,73 +2,76 @@
|
|||
|
||||
namespace App\Admin\Controllers\Store;
|
||||
|
||||
use App\Models\Store\{Store, StockLog};
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\{Form, Grid};
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Layout\Content;
|
||||
use Dcat\Admin\Models\Administrator;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Dcat\Admin\Traits\HasFormResponse;
|
||||
use App\Models\ProductSku;
|
||||
use App\Models\{ProductCategory, ProductSku};
|
||||
use App\Models\Store\{Store, ProductSku as StoreProductSku};
|
||||
|
||||
class ProductController extends Controller
|
||||
class ProductController extends AdminController
|
||||
{
|
||||
use HasFormResponse;
|
||||
public function index($store_id, Request $request)
|
||||
protected $translation = 'store-product';
|
||||
|
||||
public function listByStore()
|
||||
{
|
||||
$store = Store::findOrFail($store_id);
|
||||
$query = $store->productSkus();
|
||||
if ($request->filled('key')) {
|
||||
$query->where('name', 'like', '%'.$request->input('key').'%');
|
||||
$list = StoreProductSku::with(['productSku'])->where('store_id', request('q'))->get();
|
||||
$data = [];
|
||||
foreach($list as $item) {
|
||||
array_push($data, ['id' => $item->productSku->id, 'text' => $item->productSku->name]);
|
||||
}
|
||||
$list = $query->paginate();
|
||||
return $list;
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function create($store_id)
|
||||
protected function grid()
|
||||
{
|
||||
$store = Store::findOrFail($store_id);
|
||||
$form = Form::make();
|
||||
$form->select('product', '商品')->options(ProductSku::class)->ajax('api/product-skus');
|
||||
$form->switch('status', '上架')->default(1);
|
||||
return (new Content())->title('新增')->body($form);
|
||||
$grid = new Grid(StoreProductSku::with(['store', 'productSku.category']));
|
||||
$grid->model()->orderBy('id', 'desc');
|
||||
|
||||
$grid->column('id', 'ID');
|
||||
$grid->column('store.title', '店铺');
|
||||
$grid->column('productSku.category.name', '分类');
|
||||
$grid->column('productSku.name', '名称');
|
||||
$grid->column('productSku.cost_price', '成本价')->display(function ($value) {
|
||||
return bcdiv($value, 100, 2);;
|
||||
});
|
||||
$grid->column('productSku.sell_price', '销售价')->display(function ($value) {
|
||||
return bcdiv($value, 100, 2);;
|
||||
});
|
||||
$grid->column('amount', '库存')->sortable();
|
||||
$grid->column('productSku.specs', '规格')->label();
|
||||
$grid->column('status', '状态')->switch();
|
||||
$grid->paginate(10);
|
||||
|
||||
$grid->showCreateButton();
|
||||
$grid->enableDialogCreate();
|
||||
|
||||
$grid->showDeleteButton();
|
||||
// $grid->showRowSelector();
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->equal('store_id')->select(Store::pluck('title', 'id'))->width(3);
|
||||
$filter->equal('productSku.category_id', '分类')->select(ProductCategory::withDepth()->having('depth', '=', 2)->pluck('name', 'id'))->width(3);
|
||||
$filter->like('productSku.name', '名称')->width(3);
|
||||
});
|
||||
return $grid;
|
||||
}
|
||||
|
||||
public function store($store_id, Request $request)
|
||||
protected function form()
|
||||
{
|
||||
$store = Store::findOrFail($store_id);
|
||||
$product_id = $request->input('product');
|
||||
if ($product_id) {
|
||||
$product = $store->productSkus()->find($product_id);
|
||||
if ($product) {
|
||||
$store->productSkus()->updateExistingPivot($product_id, $request->only(['status']));
|
||||
} else {
|
||||
$store->productSkus()->attach([
|
||||
$product_id => $request->only(['status'])
|
||||
]);
|
||||
$form = Form::make(StoreProductSku::with(['productSku']));
|
||||
$form->select('store_id')->options(Store::pluck('title', 'id'));
|
||||
$form->select('product_sku_id')->options(ProductSku::class)->ajax('api/product-skus');
|
||||
$form->switch('status')->default(1);
|
||||
$form->saving(function (Form $form) {
|
||||
if ($form->isCreating()) {
|
||||
$store_id = $form->input('store_id');
|
||||
$product_sku_id = $form->input('product_sku_id');
|
||||
if (StoreProductSku::where(compact('store_id', 'product_sku_id'))->exists()) {
|
||||
return $form->response()->error('该商品已经存在');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->sendResponse($this->response()->success(trans('admin.save_succeeded')));
|
||||
}
|
||||
|
||||
public function update($store_id, $id, Request $request)
|
||||
{
|
||||
$store = Store::findOrFail($store_id);
|
||||
$product = $store->productSkus()->wherePivot('id', $id)->firstOrFail();
|
||||
$store->productSkus()->updateExistingPivot($product->id, $request->only(['status']));
|
||||
return $this->sendResponse($this->response()->success(trans('admin.update_succeeded')));
|
||||
}
|
||||
|
||||
public function destroy($store_id, $id)
|
||||
{
|
||||
$store = Store::findOrFail($store_id);
|
||||
$product = $store->productSkus()->wherePivot('id', $id)->firstOrFail();
|
||||
// 删除库存记录
|
||||
$store->stockLogs()->where('product_sku_id', $product->id)->delete();
|
||||
// 删除商品关联
|
||||
$store->productSkus()->wherePivot('id', $id)->detach();
|
||||
return $this->sendResponse($this->response()->success(trans('admin.delete_succeeded')));
|
||||
});
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,69 +2,91 @@
|
|||
|
||||
namespace App\Admin\Controllers\Store;
|
||||
|
||||
use App\Models\Store\Store;
|
||||
use App\Models\Tag;
|
||||
use Dcat\Admin\{Form, Admin};
|
||||
use App\Models\Store\{Store, StockLog, ProductSku};
|
||||
use Dcat\Admin\{Form, Grid, Admin};
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Dcat\Admin\Layout\Content;
|
||||
use Dcat\Admin\Models\Administrator;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Dcat\Admin\Traits\HasFormResponse;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StockController extends Controller
|
||||
class StockController extends AdminController
|
||||
{
|
||||
use HasFormResponse;
|
||||
|
||||
public function create($store_id)
|
||||
protected $translation = 'store-stock';
|
||||
protected function grid()
|
||||
{
|
||||
$store = Store::findOrFail($store_id);
|
||||
$form = Form::make();
|
||||
$form->select('tag', '类目')->options(Tag::where('type', Tag::TYPE_STORE_STOCK)->pluck('name', 'id'));
|
||||
$form->text('tag_name', '自定义类目');
|
||||
$form->select('product', '商品')->options($store->productSkus()->select(['store_product_skus.id', 'product_skus.name'])->pluck('name', 'id'))->required();
|
||||
$form->number('amount', '库存')->help('正数为增加, 负数为减少')->default(0)->required();
|
||||
$form->text('remarks', '备注');
|
||||
return (new Content())->title('新增')->body($form);
|
||||
$grid = new Grid(StockLog::with(['store', 'productSku', 'tag']));
|
||||
|
||||
$grid->model()->orderBy('created_at', 'desc');
|
||||
|
||||
$grid->column('store.title', '门店');
|
||||
$grid->column('productSku.name', '商品');
|
||||
$grid->column('tag.name', '类目');
|
||||
$grid->column('amount')->display(function ($value) {
|
||||
return '<span class="text-'.($value > 0 ? 'success' : 'danger') .'">'.$value.'</span>';
|
||||
});
|
||||
$grid->column('balance');
|
||||
$grid->column('operator', '操作人')->display(function ($v) {
|
||||
if ($v instanceof \App\Models\Admin\Administrator) {
|
||||
return $v->name . '<span class="label bg-primary">管理员</span>';
|
||||
} else if ($v instanceof \App\Models\User) {
|
||||
return $v->phone . '<span class="label bg-info">员工</span>';
|
||||
}
|
||||
|
||||
return '未知身份';
|
||||
});
|
||||
$grid->column('remarks', '备注');
|
||||
$grid->column('created_at', '操作时间');
|
||||
|
||||
$grid->disableActions();
|
||||
$grid->showCreateButton();
|
||||
$grid->enableDialogCreate();
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->equal('store_id')->select(Store::pluck('title', 'id'))->width(3);
|
||||
$filter->equal('tag.name', '类目')->select(StockLog::tags()->pluck('name', 'id'))->width(3);
|
||||
});
|
||||
return $grid;
|
||||
}
|
||||
|
||||
public function store($store_id, Request $request)
|
||||
protected function form()
|
||||
{
|
||||
$request->validate([
|
||||
'amount' => ['required', Rule::notIn([0])],
|
||||
'product' => 'required',
|
||||
'tag' => 'required_without:tag_name'
|
||||
], [
|
||||
'amount.not_in' => '库存不能为0',
|
||||
'tag.required_without' => '类目必填',
|
||||
]);
|
||||
if ($request->filled('tag')) {
|
||||
$tag = Tag::findOrFail($request->input('tag'));
|
||||
} else {
|
||||
$tag = Tag::firstOrCreate([
|
||||
'type' => Tag::TYPE_STORE_STOCK,
|
||||
'name' => $request->input('tag_name')
|
||||
]);
|
||||
}
|
||||
$store = Store::findOrFail($store_id);
|
||||
$product = $store->productSkus()->wherePivot('id', $request->input('product'))->firstOrFail();
|
||||
$administrator = Admin::user();
|
||||
$amount = $request->input('amount');
|
||||
if ($product->pivot->amount + $amount < 0) {
|
||||
return $this->sendResponse($this->response()->error('扣减库存不能超过现有库存'));
|
||||
}
|
||||
$store->productSkus()->updateExistingPivot($product->id, [
|
||||
'amount' => $product->pivot->amount + $amount
|
||||
]);
|
||||
$store->stockLogs()->create([
|
||||
'operator_type' => get_class($administrator),
|
||||
'operator_id' => $administrator->id,
|
||||
'amount' => $request->input('amount'),
|
||||
'product_sku_id' => $product->id,
|
||||
'remarks' => $request->input('remarks'),
|
||||
'tag_id' => $tag->id
|
||||
]);
|
||||
return $this->sendResponse($this->response()->success(trans('admin.save_succeeded')));
|
||||
$form = Form::make(new StockLog());
|
||||
$form->select('tag_id')->options(StockLog::tags()->pluck('name', 'id'))->required();
|
||||
$form->select('store_id')->options(Store::pluck('title', 'id'))->required()->load('product_sku_id', 'store/product-by-store');
|
||||
$form->select('product_sku_id')->required();
|
||||
$form->number('amount')->help('正数为增加, 负数为减少')->default(0)->required();
|
||||
$form->text('remarks');
|
||||
$form->hidden('operator_type');
|
||||
$form->hidden('operator_id');
|
||||
$form->hidden('balance');
|
||||
|
||||
$form->saving(function (Form $form) {
|
||||
if ($form->isCreating()) {
|
||||
$store_id = $form->input('store_id');
|
||||
$product_sku_id = $form->input('product_sku_id');
|
||||
$amount = $form->input('amount');
|
||||
if ($amount == 0) {
|
||||
return $form->response()->error('数量不能为0');
|
||||
}
|
||||
$product = ProductSku::where(compact('store_id', 'product_sku_id'))->first();
|
||||
if (!$product) {
|
||||
return $form->response()->error('门店不存在该商品');
|
||||
}
|
||||
|
||||
// 修改库存
|
||||
$balance = $product->amount + $amount;
|
||||
if ($balance < 0) {
|
||||
return $form->response()->error('商品库存不能小于0');
|
||||
}
|
||||
$form->input('balance', $balance);
|
||||
$product->update([
|
||||
'amount' => $balance
|
||||
]);
|
||||
|
||||
// 操作人
|
||||
$administrator = Admin::user();
|
||||
$form->input('operator_type', get_class($administrator));
|
||||
$form->input('operator_id', $administrator->id);
|
||||
}
|
||||
});
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,17 +10,18 @@ use Dcat\Admin\Http\Controllers\AdminController;
|
|||
use Carbon\Carbon;
|
||||
use Dcat\Admin\Admin;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Dcat\Admin\Models\Administrator;
|
||||
use App\Models\Admin\Administrator;
|
||||
use Dcat\Admin\Layout\Row;
|
||||
use Dcat\Admin\Widgets\{Box, Tab, Card};
|
||||
use Dcat\Admin\Layout\Content;
|
||||
|
||||
class StoreController extends AdminController
|
||||
{
|
||||
/**
|
||||
* Make a grid builder.
|
||||
*
|
||||
* @return Grid
|
||||
*/
|
||||
public function info(Content $content)
|
||||
{
|
||||
return $content->title('总览');
|
||||
}
|
||||
|
||||
protected function grid()
|
||||
{
|
||||
$query = Store::query();
|
||||
|
|
@ -39,13 +40,13 @@ class StoreController extends AdminController
|
|||
$grid->column('title');
|
||||
$grid->column('image')->image('', 100, 100);
|
||||
$grid->column('status')->switch();
|
||||
$grid->column('sort');
|
||||
$grid->column('sort')->editable();
|
||||
$grid->column('created_at');
|
||||
|
||||
$grid->disableCreateButton(!$canAdmin);
|
||||
$grid->enableDialogCreate();
|
||||
$grid->showEditButton();
|
||||
$grid->showViewButton();
|
||||
$grid->showQuickEditButton();
|
||||
$grid->showDeleteButton($canAdmin);
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
|
|
@ -64,15 +65,7 @@ class StoreController extends AdminController
|
|||
*/
|
||||
protected function detail($id)
|
||||
{
|
||||
$query = Store::query();
|
||||
$user = Admin::user();
|
||||
$canAdmin = $this->canAdmin();
|
||||
if (!$canAdmin) {
|
||||
$ids = DB::table('store_admin_users')->where('administrator_id', $user->id)->pluck('store_id');
|
||||
$query = $query->whereIn('id', $ids);
|
||||
}
|
||||
$row = new Row();
|
||||
$show = Show::make($id, $query, function (Show $show) use ($canAdmin) {
|
||||
$show = Show::make($id, new Store(), function (Show $show) {
|
||||
|
||||
$show->field('id');
|
||||
$show->field('title');
|
||||
|
|
@ -81,22 +74,20 @@ class StoreController extends AdminController
|
|||
$show->field('status')->using([ 0 => '关闭', 1 => '开启' ]);
|
||||
$show->field('remarks');
|
||||
$show->field('created_at');
|
||||
|
||||
$show->panel()->tools(function ($tools) {
|
||||
$tools->disableDelete();
|
||||
});
|
||||
});
|
||||
$row->column(5, $show);
|
||||
return $show;
|
||||
// $row = new Row();
|
||||
// $row->column(5, $show);
|
||||
|
||||
$tab = Tab::make()->withCard();
|
||||
$tab->add('商品', Card::make($this->gridProduct($id)));
|
||||
$tab->add('库存', Card::make($this->gridStock($id)));
|
||||
if ($canAdmin) {
|
||||
$tab->add('管理员', Card::make($this->gridAdmin($id)));
|
||||
}
|
||||
// $tab = Tab::make()->withCard();
|
||||
// $tab->add('商品', Card::make($this->gridProduct($id)));
|
||||
// $tab->add('库存', Card::make($this->gridStock($id)));
|
||||
// if ($canAdmin) {
|
||||
// $tab->add('管理员', Card::make($this->gridAdmin($id)));
|
||||
// }
|
||||
|
||||
$row->column(7, $tab);
|
||||
return $row;
|
||||
// $row->column(7, $tab);
|
||||
// return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -106,18 +97,9 @@ class StoreController extends AdminController
|
|||
*/
|
||||
protected function form()
|
||||
{
|
||||
$query = Store::query();
|
||||
$user = Admin::user();
|
||||
$canAdmin = $this->canAdmin();
|
||||
if (!$canAdmin) {
|
||||
$ids = DB::table('store_admin_users')->where('administrator_id', $user->id)->pluck('store_id');
|
||||
$query = $query->whereIn('id', $ids);
|
||||
}
|
||||
return Form::make($query, function (Form $form) use ($canAdmin) {
|
||||
return Form::make(Store::with(['administrators']), function (Form $form) {
|
||||
$form->display('id');
|
||||
$form->text('title');
|
||||
$form->switch('status')->default(1);
|
||||
$form->number('sort')->min(1)->default(1);
|
||||
$form->image('image')
|
||||
->required()
|
||||
->move('store/'.Carbon::now()->toDateString())
|
||||
|
|
@ -126,9 +108,24 @@ class StoreController extends AdminController
|
|||
->retainable()
|
||||
->autoUpload();
|
||||
|
||||
$form->tree('administrators', '选择管理员')
|
||||
->nodes(Administrator::all()->toArray())
|
||||
->setTitleColumn('name')
|
||||
->value($form->model()->administrators ? $form->model()->administrators->pluck('id') : '')
|
||||
->customFormat(function ($v) {
|
||||
if (!$v) {
|
||||
return [];
|
||||
}
|
||||
return array_column($v, 'id');
|
||||
});
|
||||
$form->text('remarks');
|
||||
|
||||
$form->switch('status')->default(1);
|
||||
$form->number('sort')->min(1)->default(1);
|
||||
|
||||
$form->disableDeleteButton();
|
||||
$form->footer(function ($footer) {
|
||||
$footer->disableEditingCheck();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Controllers\Store;
|
||||
|
||||
use Dcat\Admin\{Form, Grid, Admin};
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use App\Models\{User, UserInfo};
|
||||
|
||||
class UserController extends AdminController
|
||||
{
|
||||
protected $translation = 'store-user';
|
||||
protected function grid()
|
||||
{
|
||||
$query = UserInfo::with(['user'])
|
||||
->withCount(['inviteOrders', 'inviteUserInfos'])
|
||||
->withSum('inviteOrders', 'total_amount');
|
||||
$grid = Grid::make($query);
|
||||
|
||||
$grid->model()
|
||||
->where('is_company', 1)
|
||||
->orderBy('created_at', 'desc');
|
||||
|
||||
$grid->column('user.id');
|
||||
$grid->column('user.phone', '手机号')->copyable();
|
||||
$grid->column('invite_orders_count', '帮下单数');
|
||||
$grid->column('invite_orders_sum_total_amount', '帮下单总额')->display(function ($value) {
|
||||
return bcdiv($value, 100, 2);
|
||||
});
|
||||
$grid->column('invite_user_infos_count', '邀请人数');
|
||||
$grid->column('user.created_at', '注册时间');
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->like('user.phone', '手机号')->width(3);
|
||||
$filter->between('user.created_at', '注册时间')->dateTime()->width(7);
|
||||
});
|
||||
|
||||
$grid->disableActions();
|
||||
return $grid;
|
||||
}
|
||||
}
|
||||
|
|
@ -53,10 +53,9 @@ class UserController extends AdminController
|
|||
});
|
||||
});
|
||||
$grid->column('phone')->copyable();
|
||||
$grid->column('userInfo.nickname');
|
||||
$grid->column('userInfo.code')->copyable();
|
||||
$grid->column('userInfo.inviterInfo.user.phone')->copyable();
|
||||
$grid->column('userInfo.growth_value')->filter(
|
||||
$grid->column('user_info.code')->copyable();
|
||||
$grid->column('user_info.inviterInfo.user.phone')->copyable();
|
||||
$grid->column('user_info.growth_value')->filter(
|
||||
Grid\Column\Filter\Between::make()
|
||||
)->modal(function ($modal) {
|
||||
$modal->title('成长值');
|
||||
|
|
@ -82,7 +81,7 @@ class UserController extends AdminController
|
|||
// PriceBetween::make()
|
||||
// );
|
||||
|
||||
$grid->column('userInfo.is_company')->bool();
|
||||
$grid->column('user_info.is_company')->bool();
|
||||
$grid->column('created_at')->sortable();
|
||||
$grid->column('status')->using([-1=>'冻结', 1=>'正常', 2=>'禁用'])
|
||||
->dot([
|
||||
|
|
@ -159,9 +158,9 @@ class UserController extends AdminController
|
|||
})->badge();
|
||||
$show->width(6)->field('phone');
|
||||
$show->field('user_info.inviter_info.user.phone');
|
||||
// $show->field('user_info.nickname');
|
||||
// $show->field('user_info.gender')->using(UserInfo::$genderTexts)->label();
|
||||
// $show->field('user_info.birthday');
|
||||
// $show->field('userInfo.nickname');
|
||||
// $show->field('userInfo.gender')->using(UserInfo::$genderTexts)->label();
|
||||
// $show->field('userInfo.birthday');
|
||||
|
||||
$show->field('user_info.growth_value');
|
||||
$show->field('profit');
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ class Product
|
|||
'market_price' => $cells[5] * 100,
|
||||
'cost_price' => $cells[6] * 100,
|
||||
'vip_price' => $cells[7] * 100,
|
||||
'sales_value' => $cells[8] * 100,
|
||||
'sales_value' => $cells[8],
|
||||
]);
|
||||
|
||||
$product = ProductSpu::updateOrCreate(['name' => $goods['name']],$goods);
|
||||
|
|
|
|||
|
|
@ -174,10 +174,14 @@ Route::group([
|
|||
/** 调试接口 **/
|
||||
// $router->get('test', 'HomeController@test');
|
||||
|
||||
$router->resource('store/{store_id}/product', 'Store\ProductController');
|
||||
$router->resource('store/{store_id}/admin', 'Store\AdministratorController');
|
||||
$router->resource('store/{store_id}/stock', 'Store\StockController');
|
||||
$router->resource('store', 'Store\StoreController');
|
||||
$router->get('store/product-by-store', 'Store\ProductController@listByStore');
|
||||
$router->get('store/info', 'Store\StoreController@info');
|
||||
$router->resource('store/list', 'Store\StoreController');
|
||||
$router->resource('store/product', 'Store\ProductController');
|
||||
$router->resource('store/stock', 'Store\StockController');
|
||||
$router->resource('store/order', 'Store\OrderController');
|
||||
$router->resource('store/user', 'Store\UserController');
|
||||
// $router->resource('store/{store_id}/admin', 'Store\AdministratorController');
|
||||
|
||||
$router->resource('profit', 'OrderProfitController');
|
||||
|
||||
|
|
|
|||
|
|
@ -40,11 +40,14 @@ class UnlineController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* 发货
|
||||
* 提货
|
||||
*/
|
||||
public function package($id, Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
if (!$user->userInfo->is_company) {
|
||||
throw new BizException('非内部员工');
|
||||
}
|
||||
$request->validate([
|
||||
'products' => 'required|array',
|
||||
'products.*.id' => 'required',
|
||||
|
|
@ -101,11 +104,14 @@ class UnlineController extends Controller
|
|||
if (count($package_params) === 0) {
|
||||
throw new BizException('提货商品不存在');
|
||||
}
|
||||
$service_package->createPackage($order, [
|
||||
$package = $service_package->createPackage($order, [
|
||||
'shipping_company' => '提货',
|
||||
'shipping_number' => $user->id,
|
||||
'packages' => $package_params
|
||||
]);
|
||||
$package->update([
|
||||
'inviter_id' => $user->id
|
||||
]);
|
||||
DB::commit();
|
||||
return response()->noContent();
|
||||
} catch (Throwable $th) {
|
||||
|
|
|
|||
|
|
@ -134,6 +134,11 @@ class Order extends Model
|
|||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function inviter()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'inviter_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 下单人信息
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class OrderPackage extends Model
|
|||
];
|
||||
|
||||
protected $fillable = [
|
||||
'remarks', 'status', 'is_failed', 'checked_at', 'last_news',
|
||||
'remarks', 'status', 'is_failed', 'checked_at', 'last_news', 'inviter_id',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -72,6 +72,11 @@ class OrderPackage extends Model
|
|||
return $this->belongsTo(Order::class, 'order_id');
|
||||
}
|
||||
|
||||
public function inviter()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'inviter_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 货运单商品
|
||||
*
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ class ProductSku extends Model
|
|||
|
||||
protected $fillable = ['amount', 'product_sku_id', 'status', 'store_id'];
|
||||
|
||||
protected $attributes = [
|
||||
'status' => 0,
|
||||
'amount' => 0
|
||||
];
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
public function store()
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace App\Models\Store;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
use App\Models\Tag;
|
||||
|
||||
class StockLog extends Model
|
||||
{
|
||||
|
|
@ -12,7 +13,12 @@ class StockLog extends Model
|
|||
|
||||
protected $table = 'store_stock_logs';
|
||||
|
||||
protected $fillable = ['operator_type', 'operator_id', 'amount', 'product_sku_id', 'remarks', 'source_id', 'source_type', 'store_id', 'tag_id'];
|
||||
protected $fillable = ['operator_type', 'operator_id', 'amount', 'product_sku_id', 'remarks', 'balance', 'source_id', 'source_type', 'store_id', 'tag_id'];
|
||||
|
||||
public static function tags()
|
||||
{
|
||||
return Tag::where('type', Tag::TYPE_STORE_STOCK);
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
|
|
@ -36,6 +42,6 @@ class StockLog extends Model
|
|||
|
||||
public function tag()
|
||||
{
|
||||
return $this->belongsTo(\App\Models\Tag::class, 'tag_id');
|
||||
return $this->belongsTo(Tag::class, 'tag_id');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class Store extends Model
|
|||
|
||||
public function administrators()
|
||||
{
|
||||
return $this->belongsToMany(\Dcat\Admin\Models\Administrator::class, 'store_administrators', 'store_id', 'administrator_id');
|
||||
return $this->belongsToMany(\App\Models\Admin\Administrator::class, 'store_administrators', 'store_id', 'administrator_id');
|
||||
}
|
||||
|
||||
public function productSkus()
|
||||
|
|
|
|||
|
|
@ -119,6 +119,14 @@ class User extends Model implements AuthorizableContract, AuthenticatableContrac
|
|||
return $this->hasMany(Order::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 员工帮下的订单
|
||||
*/
|
||||
public function inviteOrders()
|
||||
{
|
||||
return $this->hasMany(Order::class, 'inviter_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 属于此用户的订单包裹
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -104,6 +104,16 @@ class UserInfo extends Model
|
|||
return $this->belongsTo(UserInfo::class, 'real_inviter_id');
|
||||
}
|
||||
|
||||
public function inviteOrders()
|
||||
{
|
||||
return $this->hasMany(Order::class, 'inviter_id', 'user_id');
|
||||
}
|
||||
|
||||
public function inviteUserInfos()
|
||||
{
|
||||
return $this->hasMany(UserInfo::class, 'inviter_id', 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取此用户的所有父级ID
|
||||
*
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ class DistributeService
|
|||
*/
|
||||
public function storeByOrder(Order $order)
|
||||
{
|
||||
// 订单已取消
|
||||
if ($order->isCancelled()) {
|
||||
// 订单已取消, 换货后生成的新订单
|
||||
if ($order->isCancelled() || $order->is_change) {
|
||||
return false;
|
||||
}
|
||||
// 订单成长值
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ class CreateOrderPackagesTable extends Migration
|
|||
$table->unsignedTinyInteger('status')->default(0)->comment('快递状态:0在途,1揽收,2疑难,3签收,4退签,5派件,14拒签');
|
||||
$table->timestamp('checked_at')->nullable()->comment('签收时间');
|
||||
$table->string('remarks')->nullable()->comment('备注');
|
||||
$table->unsignedBigInteger('inviter_id')->nullable()->comment('提货员工(users.id)');
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('shipping_number');
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class CreateStoresTable extends Migration
|
|||
$table->unsignedBigInteger('store_id');
|
||||
$table->unsignedBigInteger('product_sku_id');
|
||||
$table->integer('amount')->comment('库存变更数量(正/负值)');
|
||||
$table->integer('balance')->default(0)->comment('剩余');
|
||||
$table->unsignedBigInteger('tag_id')->comment('变更类目(tags.id)');
|
||||
$table->nullableMorphs('operator');
|
||||
$table->string('remarks')->nullable()->comment('备注');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddBalanceToStoreLogs extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('store_stock_logs', function (Blueprint $table) {
|
||||
$table->integer('balance')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('store_stock_logs', function (Blueprint $table) {
|
||||
$table->dropColumn('balance');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddInviterIdToOrderPackages extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('order_packages', function (Blueprint $table) {
|
||||
$table->unsignedBigInteger('inviter_id')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('order_packages', function (Blueprint $table) {
|
||||
$table->dropColumn(['inviter_id']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -50,7 +50,6 @@ class AdminMenuSeeder extends Seeder
|
|||
'icon' => 'fa fa-shopping-bag',
|
||||
'uri' => '',
|
||||
'children'=>[
|
||||
[ 'title' => '门店管理', 'icon' => '', 'uri' => 'store' ],
|
||||
[
|
||||
'title' =>'文章管理',
|
||||
'icon' => '',
|
||||
|
|
@ -83,6 +82,19 @@ class AdminMenuSeeder extends Seeder
|
|||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'title' => '门店管理',
|
||||
'icon' => 'fa fa-university',
|
||||
'uri' => '',
|
||||
'children' => [
|
||||
['title' => '总览', 'uri' => 'store/info', 'icon' => ''],
|
||||
['title' => '信息管理', 'uri' => 'store/list', 'icon' => ''],
|
||||
['title' => '商品管理', 'uri' => 'store/product', 'icon' => ''],
|
||||
['title' => '员工业绩', 'uri' => 'store/user', 'icon' => ''],
|
||||
['title' => '订单管理', 'uri' => 'store/order', 'icon' => ''],
|
||||
['title' => '库存管理', 'uri' => 'store/stock', 'icon' => ''],
|
||||
]
|
||||
],
|
||||
[
|
||||
'title' => '商品管理',
|
||||
'icon' => 'fa fa-shopping-cart',
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Order;
|
||||
use App\Models\{Setting, ShareBg};
|
||||
use App\Models\{Setting, ShareBg, Tag};
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class AppSettingSeeder extends Seeder
|
||||
|
|
@ -16,7 +16,6 @@ class AppSettingSeeder extends Seeder
|
|||
public function run()
|
||||
{
|
||||
Setting::truncate();
|
||||
ShareBg::truncate();
|
||||
foreach ([
|
||||
'app'=> [
|
||||
'value'=> [
|
||||
|
|
@ -106,6 +105,7 @@ class AppSettingSeeder extends Seeder
|
|||
}
|
||||
|
||||
// 分享背景图
|
||||
ShareBg::truncate();
|
||||
ShareBg::create([
|
||||
'image' => '',
|
||||
'x' => 0,
|
||||
|
|
@ -113,5 +113,16 @@ class AppSettingSeeder extends Seeder
|
|||
'size' => 0,
|
||||
'is_use' => 1,
|
||||
]);
|
||||
|
||||
// tags
|
||||
Tag::truncate();
|
||||
Tag::create([
|
||||
'type' => Tag::TYPE_STORE_STOCK,
|
||||
'name' => '出库'
|
||||
]);
|
||||
Tag::create([
|
||||
'type' => Tag::TYPE_STORE_STOCK,
|
||||
'name' => '入库'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'store' => '门店管理',
|
||||
'Order' => '订单管理',
|
||||
'order' => '订单管理',
|
||||
],
|
||||
'fields' => [
|
||||
'user_id' => '用户',
|
||||
'user'=>[
|
||||
'phone' => '用户',
|
||||
],
|
||||
'inviter'=>[
|
||||
'phone' => '员工',
|
||||
],
|
||||
'userCoupon'=>[
|
||||
'coupon_name' => '优惠券',
|
||||
],
|
||||
'sn' => '订单编号',
|
||||
'user_coupon_id' => '使用优惠券',
|
||||
'coupon_discount_amount' => '优惠券金额',
|
||||
'vip_discount_amount' => '会员优惠',
|
||||
'reduced_amount' => '减免金额',
|
||||
'bargain_amount' => '砍价金额',
|
||||
'shipping_fee' => '运费',
|
||||
'products_total_amount' => '商品总额',
|
||||
'total_amount' => '订单总额',
|
||||
'weight' => '订单重量',
|
||||
'note' => '客户备注',
|
||||
'remark' => '订单备注',
|
||||
'pay_sn' => '支付单号',
|
||||
'pay_way' => '支付方式',
|
||||
'pay_at' => '支付时间',
|
||||
'consignee_name' => '收货人',
|
||||
'consignee_telephone' => '联系方式',
|
||||
'consignee_zone' => '收货地区',
|
||||
'consignee_address' => '收货地址',
|
||||
'consignee'=>'收货地址',
|
||||
'status' => '订单状态',
|
||||
'order_status'=>'订单状态',
|
||||
'shipping_state'=>'物流状态',
|
||||
'completed_at' => '完成时间',
|
||||
'created_at' => '下单时间',
|
||||
'name'=>'商品名称',
|
||||
'cover'=>'商品图',
|
||||
'sell_price'=>'价格',
|
||||
'quantity' => '数量',
|
||||
'after_sale_state'=>'售后状态',
|
||||
'product_total_amount'=>'总价',
|
||||
'shipping_company' => '快递公司',
|
||||
'shipping_number' => '快递单号',
|
||||
'packages'=>'包裹内容',
|
||||
'order_product_id' =>'商品',
|
||||
'quantity'=>'数量',
|
||||
'remain_quantity'=>'待发',
|
||||
'tags'=>'标签',
|
||||
'profit' => '累计返利',
|
||||
'sales_value' => '成长值',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'store' => '门店管理',
|
||||
'Product' => '商品管理',
|
||||
'product' => '商品管理',
|
||||
],
|
||||
'fields' => [
|
||||
'store_id' => '门店',
|
||||
'product_sku_id' => '商品',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'store' => '门店管理',
|
||||
'Stock' => '库存记录',
|
||||
'stock' => '库存记录',
|
||||
],
|
||||
'fields' => [
|
||||
'store_id' => '门店',
|
||||
'product_sku_id' => '商品',
|
||||
'amount' => '数量',
|
||||
'tag' => '类目',
|
||||
'tag_id' => '类目',
|
||||
'operator' => '操作人',
|
||||
'remarks' => '备注',
|
||||
'balance' => '剩余',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'store' => '门店管理',
|
||||
'User' => '员工业绩',
|
||||
'user' => '员工业绩',
|
||||
],
|
||||
'fields' => [
|
||||
'phone' => '手机号',
|
||||
'created_at' => '注册时间',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
];
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
return [
|
||||
'labels' => [
|
||||
'Store' => '门店管理',
|
||||
'store' => '门店管理',
|
||||
'Store' => '信息管理',
|
||||
'store' => '信息管理',
|
||||
],
|
||||
'fields' => [
|
||||
'title' => '名称',
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ return [
|
|||
'created_at' => '注册时间',
|
||||
'agent' => '代理',
|
||||
'user_info'=>[
|
||||
'code' => '邀请码',
|
||||
'avatar' => '头像',
|
||||
'nickname' => '昵称',
|
||||
'growth_value'=>'成长值',
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
*
|
||||
!excel-template
|
||||
!public/
|
||||
!.gitignore
|
||||
|
|
|
|||
Loading…
Reference in New Issue