143 lines
4.8 KiB
PHP
143 lines
4.8 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Customer;
|
||
|
||
use App\Exceptions\RepositoryException;
|
||
use App\Http\Requests\Customer\CustomerLevelFormRequest;
|
||
use App\Models\CustomerLevelModel;
|
||
use App\Models\NoticeModel;
|
||
use App\Models\StoreModel;
|
||
use Illuminate\Http\JsonResponse;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Support\Facades\Auth;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||
use Modules\Common\Http\Controllers\BaseController;
|
||
use Modules\SystemTool\Services\SysFileService;
|
||
|
||
/**
|
||
* 客户等级管理(同一商品按等级上浮比例定价:售价 = 成本价 × (100 + percent) / 100)
|
||
*/
|
||
#[RequestAttribute('/customer/level', 'customer.level')]
|
||
class CustomerLevelController extends BaseController
|
||
{
|
||
protected array $searchField = [
|
||
'name' => 'like',
|
||
'status' => '=',
|
||
];
|
||
|
||
/** 等级列表 */
|
||
#[GetRoute(authorize: 'query')]
|
||
public function query(Request $request): JsonResponse
|
||
{
|
||
$params = $request->all();
|
||
$pageSize = $params['pageSize'] ?? 10;
|
||
$data = $this->buildSearch($params, CustomerLevelModel::query())
|
||
->orderBy('sort')
|
||
->orderBy('id', 'desc')
|
||
->paginate($pageSize)
|
||
->toArray();
|
||
return $this->success($data);
|
||
}
|
||
|
||
/** 上传等级图片文件 */
|
||
#[PostRoute('/upload', 'create')]
|
||
public function uploadImage(Request $request, SysFileService $service): JsonResponse
|
||
{
|
||
$data = $request->validate(['file' => 'required|file']);
|
||
$result = $service->upload(
|
||
$data['file'],
|
||
8,
|
||
20,
|
||
Auth::id()
|
||
);
|
||
return $this->success($result);
|
||
}
|
||
|
||
/** 创建等级 */
|
||
#[PostRoute(authorize: 'create')]
|
||
public function create(CustomerLevelFormRequest $request): JsonResponse
|
||
{
|
||
CustomerLevelModel::create($request->validated());
|
||
return $this->success();
|
||
}
|
||
|
||
/** 编辑等级(上浮比例变更时通知该等级下门店用户) */
|
||
#[PutRoute(route: '/{id}', authorize: 'update', where: ['id' => '[0-9]+'])]
|
||
public function update(int $id, CustomerLevelFormRequest $request): JsonResponse
|
||
{
|
||
$model = CustomerLevelModel::find($id);
|
||
if (empty($model)) {
|
||
throw new RepositoryException('客户等级不存在');
|
||
}
|
||
$validated = $request->validated();
|
||
DB::transaction(function () use ($model, $validated) {
|
||
$model->update($validated);
|
||
// 上浮比例变化 → 该等级下所有商品的售价联动变化,通知受影响门店用户
|
||
if ($model->wasChanged('percent')) {
|
||
$this->notifyPriceChange($model);
|
||
}
|
||
});
|
||
return $this->success();
|
||
}
|
||
|
||
/** 删除等级(被门店引用时拒绝) */
|
||
#[DeleteRoute(route: '/{id}', authorize: 'delete', where: ['id' => '[0-9]+'])]
|
||
public function delete(int $id): JsonResponse
|
||
{
|
||
$model = CustomerLevelModel::find($id);
|
||
if (empty($model)) {
|
||
throw new RepositoryException('客户等级不存在');
|
||
}
|
||
if ($model->stores()->exists()) {
|
||
throw new RepositoryException('该等级下存在门店,无法删除');
|
||
}
|
||
$model->delete();
|
||
return $this->success();
|
||
}
|
||
|
||
/** 等级下拉选项(门店表单 / 价格矩阵用) */
|
||
#[GetRoute('/options', 'query')]
|
||
public function options(): JsonResponse
|
||
{
|
||
$data = CustomerLevelModel::query()
|
||
->where('status', CustomerLevelModel::STATUS_NORMAL)
|
||
->orderBy('sort')
|
||
->get(['id', 'name', 'percent'])
|
||
->toArray();
|
||
return $this->success($data);
|
||
}
|
||
|
||
/**
|
||
* 上浮比例变更后,给该等级下全部正常门店生成价格变更通知
|
||
*/
|
||
private function notifyPriceChange(CustomerLevelModel $level): void
|
||
{
|
||
$storeIds = StoreModel::query()
|
||
->where('status', StoreModel::STATUS_NORMAL)
|
||
->where('level_id', $level->id)
|
||
->pluck('id');
|
||
|
||
$content = mb_substr(
|
||
'您所在客户等级「' . $level->name . '」的价格上浮比例已调整为 ' . (float) $level->percent . '%,商品价格将按新比例显示',
|
||
0,
|
||
500
|
||
);
|
||
|
||
foreach ($storeIds as $storeId) {
|
||
NoticeModel::create([
|
||
'store_id' => $storeId,
|
||
'type' => NoticeModel::TYPE_PRICE,
|
||
'title' => '商品价格变更',
|
||
'content' => $content,
|
||
'data' => ['level_id' => $level->id],
|
||
'is_read' => NoticeModel::UNREAD,
|
||
]);
|
||
}
|
||
}
|
||
}
|