6
0
Fork 0

添加批零管理的商品模块

release
vine_liutk 2022-01-13 11:01:51 +08:00 committed by 李静
parent d95d529234
commit d053ec7072
18 changed files with 558 additions and 3 deletions

View File

@ -0,0 +1,38 @@
<?php
namespace App\Admin\Actions\Grid;
use App\Admin\Forms\DealerProductLvlRule as DealerProductLvlRuleForm;
use Dcat\Admin\Grid\RowAction;
use Dcat\Admin\Widgets\Modal;
class DealerProductLvlRule extends RowAction
{
public function title()
{
if ($this->title) {
return $this->title;
}
return '<i class="feather icon-package grid-action-icon"></i> 等级规则 &nbsp;&nbsp;';
}
/**
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.dealer_products.lvl_rules');
}
public function render()
{
$form = DealerProductLvlRuleForm::make()->payload(['id'=>$this->getKey()]);
return Modal::make()
->lg()
->title($this->title())
->body($form)
->button($this->title());
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace App\Admin\Actions\Grid;
use App\Admin\Forms\DealerProductSaleRule as DealerProductSaleRuleForm;
use Dcat\Admin\Grid\RowAction;
use Dcat\Admin\Widgets\Modal;
class DealerProductSaleRule extends RowAction
{
public function title()
{
if ($this->title) {
return $this->title;
}
return '<i class="feather icon-bar-chart grid-action-icon"></i> 销售规则 &nbsp;&nbsp;';
}
/**
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.dealer_products.sale_rules');
}
public function render()
{
$form = DealerProductSaleRuleForm::make()->payload(['id'=>$this->getKey()]);
return Modal::make()
->lg()
->title($this->title())
->body($form)
->button($this->title());
}
}

View File

@ -2,6 +2,8 @@
namespace App\Admin\Controllers;
use App\Admin\Actions\Grid\DealerProductLvlRule as DealerProductLvlRuleAction;
use App\Admin\Actions\Grid\DealerProductSaleRule as DealerProductSaleRuleAction;
use App\Admin\Repositories\DealerProduct;
use Carbon\Carbon;
use Dcat\Admin\Admin;
@ -23,7 +25,8 @@ class DealerProductController extends AdminController
return Grid::make(new DealerProduct(), function (Grid $grid) {
$grid->column('id')->sortable();
$grid->column('name');
$grid->column('subtitle');
$grid->column('unit')->label();
// $grid->column('subtitle');
$grid->column('cover')->image(80, 80);
// $grid->column('images');
// $grid->column('description');
@ -51,6 +54,12 @@ class DealerProductController extends AdminController
$grid->actions(function (Grid\Displayers\Actions $actions) {
$actions->disableEdit(Admin::user()->cannot('dcat.admin.dealer_products.edit'));
$actions->disableDelete(Admin::user()->cannot('dcat.admin.dealer_products.destroy'));
if (Admin::user()->can('dcat.admin.dealers_products.lvl_rules')) {
$actions->append(new DealerProductLvlRuleAction());
}
if (Admin::user()->can('dcat.admin.dealers_products.sale_rules')) {
$actions->append(new DealerProductSaleRuleAction());
}
});
$grid->filter(function (Grid\Filter $filter) {
$filter->panel();
@ -94,7 +103,8 @@ class DealerProductController extends AdminController
return Form::make(new DealerProduct(), function (Form $form) {
$form->display('id');
$form->text('name')->required();
$form->text('subtitle');
$form->text('unit')->required();
// $form->text('subtitle');
$form->divider();
$form->image('cover')
->move('dealer-products/cover/'.Carbon::now()->toDateString())

View File

@ -0,0 +1,110 @@
<?php
namespace App\Admin\Forms;
use App\Models\DealerProduct;
use App\Models\DealerProductLvlRule as DealerProductLvlRuleModel;
use Dcat\Admin\Contracts\LazyRenderable;
use Dcat\Admin\Form\NestedForm;
use Dcat\Admin\Traits\LazyWidget;
use Dcat\Admin\Widgets\Form;
use Illuminate\Support\Facades\DB;
use Throwable;
class DealerProductLvlRule extends Form implements LazyRenderable
{
use LazyWidget;
/**
* 权限判断,如不需要可以删除此方法
*
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.dealer_products.lvl_rules');
}
/**
* Handle the form request.
*
* @param array $input
*
* @return mixed
*/
public function handle(array $input)
{
$productId = $this->payload['id'] ?? 0;
$product = DealerProduct::findOrFail($productId);
$lvlRules = [];
$delRules = [];
foreach ($input['lvlRules'] as $rule) {
if ($rule['_remove_'] == 1) {
$delRules[] = $rule['id'];
} else {
if (is_null($rule['id'])) {
$lvlRules[] = new DealerProductLvlRuleModel($rule);
} else {
$_rule = DealerProductLvlRuleModel::find($rule['id']);
$_rule['lvl'] = $rule['id'];
$_rule['sale_price'] = $rule['sale_price'];
$_rule['min_order_amount'] = $rule['min_order_amount'];
$lvlRules[] = $_rule;
}
}
}
try {
DB::beginTransaction();
$product->lvlRules()->saveMany($lvlRules);
DealerProductLvlRuleModel::whereIn('id', $delRules)->delete();
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
return $this->response()->error('操作失败:'.$th->getMessage())->refresh();
}
return $this->response()
->success(__('admin.update_succeeded'))
->refresh();
}
/**
* Build a form here.
*/
public function form()
{
$this->hasMany('lvlRules', '等级规则', function (NestedForm $form) {
$form->select('lvl')->options([
2 => '金牌经销商',
3 => '特邀经销商',
4 => '签约经销商',
5 => '二级经销商',
6 => '一级经销商',
]);
$form->currency('sale_price', '等级进货单价')->symbol('¥');
$form->currency('min_order_amount', '等级单次最低进货价')->symbol('¥');
});
}
/**
* The data of the form.
*
* @return array
*/
public function default()
{
$productId = $this->payload['id'] ?? 0;
$product = DealerProduct::findOrFail($productId);
return [
'lvlRules' => $product->lvlRules,
// 'email' => 'John.Doe@gmail.com',
];
}
}

