前端商品列表
This commit is contained in:
@@ -7,6 +7,7 @@ use App\Models\StoreModel;
|
||||
use App\Models\UserModel;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\SystemUser\Models\SysAccessToken;
|
||||
|
||||
/**
|
||||
* 小程序端控制器基类
|
||||
@@ -29,7 +30,30 @@ abstract class BaseMiniController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* 门店端前置校验:type=门店 且 store_id>0 且门店正常
|
||||
* 可选登录场景手动识别当前用户(路由关闭 authorize 时使用)
|
||||
*
|
||||
* 手动解析 Bearer token;未携带 token、token 无效或非小程序用户时返回 null(不抛错)。
|
||||
*/
|
||||
protected function optionalUser(Request $request): ?UserModel
|
||||
{
|
||||
$token = $request->bearerToken();
|
||||
if (empty($token)) {
|
||||
return null;
|
||||
}
|
||||
$accessToken = SysAccessToken::findToken($token);
|
||||
if ($accessToken === null || $accessToken->tokenable_type !== UserModel::class) {
|
||||
return null;
|
||||
}
|
||||
$user = UserModel::find($accessToken->tokenable_id);
|
||||
if ($user === null || $user->status === UserModel::STATUS_DISABLED) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 门店端前置校验
|
||||
*/
|
||||
protected function ensureStoreBound(UserModel $user): StoreModel
|
||||
{
|
||||
@@ -46,8 +70,6 @@ abstract class BaseMiniController extends BaseController
|
||||
|
||||
/**
|
||||
* 用户当前绑定的正常门店(未绑定/已停用返回 null,不抛错)
|
||||
*
|
||||
* 供商品浏览等「弱前置」场景使用:未绑定门店仍可浏览商品,仅价格不可见。
|
||||
*/
|
||||
protected function boundStore(UserModel $user): ?StoreModel
|
||||
{
|
||||
|
||||
@@ -12,10 +12,7 @@ use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
|
||||
/**
|
||||
* 小程序商品(分类树 + 列表)
|
||||
*
|
||||
* 商品浏览仅需登录:未绑定门店/门店未设客户等级的用户也可查看商品,仅价格不可见(price=null);
|
||||
* 加购、下单仍由购物车/订单前置校验拦截,要求绑定门店并已设客户等级。
|
||||
* 小程序商品
|
||||
*/
|
||||
#[RequestAttribute('/mini', 'mini', authGuard: 'users')]
|
||||
class ProductController extends BaseMiniController
|
||||
@@ -56,22 +53,15 @@ class ProductController extends BaseMiniController
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品列表:价格取当前门店客户等级价;
|
||||
* 商品列表
|
||||
*/
|
||||
#[GetRoute('/product/list', authorize: false)]
|
||||
public function products(Request $request): JsonResponse
|
||||
{
|
||||
$user = $this->currentUser($request);
|
||||
$levelId = $this->boundStore($user)?->level_id ?? 0;
|
||||
|
||||
$query = ProductModel::query()
|
||||
->where('status', ProductModel::STATUS_ON)
|
||||
->with('category:id,name');
|
||||
|
||||
if ($levelId > 0) {
|
||||
$query->with(['prices' => static fn ($q) => $q->where('level_id', $levelId)]);
|
||||
}
|
||||
|
||||
$categoryId = (int) $request->input('category_id', 0);
|
||||
if ($categoryId > 0) {
|
||||
$query->where('category_id', $categoryId);
|
||||
@@ -79,8 +69,7 @@ class ProductController extends BaseMiniController
|
||||
$keyword = trim((string) $request->input('keyword', ''));
|
||||
if ($keyword !== '') {
|
||||
$query->where(static function ($q) use ($keyword) {
|
||||
$q->where('name', 'like', '%' . $keyword . '%')
|
||||
->orWhere('spec', 'like', '%' . $keyword . '%');
|
||||
$q->where('name', 'like', '%' . $keyword . '%');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -90,12 +79,28 @@ class ProductController extends BaseMiniController
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
|
||||
// 扁平化价格:prices[0].actual_price → price(访问器经 toArray 自动输出换算后实际价;
|
||||
// 未绑定门店或未设等级价为 null——未加载 prices 时 ?? null 兜底)
|
||||
// unset prices 同时移除 price_type/percent,门店端无法反推成本;cost_price 已被 $hidden 过滤
|
||||
foreach ($data['data'] as &$row) {
|
||||
$row['price'] = $row['prices'][0]['actual_price'] ?? null;
|
||||
unset($row['prices']);
|
||||
$row['price'] = null;
|
||||
}
|
||||
|
||||
// 用户
|
||||
$user = $this->optionalUser($request);
|
||||
if (!$user) return $this->success($data);
|
||||
// 门店
|
||||
$store = $this->boundStore($user);
|
||||
if(!$store) return $this->success('12313');
|
||||
|
||||
if ($store->level_id > 0) {
|
||||
foreach ($data['data'] as &$row) {
|
||||
$model = ProductPriceModel::where('product_id', $row['id'])->where('level_id', $store->level_id)->first();
|
||||
$price = ProductPriceModel::calcActualPrice(
|
||||
$model->price_type,
|
||||
$model->price,
|
||||
$model->percent,
|
||||
$row->cost_price,
|
||||
);
|
||||
$row['price'] = $price;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success($data);
|
||||
|
||||
Reference in New Issue
Block a user