fix(skill): correct pagination total and sort order on SkillMarket (issue #48)

This commit is contained in:
matevip 2026-04-30 17:45:02 +08:00
parent a0c6ed5a86
commit 46ac58500c
2 changed files with 21 additions and 10 deletions

View File

@ -96,8 +96,14 @@ public class SkillService {
wrapper.eq(SkillEntity::getSecurityScanStatus, scanStatus.trim().toUpperCase()); wrapper.eq(SkillEntity::getSecurityScanStatus, scanStatus.trim().toUpperCase());
} }
wrapper.orderByDesc(SkillEntity::getBuiltin) // Builtin first ('builtin' < 'dynamic' < 'mcp' alphabetically), then by
.orderByDesc(SkillEntity::getCreateTime); // name for a stable order. Sorting on skill_type instead of the
// `builtin` boolean because SkillInstaller leaves the boolean NULL on
// user-installed rows; sorting on name instead of create_time because
// the 20 seeded builtins share a near-identical create_time and looked
// random within the group (issue #48).
wrapper.orderByAsc(SkillEntity::getSkillType)
.orderByAsc(SkillEntity::getName);
return skillMapper.selectPage(pageParam, wrapper); return skillMapper.selectPage(pageParam, wrapper);
} }

View File

@ -434,17 +434,22 @@ async function loadSkills() {
const data = res.data || {} const data = res.data || {}
const records: Skill[] = Array.isArray(data.records) ? data.records : [] const records: Skill[] = Array.isArray(data.records) ? data.records : []
skills.value = records skills.value = records
// Defensive total: if the backend pagination count is broken (seen with the // Trust the backend total when it's positive. Only fall back to an inferred
// old hardcoded-H2 MyBatisPlus interceptor on MySQL), infer a floor so the // floor when the backend reports 0 (broken pagination interceptor) using
// user can at least reach the next page. The real total overrides this. // Math.max unconditionally produced an off-by-one whenever total was an
// exact multiple of the page size (the last page is full but has no
// successor; issue #48).
const reportedTotal = Number(data.total) || 0 const reportedTotal = Number(data.total) || 0
const inferredMin = records.length >= query.size if (reportedTotal > 0) {
? query.page * query.size + 1 // at least one more page exists total.value = reportedTotal
: (query.page - 1) * query.size + records.length } else if (records.length > 0) {
total.value = Math.max(reportedTotal, inferredMin) total.value = records.length >= query.size
if (records.length > 0 && reportedTotal === 0) { ? query.page * query.size + 1
: (query.page - 1) * query.size + records.length
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.warn('[SkillMarket] backend returned records but total=0; rebuild server JAR to pick up the DbType fix') console.warn('[SkillMarket] backend returned records but total=0; rebuild server JAR to pick up the DbType fix')
} else {
total.value = 0
} }
} catch (e) { } catch (e) {
skills.value = [] skills.value = []