6
0
Fork 0

添加商品库存变动

release
vine_liutk 2022-01-15 14:50:23 +08:00 committed by 李静
parent 7a36086928
commit 0fe2f5779a
11 changed files with 293 additions and 4 deletions

View File

@ -0,0 +1,13 @@
<?php
namespace App\Endpoint\Api\Filters;
use EloquentFilter\ModelFilter;
class DealerUserProductLogFilter extends ModelFilter
{
public function productId($productId)
{
$this->where('product_id', $productId);
}
}

View File

@ -0,0 +1,86 @@
<?php
namespace App\Endpoint\Api\Http\Controllers\Dealer;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\Dealer\UserProductLogResource;
use App\Endpoint\Api\Http\Resources\Dealer\UserProductResource;
use App\Exceptions\BizException;
use App\Helpers\Paginator;
use App\Models\DealerUserProductLog;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Throwable;
class UserProductController extends Controller
{
public function index(Request $request)
{
$list = $request->user()->dealerProducts()
->with('product')
->orderBy('product_id', 'asc')
->simplePaginate(Paginator::resolvePerPage('per_page', 20, 50));
return UserProductResource::collection($list);
}
public function show($id, Request $request)
{
$product = $request->user()->dealerProducts()
->with('product')
->where('product_id', $id)
->first();
return UserProductResource::make($product);
}
public function logs(Request $request)
{
$list = $request->user()->dealerProductLogs()->filter($request->all())
->with('product')
->orderBy('created_at', 'desc')
->simplePaginate(Paginator::resolvePerPage('per_page', 20, 50));
return UserProductLogResource::collection($list);
}
/**
* 线下去库存
*
* @param Request $request
* @return void
*/
public function offlineOutQty(Request $request)
{
$input = $request->validate([
'product_id'=>['bail', 'required', 'int', 'min:0'],
'num'=>['bail', 'required', 'int', 'min:1'],
'remark'=> ['bail', 'string', 'max:200'],
], [], [
'product_id' => '商品',
'num' => '数量',
'remark'=>'备注',
]);
$product = $request->user()->dealerProducts()
->where('product_id', $input['product_id'])
->first();
if (!$product) {
throw new BizException('您还没有该商品');
}
try {
DB::beginTransaction();
$product->decrement('stock', $input['num']);
DealerUserProductLog::create([
'user_id'=> $request->user()->id,
'product_id'=> $input['product_id'],
'type' => DealerUserProductLog::TYPE_OFFLINE_OUT,
'qty'=>$input['num'],
'remark'=>$input['remark']??null,
]);
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('系统繁忙,请稍后再试');
}
return response()->noContent();
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\Endpoint\Api\Http\Resources\Dealer;
use App\Models\DealerUserProductLog;
use Illuminate\Http\Resources\Json\JsonResource;
class UserProductLogResource 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 [
'product_name'=> $this->product?->name,
'remark' => $this->remark,
'qty' => ($this->type == DealerUserProductLog::TYPE_ORDER_IN ? '+' : '-').$this->qty.$this->product?->unit,
'created_at' => $this->created_at->toDateTimeString(),
];
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\Endpoint\Api\Http\Resources\Dealer;
use Illuminate\Http\Resources\Json\JsonResource;
class UserProductResource 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 [
'product_id' => $this->product_id,
'name' => $this->product?->name,
'cover' => (string) $this->product?->cover,
'price' => (string) $this->product?->price,
'stock' => (int) $this->stock,
];
}
}

View File

