注意⚠️:仅是商品详情展示优惠券,并不会涉及下单使用
1、文件:/app/controller/api/v1/product/StoreProduct.php
修改:商品详情查询可领券、已领券时,增加传入当前门店 store_id(中间之前参数不要动)
【修改前】
$coupons = $couponIssueServices->getProductCouponList(
$uid, $id,
'id,type,category,coupon_type,...',
20
);
$couponsReceive = $couponIssueServices->getIssueCouponListReceive(
$uid, $id,
'id,type,category,coupon_type,...',
20
);
【修改后】
$coupons = $couponIssueServices->getProductCouponList(
$uid, $id,
'id,type,category,coupon_type,...',
20,
(int)$store_id // 新增:当前请求门店
);
$couponsReceive = $couponIssueServices->getIssueCouponListReceive(
$uid, $id,
'id,type,category,coupon_type,...',
20,
(int)$store_id // 新增:当前请求门店
);2、文件:/app/controller/api/v1/product/StoreProductReservation.php
修改:预约商品详情查询可领券时,增加传入门店 storeId
【修改前】
$result['coupons'] = $couponIssueServices->getProductCouponList(
$uid,
(int)$productId,
'id,coupon_type,coupon_title,...',
3
);【修改后】
$result['coupons'] = $couponIssueServices->getProductCouponList(
$uid,
(int)$productId,
'id,coupon_type,coupon_title,...',
3,
(int)$storeId // 新增
);3、文件:/app/controller/api/store/product/StoreProductReservation.php
修改:门店端预约商品详情查询可领券时,增加传入门店 storeId(中间之前参数不要动)
【修改前】
$result['coupons'] = $couponIssueServices->getProductCouponList(
$uid,
(int)$productId,
'id,coupon_type,coupon_title,...',
3
);【修改后】
$result['coupons'] = $couponIssueServices->getProductCouponList(
$uid,
(int)$productId,
'id,coupon_type,coupon_title,...',
3,
$storeId // 新增
);4、文件:/app/services/activity/coupon/StoreCouponIssueServices.php
修改1:getProductCouponList 增加 store_id 参数;查询条件增加 relation_id;过滤改为 isApplicableStore
【修改前】
public function getProductCouponList(
int $uid, int $product_id, string $field = '*', int $limit = 0
) {
// ...拼 cate_id / brand_id / productIds ...
$where = [
'product_id' => $productIds,
'cate_id' => $cateId,
'brand_id' => $brandIds,
// 无 relation_id
];
$list = $this->dao->getIssueCouponListNew($uid, $where, $field, $page, $limit);
// 仅门店商品才有 store_id
$store_id = $productInfo['type'] == 1 ? ($productInfo['relation_id'] ?? 0) : 0;
foreach ($list as &$item) {
if ($store_id && isset($item['applicable_type']) && ...) {
$applicable_store_id = is_array($item['applicable_store_id'])
? $item['applicable_store_id']
: explode(',', $item['applicable_store_id']);
// 内联过滤:不适用门店 / 指定门店不含 / 他店发行券
if ($item['applicable_type'] == 0
|| ($item['applicable_type'] == 2 && !in_array($store_id, $applicable_store_id))
|| ($item['coupon_issue_type'] == 1 && $item['relation_id'] != $store_id)
) {
continue;
}
}
// ...格式化后入 $result
}
}【修改后】
public function getProductCouponList(
int $uid, int $product_id, string $field = '*', int $limit = 0,
int $store_id = 0 // 新增
) {
/** @var StoreCouponUserServices $couponUserServices */
$couponUserServices = app()->make(StoreCouponUserServices::class);
// ...拼 cate_id / brand_id / productIds ...
[$storeId, $relationIds] = $this->resolveProductCouponStoreScope($productInfo, $store_id);
$where = [
'product_id' => $productIds,
'cate_id' => $cateId,
'brand_id' => $brandIds,
'relation_id' => $relationIds, // SQL 先按归属收窄
];
$list = $this->dao->getIssueCouponListNew($uid, $where, $field, $page, $limit);
foreach ($list as &$item) {
// 与下单用券规则统一
if (!$couponUserServices->isApplicableStore($item, $storeId)) {
continue;
}
// ...格式化后入 $result
}
}5、文件:/app/services/activity/coupon/StoreCouponIssueServices.php
修改2:getIssueCouponListReceive 同样增加 store_id、relation_id 查询,并改用 isApplicableStore
【修改前】
public function getIssueCouponListReceive(
int $uid, int $product_id, string $field = '*', int $limit = 0
) {
// ...拼 cate_id / brand_id / productIds ...
$where = [
'product_id' => $productIds,
'cate_id' => $cateId,
'brand_id' => $brandIds,
// 无 relation_id
];
$list = $this->dao->getIssueCouponListReceive($uid, $where, $field, 0, $limit);
// 仅门店商品才有 store_id
$store_id = $productInfo['type'] == 1 ? ($productInfo['relation_id'] ?? 0) : 0;
foreach ($list as $key => &$item) {
if ($store_id && isset($item['applicable_type']) && ...) {
$applicable_store_id = is_array($item['applicable_store_id'])
? $item['applicable_store_id']
: explode(',', $item['applicable_store_id']);
// 内联过滤:不适用门店 / 指定门店不含 / 他店发行券
if ($item['applicable_type'] == 0
|| ($item['applicable_type'] == 2 && !in_array($store_id, $applicable_store_id))
|| ($item['coupon_issue_type'] == 1 && $item['relation_id'] != $store_id)
) {
continue;
}
}
// ...格式化后入 $result
}
}【修改后】
public function getIssueCouponListReceive(
int $uid, int $product_id, string $field = '*', int $limit = 0,
int $store_id = 0 // 新增
) {
/** @var StoreCouponUserServices $couponUserServices */
$couponUserServices = app()->make(StoreCouponUserServices::class);
// ...拼 cate_id / brand_id / productIds ...
[$storeId, $relationIds] = $this->resolveProductCouponStoreScope($productInfo, $store_id);
$where = [
'product_id' => $productIds,
'cate_id' => $cateId,
'brand_id' => $brandIds,
'relation_id' => $relationIds, // SQL 先按归属收窄
];
$list = $this->dao->getIssueCouponListReceive($uid, $where, $field, 0, $limit);
foreach ($list as $key => &$item) {
// 与下单用券规则统一
if (!$couponUserServices->isApplicableStore($item, $storeId)) {
continue;
}
// ...格式化后入 $result
}
}6、文件:/app/services/activity/coupon/StoreCouponIssueServices.php
修改3:新增 resolveProductCouponStoreScope,按商品类型解析门店和 relation_id 查询范围
说明:
平台商品(type!=1) -> relation_id in [0]
同步门店商品(type=1,pid>0) -> relation_id in [0, 本店]
门店自建商品(type=1,pid=0) -> relation_id in [本店]
【修改前】
无此方法需要新增【修改后】
/**
* 解析商品优惠券门店范围
* 平台商品仅平台券;同步门店商品(type=1,pid>0)为本店+平台;门店自建(type=1,pid=0)仅本店
* @return array{0: int, 1: array} [有效门店ID, relation_id查询范围]
*/
private function resolveProductCouponStoreScope(array $productInfo, int $requestStoreId = 0): array
{
$productType = (int)($productInfo['type'] ?? 0);
$productPid = (int)($productInfo['pid'] ?? 0);
$productStoreId = $productType === 1 ? (int)($productInfo['relation_id'] ?? 0) : 0;
// 门店商品优先用商品门店,平台商品用请求门店
$storeId = $productStoreId ?: $requestStoreId;
if ($productType !== 1) {
return [$storeId, [0]]; // 平台商品 → 仅平台券
}
if ($productPid > 0) {
return [$storeId, [0, $storeId]]; // 同步门店商品 → 平台 + 本店
}
return [$storeId, [$storeId]]; // 门店自建 → 仅本店
}7、文件:/app/dao/activity/coupon/StoreCouponIssueDao.php
修改:getIssueCouponListNew、getIssueCouponListReceive 两处 relation_id 条件
支持 relation_id=0,并支持数组 whereIn
【修改前】
->when(isset($where['relation_id']) && $where['relation_id'] > 0, function ($query) use ($where) {
$query->where('relation_id', $where['relation_id']);
})【修改后】
->when(array_key_exists('relation_id', $where), function ($query) use ($where) {
$relationId = $where['relation_id'];
if (is_array($relationId)) {
$query->whereIn('relation_id', $relationId);
} else {
$query->where('relation_id', $relationId);
}
})8、重启swoole
注意⚠️可以参考完整修复说明文件