View File

@ -0,0 +1,103 @@
<?php
namespace App\Admin\Forms;
use App\Models\DealerProduct;
use App\Models\DealerProductSaleRule as DealerProductSaleRuleModel;
use Dcat\Admin\Contracts\LazyRenderable;
use Dcat\Admin\Form\NestedForm;
use Dcat\Admin\Traits\LazyWidget;
use Dcat\Admin\Widgets\Form;
use Illuminate\Support\Facades\DB;
use Throwable;
class DealerProductSaleRule extends Form implements LazyRenderable
{
use LazyWidget;
/**
* 权限判断,如不需要可以删除此方法
*
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return $user->can('dcat.admin.dealer_products.sale_rules');
}
/**
* Handle the form request.
*
* @param array $input
*
* @return mixed
*/
public function handle(array $input)
{
$productId = $this->payload['id'] ?? 0;
$product = DealerProduct::findOrFail($productId);
$saleRules = [];
$delRules = [];
foreach ($input['saleRules'] as $rule) {
if ($rule['_remove_'] == 1) {
$delRules[] = $rule['id'];
} else {
if (is_null($rule['id'])) {
$saleRules[] = new DealerProductSaleRuleModel($rule);
} else {
$_rule = DealerProductSaleRuleModel::find($rule['id']);
$_rule['lvl'] = $rule['id'];
$_rule['sale_price'] = $rule['sale_price'];
$_rule['min_order_amount'] = $rule['min_order_amount'];
$saleRules[] = $_rule;
}
}
}
try {
DB::beginTransaction();
$product->saleRules()->saveMany($saleRules);
DealerProductSaleRuleModel::whereIn('id', $delRules)->delete();
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
return $this->response()->error('操作失败:'.$th->getMessage())->refresh();
}
return $this->response()
->success(__('admin.update_succeeded'))
->refresh();
}
/**
* Build a form here.
*/
public function form()
{
$this->hasMany('saleRules', '销售规则', function (NestedForm $form) {
$form->number('qty', '达到数量')->min(0);
$form->currency('price', '进货单价')->symbol('¥');
});
}
/**
* The data of the form.
*
* @return array
*/
public function default()
{
$productId = $this->payload['id'] ?? 0;
$product = DealerProduct::findOrFail($productId);
return [
'saleRules' => $product->saleRules,
// 'email' => 'John.Doe@gmail.com',
];
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Endpoint\Api\Http\Controllers\Dealer;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\Dealer\ProductResource;
use App\Endpoint\Api\Http\Resources\Dealer\ProductSimpleResource;
use App\Helpers\Paginator;
use App\Models\DealerProduct;
use Illuminate\Http\Request;
class ProductController extends Controller
{
/**
* @param \Illuminate\Http\Request $request
* @return void
*/
public function index(Request $request)
{
// $input = $request->input();
$products = DealerProduct::select(['id', 'name', 'cover', 'price', 'is_sale'])
->online()
->simplePaginate(Paginator::resolvePerPage('per_page', 20, 50));
return ProductSimpleResource::collection($products);
}
public function show($id, Request $request)
{
$product = DealerProduct::with(['saleRules'])->online()->findOrFail($id);
return ProductResource::make($product);
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Endpoint\Api\Http\Controllers\Dealer;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\Dealer\UserInfoResource;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* 个人信息
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function show(Request $request)
{
$user = $request->user();
return response()->json([
'phone' => $user->phone,
'user_info' => UserInfoResource::make($user->userInfo),
]);
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Endpoint\Api\Http\Resources\Dealer;
use Illuminate\Http\Resources\Json\JsonResource;
class ProductLvlRuleResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'lvl' => $this->lvl,
'sale_price' => $this->sale_price,
'min_order_amount' => $this->min_order_amount,
];
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Endpoint\Api\Http\Resources\Dealer;
use Illuminate\Http\Resources\Json\JsonResource;
class ProductResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'unit' => $this->unit,
'cover' => (string) $this->cover,
'images' => $this->images,
'price' => (string) $this->price,
'is_online' => $this->isOnline(),
'description' => (string) $this->description,
// 'lvl_rules' => $this->whenLoaded('lvlRules', ProductLvlRuleResource::collection($this->lvlRules)),
'sale_rules' => $this->whenLoaded('saleRules', ProductSaleRuleResource::collection($this->saleRules)),
];
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Endpoint\Api\Http\Resources\Dealer;
use Illuminate\Http\Resources\Json\JsonResource;
class ProductSaleRuleResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'qty' => $this->qty,
];
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\Endpoint\Api\Http\Resources\Dealer;
use Illuminate\Http\Resources\Json\JsonResource;
class ProductSimpleResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'cover' => (string) $this->cover,
'price' => (string) $this->price,
'is_online' => $this->isOnline(),
];
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Endpoint\Api\Http\Resources\Dealer;
use Illuminate\Http\Resources\Json\JsonResource;
class UserInfoResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'nickname' => (string) $this->nickname,
'avatar' => (string) $this->avatar,
'gender' => (string) $this->gender,
'birthday' => (string) $this->birthday?->toDateString(),
'code' => (string) $this->code,
'sale_values'=> '0.00', //todo-当前团队业绩
'guanli_values'=> '0.00', //todo-预计管理津贴
'lvl_name'=> '签约经销商',
];
}
}

