Fix sqlite ambiguous status in subscription expiry top10 queries
This commit is contained in:
@@ -226,6 +226,8 @@ class SiteSubscriptionController extends Controller
|
|||||||
'merchant_id' => trim((string) $request->query('merchant_id', '')),
|
'merchant_id' => trim((string) $request->query('merchant_id', '')),
|
||||||
'plan_id' => trim((string) $request->query('plan_id', '')),
|
'plan_id' => trim((string) $request->query('plan_id', '')),
|
||||||
'expiry' => trim((string) $request->query('expiry', '')),
|
'expiry' => trim((string) $request->query('expiry', '')),
|
||||||
|
'ends_from' => trim((string) $request->query('ends_from', '')),
|
||||||
|
'ends_to' => trim((string) $request->query('ends_to', '')),
|
||||||
];
|
];
|
||||||
|
|
||||||
$query = $this->applyFilters(
|
$query = $this->applyFilters(
|
||||||
@@ -474,31 +476,56 @@ class SiteSubscriptionController extends Controller
|
|||||||
|
|
||||||
protected function applyFilters(Builder $query, array $filters): Builder
|
protected function applyFilters(Builder $query, array $filters): Builder
|
||||||
{
|
{
|
||||||
|
// 说明:该方法既会用于普通列表查询(无 join),也会用于「到期提醒 Top10」统计(有 join merchants/plans)。
|
||||||
|
// 为避免在 SQLite 下出现 "ambiguous column name",这里统一对 site_subscriptions 的字段加上表前缀。
|
||||||
|
$t = 'site_subscriptions';
|
||||||
|
|
||||||
return $query
|
return $query
|
||||||
->when($filters['status'] !== '', fn (Builder $builder) => $builder->where('status', $filters['status']))
|
->when($filters['status'] !== '', fn (Builder $builder) => $builder->where($t . '.status', $filters['status']))
|
||||||
->when(($filters['merchant_id'] ?? '') !== '', fn (Builder $builder) => $builder->where('merchant_id', (int) $filters['merchant_id']))
|
->when(($filters['merchant_id'] ?? '') !== '', fn (Builder $builder) => $builder->where($t . '.merchant_id', (int) $filters['merchant_id']))
|
||||||
->when(($filters['plan_id'] ?? '') !== '', fn (Builder $builder) => $builder->where('plan_id', (int) $filters['plan_id']))
|
->when(($filters['plan_id'] ?? '') !== '', fn (Builder $builder) => $builder->where($t . '.plan_id', (int) $filters['plan_id']))
|
||||||
->when(($filters['expiry'] ?? '') !== '', function (Builder $builder) use ($filters) {
|
->when(($filters['expiry'] ?? '') !== '', function (Builder $builder) use ($filters, $t) {
|
||||||
$expiry = (string) ($filters['expiry'] ?? '');
|
$expiry = (string) ($filters['expiry'] ?? '');
|
||||||
if ($expiry === 'expired') {
|
if ($expiry === 'expired') {
|
||||||
$builder->whereNotNull('ends_at')->where('ends_at', '<', now());
|
$builder->whereNotNull($t . '.ends_at')->where($t . '.ends_at', '<', now());
|
||||||
} elseif ($expiry === 'expiring_7d') {
|
} elseif ($expiry === 'expiring_7d') {
|
||||||
$builder->whereNotNull('ends_at')
|
$builder->whereNotNull($t . '.ends_at')
|
||||||
->where('ends_at', '>=', now())
|
->where($t . '.ends_at', '>=', now())
|
||||||
->where('ends_at', '<', now()->addDays(7));
|
->where($t . '.ends_at', '<', now()->addDays(7));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->when($filters['keyword'] !== '', function (Builder $builder) use ($filters) {
|
->when(($filters['ends_from'] ?? '') !== '' || ($filters['ends_to'] ?? '') !== '', function (Builder $builder) use ($filters, $t) {
|
||||||
|
// 到期时间范围筛选:用于运营按 ends_at 精确定位
|
||||||
|
// 容错:仅接受 YYYY-MM-DD
|
||||||
|
$from = trim((string) ($filters['ends_from'] ?? ''));
|
||||||
|
$to = trim((string) ($filters['ends_to'] ?? ''));
|
||||||
|
|
||||||
|
if ($from !== '' && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $from)) {
|
||||||
|
$from = '';
|
||||||
|
}
|
||||||
|
if ($to !== '' && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $to)) {
|
||||||
|
$to = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($from !== '' && $to !== '') {
|
||||||
|
$builder->whereBetween($t . '.ends_at', [$from . ' 00:00:00', $to . ' 23:59:59']);
|
||||||
|
} elseif ($from !== '') {
|
||||||
|
$builder->where($t . '.ends_at', '>=', $from . ' 00:00:00');
|
||||||
|
} elseif ($to !== '') {
|
||||||
|
$builder->where($t . '.ends_at', '<=', $to . ' 23:59:59');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
->when($filters['keyword'] !== '', function (Builder $builder) use ($filters, $t) {
|
||||||
// 关键词搜索:订阅号 / 站点 / 套餐 / 计费周期
|
// 关键词搜索:订阅号 / 站点 / 套餐 / 计费周期
|
||||||
$keyword = trim((string) ($filters['keyword'] ?? ''));
|
$keyword = trim((string) ($filters['keyword'] ?? ''));
|
||||||
if ($keyword === '') {
|
if ($keyword === '') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$builder->where(function (Builder $q) use ($keyword) {
|
$builder->where(function (Builder $q) use ($keyword, $t) {
|
||||||
$q->where('subscription_no', 'like', '%' . $keyword . '%')
|
$q->where($t . '.subscription_no', 'like', '%' . $keyword . '%')
|
||||||
->orWhere('plan_name', 'like', '%' . $keyword . '%')
|
->orWhere($t . '.plan_name', 'like', '%' . $keyword . '%')
|
||||||
->orWhere('billing_cycle', 'like', '%' . $keyword . '%')
|
->orWhere($t . '.billing_cycle', 'like', '%' . $keyword . '%')
|
||||||
->orWhereHas('merchant', function (Builder $mq) use ($keyword) {
|
->orWhereHas('merchant', function (Builder $mq) use ($keyword) {
|
||||||
$mq->where('name', 'like', '%' . $keyword . '%')
|
$mq->where('name', 'like', '%' . $keyword . '%')
|
||||||
->orWhere('slug', 'like', '%' . $keyword . '%');
|
->orWhere('slug', 'like', '%' . $keyword . '%');
|
||||||
@@ -509,7 +536,7 @@ class SiteSubscriptionController extends Controller
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (ctype_digit($keyword)) {
|
if (ctype_digit($keyword)) {
|
||||||
$q->orWhere('id', (int) $keyword);
|
$q->orWhere($t . '.id', (int) $keyword);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -272,6 +272,8 @@
|
|||||||
<option value="expiring_7d" @selected(($filters['expiry'] ?? '') === 'expiring_7d')>7天内到期</option>
|
<option value="expiring_7d" @selected(($filters['expiry'] ?? '') === 'expiring_7d')>7天内到期</option>
|
||||||
<option value="expired" @selected(($filters['expiry'] ?? '') === 'expired')>已过期</option>
|
<option value="expired" @selected(($filters['expiry'] ?? '') === 'expired')>已过期</option>
|
||||||
</select>
|
</select>
|
||||||
|
<input type="date" name="ends_from" data-role="sub-ends-from" placeholder="到期时间从" value="{{ $filters['ends_from'] ?? '' }}" class="w-180">
|
||||||
|
<input type="date" name="ends_to" data-role="sub-ends-to" placeholder="到期时间到" value="{{ $filters['ends_to'] ?? '' }}" class="w-180">
|
||||||
<select name="merchant_id">
|
<select name="merchant_id">
|
||||||
<option value="">全部站点</option>
|
<option value="">全部站点</option>
|
||||||
@foreach(($merchants ?? []) as $merchant)
|
@foreach(($merchants ?? []) as $merchant)
|
||||||
|
|||||||
Reference in New Issue
Block a user