|
- /**
- * AI 取名结果解析(从 ai-name 页面抽出,供创作页与详情弹窗共用)
- *
- * 后端返回的 content 可能是:
- * 1) JSON({ summary, names: [] })
- * 2) JSON Lines(每行一个 {type:'summary'|'name'})
- * 3) 【名字】+ 拼音/评分/出处… 的标记文本
- */
-
- export function parseNameResult(content) {
- if (!content) return { summary: '', names: [] }
- let text = String(content).trim()
- .replace(/^```json\s*/i, '')
- .replace(/^```\s*/i, '')
- .replace(/```$/i, '')
- .trim()
-
- const line = parseJsonLines(text)
- if (line.names.length) return line
-
- const marked = parseMarkedText(text)
- if (marked.names.length) return marked
-
- const s = text.indexOf('{')
- const e = text.lastIndexOf('}')
- if (s >= 0 && e > s) text = text.substring(s, e + 1)
- try {
- const d = JSON.parse(text)
- return { summary: d.summary || '', names: Array.isArray(d.names) ? d.names : [] }
- } catch {
- return { summary: text, names: [] }
- }
- }
-
- function parseJsonLines(text) {
- const d = { summary: '', names: [] }
- String(text || '').split(/\r?\n/).forEach((l) => {
- l = l.trim()
- if (!l) return
- try {
- const i = JSON.parse(l)
- if (i.type === 'summary') d.summary = i.content || ''
- if (i.type === 'name' && i.data) d.names.push(i.data)
- } catch { /* 忽略非 JSON 行 */ }
- })
- return d
- }
-
- function parseMarkedText(text) {
- const d = { summary: '', names: [] }
- const v = String(text || '')
- const sm = v.match(/整体建议[::]([\s\S]*?)(?=\n\s*【|$)/)
- if (sm) d.summary = sm[1].trim()
- const reg = /【([^】]+)】([\s\S]*?)(?=\n\s*【|$)/g
- let m
- while ((m = reg.exec(v))) {
- const body = m[2] || ''
- const name = resolveNameBlockTitle(m[1], body)
- d.names.push({
- name,
- pinyin: matchField(body, '拼音'),
- score: parseInt(matchField(body, '评分')) || 90,
- source: matchField(body, '出处'),
- wuxing: matchField(body, '五行'),
- meaning: matchField(body, '寓意'),
- tone: matchField(body, '音律'),
- reason: matchField(body, '推荐'),
- })
- }
- d.names = d.names.filter(i => i.name).slice(0, 5)
- return d
- }
-
- function resolveNameBlockTitle(title, body) {
- const n = String(title || '').trim()
- if (!['姓名', '名字', '候选名'].includes(n)) return n
- const fr = /^(拼音|评分|出处|五行|寓意|音律|推荐)[::]/
- const line = String(body || '').split(/\r?\n/).map(i => i.trim()).find(i => i && !fr.test(i))
- return line ? line.replace(/^姓名[::]/, '').trim() : n
- }
-
- function matchField(body, label) {
- const r = new RegExp(`${label}[::]([^\\n\\r]*)`)
- const m = String(body || '').match(r)
- return m ? m[1].trim() : ''
- }
-
- /** 名字详情展示字段 */
- export const NAME_FIELDS = [
- { key: 'source', label: '出处' },
- { key: 'wuxing', label: '五行' },
- { key: 'meaning', label: '寓意' },
- { key: 'tone', label: '音律' },
- { key: 'reason', label: '推荐' },
- ]
-
- /** 把名字结果拼成可复制文本 */
- export function buildNameCopyText(result) {
- const names = result?.names || []
- if (!names.length) return ''
- const lines = []
- if (result.summary) lines.push(result.summary)
- names.forEach((item) => {
- lines.push(`${item.name}${item.score ? `(${item.score}分)` : ''}`)
- NAME_FIELDS.forEach((f) => {
- if (item[f.key]) lines.push(`${f.label}:${item[f.key]}`)
- })
- if (item.pinyin) lines.push(`拼音:${item.pinyin}`)
- lines.push('')
- })
- return lines.join('\n')
- }
|