招标解析
This commit is contained in:
parent
887b3ab82b
commit
f591ac9298
|
|
@ -53,13 +53,13 @@ const HTML_TAG_REG = /<\/?[a-z][\s\S]*>/i
|
|||
const MAX_PARSE_DEPTH = 5
|
||||
|
||||
function formatSectionValue(raw, depth = 0) {
|
||||
const fallback = { content: '--', isHtml: false, tableRows: null }
|
||||
const fallback = { content: '--', isHtml: false, tableRows: null, hasScoreRange: false }
|
||||
if (raw === undefined || raw === null) {
|
||||
return fallback
|
||||
}
|
||||
if (depth > MAX_PARSE_DEPTH) {
|
||||
const content = String(raw)
|
||||
return { content, isHtml: HTML_TAG_REG.test(content), tableRows: null }
|
||||
return { content, isHtml: HTML_TAG_REG.test(content), tableRows: null, hasScoreRange: false }
|
||||
}
|
||||
if (typeof raw === 'string') {
|
||||
const trimmed = raw.trim()
|
||||
|
|
@ -70,13 +70,13 @@ function formatSectionValue(raw, depth = 0) {
|
|||
const parsed = JSON.parse(trimmed)
|
||||
return formatSectionValue(parsed, depth + 1)
|
||||
} catch (error) {
|
||||
return { content: trimmed, isHtml: HTML_TAG_REG.test(trimmed), tableRows: null }
|
||||
return { content: trimmed, isHtml: HTML_TAG_REG.test(trimmed), tableRows: null, hasScoreRange: false }
|
||||
}
|
||||
}
|
||||
if (Array.isArray(raw)) {
|
||||
const tableRows = buildTableRows(raw, depth)
|
||||
const { rows: tableRows, hasScoreRange } = buildTableRows(raw, depth)
|
||||
if (tableRows.length > 0) {
|
||||
return { content: '', isHtml: false, tableRows }
|
||||
return { content: '', isHtml: false, tableRows, hasScoreRange }
|
||||
}
|
||||
const lines = raw.map(item => {
|
||||
if (typeof item === 'object' && item !== null) {
|
||||
|
|
@ -88,7 +88,7 @@ function formatSectionValue(raw, depth = 0) {
|
|||
return formatSectionValue(item, depth + 1).content
|
||||
}).filter(Boolean)
|
||||
const content = lines.length > 0 ? lines.join('\n') : '--'
|
||||
return { content, isHtml: false, tableRows: null }
|
||||
return { content, isHtml: false, tableRows: null, hasScoreRange: false }
|
||||
}
|
||||
if (typeof raw === 'object') {
|
||||
if (Object.prototype.hasOwnProperty.call(raw, 'value')) {
|
||||
|
|
@ -99,10 +99,14 @@ function formatSectionValue(raw, depth = 0) {
|
|||
return `${key}:${formatted.content}`
|
||||
}).filter(Boolean)
|
||||
const content = lines.length > 0 ? lines.join('\n') : '--'
|
||||
return { content, isHtml: false, tableRows: null }
|
||||
return { content, isHtml: false, tableRows: null, hasScoreRange: false }
|
||||
}
|
||||
const content = String(raw)
|
||||
return { content, isHtml: HTML_TAG_REG.test(content), tableRows: null }
|
||||
return { content, isHtml: HTML_TAG_REG.test(content), tableRows: null, hasScoreRange: false }
|
||||
}
|
||||
|
||||
function hasScoreValue(value) {
|
||||
return value !== undefined && value !== null && value !== ''
|
||||
}
|
||||
|
||||
function buildTableRows(items, depth) {
|
||||
|
|
@ -111,7 +115,7 @@ function buildTableRows(items, depth) {
|
|||
return null
|
||||
}
|
||||
const title = item.name ?? item.label ?? item.title ?? item.key ?? ''
|
||||
if (!title && title !== 0) {
|
||||
if (title === '' || title === undefined) {
|
||||
return null
|
||||
}
|
||||
const valueSource = item.content ?? item.value ?? item.text ?? item.desc ?? item.detail
|
||||
|
|
@ -120,13 +124,24 @@ function buildTableRows(items, depth) {
|
|||
? formatted.tableRows.map(row => `${row.title}:${row.value}`).join('\n')
|
||||
: ''
|
||||
const value = nestedTable || formatted.content || '--'
|
||||
const minScore = item.minScore ?? item.scoreMin ?? item.min ?? item.lowScore
|
||||
const maxScore = item.maxScore ?? item.scoreMax ?? item.max ?? item.highScore
|
||||
const scoreRange = item.scoreRange ?? item.range ?? item.score ?? null
|
||||
return {
|
||||
title,
|
||||
value,
|
||||
isHtml: formatted.isHtml
|
||||
isHtml: formatted.isHtml,
|
||||
minScore,
|
||||
maxScore,
|
||||
scoreRange
|
||||
}
|
||||
}).filter(Boolean)
|
||||
return rows
|
||||
const hasScoreRange = rows.some(row =>
|
||||
hasScoreValue(row.minScore) ||
|
||||
hasScoreValue(row.maxScore) ||
|
||||
hasScoreValue(row.scoreRange)
|
||||
)
|
||||
return { rows, hasScoreRange }
|
||||
}
|
||||
|
||||
const collectSectionsFromNode = (node) => {
|
||||
|
|
@ -140,7 +155,8 @@ const collectSectionsFromNode = (node) => {
|
|||
title: target.name,
|
||||
content: formatted.content,
|
||||
isHtml: formatted.isHtml,
|
||||
tableRows: formatted.tableRows
|
||||
tableRows: formatted.tableRows,
|
||||
hasScoreRange: formatted.hasScoreRange
|
||||
})
|
||||
}
|
||||
if (target.children && target.children.length) {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,9 @@
|
|||
<table class="section-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>标题</th>
|
||||
<th>内容</th>
|
||||
<th>{{ hasScoreRange(section) ? '名称' : '标题' }}</th>
|
||||
<th>{{ hasScoreRange(section) ? '详情' : '内容' }}</th>
|
||||
<th v-if="hasScoreRange(section)">分值范围</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
@ -34,6 +35,9 @@
|
|||
v-html="formatPlainText(row.value)"></div>
|
||||
<div v-else v-html="row.value"></div>
|
||||
</td>
|
||||
<td class="cell-score" v-if="hasScoreRange(section)">
|
||||
{{ formatScoreRange(row) }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -60,8 +64,9 @@
|
|||
<table class="section-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>标题</th>
|
||||
<th>内容</th>
|
||||
<th>{{ hasScoreRange(section) ? '名称' : '标题' }}</th>
|
||||
<th>{{ hasScoreRange(section) ? '详情' : '内容' }}</th>
|
||||
<th v-if="hasScoreRange(section)">分值范围</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
@ -73,6 +78,9 @@
|
|||
v-html="formatPlainText(row.value)"></div>
|
||||
<div v-else v-html="row.value"></div>
|
||||
</td>
|
||||
<td class="cell-score" v-if="hasScoreRange(section)">
|
||||
{{ formatScoreRange(row) }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -107,8 +115,9 @@
|
|||
<table class="section-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>标题</th>
|
||||
<th>内容</th>
|
||||
<th>{{ hasScoreRange(section) ? '名称' : '标题' }}</th>
|
||||
<th>{{ hasScoreRange(section) ? '详情' : '内容' }}</th>
|
||||
<th v-if="hasScoreRange(section)">分值范围</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
@ -120,6 +129,9 @@
|
|||
v-html="formatPlainText(row.value)"></div>
|
||||
<div v-else v-html="row.value"></div>
|
||||
</td>
|
||||
<td class="cell-score" v-if="hasScoreRange(section)">
|
||||
{{ formatScoreRange(row) }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -146,8 +158,9 @@
|
|||
<table class="section-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>标题</th>
|
||||
<th>内容</th>
|
||||
<th>{{ hasScoreRange(section) ? '名称' : '标题' }}</th>
|
||||
<th>{{ hasScoreRange(section) ? '详情' : '内容' }}</th>
|
||||
<th v-if="hasScoreRange(section)">分值范围</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
@ -159,6 +172,9 @@
|
|||
v-html="formatPlainText(row.value)"></div>
|
||||
<div v-else v-html="row.value"></div>
|
||||
</td>
|
||||
<td class="cell-score" v-if="hasScoreRange(section)">
|
||||
{{ formatScoreRange(row) }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -289,11 +305,34 @@ export default {
|
|||
hasTable(rows) {
|
||||
return Array.isArray(rows) && rows.length > 0
|
||||
},
|
||||
hasScoreRange(section) {
|
||||
return Boolean(section && section.hasScoreRange)
|
||||
},
|
||||
formatPlainText(text) {
|
||||
if (!text) {
|
||||
return '--'
|
||||
}
|
||||
return text.replace(/\n/g, '<br/>')
|
||||
},
|
||||
formatScoreRange(row) {
|
||||
if (!row) {
|
||||
return '--'
|
||||
}
|
||||
if (row.scoreRange !== undefined && row.scoreRange !== null && row.scoreRange !== '') {
|
||||
return row.scoreRange
|
||||
}
|
||||
const hasMin = row.minScore !== undefined && row.minScore !== null && row.minScore !== ''
|
||||
const hasMax = row.maxScore !== undefined && row.maxScore !== null && row.maxScore !== ''
|
||||
if (hasMin && hasMax) {
|
||||
return `${row.minScore} ~ ${row.maxScore}`
|
||||
}
|
||||
if (hasMin) {
|
||||
return `${row.minScore}`
|
||||
}
|
||||
if (hasMax) {
|
||||
return `${row.maxScore}`
|
||||
}
|
||||
return '--'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -585,6 +624,13 @@ export default {
|
|||
color: #606266;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.cell-score {
|
||||
width: 140px;
|
||||
color: #303133;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue