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