View File

@ -16,6 +16,7 @@ use App\Endpoint\Api\Http\Controllers\Auth\RegisterController;
use App\Endpoint\Api\Http\Controllers\Auth\ResetPasswordController;
use App\Endpoint\Api\Http\Controllers\CaptchaController;
use App\Endpoint\Api\Http\Controllers\ClickController;
use App\Endpoint\Api\Http\Controllers\Dealer;
use App\Endpoint\Api\Http\Controllers\Merchant;
use App\Endpoint\Api\Http\Controllers\MessageController;
use App\Endpoint\Api\Http\Controllers\Order\OrderController;
@ -207,4 +208,19 @@ Route::group([
// 老配额领取记录
Route::get('quota-v1-logs', [Merchant\QuotaLogController::class, 'quotaV1Logs']);
});
Route::group([
'prefix'=>'dealer',
'middleware' => [
'guard:api',
'ability:dealer',
],
], function () {
//个人信息
Route::get('me', [Dealer\UserController::class, 'show']);
//商品列表
Route::get('products', [Dealer\ProductController::class, 'index']);
//商品详情
Route::get('products/{id}', [Dealer\ProductController::class, 'show']);
});
});

View File

@ -14,8 +14,14 @@ class DealerProduct extends Model
protected $casts = [
'images' => JsonArray::class,
'is_sale' => 'bool',
];
public function scopeOnline($query)
{
return $query->where('is_sale', true);
}
public function lvlRules()
{
return $this->hasMany(DealerProductLvlRule::class, 'product_id');
@ -23,6 +29,11 @@ class DealerProduct extends Model
public function saleRules()
{
return $this->hasMany(DealerProductSaleRule::class, 'product_id');
return $this->hasMany(DealerProductSaleRule::class, 'product_id')->orderBy('qty', 'asc');
}
public function isOnline()
{
return $this->is_sale;
}
}

View File

@ -8,4 +8,8 @@ use Illuminate\Database\Eloquent\Model;
class DealerProductLvlRule extends Model
{
use HasFactory;
protected $fillable = [
'lvl', 'sale_price', 'min_order_amount',
];
}

View File

@ -8,4 +8,8 @@ use Illuminate\Database\Eloquent\Model;
class DealerProductSaleRule extends Model
{
use HasFactory;
protected $fillable = [
'qty', 'price',
];
}

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddUnitToDealerProductsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('dealer_products', function (Blueprint $table) {
//
$table->string('unit')->nullable()->comment('单位');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('dealer_products', function (Blueprint $table) {
//
$table->dropColumn('unit');
});
}
}

View File

@ -15,6 +15,7 @@ return [
'stock' => '库存',
'sales_count' => '销量',
'is_sale' => '是否在售',
'unit'=>'单位',
],
'options' => [
],