diff --git a/app/Admin/Actions/Grid/DealerProductLvlRule.php b/app/Admin/Actions/Grid/DealerProductLvlRule.php
new file mode 100644
index 00000000..1ff22d20
--- /dev/null
+++ b/app/Admin/Actions/Grid/DealerProductLvlRule.php
@@ -0,0 +1,38 @@
+title) {
+ return $this->title;
+ }
+ return ' 等级规则 ';
+ }
+
+ /**
+ * @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());
+ }
+}
diff --git a/app/Admin/Actions/Grid/DealerProductSaleRule.php b/app/Admin/Actions/Grid/DealerProductSaleRule.php
new file mode 100644
index 00000000..58cad4c2
--- /dev/null
+++ b/app/Admin/Actions/Grid/DealerProductSaleRule.php
@@ -0,0 +1,38 @@
+title) {
+ return $this->title;
+ }
+ return ' 销售规则 ';
+ }
+
+ /**
+ * @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());
+ }
+}
diff --git a/app/Admin/Controllers/DealerProductController.php b/app/Admin/Controllers/DealerProductController.php
index baee630d..8755dc05 100644
--- a/app/Admin/Controllers/DealerProductController.php
+++ b/app/Admin/Controllers/DealerProductController.php
@@ -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())
diff --git a/app/Admin/Forms/DealerProductLvlRule.php b/app/Admin/Forms/DealerProductLvlRule.php
new file mode 100644
index 00000000..5f002160
--- /dev/null
+++ b/app/Admin/Forms/DealerProductLvlRule.php
@@ -0,0 +1,110 @@
+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',
+ ];
+ }
+}
diff --git a/app/Admin/Forms/DealerProductSaleRule.php b/app/Admin/Forms/DealerProductSaleRule.php
new file mode 100644
index 00000000..9476d324
--- /dev/null
+++ b/app/Admin/Forms/DealerProductSaleRule.php
@@ -0,0 +1,103 @@
+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',
+ ];
+ }
+}
diff --git a/app/Endpoint/Api/Http/Controllers/Dealer/ProductController.php b/app/Endpoint/Api/Http/Controllers/Dealer/ProductController.php
new file mode 100644
index 00000000..4275f950
--- /dev/null
+++ b/app/Endpoint/Api/Http/Controllers/Dealer/ProductController.php
@@ -0,0 +1,33 @@
+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);
+ }
+}
diff --git a/app/Endpoint/Api/Http/Controllers/Dealer/UserController.php b/app/Endpoint/Api/Http/Controllers/Dealer/UserController.php
new file mode 100644
index 00000000..9c76866b
--- /dev/null
+++ b/app/Endpoint/Api/Http/Controllers/Dealer/UserController.php
@@ -0,0 +1,26 @@
+user();
+
+ return response()->json([
+ 'phone' => $user->phone,
+ 'user_info' => UserInfoResource::make($user->userInfo),
+ ]);
+ }
+}
diff --git a/app/Endpoint/Api/Http/Resources/Dealer/ProductLvlRuleResource.php b/app/Endpoint/Api/Http/Resources/Dealer/ProductLvlRuleResource.php
new file mode 100644
index 00000000..9a0be60e
--- /dev/null
+++ b/app/Endpoint/Api/Http/Resources/Dealer/ProductLvlRuleResource.php
@@ -0,0 +1,23 @@
+ $this->lvl,
+ 'sale_price' => $this->sale_price,
+ 'min_order_amount' => $this->min_order_amount,
+ ];
+ }
+}
diff --git a/app/Endpoint/Api/Http/Resources/Dealer/ProductResource.php b/app/Endpoint/Api/Http/Resources/Dealer/ProductResource.php
new file mode 100644
index 00000000..efc1933c
--- /dev/null
+++ b/app/Endpoint/Api/Http/Resources/Dealer/ProductResource.php
@@ -0,0 +1,30 @@
+ $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)),
+ ];
+ }
+}
diff --git a/app/Endpoint/Api/Http/Resources/Dealer/ProductSaleRuleResource.php b/app/Endpoint/Api/Http/Resources/Dealer/ProductSaleRuleResource.php
new file mode 100644
index 00000000..030daf95
--- /dev/null
+++ b/app/Endpoint/Api/Http/Resources/Dealer/ProductSaleRuleResource.php
@@ -0,0 +1,21 @@
+ $this->qty,
+ ];
+ }
+}
diff --git a/app/Endpoint/Api/Http/Resources/Dealer/ProductSimpleResource.php b/app/Endpoint/Api/Http/Resources/Dealer/ProductSimpleResource.php
new file mode 100644
index 00000000..471a2edc
--- /dev/null
+++ b/app/Endpoint/Api/Http/Resources/Dealer/ProductSimpleResource.php
@@ -0,0 +1,25 @@
+ $this->id,
+ 'name' => $this->name,
+ 'cover' => (string) $this->cover,
+ 'price' => (string) $this->price,
+ 'is_online' => $this->isOnline(),
+ ];
+ }
+}
diff --git a/app/Endpoint/Api/Http/Resources/Dealer/UserInfoResource.php b/app/Endpoint/Api/Http/Resources/Dealer/UserInfoResource.php
new file mode 100644
index 00000000..43d5248e
--- /dev/null
+++ b/app/Endpoint/Api/Http/Resources/Dealer/UserInfoResource.php
@@ -0,0 +1,28 @@
+ (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'=> '签约经销商',
+ ];
+ }
+}
diff --git a/app/Endpoint/Api/routes.php b/app/Endpoint/Api/routes.php
index a828b7a3..926d799c 100644
--- a/app/Endpoint/Api/routes.php
+++ b/app/Endpoint/Api/routes.php
@@ -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']);
+ });
});
diff --git a/app/Models/DealerProduct.php b/app/Models/DealerProduct.php
index e603a7a6..df20db61 100644
--- a/app/Models/DealerProduct.php
+++ b/app/Models/DealerProduct.php
@@ -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;
}
}
diff --git a/app/Models/DealerProductLvlRule.php b/app/Models/DealerProductLvlRule.php
index 353c6e3d..450f62ef 100644
--- a/app/Models/DealerProductLvlRule.php
+++ b/app/Models/DealerProductLvlRule.php
@@ -8,4 +8,8 @@ use Illuminate\Database\Eloquent\Model;
class DealerProductLvlRule extends Model
{
use HasFactory;
+
+ protected $fillable = [
+ 'lvl', 'sale_price', 'min_order_amount',
+ ];
}
diff --git a/app/Models/DealerProductSaleRule.php b/app/Models/DealerProductSaleRule.php
index bc14ef77..0a9edab9 100644
--- a/app/Models/DealerProductSaleRule.php
+++ b/app/Models/DealerProductSaleRule.php
@@ -8,4 +8,8 @@ use Illuminate\Database\Eloquent\Model;
class DealerProductSaleRule extends Model
{
use HasFactory;
+
+ protected $fillable = [
+ 'qty', 'price',
+ ];
}
diff --git a/database/migrations/2022_01_13_105530_add_unit_to_dealer_products_table.php b/database/migrations/2022_01_13_105530_add_unit_to_dealer_products_table.php
new file mode 100644
index 00000000..f41b58fc
--- /dev/null
+++ b/database/migrations/2022_01_13_105530_add_unit_to_dealer_products_table.php
@@ -0,0 +1,34 @@
+string('unit')->nullable()->comment('单位');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('dealer_products', function (Blueprint $table) {
+ //
+ $table->dropColumn('unit');
+ });
+ }
+}
diff --git a/resources/lang/zh_CN/dealer-product.php b/resources/lang/zh_CN/dealer-product.php
index 623df182..d307fd69 100644
--- a/resources/lang/zh_CN/dealer-product.php
+++ b/resources/lang/zh_CN/dealer-product.php
@@ -15,6 +15,7 @@ return [
'stock' => '库存',
'sales_count' => '销量',
'is_sale' => '是否在售',
+ 'unit'=>'单位',
],
'options' => [
],