fix: 产品兼容性 - 分页列表及导出bug修复
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 5s

This commit is contained in:
2026-08-12 10:35:42 +08:00
parent 0234c3d959
commit 20ac0fde15

View File

@@ -9,6 +9,7 @@ use app\admin\model\v1\ProductCompatPartsModel;
use app\admin\model\v1\ProductCompatTypesModel;
use app\admin\validate\v1\ProductCompatValidate;
use Generator;
use think\db\Query;
class ProductCompat
{
@@ -20,8 +21,8 @@ class ProductCompat
$params = request()->param([
'compatible_model',
'model',
'type_id',
'part_id',
'type_id/d',
'part_id/d',
'brand_name',
'page/d' => 1,
'size/d' => 10
@@ -45,10 +46,10 @@ class ProductCompat
->language(request()->lang_id)
->where(function ($query) use($params) {
if (!empty($params['type_id'])) {
$query->typeId($params['type_id']);
$query->where('type_id', '=', $params['type_id']);
}
if (!empty($params['part_id'])) {
$query->partId($params['part_id']);
$query->where('part_id', '=', $params['part_id']);
}
})
->withSearch(['model', 'brand_name', 'compatible_model'], [
@@ -313,7 +314,7 @@ class ProductCompat
'brand_name'
]);
$list = ProductCompatModel::withoutField([
$query = ProductCompatModel::withoutField([
'language_id',
'deleted_at'
])
@@ -323,9 +324,6 @@ class ProductCompat
},
'parts' => function ($query) {
$query->field(['id', 'name']);
},
'compatible_models' => function ($query) {
$query->field(['compat_id', 'compatible_model']);
}
])
->language(request()->lang_id)
@@ -341,9 +339,7 @@ class ProductCompat
'model' => $params['model'] ?? null,
'brand_name' => $params['brand_name'] ?? null,
'compatible_model' => $params['compatible_model'] ?? null,
])
->order(['updated_at' => 'desc'])
->cursor();
]);
$schema = [
'id' => 'id',
@@ -363,33 +359,58 @@ class ProductCompat
'updated_at' => '更新时间'
];
return xlsx_writer($this->xlsxRowGenerator($list), $schema, '产品兼容性' . date('YmdHis'));
return xlsx_writer($this->xlsxRowGenerator($query), $schema, '产品兼容性' . date('YmdHis'));
}
private function xlsxRowGenerator(Generator $list)
private function xlsxRowGenerator(Query $query, int $page_size = 500): Generator
{
foreach ($list as $item) {
$compatible_models = [];
foreach ($item['compatible_models'] as $model) {
$compatible_models[] = $model['compatible_model'];
// 主键游标分页,避免 offset 深翻页的性能问题
$last_id = 0;
while (true) {
$items = (clone $query)
->where('id', '>', $last_id)
->order(['id' => 'asc'])
->limit($page_size)
->select();
if ($items->isEmpty()) {
break;
}
yield [
'id' => $item['id'],
'type_name' => $item['types']['type_name'],
'brand_name' => $item['brand_name'],
'model' => $item['model'],
'part_name' => $item['parts']['part_name'],
'level_name' => $item['level_name'],
'spec_name' => $item['spec_name'],
'series_name' => $item['series_name'],
'capacity' => $item['capacity'],
'frequency' => $item['frequency'],
'compatible_models' => implode(',', $compatible_models),
'praise_count' => $item['praise_count'],
'sort' => $item['sort'],
'created_at' => $item['created_at'],
'updated_at' => $item['updated_at']
];
// 仅查询当前批次的兼容型号,避免一次性拉取全量 id 及巨型 IN 子句
$compat_map = [];
$compat_ids = $items->column('id');
if (!empty($compat_ids)) {
$compat_models = ProductCompatModelsModel::field(['compat_id', 'compatible_model'])
->where('compat_id', 'in', $compat_ids)
->order(['id' => 'asc'])
->select()
->toArray();
foreach ($compat_models as $compat_model) {
$compat_map[$compat_model['compat_id']][] = $compat_model['compatible_model'];
}
}
foreach ($items as $item) {
yield [
'id' => $item['id'],
'type_name' => $item['types']['name'] ?? '',
'brand_name' => $item['brand_name'],
'model' => $item['model'],
'part_name' => $item['parts']['name'] ?? '',
'level_name' => $item['level_name'],
'spec_name' => $item['spec_name'],
'series_name' => $item['series_name'],
'capacity' => $item['capacity'],
'frequency' => $item['frequency'],
'compatible_models' => implode(',', $compat_map[$item['id']] ?? []),
'praise_count' => $item['praise_count'],
'sort' => $item['sort'],
'created_at' => $item['created_at'],
'updated_at' => $item['updated_at']
];
}
// 推进游标,按主键继续取下一页
$last_id = $items->last()->id;
}
}