Files
xin-procurement/app/Http/Controllers/Customer/CustomerLevelController.php
T
2026-08-17 16:27:15 +08:00

149 lines
5.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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 App\Models\UserModel;
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
{
$userIds = UserModel::query()
->where('status', UserModel::STATUS_NORMAL)
->whereIn('store_id', function ($q) use ($level) {
$q->select('id')
->from('store')
->where('status', StoreModel::STATUS_NORMAL)
->where('level_id', $level->id);
})
->pluck('id');
$content = mb_substr(
'您所在客户等级「' . $level->name . '」的价格上浮比例已调整为 ' . (float) $level->percent . '%,商品价格将按新比例显示',
0,
500
);
foreach ($userIds as $userId) {
NoticeModel::create([
'user_id' => $userId,
'type' => NoticeModel::TYPE_PRICE,
'title' => '商品价格变更',
'content' => $content,
'data' => ['level_id' => $level->id],
'is_read' => NoticeModel::UNREAD,
]);
}
}
}