修改:主体识别严格对比
continuous-integration/drone/push Build was killed
continuous-integration/drone/promote/prod Build is passing

This commit is contained in:
Linzm committed 2026-11-11 16:35:32 +08:00
1 parent 2f9d443a6a
commit 500bdbbf66
3 files changed
+152 -36

No files matched your search

+104 -8
View File
@@ -9,6 +9,8 @@ export interface ImageInspect {
isCartoon: boolean
personCount: number
petCount: number
/** 道具数量(若接口有返回) */
propCount: number
reviewStatus: string
conclusion: string
/** 主体识别 check_id,后续下单可用 */
@@ -40,12 +42,70 @@ export function mapInspectImageType(raw: unknown): ImageKind {
function countField(data: Record<string, unknown>, keys: string[]) {
for (const key of keys) {
if (!(key in data)) continue
const value = Number(data[key])
if (Number.isFinite(value)) return Math.max(0, Math.trunc(value))
}
return 0
}
function hasOwnCount(data: Record<string, unknown>, keys: string[]) {
return keys.some((key) => key in data && Number.isFinite(Number(data[key])))
}
type KeywordBucket = 'person' | 'pet' | 'prop' | 'other'
/** 按 category / 中英文关键词区分人物、宠物、道具 */
function classifyKeywordBucket(item: Record<string, unknown>): KeywordBucket {
const category = Number(item.category ?? item.Category ?? 0)
if (category === 1) return 'person'
if (category === 2) return 'pet'
if (category === 3) return 'prop'
const text = `${item.cn || ''} ${item.en || ''} ${item.name || ''} ${item.label || ''}`.toLowerCase()
if (/人|人物|人脸|儿童|成人|person|people|human|face|child|man|woman|boy|girl/.test(text)) {
return 'person'
}
if (
/宠|宠物|猫|狗|兔|鸟|鼠|仓鼠|龙猫|鹦鹉|pet|cat|dog|rabbit|bird|hamster|animal/.test(
text,
)
) {
return 'pet'
}
if (/道|具|prop|道具|物件|object/.test(text)) return 'prop'
return 'other'
}
function countFromKeywords(raw: unknown): {
personCount: number
petCount: number
propCount: number
hasKeywords: boolean
} {
if (!Array.isArray(raw) || raw.length === 0) {
return { personCount: 0, petCount: 0, propCount: 0, hasKeywords: false }
}
let personCount = 0
let petCount = 0
let propCount = 0
let useful = false
raw.forEach((entry) => {
const item = asRecord(entry)
if (!item) return
const n = Number(item.count ?? item.num ?? 1)
const count = Number.isFinite(n) ? Math.max(0, Math.trunc(n)) : 1
if (count <= 0) return
const bucket = classifyKeywordBucket(item)
if (bucket === 'other') return
useful = true
if (bucket === 'person') personCount += count
else if (bucket === 'pet') petCount += count
else if (bucket === 'prop') propCount += count
})
return { personCount, petCount, propCount, hasKeywords: useful }
}
/** 规范化 classify 接口 data(拦截器已解包 code=1000 的 data) */
export function normalizeInspect(body: unknown): ImageInspect {
const root = asRecord(body) || {}
@@ -56,23 +116,58 @@ export function normalizeInspect(body: unknown): ImageInspect {
(nested.image_type != null ||
nested.person_count != null ||
nested.is_cartoon != null ||
nested.check_id != null)
nested.check_id != null ||
nested.keywords != null)
? nested
: root
const imageType = mapInspectImageType(data.image_type ?? data.imageType)
const isCartoonRaw = data.is_cartoon ?? data.isCartoon
const isCartoon =
typeof isCartoonRaw === 'boolean' ? isCartoonRaw : imageType === 'cartoon'
const fieldPerson = countField(data, [
'person_count',
'personCount',
'headcount',
'head_count',
])
const fieldPet = countField(data, ['pet_count', 'petCount'])
const fieldProp = countField(data, ['prop_count', 'propCount'])
const hasFieldPerson = hasOwnCount(data, [
'person_count',
'personCount',
'headcount',
'head_count',
])
const hasFieldPet = hasOwnCount(data, ['pet_count', 'petCount'])
const hasFieldProp = hasOwnCount(data, ['prop_count', 'propCount'])
const fromKeywords = countFromKeywords(data.keywords)
/**
* 严格按类别取数:
* - keywords 能分出人物/宠物时优先用(避免把宠物误记成人物)
* - 否则回退 person_count / pet_count
*/
let personCount = fieldPerson
let petCount = fieldPet
let propCount = fieldProp
if (fromKeywords.hasKeywords) {
personCount = fromKeywords.personCount
petCount = fromKeywords.petCount
propCount = fromKeywords.propCount
} else {
if (!hasFieldPerson) personCount = 0
if (!hasFieldPet) petCount = 0
if (!hasFieldProp) propCount = 0
}
return {
imageType,
isCartoon,
personCount: countField(data, [
'person_count',
'personCount',
'headcount',
'head_count',
]),
petCount: countField(data, ['pet_count', 'petCount']),
personCount,
petCount,
propCount,
reviewStatus: String(data.review_status || ''),
conclusion: String(data.conclusion || ''),
checkId: countField(data, ['check_id', 'checkId']),
@@ -91,5 +186,6 @@ export function formatSubjectFromInspect(result: ImageInspect) {
const parts: string[] = []
if (result.personCount > 0) parts.push(`${result.personCount}人`)
if (result.petCount > 0) parts.push(`${result.petCount}宠物`)
if (result.propCount > 0) parts.push(`${result.propCount}道具`)
return parts.join('+')
}