diff --git a/app/Admin/Controllers/Store/AdministratorController.php b/app/Admin/Controllers/Store/AdministratorController.php deleted file mode 100644 index 4d2e45b5..00000000 --- a/app/Admin/Controllers/Store/AdministratorController.php +++ /dev/null @@ -1,48 +0,0 @@ -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'))); - } -} diff --git a/app/Admin/Controllers/Store/OrderController.php b/app/Admin/Controllers/Store/OrderController.php new file mode 100644 index 00000000..781c51e1 --- /dev/null +++ b/app/Admin/Controllers/Store/OrderController.php @@ -0,0 +1,55 @@ +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; + } +} diff --git a/app/Admin/Controllers/Store/ProductController.php b/app/Admin/Controllers/Store/ProductController.php index 0b66ebe2..e368fe50 100644 --- a/app/Admin/Controllers/Store/ProductController.php +++ b/app/Admin/Controllers/Store/ProductController.php @@ -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; } } diff --git a/app/Admin/Controllers/Store/StockController.php b/app/Admin/Controllers/Store/StockController.php index 3d9beba0..978d778f 100644 --- a/app/Admin/Controllers/Store/StockController.php +++ b/app/Admin/Controllers/Store/StockController.php @@ -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 ''.$value.''; + }); + $grid->column('balance'); + $grid->column('operator', '操作人')->display(function ($v) { + if ($v instanceof \App\Models\Admin\Administrator) { + return $v->name . '管理员'; + } else if ($v instanceof \App\Models\User) { + return $v->phone . '员工'; + } + + 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; } } diff --git a/app/Admin/Controllers/Store/StoreController.php b/app/Admin/Controllers/Store/StoreController.php index 32d6026c..c314d41b 100644 --- a/app/Admin/Controllers/Store/StoreController.php +++ b/app/Admin/Controllers/Store/StoreController.php @@ -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(); + }); }); } diff --git a/app/Admin/Controllers/Store/UserController.php b/app/Admin/Controllers/Store/UserController.php new file mode 100644 index 00000000..1c2bcf0b --- /dev/null +++ b/app/Admin/Controllers/Store/UserController.php @@ -0,0 +1,41 @@ +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; + } +} diff --git a/app/Admin/Controllers/UserController.php b/app/Admin/Controllers/UserController.php index f2aa0e6b..c72cb3e5 100644 --- a/app/Admin/Controllers/UserController.php +++ b/app/Admin/Controllers/UserController.php @@ -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'); diff --git a/app/Admin/Imports/Product.php b/app/Admin/Imports/Product.php index d71bcc43..e13d2d84 100644 --- a/app/Admin/Imports/Product.php +++ b/app/Admin/Imports/Product.php @@ -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); diff --git a/app/Admin/routes.php b/app/Admin/routes.php index 531753cf..26586829 100644 --- a/app/Admin/routes.php +++ b/app/Admin/routes.php @@ -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'); diff --git a/app/Endpoint/Api/Http/Controllers/Order/UnlineController.php b/app/Endpoint/Api/Http/Controllers/Order/UnlineController.php index 9e587365..c9346698 100644 --- a/app/Endpoint/Api/Http/Controllers/Order/UnlineController.php +++ b/app/Endpoint/Api/Http/Controllers/Order/UnlineController.php @@ -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) { diff --git a/app/Models/Order.php b/app/Models/Order.php index 3ad34e92..19692b36 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -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'); + } + /** * 下单人信息 */ diff --git a/app/Models/OrderPackage.php b/app/Models/OrderPackage.php index 6ccbce4a..ef708c71 100644 --- a/app/Models/OrderPackage.php +++ b/app/Models/OrderPackage.php @@ -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'); + } + /** * 货运单商品 * diff --git a/app/Models/Store/ProductSku.php b/app/Models/Store/ProductSku.php index 8fd992e4..b58149cc 100644 --- a/app/Models/Store/ProductSku.php +++ b/app/Models/Store/ProductSku.php @@ -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() diff --git a/app/Models/Store/StockLog.php b/app/Models/Store/StockLog.php index aa49c18a..f51f0fab 100644 --- a/app/Models/Store/StockLog.php +++ b/app/Models/Store/StockLog.php @@ -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'); } } diff --git a/app/Models/Store/Store.php b/app/Models/Store/Store.php index 4ba14649..bbc8b916 100644 --- a/app/Models/Store/Store.php +++ b/app/Models/Store/Store.php @@ -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() diff --git a/app/Models/User.php b/app/Models/User.php index 5d6db0a9..d1fbcb77 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -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'); + } + /** * 属于此用户的订单包裹 */ diff --git a/app/Models/UserInfo.php b/app/Models/UserInfo.php index 238acc25..f11e60bb 100644 --- a/app/Models/UserInfo.php +++ b/app/Models/UserInfo.php @@ -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 * diff --git a/app/Services/DistributeService.php b/app/Services/DistributeService.php index bc5adf20..b817f302 100644 --- a/app/Services/DistributeService.php +++ b/app/Services/DistributeService.php @@ -21,8 +21,8 @@ class DistributeService */ public function storeByOrder(Order $order) { - // 订单已取消 - if ($order->isCancelled()) { + // 订单已取消, 换货后生成的新订单 + if ($order->isCancelled() || $order->is_change) { return false; } // 订单成长值 diff --git a/database/migrations/2021_12_14_195244_create_order_packages_table.php b/database/migrations/2021_12_14_195244_create_order_packages_table.php index 50d116f7..c07fe3ae 100644 --- a/database/migrations/2021_12_14_195244_create_order_packages_table.php +++ b/database/migrations/2021_12_14_195244_create_order_packages_table.php @@ -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'); diff --git a/database/migrations/2022_05_06_161251_create_stores_table.php b/database/migrations/2022_05_06_161251_create_stores_table.php index cd381a19..afddb0f2 100644 --- a/database/migrations/2022_05_06_161251_create_stores_table.php +++ b/database/migrations/2022_05_06_161251_create_stores_table.php @@ -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('备注'); diff --git a/database/migrations/2022_05_19_160621_add_balance_to_store_logs.php b/database/migrations/2022_05_19_160621_add_balance_to_store_logs.php new file mode 100644 index 00000000..e3f8c8eb --- /dev/null +++ b/database/migrations/2022_05_19_160621_add_balance_to_store_logs.php @@ -0,0 +1,32 @@ +integer('balance')->default(0); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('store_stock_logs', function (Blueprint $table) { + $table->dropColumn('balance'); + }); + } +} diff --git a/database/migrations/2022_05_19_174550_add_inviter_id_to_order_packages.php b/database/migrations/2022_05_19_174550_add_inviter_id_to_order_packages.php new file mode 100644 index 00000000..6c075cf0 --- /dev/null +++ b/database/migrations/2022_05_19_174550_add_inviter_id_to_order_packages.php @@ -0,0 +1,32 @@ +unsignedBigInteger('inviter_id')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('order_packages', function (Blueprint $table) { + $table->dropColumn(['inviter_id']); + }); + } +} diff --git a/database/seeders/AdminMenuSeeder.php b/database/seeders/AdminMenuSeeder.php index c9645a12..9b1e2135 100644 --- a/database/seeders/AdminMenuSeeder.php +++ b/database/seeders/AdminMenuSeeder.php @@ -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', diff --git a/database/seeders/AppSettingSeeder.php b/database/seeders/AppSettingSeeder.php index 0071a499..cce94202 100644 --- a/database/seeders/AppSettingSeeder.php +++ b/database/seeders/AppSettingSeeder.php @@ -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' => '入库' + ]); } } diff --git a/resources/lang/zh_CN/store-order.php b/resources/lang/zh_CN/store-order.php new file mode 100644 index 00000000..230fecf9 --- /dev/null +++ b/resources/lang/zh_CN/store-order.php @@ -0,0 +1,63 @@ + [ + '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' => [ + ], +]; diff --git a/resources/lang/zh_CN/store-product.php b/resources/lang/zh_CN/store-product.php new file mode 100644 index 00000000..18bcfa28 --- /dev/null +++ b/resources/lang/zh_CN/store-product.php @@ -0,0 +1,15 @@ + [ + 'store' => '门店管理', + 'Product' => '商品管理', + 'product' => '商品管理', + ], + 'fields' => [ + 'store_id' => '门店', + 'product_sku_id' => '商品', + ], + 'options' => [ + ], +]; diff --git a/resources/lang/zh_CN/store-stock.php b/resources/lang/zh_CN/store-stock.php new file mode 100644 index 00000000..1d63930b --- /dev/null +++ b/resources/lang/zh_CN/store-stock.php @@ -0,0 +1,21 @@ + [ + 'store' => '门店管理', + 'Stock' => '库存记录', + 'stock' => '库存记录', + ], + 'fields' => [ + 'store_id' => '门店', + 'product_sku_id' => '商品', + 'amount' => '数量', + 'tag' => '类目', + 'tag_id' => '类目', + 'operator' => '操作人', + 'remarks' => '备注', + 'balance' => '剩余', + ], + 'options' => [ + ], +]; diff --git a/resources/lang/zh_CN/store-user.php b/resources/lang/zh_CN/store-user.php new file mode 100644 index 00000000..77a72869 --- /dev/null +++ b/resources/lang/zh_CN/store-user.php @@ -0,0 +1,15 @@ + [ + 'store' => '门店管理', + 'User' => '员工业绩', + 'user' => '员工业绩', + ], + 'fields' => [ + 'phone' => '手机号', + 'created_at' => '注册时间', + ], + 'options' => [ + ], +]; diff --git a/resources/lang/zh_CN/store.php b/resources/lang/zh_CN/store.php index e4d230bf..ad8c5a05 100644 --- a/resources/lang/zh_CN/store.php +++ b/resources/lang/zh_CN/store.php @@ -2,8 +2,8 @@ return [ 'labels' => [ - 'Store' => '门店管理', - 'store' => '门店管理', + 'Store' => '信息管理', + 'store' => '信息管理', ], 'fields' => [ 'title' => '名称', diff --git a/resources/lang/zh_CN/user.php b/resources/lang/zh_CN/user.php index be33c8ff..b2757c93 100644 --- a/resources/lang/zh_CN/user.php +++ b/resources/lang/zh_CN/user.php @@ -18,6 +18,7 @@ return [ 'created_at' => '注册时间', 'agent' => '代理', 'user_info'=>[ + 'code' => '邀请码', 'avatar' => '头像', 'nickname' => '昵称', 'growth_value'=>'成长值', diff --git a/storage/app/.gitignore b/storage/app/.gitignore index 8f4803c0..0689cbd0 100644 --- a/storage/app/.gitignore +++ b/storage/app/.gitignore @@ -1,3 +1,4 @@ * +!excel-template !public/ !.gitignore