@ -218,6 +218,12 @@ Route::group([
], function () {
//个人信息
Route::get('me', [Dealer\UserController::class, 'show']);
//我的库存
Route::get('user-products', [Dealer\UserProductController::class, 'index']);
Route::get('user-products/{product}', [Dealer\UserProductController::class, 'show']);
Route::get('user-products-logs', [Dealer\UserProductController::class, 'logs']);
Route::post('user-products/offline-out', [Dealer\UserProductController::class, 'offlineOutQty']);
//商品列表
Route::get('products', [Dealer\ProductController::class, 'index']);
//商品详情

View File

@ -71,7 +71,9 @@ class DealerOrder extends Model
*/
public function scopeOnlyPaid($query)
{
return $query->where('status', DealerOrderStatus::Confirming);
return $query->whereBetween('status', [
DealerOrderStatus::Confirming, DealerOrderStatus::Shipped,
]);
}
/**

View File

@ -8,4 +8,15 @@ use Illuminate\Database\Eloquent\Model;
class DealerUserProduct extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'product_id',
'stock',
];
public function product()
{
return $this->belongsTo(DealerProduct::class, 'product_id');
}
}

View File

@ -2,10 +2,31 @@
namespace App\Models;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use EloquentFilter\Filterable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class DealerUserProductLog extends Model
{
use HasFactory;
use Filterable;
use HasDateTimeFormatter;
public const TYPE_ORDER_IN = 1; //采购加库存
public const TYPE_ORDER_OUT = 2; //发货扣库存
public const TYPE_OFFLINE_OUT = 3;//线下去库存
protected $fillable = [
'user_id',
'product_id',
'type',
'qty',
'remark',
];
public function product()
{
return $this->belongsTo(DealerProduct::class, 'product_id');
}
}

View File

@ -170,6 +170,24 @@ class User extends Model implements AuthorizableContract, AuthenticatableContrac
return $this->hasMany(DealerOrder::class, 'consignor_id');
}
/**
* 经销商商品库存
*
*/
public function dealerProducts()
{
return $this->hasMany(DealerUserProduct::class, 'user_id');
}
/**
* 经销商商品库存
*
*/
public function dealerProductLogs()
{
return $this->hasMany(DealerUserProductLog::class, 'user_id');
}
/**
* 确认此用户是否是 VIP
*

View File

@ -7,6 +7,7 @@ use App\Enums\DealerOrderStatus;
use App\Exceptions\BizException;
use App\Models\DealerOrder;
use App\Models\DealerProduct;
use App\Models\DealerUserProductLog;
use App\Models\ShippingAddress;
use App\Models\User;
use App\Models\UserInfo;
@ -175,11 +176,11 @@ class OrderService
if (!$order->isPaid()) {
throw new BizException('订单状态异常,请刷新后再试');
}
//todo-扣减发货人库存
//扣减发货人库存
if ($order->consignor) {
$this->orderOutQty($order);
}
$order->update([
'status' => DealerOrderStatus::Shipped,
'shipping_time' => now(),
@ -191,7 +192,8 @@ class OrderService
if (!$order->isShipping()) {
throw new BizException('订单状态异常,请刷新后再试');
}
//todo-增加自己的库存
//增加自己的库存
$this->orderInQty($order);
$order->update([
'status' => DealerOrderStatus::Completed,
@ -240,6 +242,52 @@ class OrderService
return $user->shippingAddresses()->where('is_default', true)->first();
}
/**
* 用户通过下单新增库存
*
* @return void
*/
protected function orderInQty(DealerOrder $order)
{
foreach ($order->products as $product) {
$userProduct = $order->user->dealerProducts()->firstOrCreate([
'product_id'=> $product->product_id,
]);
$userProduct->increment('stock', $product->qty);
DealerUserProductLog::create([
'user_id'=> $order->user_id,
'product_id'=> $product->product_id,
'type' => DealerUserProductLog::TYPE_ORDER_IN,
'qty'=>$product->qty,
'remark'=>'订单:'.$order->sn,
]);
}
}
/**
* 用户通过订单扣减库存
*
* @return void
*/
protected function orderOutQty(DealerOrder $order)
{
foreach ($order->products as $product) {
$userProduct = $order->consignor->dealerProducts()->firstOrCreate([
'product_id'=> $product->product_id,
]);
$userProduct->decrement('stock', $product->qty);
DealerUserProductLog::create([
'user_id'=> $order->consignor_id,
'product_id'=> $product->product_id,
'type' => DealerUserProductLog::TYPE_ORDER_OUT,
'qty'=>$product->qty,
'remark' =>'订单:'.$order->sn,
]);
}
}
public function getConsignor(User $user, $totalAmount, ?User $lastConsignor = null)
{
//todo-改成配置

View File

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